# ----------------------------------------------------------------------------------------------------------------------
# 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()