def test_run_apifile_modified(tmpdir): c = {'a': 'b', 'c': 'd', 'state': {'nodes': 0}} apifile = tmpdir.join('api_file.json') apifile.write_text(j_dump(c), 'utf-8') nodelist = tmpdir.join('nodelist.json') nodelist.write_text(j_dump({ 'version': 1, 'nodes': [ {'status': {'clients': 23, 'online': True}}, {'status': {'clients': 42, 'online': False}} ], 'updated_at': 'never' }), 'utf-8') side = tmpdir.join('a.json') car = tmpdir.join('c.yaml') assert tmpdir.listdir() == [apifile, nodelist] assert run([ str(apifile), '-n', str(nodelist), '-s', str(side), str(car) ]) is False assert sorted(tmpdir.listdir()) == sorted([side, apifile, car, nodelist]) assert j_load(side.read_text('utf-8')) == 'b' assert y_load(car.read_text('utf-8')) == 'd' c['state']['nodes'] = 1 assert j_load(apifile.read_text('utf-8')) == c assert tmpdir.remove() is None
def generate_feedback_template(self, exercise_number, target_path, printer): path = self._get_exercise_meta_path(exercise_number) if not self.has_exercise_meta(exercise_number): raise FileExistsError("The exercise meta data was not created") with open(path, 'r', encoding='utf-8') as fp: template_data = SimpleNamespace(**j_load(fp)) with open(os.path.join(target_path, "submission_meta.json"), 'r', encoding='utf-8') as fp: submission_data = SimpleNamespace(**j_load(fp)) lines = list() lines.append('┌' + '─' * 98 + '┐') lines.append(f'│{template_data.title:^98}│') lines.append('└' + '─' * 98 + '┘') lines.append(f'Handed in as: {submission_data.original_name}') lines.append('') if self.muesli_data.feedback.show_problems: if len(submission_data.problems) > 0: lines.append( "The following issues occured with the name of the file:") for problem in submission_data.problems: lines.append(" ■ " + problem) lines.append( "Please make sure to correct the issues for the next sheet." ) lines.append("") else: lines.append("Great, thanks for naming the file correctly.") lines.append("") for task_name, max_credits in template_data.max_credits: max_credits = f'[Max: {max_credits}]' lines.append(f'{task_name:<100}'[:-len(max_credits)] + max_credits) lines.append('─' * 100) lines.append(self.muesli_data.feedback.default_answer) lines.append("") lines.append("") feedback_path = os.path.join( target_path, f'{self.muesli_data.feedback.file_name}.txt') if os.path.exists(feedback_path): printer.warning( f"There is already a generated feedback file at {target_path}." f" Please remove it manually, if you want to recreate it.") else: with open(feedback_path, 'w', encoding='utf-8') as fp: for line in lines: print(line, file=fp)
def __init__(self): path = Path("/etc/labertasche/mail_credentials.json") if system().lower() == "windows": path = Path("mail_credentials.json") with path.open("r") as fp: self.credentials = j_load(fp)
def load_student_name_matches(self): path = p_join(self._meta_path, f'04_student_name_matches.json') result = dict() if os.path.exists(path): with open(path, 'r') as fp: result = j_load(fp) return result
def test_all_with(name, repeats=1000): no_profile = True with open(name, 'r') as in_file: obj = j_load(in_file) print('%s (%d)' % (name, in_file.tell())) gc.disable() for lib in TEST_LIBS: start = time() with profiled(lib.name(), no_profile=no_profile): for _ in range(repeats): lib.encode(obj) enc_time = time() - start gc.collect() encoded = lib.encode(obj) start = time() with profiled(lib.name(), no_profile=no_profile): for _ in range(repeats): lib.decode(encoded) dec_time = time() - start gc.collect() print('%20s (enc/dec): %.3f / %.3f' % (lib.name(), enc_time, dec_time)) gc.enable()
def load_subgroup_data(data_dir, group_headers, data_config, subgroup_data): variants = data_config.variants group_names = {group_id: getattr(data_config.group_names, group_id) for group_id in data_config.group_ids} x_range = parse_x(data_config.x) result = dict() for group_header in group_headers: group_data = getattr(subgroup_data.values, group_header) rows = list() with open(p_join(data_dir, group_data.file), 'r', encoding='utf-8') as fp: data = {e["name"]: e for e in j_load(fp)["benchmarks"]} for x in x_range: tmp = list() data_keys = set() for variant, group_id in product(variants, data_config.group_ids): kwargs = {"x": x, "variant": variant, "group_name": group_names[group_id]} data_key = group_data.key.format(**kwargs) if data_key not in data_keys: data_keys.add(data_key) tmp.append(data[data_key]["cpu_time"]) rows.append(tmp) result[group_header] = np.round(np.array(rows), 4) return result
def __init__(self, what: str): if system().lower() == "windows": path = Path("mail_credentials.json") else: path = Path("/etc/tw2hugo/mail_credentials.json") with path.open("r") as fp: credentials = j_load(fp) if not credentials['enable']: return message = MIMEText(what, _charset='utf8') message['Subject'] = "Tweet2Hugo alarm report" message['From'] = credentials['email-sendfrom'] message['To'] = credentials['email-sendto'] try: with SMTP_SSL(host=credentials['smtp-server'], port=credentials['smtp-port'], context=create_default_context()) as server: server.login(user=credentials['email-user'], password=credentials['email-password']) server.sendmail(to_addrs=credentials['email-sendto'], msg=message.as_string(), from_addr=credentials['email-sendfrom']) except SMTPHeloError as helo: print(f"SMTPHeloError: {helo}") except SMTPAuthenticationError as auth_error: print(f"Authentication Error: {auth_error}") except SMTPException as e: print(f"SMTPException: {e}")
def __call__(self, *args): exercise_number = int(args[0]) finished_folder = self._storage.get_finished_folder(exercise_number) meta_file_name = "meta.json" data = defaultdict(dict) for directory in os.listdir(finished_folder): with open(p_join(finished_folder, directory, meta_file_name), 'r', encoding="utf-8") as fp: meta = SimpleNamespace(**j_load(fp)) for muesli_id in meta.muesli_ids: student = self._storage.get_student_by_muesli_id(muesli_id) data[student.tutorial_id][muesli_id] = meta.credits_per_task for tutorial_id, student_data in data.items(): tutorial = self._storage.get_tutorial_by_id(tutorial_id) self.printer.inform( f"Uploading credits to {tutorial.time} for {len(student_data.keys()):>3d} students ... ", end='' ) exercise_id = self._muesli.get_exercise_id( tutorial_id, self._storage.muesli_data.exercise_prefix, exercise_number ) status, number_of_changes = self._muesli.upload_credits(tutorial_id, exercise_id, student_data) if status: self.printer.confirm("[Ok]", end="") self.printer.inform(f" Changed {number_of_changes:>3d} entries.") else: self.printer.error("[Err]") self.printer.error("Please check your connection state.")
def test_all_with(name, repeats=1000): no_profile = True with open(name, 'r') as in_file: obj = j_load(in_file) row_start = '"%s",%d' % (name, in_file.tell()) gc.disable() for lib in TEST_LIBS: start = time() with profiled(lib.name(), no_profile=no_profile): for _ in range(repeats): lib.encode(obj) enc_time = time() - start gc.collect() encoded = lib.encode(obj) start = time() with profiled(lib.name(), no_profile=no_profile): for _ in range(repeats): lib.decode(encoded) dec_time = time() - start gc.collect() print('%s,"%s",%.3f,%.3f' % (row_start, lib.name(), enc_time, dec_time)) gc.enable()
def load_tutorial_ids(self, mode='my'): path = p_join(self._meta_path, f'02_{mode}_ids.json') result = list(), "Missing" if os.path.exists(path): with open(path, 'r') as fp: result = j_load(fp), "Loaded" return result
def load_tutorial_data(self): path = p_join(self._meta_path, f'03_tutorials.json') result = dict(), "Missing" if os.path.exists(path): with open(path, 'r') as fp: result = {int(k): Tutorial.from_json(v) for k, v in j_load(fp).items()}, "Loaded" return result
def load_students(self, tutorial_id): directory = ensure_folder_exists(p_join(self._meta_path, "students")) path = p_join(directory, f'students_{tutorial_id}.json') result = list(), "Missing" if os.path.exists(path): with open(path, 'r') as fp: result = [Student.from_json(student) for student in j_load(fp)], "Loaded" return result
def load_my_name(self): result = None, 'Missing' path = p_join(self._meta_path, f'01_my_name.json') if os.path.exists(path): with open(path, 'r') as fp: result = j_load(fp), 'Loaded' return result
def _handle_end_of_audio(self, _, __): self.pipeline_test.set_state(Gst.State.NULL) self.btn_start.config(text="Start") if not self.audio_descr_fn: return keyword = self.keyword result = self.timestamps audio_file_descriptor_json = j_load(open(self.audio_descr_fn)) num_of_words = audio_file_descriptor_json["num-of-words"] if num_of_words <= 0: return if keyword not in audio_file_descriptor_json: messagebox.showwarning("KWS warning", "Keyword \"{0}\" was not found in the selected descriptor.\n" "Quality of KWS can't be measured".format(keyword)) return ##################################################### # num_of_truly_detected_keywords # # DR = ------------------------------- * 100 % # # num_of_real_keywords # ##################################################### ##################################################### # num_of_false_detected_keywords # # FA = ------------------------------------ * 100 % # # num_of_words - num_of_real_keywords # ##################################################### num_of_real_keywords = len(audio_file_descriptor_json[keyword]) real_keywords_list = audio_file_descriptor_json[keyword] truly_detected = [] false_detected = [] undetected = list(real_keywords_list) # a copy of real_keywords_list for i in range(0, len(result)): val = round(result[i]) try: undetected.index(val) undetected.remove(val) truly_detected.append(val) except ValueError: false_detected.append(val) # all necessary vars print(truly_detected, false_detected, undetected) num_of_truly_detected_keywords = len(truly_detected) num_of_false_detected_keywords = len(false_detected) DR = (float(num_of_truly_detected_keywords) / num_of_real_keywords) * 100 DR_str = '%.2f' % DR FA = (float(num_of_false_detected_keywords) / (num_of_words - num_of_real_keywords)) * 100 FA_str = '%.2f' % FA self.detection_rate_sv.set("{0} %".format(DR_str)) self.faulty_alarm_sv.set("{0} %".format(FA_str))
def load_next_submissions(self, next_exercise_number): next_exercise_unpacked_folder = Path(self._storage.get_preprocessed_folder(next_exercise_number)) all_next_submissions = {} for next_submission in next_exercise_unpacked_folder.iterdir(): next_meta = Path(next_submission / "submission_meta.json") if next_meta.is_file(): with open(next_meta, "r") as file: for muesli_id in j_load(file)["muesli_student_ids"]: all_next_submissions[muesli_id] = next_submission return all_next_submissions
def test_save_specs(self): """ Should save toy_specs into json file. """ specs = get_specs_lenet_toy() with TemporaryDirectory() as tmp_dir_name: result_saver.save_specs(tmp_dir_name, 'prefix', specs) result_file_path = os.path.join(tmp_dir_name, 'prefix-specs.json') with open(result_file_path, 'r') as result_file: self.assertEqual(asdict(specs), j_load(result_file))
def __call__(self, exercise_number): ex_folder = Path(self._storage.get_exercise_folder(exercise_number)) name_file = ex_folder / "names.json" zip_file_names = self.find_zip_files(exercise_number) self.printer.inform(f"Found {len(zip_file_names)} input files.") if name_file.is_file(): with open(name_file, "r") as file: names = j_load(file) problems = [ problem for prob_list in self.find_errors(names, zip_file_names) for problem in prob_list ] self.printer.warning(f"{len(names)} names were already parsed.") self.printer.inform("You have the following options:") self.printer.indent() self.printer.inform("a) Restart from scratch,") self.printer.inform( f"b) Resolve conflicts and missing/ignored files ({len(problems)})," ) self.printer.inform(f"c) Abort.") self.printer.outdent() while True: answer = self.printer.ask("Please choose an option (a/b/c):") if answer in "abc": if answer == "a": names = {} elif answer == "b": pass elif answer == "c": return break else: names = {} try: if len(names) == 0: for file in zip_file_names: names[file] = self.parse_names_from_file( file, exercise_number) self.fix_errors(names, exercise_number) except: if self.printer.yes_no( "An error occurred. Do you want to store the current state?" ): self.store_result(name_file, names) return self.store_result(name_file, names)
def __call__(self, *args): exercise_number, debug = self. \ _parse_arguments(args) if debug: self.printer.confirm("Running in debug mode.") assignment_file = p_join( self._storage.get_exercise_folder(exercise_number), "cross-assignments.json") assert not os.path.isfile( assignment_file), "You already sent cross-feedback tasks to people" ex_folder = Path(self._storage.get_exercise_folder(exercise_number)) name_file = ex_folder / "names.json" with open(name_file, "r") as file: names = j_load(file) raw_folder = Path(self._storage.get_raw_folder(exercise_number)) cross_folder = Path(self._storage.get_cross_folder(exercise_number)) if cross_folder.is_dir(): if len(list(cross_folder.iterdir())) > 0: raise ValueError(f"{cross_folder} exists and is not empty.") else: cross_folder.mkdir() # Collect all submission files and corresponding uploader submissions = [] for file_name, data in names.items(): file_path = raw_folder / file_name submissions.append((file_path, data["muesli_student_ids"])) # Find a permutation without self-assignment while True: new_order = np.random.permutation(len(submissions)) if np.all(new_order != np.arange(len(submissions))): break with open(assignment_file, "w") as file: data = [] for src_idx, tgt_idx in enumerate(new_order): src_file, src_students = submissions[src_idx] tgt_file, tgt_students = submissions[tgt_idx] shutil.copyfile(src_file, cross_folder / tgt_file.name) data.append({ "submission": src_file.name, "submission_by_muesli_student_ids": src_students, "assigned_to_muesli_student_ids": tgt_students, }) json_save(data, file)
def __call__(self, *args): exercise_number, debug = self._parse_arguments(args) if debug: self.printer.confirm("Running in debug mode.") finished_folder = Path(self._storage.get_finished_folder(exercise_number)) feedback_file_name = f"{self._storage.muesli_data.feedback.file_name}.txt" meta_file_name = "meta.json" with EMailSender(self._storage.email_account, self._storage.my_name) as sender: for directory in finished_folder.iterdir(): if not (directory / meta_file_name).is_file(): self.printer.inform(f"Skipping {directory.name}.") continue students = list() with open(directory / meta_file_name, 'r') as fp: meta = SimpleNamespace(**j_load(fp)) for muesli_id in meta.muesli_ids: try: student = self._storage.get_student_by_muesli_id(muesli_id) students.append(student) except ValueError: self.printer.error(f"Did not find student with id {muesli_id}, maybe he left the tutorial?") feedback_path = directory / feedback_file_name message = list() message.append("This feedback is for:") for student in students: message.append(f"• {student.muesli_name} ({student.muesli_mail})") message.append("") message.append("Tutor notes are in Feedback.txt, with explanations about where you did really well and where you did not.") message.append("") if len(list(directory.glob("Original and Comments/Cross by *"))) > 0: message.append("You also got feedback from another student group. Be sure to check it out.") message.append("") message.append(f"LG {self._storage.my_name_alias}") message = "\n".join(message) shutil.make_archive(directory / "Comments", "zip", directory, "Original and Comments") archive_zip = directory / "Comments.zip" student_names = ', '.join([student.muesli_name for student in students]) self.printer.inform(f"Sending feedback to {student_names} ... ", end='') try: sender.send_mail(students, message, f'[IFML-20] Feedback to {self._storage.muesli_data.exercise_prefix} {exercise_number}', [feedback_path, archive_zip], debug=debug) self.printer.confirm("[Ok]") except BaseException as e: self.printer.error(f"[Err] - {e}")
def __call__(self, exercise_number, debug_flag=False): preprocessed_folder = Path(self._storage.get_preprocessed_folder(exercise_number)) if debug_flag == "--debug": debug_flag = True elif debug_flag is not False: raise ValueError(f"Invalid argument {debug_flag!r}.") if not preprocessed_folder.is_dir(): self.printer.error(f"The data for exercise {exercise_number} was not preprocessed. Run workflow.unzip first.") return with EMailSender(self._storage.email_account, self._storage.my_name) as sender: for src_directory in preprocessed_folder.iterdir(): if src_directory.name.startswith("."): continue with open(src_directory / "submission_meta.json", "rb") as file: submission_info = j_load(file) new_line = '\n' problems = submission_info["problems"] if len(problems) > 0: problem_string = "Assigning the names was not easy; these issues occurred when parsing:" problem_string += '\n'.join("- " + problem for problem in problems) else: problem_string = "There were no issues parsing the file name. You are awesome!" students = [self._storage.get_student_by_muesli_id(muesli_student_id) for muesli_student_id in submission_info["muesli_student_ids"]] for student in students: message = f"""Dear {student.muesli_name}, you or a team mate uploaded {submission_info["original_name"]!r} to Moodle as a hand in to sheet {exercise_number}. We associate this hand in to the following students: {new_line.join('- ' + student.muesli_name for student in students)} {problem_string} Have an awesome day! {self._storage.my_name} """ self.printer.inform(f"Sending confirmation email to {student.moodle_name} ... ", end='') try: sender.send_mail([student], message, f'[Fundamentals of Machine Learning] Your submission to {self._storage.muesli_data.exercise_prefix} {exercise_number} was received', debug=debug_flag) self.printer.confirm("[Ok]") except BaseException as e: self.printer.error(f"[Err] - {e}") self.printer.inform("─" * 100)
def parse_param_file(filepath='./params.txt'): """ parse a params file which we assume is a dictionary :param filepath: str: path to params file :return: dictionary of paramters """ # maybe use json loads if you end up writing parameter files non-manually logging.debug('parsing params file') with open(filepath, 'r') as f: arguments = j_load(f) f.close() # TODO: add some checks to user passed data return arguments
def load_struct(content, fallback=None, as_yaml=False,): ''' Contextmanager to unpickle either *json* or *yaml* from a string :param content: string to unpickle :param fallback: data to return in case of unpickle failure :param as_yaml: read as *yaml* instead of *json* :yield: unpickled ``content`` ''' try: yield ( y_load(content) if as_yaml else j_load(content) ) if isinstance(content, str) else fallback except (ValueError, ScannerError, ParserError): yield fallback
def __call__(self, *args): exercise_number, debug = self._parse_arguments(args) if debug: self.printer.confirm("Running in debug mode.") finished_folder = self._storage.get_finished_folder(exercise_number) feedback_file_name = f"{self._storage.muesli_data.feedback.file_name}.txt" meta_file_name = "meta.json" with EMailSender(self._storage.email_account, self._storage.my_name) as sender: for directory in os.listdir(finished_folder): students = list() with open(p_join(finished_folder, directory, meta_file_name), 'r', encoding="utf-8") as fp: meta = SimpleNamespace(**j_load(fp)) for muesli_id in meta.muesli_ids: try: student = self._storage.get_student_by_muesli_id(muesli_id) students.append(student) except ValueError: self.printer.error(f"Did not find student with id {muesli_id}, maybe he left the tutorial?") feedback_path = p_join(finished_folder, directory, feedback_file_name) message = list() message.append("Dieses Feedback ist für:") for student in students: message.append(f"• {student.muesli_name} ({student.muesli_mail})") message.append("") message.append("Das Feedback befindet sich im Anhang.") message.append("") message.append(f"LG {self._storage.my_name_alias}") message = "\n".join(message) student_names = ', '.join([student.muesli_name for student in students]) self.printer.inform(f"Sending feedback to {student_names} ... ", end='') try: sender.send_feedback( students, message, feedback_path, self._storage.muesli_data.exercise_prefix, exercise_number, debug=debug ) self.printer.confirm("[Ok]") except BaseException as e: self.printer.error(f"[Err] - {e}")
def load_config(name): logger.debug("Reading config file: %s", name) from openmtc_server.configuration import MainConfiguration, SimpleOption from openmtc_cse.configuration import OneM2MConfiguration MainConfiguration.__options__["onem2m"] = SimpleOption(OneM2MConfiguration) try: with open(name) as f: from json import load as j_load config = j_load(f) config = MainConfiguration(config) except Exception as e: raise ConfigurationError("Failed to load config file %s: %s" % (name, e)) return config
def __init__(self): self.path = str() self.credentials = str() if system().lower() == "windows": self.path = Path("twitter.json") else: self.path = Path("/etc/tw2hugo/twitter.json") try: with self.path.open('r') as fp: self.credentials = j_load(fp) except FileNotFoundError: mail("Could not find bearer token file! Script was discontinued.") exit(1)
def __call__(self, exercise_number, next_exercise_number=None): if next_exercise_number is None: self.printer.warning("You are omitting loading the feedback from the next submission") if not self.printer.yes_no("Continue?"): return preprocessed_folder = Path(self._storage.get_preprocessed_folder(exercise_number)) working_folder = Path(self._storage.get_working_folder(exercise_number)) if not preprocessed_folder.is_dir(): self.printer.error(f"The data for exercise {exercise_number} was not preprocessed. Run workflow.unzip first.") return can_generate_feedback = self.load_muesli_data(exercise_number) if next_exercise_number is not None: all_next_submissions = self.load_next_submissions(next_exercise_number) cross_assignments = self.load_cross_assignments(exercise_number) else: all_next_submissions = {} cross_assignments = [] my_student_muesli_ids = [student.muesli_student_id for student in self._storage.my_students] for src_directory in preprocessed_folder.iterdir(): if src_directory.name.startswith("."): continue with open(src_directory / "submission_meta.json", "rb") as file: submission_info = j_load(file) submission_muesli_ids = submission_info["muesli_student_ids"] any_own_student_detected = any(muesli_id in my_student_muesli_ids for muesli_id in submission_muesli_ids) if any_own_student_detected: not_my_students = [self._storage.get_student_by_muesli_id(muesli_id) for muesli_id in submission_muesli_ids if muesli_id not in my_student_muesli_ids] if len(not_my_students) > 0: self.printer.warning(f"There are students among {src_directory.name} who do not belong to your group: {', '.join([student.muesli_name for student in not_my_students])}.") if not self.printer.yes_no("Please talk to the head tutor. Continue anyway?", default="n"): return target_directory = working_folder / src_directory.name if not target_directory.is_dir(): shutil.copytree(src_directory, target_directory) if can_generate_feedback and target_directory.is_dir(): self._storage.generate_feedback_template(exercise_number, target_directory, self.printer) self.copy_own_feedback(submission_muesli_ids, all_next_submissions, target_directory) self.copy_cross_feedback(cross_assignments, submission_muesli_ids, all_next_submissions, target_directory)
def load_exchanged_students(self, mode): if mode == 'imported': file_name = "imported_students.json" elif mode == 'exported': file_name = "exported_students.json" else: raise ValueError(f"Unknown mode '{mode}' (storage.py: load_exchanged_students)") directory = ensure_folder_exists(p_join(self._meta_path, "students")) path = p_join(directory, file_name) result = list() if os.path.exists(path): with open(path, 'r') as fp: result = j_load(fp) return result
def load_presented_scores(self): directory = ensure_folder_exists(p_join(self._meta_path, "students")) path = p_join(directory, "presented_information.json") result = dict(), "Missing" if os.path.exists(path): with open(path, 'r') as fp: data = j_load(fp) presented_scores = defaultdict(dict) for outer_key, outer_value in data.items(): for inner_key, inner_value in outer_value.items(): presented_scores[int(outer_key)][int(inner_key)] = inner_value presented_scores = dict(presented_scores) result = presented_scores, "Loaded" return result
def load_cross_assignments(self, exercise_number): assignment_file = Path(self._storage.get_exercise_folder(exercise_number)) / "cross-assignments.json" assignments = [] if not assignment_file.is_file(): if self.printer.yes_no("cross-assignments.json was not found. Do you want to continue anyway?", None): return assignments else: raise NotImplementedError("Don't worry about this error") with open(assignment_file, "r") as file: data = j_load(file) for assignment in data: assignments.append(( assignment["submission_by_muesli_student_id"], assignment["assigned_to_muesli_student_id"] )) return assignments
def load_struct( content, fallback=None, as_yaml=False, ): ''' Contextmanager to unpickle either *json* or *yaml* from a string :param content: string to unpickle :param fallback: data to return in case of unpickle failure :param as_yaml: read as *yaml* instead of *json* :yield: unpickled ``content`` ''' try: yield (y_load(content) if as_yaml else j_load(content)) if isinstance( content, str) else fallback except (ValueError, ScannerError, ParserError): yield fallback
def __call__(self, *args): exercise_number, debug = self. \ _parse_arguments(args) if debug: self.printer.confirm("Running in debug mode.") raw_folder = self._storage.get_raw_folder(exercise_number) assignment_file = p_join(self._storage.get_exercise_folder(exercise_number), "cross-assignments.json") assert not os.path.isfile(assignment_file), "You already sent cross-feedback tasks to people" # Collect all submission files and corresponding uploader submissions = [] with open(p_join(raw_folder, "meta.json")) as file: submission_list = j_load(file) for submission in submission_list: sub_info = SimpleNamespace(**submission) student = self._storage.get_student_by_moodle_id(sub_info.moodle_student_id) submissions.append((student, sub_info.file_name)) # Find a permutation without self-assignment while True: new_order = np.random.permutation(len(submissions)) if np.all(new_order != np.arange(len(submissions))): break with open(assignment_file, "w") as file: data = [] for submission_idx, (assigned_to_student, _) in zip(new_order, submissions): creator_student, assigned_file = submissions[submission_idx] data.append({ "submission": assigned_file, "submission_by_muesli_student_id": creator_student.muesli_student_id, "assigned_to_muesli_student_id": assigned_to_student.muesli_student_id, }) json_save(data, file) with EMailSender(self._storage.email_account, self._storage.my_name) as sender: for submission_idx, (student, _) in zip(new_order, submissions): creator_student, assigned_file = submissions[submission_idx] message = f"""Dear {student.moodle_name}, please provide cross-feedback to the appended submission by another student group. For instructions, check the current Exercise Sheet. Remember that you have to give cross-feedback at least four times over the semester. Have an awesome day! {self._storage.my_name} """ self.printer.inform(f"Sending cross-feedback task to {student.moodle_name} ... ", end='') tmp_path = p_join(self._storage.get_exercise_folder(exercise_number), "cross-feedback-task.zip") try: assigned_path = p_join(raw_folder, assigned_file) shutil.copy(assigned_path, tmp_path) sender.send_mail([student], message, f'[Fundamentals of Machine Learning] Your Cross-Feedback Task {self._storage.muesli_data.exercise_prefix} {exercise_number}', tmp_path, debug=debug) self.printer.confirm("[Ok]") except BaseException as e: self.printer.error(f"[Err] - {e}") finally: os.unlink(tmp_path)
def test_load_struct_json(): for tj in ['""', '"a"', '{}', '{"a": "b"}']: with load_struct(tj, as_yaml=False) as t: assert t == j_load(tj)
def read_json(filename): input_file = open(filename) json_array = j_load(input_file) return json_array
# 群聊记录地址 record_path = os.path.join(works_dir, 'record.txt') # excel输入输出地址 raw_excel = os.path.join(works_dir, 'record.xlsx') excel_out = os.path.join(works_dir, 'train.xlsx') excel_sort = os.path.join(works_dir, 'sort_record.xlsx') tab_split_path = os.path.join(works_dir, 'tab_split.txt') tab_split_out_path = os.path.join(works_dir, 'tab_split.xlsx') sign_tab_split_path = os.path.join(works_dir, 'sign_tab_split.txt') sign_tab_split_out_path = os.path.join(works_dir, 'sign_tab_split.xlsx') # QQ号码后8位作为区分 with open(split_path, 'r', encoding='UTF-8') as f: tail = j_load(f) print(tail) # 获取字典键值 key_list = [] for key, val in tail.items(): key_list.append(key) mode = '0' # 模式1:将txt文本读取为excel # 模式2:将excel中标记的元素提取 # 模式3:将对话转换 print('Version: 0.0.3 Alpha') print('模式1:将原始QQ导出的数据转换为excel表格') print('模式2:将标记好的excel表格进行筛选') print('模式3:将筛选后的表格转换为训练数据')