-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Lines_counter.py
139 lines (118 loc) · 9.03 KB
/
Lines_counter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
print('''
Python3-скрипт, считающий количество непустых
строк файлов, размещённых в дереве папок.
Автор: Платон Быкадоров (platon.work@gmail.com), 2017-2018.
Версия: V2.3.
Лицензия: GNU General Public License version 3.
Поддержать проект: https://money.yandex.ru/to/41001832285976
Простое руководство по установке среды разработки и запуску скриптов:
github.com/PlatonB/bioinformatic-python-scripts#Установка-среды-разработки
Скрипт генерирует JSON-файл такой структуры:
{
"in_all_files": [
61, #Общефайловое количество всех непустых строк.
59, #Общефайловое количество непустых строк с вычетом их повторов в пределах каждого текста.
57 #Общефайловое количество непустых строк с вычетом их повторов.
],
"in_each_file": {
"/home/platon/_0_Диссертация/Exp/os_walk_test_1": {
"REF_os_walk_test_stat.txt": [
27, #Количество всех непустых строк одного текста.
25 #Количество непустых строк одного текста с вычетом их повторов.
],
...
},
...
}
}
''')
import os, json
src_dir_path = input('Путь к исходной верхней папке: ')
trg_dir_path = input('\nПуть к папке для конечного JSON-файла: ')
num_of_headers = input('''\nКоличество не учитываемых строк
в начале каждого исходного текста
(игнорирование ввода ==> хэдеров/шапок в текстах нет)
[0(|<enter>)|1|2|...]: ''')
if num_of_headers == '':
num_of_headers = 0
else:
num_of_headers = int(num_of_headers)
#Словарь верхнего уровня, в котором размещены такие структуры:
#- список со значаниями суммарного количества строк текстов,
#рассчитываемых без вычета и с вычетом одинаковых элементов;
#- словарь, в котором будут накапливаться пути к родительским папкам,
#имена расположенных в них файлов и длины соответствующих текстов.
statistics = {'in_all_files': [], 'in_each_file': {}}
#Суммарные длины текстов без ликвидации межфайловых повторений
#строк вычисляются без создания отдельного конкатенированного массива.
#Для вычета межфайловых повторений приходится накапливать множество.
#Это может привести к переполнению оперативной памяти.
#Пишите в Issues, если знаете способ решения проблемы.
all_strs_quan, all_files_uniq_strs_quan, all_uniq_strs = 0, 0, set()
#Работа со списком, содержащим кортежи, в каждом из
#которых находится строковый путь к текущей родительской папке,
#список с названиями её подпапок и список с названиями её файлов.
#Список названий папок и/или файлов остаётся пустым, если
#в родительской папке чего-либо из перечисленного нет.
for parent_dir_path, dir_names, file_names in sorted(os.walk(src_dir_path)):
#Нас интересуют только те кортежи,
#в которых есть имена файлов.
if file_names != []:
#Словарь {имя файла: [количество всех его строк, строк без повторов], ...}.
files_n_stats = {}
#Перебор файлов текущей родительской папки.
for file_name in file_names:
with open(os.path.join(parent_dir_path, file_name)) as src_file_opened:
#Проверка исходного файла, представляет ли он собой plain text.
#Формирование списка из всех строк текста, кроме пустых.
try:
one_file_strs = [line.split('\n')[0] for line in src_file_opened if line != '\n'][num_of_headers:]
except UnicodeDecodeError:
continue
#Количество непустых строк одного текста.
one_file_strs_quan = len(one_file_strs)
#1) Непустые строки одного текста с удалёнными
#повторами и 2) количество этих строк.
one_file_uniq_strs = set(one_file_strs)
one_file_uniq_strs_quan = len(one_file_uniq_strs)
#Метрики текста привязывается к имени соответствующего файла.
files_n_stats[file_name] = [one_file_strs_quan, one_file_uniq_strs_quan]
#Подсчёт общефайлового количества строк c игнорированием
#1) только внутрифайловых повторов, 2) всех повторов.
all_files_uniq_strs_quan += one_file_uniq_strs_quan
all_strs_quan += one_file_strs_quan
#Накопление множества для дальнейшего
#рассчёта бесповторного количества всех строк.
all_uniq_strs |= one_file_uniq_strs
#В случае, когда файлы в папке есть, но они все -
#не plain text, условие if file_names != [] и блок
#try-except не помогут избежать создания пустого
#словаря (без пар "имя файла-количество строк").
#Эта ситуация ниже предусмотрена.
if files_n_stats != {}:
#Привязка словаря пофайловых показателей к родительской папке.
statistics['in_each_file'][parent_dir_path] = files_n_stats
#Пополнение словаря суммарных показателей.
statistics['in_all_files'].append(all_strs_quan)
statistics['in_all_files'].append(all_files_uniq_strs_quan)
statistics['in_all_files'].append(len(all_uniq_strs))
#Полученная структура прописывается в JSON-файл с правильной
#обработкой кириллицы, формированием отступов и сортировкой ключей.
trg_file_name = os.path.basename(src_dir_path) + '_stat' + '.json'
with open(os.path.join(trg_dir_path, trg_file_name), 'w', encoding='utf-8') as trg_file_opened:
json.dump(statistics, trg_file_opened, ensure_ascii=False, indent=4, sort_keys=True)
##Бонус: пример парсера получаемого этим скриптом JSON-файла.
##Извлекаем пофайловые значения количества
##непустых строк без вычета их повторов.
##Созраняем результаты в список.
'''
import json
path = '/home/platon/_0_Диссертация/03_Рез/09_chr14/Biased_1000G/Biased_1000G_stat.json'
data = json.load(open(path))
res = []
for folder_key in data['in_each_file']:
for file_key in data['in_each_file'][folder_key]:
res.append(data['in_each_file'][folder_key][file_key][0])
print(res)
#[18, 0, 18, 13, 12]
'''