def take_classlist_name_input() -> str: """ Prompts user for classlist name. Repeats until user provide valid classlist name. :return: str """ classlist_name = get_user_input( prompt='Please enter a name for the class: ', validation=lambda name: not input_is_essentially_blank(name) and not definitions.DATABASE.class_name_exists(clean_for_filename(name)), validation_error_msg=lambda name: None if input_is_essentially_blank( name) else 'A class with this name already exists.') return clean_for_filename(classlist_name)
def assemble_chart_data(): """ Collect data/user input for new chart. Get classname from user, load class data, take chart data from user. Return values for chart_data_dict assembly: class_name: str chart_name: str chart_filename: str student_scores: dict chart_params: dict :return: tuple(str, str, str, dict, dict) """ class_name = select_classlist() # TODO: warn for empty classlist class_data_dict = load_class_data(class_name) student_scores: dict = take_score_data(class_name, class_data_dict) chart_name = take_chart_name() chart_filename = clean_for_filename(chart_name) chart_params = set_chart_params() # chart options here or before score entry, setting chart params, min, max scores etc return class_name, chart_name, chart_filename, student_scores, chart_params
def take_student_avatar(new_class: NewClass, student_name: str) -> Optional[str]: """ Take user supplied avatar image file. Get avatar for student: Prompts user for path to avatar file. Copies avatar file to temp dir for class. :param new_class: NewClass class object :param student_name: str :return: str or None """ avatar_file = select_avatar_file_dialogue() if avatar_file is None: return None cleaned_student_name = clean_for_filename(student_name) target_avatar_filename = f'{cleaned_student_name}.png' # TODO: append hash to filename to prevent name collisions eg cleaned versions of 'a_b.jpg' and 'a b.jpg' will be identical. # TODO: process_student_avatar() # TODO: convert to png copy_file(avatar_file, new_class.temp_avatars_dir.joinpath(target_avatar_filename)) return target_avatar_filename
def test_clean_for_filename_unmocked(self): for test_case in self.test_cases: with self.subTest(i=self.test_cases[test_case]): test_input = self.test_cases[test_case][0] expected_output = self.test_cases[test_case][1] assert clean_for_filename(test_input) == expected_output
def assemble_chart_data(loaded_class: Class) -> Tuple[str, str, dict, dict]: """ Collect data/user input for new chart. Get classname from user, if not provided, load class data, take chart data from user. Return values for chart_data_dict assembly: loaded_class: Class chart_name: str chart_filename: str student_scores: dict chart_params: dict :param loaded_class: str = None :return: tuple(str, str, dict, dict) """ student_scores: dict = take_score_data(loaded_class) chart_name = take_chart_name() chart_filename = clean_for_filename(chart_name) chart_params = set_chart_params() # chart options here or before score entry, setting chart params, min, max scores etc return chart_name, chart_filename, student_scores, chart_params
def path_safe_name(self, class_name: str) -> None: """ Set path_safe_name: filename-safe class name string. :param class_name: str :return: None """ self._path_safe_name = clean_for_filename(class_name)
def test_clean_for_filename_mocking_call(self, monkeypatch, test_input, expected_return_value): """ Mock call to scrub_candidate_filename. Essentially an input .replace(' ', '_') operation, unless behaviour changes. """ def mocked_scrub_candidate_filename(test_string): assert test_string == test_input return test_input monkeypatch.setattr(UI_functions, 'scrub_candidate_filename', mocked_scrub_candidate_filename) assert clean_for_filename(test_input) == test_input.replace(' ', '_')
def test_clean_for_filename_mocking_call(self, mocked_scrub_candidate_filename): """ Mock call to scrub_candidate_filename. Essentially an input .replace(' ', '_') operation. """ for test_case in self.test_cases: with self.subTest(i=self.test_cases[test_case]): test_input = self.test_cases[test_case][0] expected_output = test_input.replace(' ', '_') # Have scrub_candidate_filename return input_string. mocked_scrub_candidate_filename.return_value = test_input assert clean_for_filename(test_input) == expected_output mocked_scrub_candidate_filename.assert_called_once_with( test_input) mocked_scrub_candidate_filename.reset_mock(return_value=True, side_effect=True)
def take_classlist_name_input(): """ Prompts user for classlist name. It repeats until user provide correct classlist name. :return: str """ while True: classlist_name = input('Please enter a name for the class: ') if input_is_essentially_blank(classlist_name): # blank input continue classlist_name = clean_for_filename(classlist_name) if classlist_exists(classlist_name): print('A class with this name already exists.') continue break return classlist_name
def take_student_avatar(class_name, student_name): """ Prompts user for path to avatar file. :param class_name: str :param student_name: str :return: str or None """ avatar_file = select_avatar_file_dialogue() if avatar_file is None: return None cleaned_student_name = clean_for_filename(student_name) target_avatar_filename = f'{cleaned_student_name}.png' # TODO: process_student_avatar() # TODO: convert to png copy_avatar_to_app_data(class_name, avatar_file, target_avatar_filename) return target_avatar_filename
def take_student_avatar(class_name, student_name): """ Prompts user for path to avatar file. :param class_name: str :param student_name: str :return: str or None """ avatar_file = select_avatar_file_dialogue() if avatar_file is None: return None cleaned_student_name = clean_for_filename(student_name) target_avatar_filename = f'{cleaned_student_name}.png' # TODO: append hash to filename to prevent name collisions eg cleaned versions of 'a_b.jpg' and 'a b.jpg' will be identical. # TODO: process_student_avatar() # TODO: convert to png copy_avatar_to_app_data(class_name, avatar_file, target_avatar_filename) return target_avatar_filename
def test_clean_for_filename_unmocked(self, test_input, expected_return_value): assert clean_for_filename(test_input) == expected_return_value