# ---------------------------------------------------------------------------------------------------------------------- # Python-модуль для построения графиков на основе csv-файлов. # ---------------------------------------------------------------------------------------------------------------------- import matplotlib.pyplot as plt import csv import os plt.rcParams["figure.figsize"] = (7,5) def count_file_in_folder(path, str_in_file_name): """ Подсчитывает кол - во файлов в директории. :param path: Путь до директории, где мы проверяем кол - во файлов. :param str_in_file_name: Строка, которая должна содержаться в имени файла. :return: Возвращает кол - во таких файлов в директории. """ str_in_file_name, count_file = str(str_in_file_name), 0 for i in range(len(os.listdir(path))): if str_in_file_name in str(os.listdir(path)[i]): count_file += 1 return count_file + 1 def convert_date_to_time(list_date): """ Преобразовывает дату во время. :param list_date: Строка с датой прохождения теста. :return: Возвращает список списков ЧЧ.ММ.СС.МСМС. """ list_result = [] for date_tmp in list_date: if date_tmp == '__EMPTY__': list_result.append([date_tmp]) continue str_tmp = '' flag = False for char in date_tmp: if flag: if char.isdigit(): str_tmp += char else: str_tmp += '_&&_' elif char == 'T': flag = True list_result.append(str_tmp.split('_&&_')[:-1]) print(list_result, file=open('list_result.txt', 'a')) if not list_result: return None else: return list_result def arithmetic_sum(path, question, response): """ Вычисляет общее время ответа на вопрос. :param path: Путь до файла. :param question: Ключ вопроса. :param response: Ключ ответа. :return: Возвращает общее время ответа на вопрос. """ with open(path) as f: list_keys = str(f.readline()).replace('"', '').split(',') list_keys = list_keys[1:] with open(path) as f: reader = csv.DictReader(f) dict_reader_tmp = {} for i in range(len(list_keys)): dict_reader_tmp[list_keys[i]] = [] for row in reader: for i in range(len(list_keys)): if question in list_keys[i] or response in list_keys[i]: if row[list_keys[i]] == '': dict_reader_tmp[list_keys[i]].append('__EMPTY__') else: dict_reader_tmp[list_keys[i]].append(row[list_keys[i]]) dict_reader = {} dict_reader_cleared = {} for i in range(len(list_keys)): dict_reader[list_keys[i]] = [] for key in dict_reader.keys(): dict_reader[key] = convert_date_to_time(dict_reader_tmp[key]) list_keys.clear() for key in dict_reader.keys(): if dict_reader[key] is not None: list_keys.append(key) dict_reader_cleared[key] = dict_reader[key] dif = difference(dict_reader_cleared) # print('arithmetic_mean = ', sum(dif) / len(dif)) return sum(dif) def convert_str_to_int(list_from): """ Конвертирует список строк в список чисел. :param list_from: Принимает список строк. :return: Возвращает результирующий список. """ list_int_converted = [] for element in list_from: if element == '__EMPTY__': list_int_converted.append(element) continue list_int_converted.append(int(element)) return list_int_converted def sum_time(list_time): """ Сумма времени ответов на вопросы. :param list_time: Принимает список с данными по времени на каждый вопрос. :return: Возвращает сумму, в виде кортежа, времени ответов на вопросы и индексы где, была пустая строка. """ result = [] list_pop_index = [] for (offset, element) in enumerate(list_time): if '__EMPTY__' in element: list_pop_index.append(offset) result.append('__EMPTY__') continue else: result.append((element[0] * ((60 ** 2) * 1000)) + (element[1] * (60 * 1000)) + (element[2] * 1000) + element[3]) return result, list_pop_index def difference(dict_date): """ Находит разность времени начала и конца ответа на вопросы. :param dict_date: Принимает словарь времени начала и конца ответа на вопросы. :return: Возвращает разность времени начала и конца ответа на вопросы. """ list_result_question = [] list_result_response = [] for (offset, key) in enumerate(dict_date): if offset % 2 == 0: for i in range(len(dict_date[key])): list_result_question.append(convert_str_to_int(dict_date[key][i])) else: for i in range(len(dict_date[key])): list_result_response.append(convert_str_to_int(dict_date[key][i])) result_question_tmp = sum_time(list_result_question) result_response_tmp = sum_time(list_result_response) list_result_difference = [] for tuple_of_elements in zip(result_response_tmp[0], result_question_tmp[0]): if tuple_of_elements[0] == '__EMPTY__': continue elif tuple_of_elements[1] == '__EMPTY__': continue else: list_result_difference.append(tuple_of_elements[0] - tuple_of_elements[1]) return list_result_difference def graph(path_to_csv_file, type_test, len_test, write_result='off'): """ Строит график по запросу. :param path_to_csv_file: Путь до папки с csv-файлами. :param type_test: Тип теста. :param len_test: Длина теста. :param write_result: Нужно ли выводить процесс работы функции на экран(не график, а именно процесс работы.). :return: Ничего не возвращает. """ if write_result != 'on' and write_result != 'off': print('invalid arg!') return dict_result_tmp = {} for i in range(1, count_file_in_folder(path_to_csv_file, "csv")): list_result = [] for j in range(1, len_test + 1): if i == 1: dict_result_tmp['{}{}'.format(type_test, j)] = 0 question = '{}{}.firstQuestionDisplayTime'.format(type_test, j) response = '{}{}.firstResponseTime'.format(type_test, j) if write_result == 'on': print('{}.csv'.format(i), ' - ', '{}{}'.format(type_test, j), ' arithmetic_sum = ', arithmetic_sum(r'{}/{}.csv'.format(path_to_csv_file, i, type_test, j), question, response)) list_result.append(arithmetic_sum(r'{}/{}.csv'.format(path_to_csv_file, i, type_test, j) , question, response)) dict_result_tmp['{}{}'.format(type_test, j)] += list_result[j - 1] elif write_result == 'off': list_result.append(arithmetic_sum(r'{}/{}.csv'.format(path_to_csv_file, i, type_test, j) , question, response)) dict_result_tmp['{}{}'.format(type_test, j)] += list_result[j - 1] # print(dict_result_tmp) list_result = [] x = [] y = [] for key in dict_result_tmp: list_result.append(dict_result_tmp[key] / len_test) # print(list_result) for i in range(len_test): x.append(str(type_test) + str(i)) # print(x) y = list_result plt.xlabel('Номер вопроса') plt.ylabel('Время ответа на вопрос, мсек') plt.plot(x, y) def main(): """ Главная функция - точка входа. Она же управляет остальными. :return: Ничего не возвращает. """ graph('CSV_FILE', 'A', 12, write_result='on') if __name__ == "__main__": main()