Code Mining. Могут ли аналитики читать код?

от автора

Привет, Хабр! На связи участник профессионального сообщества NTA Губин Никита.

Введение

Code mining — это процесс анализа и извлечения информации из исходного кода для получения полезных данных. Аналитики, имея базовые компетенции в разработке, могут использовать их как дополнительный источник информации для улучшения процессов. Инструмент, о котором я расскажу в посте, разделяет код на логические блоки, что позволит улучшить взаимодействие DS‑специалистов и аналитиков.

Аналитики и код

Почему же аналитикам трудно самостоятельно анализировать исходный код?

Выделим несколько причин:

  • Незнакомые средства, в виде расширенного поиска по составам репозиториев;

  • Непривычное разрозненное расположение информации, которая распределена по умозрительным и непонятным для аналитика признакам;

  • Возможное несоответствие документации с исходным кодом.

Решение

В качестве решения было разработано приложение, которое парсит все файлы проекта с кодом в один excel файл, поделенный на логические блоки:

Пример работы

Пример работы

Преимущество данного решения:

  • Привычный инструмент. Excel — один из основных инструментов аналитика;

  • Код проекта, состоящий из нескольких файлов, собирается в одном месте;

  • За счет структуры файла, у аналитика появляются широкие возможности по фильтрации, анализу и поиску необходимой информации.

Реализация

Код написан на Python и предназначен для разбора кода так же на Python.

В посте будут разобраны ключевые моменты. Полный код доступен по ссылке на Github.

Изначально, необходимо собрать файлы (.py), которые в дальнейшем будем обрабатывать:

#Метод выгрузки данных def folder(fold,pth,filenames):     if fold == True:         filenames = glob(os.path.join(pth, "*.py"))     elif fold == False:         for root, dirs, files in os.walk(pth):             files = [f for f in files if not f[0] == '.']             dirs[:] = [d for d in dirs if not d[0] == '.']             for file in files:                 if(file.endswith(".py")):                     filenames.append(os.path.join(root,file))     return filenames

Предусмотрено 2 варианта сбора:

  • Только из указанной папки;

  • Из указанной папки и всех подпапок (кроме скрытых). 

Задаем DataFrame со структурой будущего excel файла:

# Создаем DataFrame с соответствующими колонками col = ['Стратегия', 'Путь', 'Исходная функция', 'Номер строки фрагмента', 'Тип фрагмента', 'Фрагмент'] df = pd.DataFrame(columns=col) 

Построчно обрабатываем файлы:

for i in my_code:     counter += 1     # Обрабатываем строку     i = i.strip(' ')     # Проверка для записи исходной строки     if 'def ' not in i:         ish += i # Обрабатываем комментарии if i[0] == '#':     if per != '':         perem()     # Заполняем IF не в одну строку     if y == 1:          df.at[row_in_dataframe, 'Стратегия'] = strategy          df.at[row_in_dataframe, 'Путь'] = path          df.at[row_in_dataframe, 'Номер строки фрагмента'] = counter          df.at[row_in_dataframe, 'Тип фрагмента'] = 'Условие IF'          df.at[row_in_dataframe, 'Фрагмент'] = usl          row_in_dataframe += 1          usl = ''          y = 0     dfwrite('Комментарий')      # Обрабатываем пустые строки elif i.strip('\n') == '':      continue 

Python обладает четкой структурой, поэтому, каждая строка проверяется на условия:

# Обрабатываем переменные elif ('=' in i) and (('if ' or 'else' or 'elif ') not in i):       y = 0       p = 1       per += i       counterP=counter        elif (p == 1) and (('if ' or 'else' or 'elif ') not in i):            per += i  # Обрабатываем IF с условием в одну строку elif (('if ' or 'else' or 'elif ') in i) and (':' in i):       if per != '':            perem()       if ret != '':            reter()       dfwrite('Условие If')       p = 0

Но если каждую строку просто записывать в DataFrame, то в итоговом результате получим «кашу».

Элементы часто занимают более одной строки, поэтому в коде предусмотрены флаги, для записи однотипных данных в одну запись. Например, когда подряд объявляются несколько переменных:

Отобранные данные записываются в DataFrame:

#Обработка фрагментов def dfwrite(fragm):     global row_in_dataframe, strategy, path, counter, i, df     df.at[row_in_dataframe,'Стратегия']=strategy     df.at[row_in_dataframe,'Путь']=path     df.at[row_in_dataframe,'Номер строки фрагмента']=counter     df.at[row_in_dataframe,'Тип фрагмента']=fragm     df.at[row_in_dataframe,'Фрагмент']=i     row_in_dataframe+=1     pass

Полученный результат записываем в Excel или в csv:

#Параметры и формат сохранения def save(df,xl,pthEnd):     if xl == True:         df.to_excel(os.path.join(pthEnd, "CodeMine_Result.xlsx"))     elif xl == False:         df.to_csv(os.path.join(pthEnd, "CodeMine_Result.csv"), encoding="windows-1251", sep="~") 

Для удобства работы добавим пользовательский интерфейс:

if __name__ == "__main__":     root = Tk()     root.geometry('600x400')     var1 = BooleanVar()     var1.set(False)     var2 = BooleanVar()     var2.set(False)      lbl = Label(text="Задайте параметры")     lbl.pack()      frame1 = Frame(borderwidth=1, relief=SOLID)     path_label = Label(frame1,text="Введите путь")     path_label.pack(anchor=NW)      path_entry = Entry(frame1, width=50)     path_entry.pack(anchor=NW)      open_button = Button(frame1,text="Открыть проводник", command=open_dir1)     open_button.pack(anchor=NW)      frame1.pack(anchor=NW, fill=X, padx=5, pady=5 )
Интерфейс

Интерфейс

Путь до обрабатываемых папок выбираем через проводник:

def open_dir1():     global path_entry,filepath1     path_entry.delete(0, END)     filepath1 = filedialog.askdirectory()     path_entry.insert(0,filepath1)  

А после выполнения программы предлагаем открыть результат:

# Сохраняем полученный DataFrame save(df, xl, pthEnd) resultMess = askyesno(title="Разбор выполнен успешно", message="Открыть полученный файл?") if resultMess == True:      if xl == True:           os.startfile(os.path.join(pthEnd, "CodeMine_Result.xlsx"))      else:           os.startfile(os.path.join(pthEnd, "CodeMine_Result.csv")) 
Сообщение после обработки

Сообщение после обработки

Давайте рассмотрим применение программы на примере:

Пример разбираемого кода

Пример разбираемого кода

Результатом разбора данного фрагмента будет excel файл:

Результат разбора

Результат разбора

На рисунке выше можно увидеть, какие переменные используются при работе и как они преобразовываются. А за счет фильтров можно отобрать только необходимую в данный момент информацию:

Фильтр по переменной Age

Фильтр по переменной Age

Вывод

Данная программа позволила привлечь к проверке исходного кода специалистов, ранее не сталкивающихся с подобными задачами. Полученная обратная связь была позитивной и, сейчас, система проходит активную стадию тестирования.

Очевидно, что это не конечный продукт и на основе обратной связи будут дорабатываться и внедряться различные методы визуализации и обработки данных. Например, на основе графов.

Но уже сейчас, можно дать ответ на вопрос из темы поста. Да, аналитики могут читать код. И основа, заложенная в тему данного поста, является тому подтверждением.


ссылка на оригинал статьи https://habr.com/ru/articles/795531/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *