diff --git a/app/main/checks/report_checks/literature_references.py b/app/main/checks/report_checks/literature_references.py index c0243d48..e02966cb 100644 --- a/app/main/checks/report_checks/literature_references.py +++ b/app/main/checks/report_checks/literature_references.py @@ -1,6 +1,7 @@ import re from .style_check_settings import StyleCheckSettings from ..base_check import BaseReportCriterion, answer +from collections import Counter class ReferencesToLiteratureCheck(BaseReportCriterion): @@ -12,6 +13,7 @@ def __init__(self, file_info, min_ref=1, max_ref=1000, headers_map=None): super().__init__(file_info) self.headers = [] self.literature_header = None + self.literature_reference_text = [] self.name_pattern = r'список[ \t]*(использованных|использованной|)[ \t]*(источников|литературы)' if headers_map: self.config = headers_map @@ -56,6 +58,8 @@ def check(self): if not number_of_sources: return answer(False, f'В Списке использованных источников не найдено ни одного источника.

Проверьте корректность использования нумированного списка.') + + duplicates = self.checking_duplicate_sources() references, ref_sequence = self.search_references(start_literature_par) all_numbers = set(range(1, number_of_sources + 1)) if len(references.symmetric_difference(all_numbers)) == 0: @@ -63,8 +67,8 @@ def check(self): return answer(False, f'Список источников оформлен верно, однако их количество ({number_of_sources}) не удовлетворяет необходимому критерию.
Количество источников должно быть не менее {self.min_ref}.') elif ref_sequence: result_str += f"Источники должны нумероваться в порядке упоминания в тексте. Неправильные последовательности: {'; '.join(num for num in ref_sequence)}" - return answer(False, result_str) - else: + return answer(False, result_str) + elif not duplicates: return answer(True, f"Пройдена!") elif len(references.difference(all_numbers)): if len(all_numbers.difference(references)) == 0: @@ -77,13 +81,23 @@ def check(self): else: all_numbers -= references result_str = f'Упомянуты не все источники из списка.
Список источников без упоминания: {", ".join(str(num) for num in sorted(all_numbers))}
Всего источников: {number_of_sources}

' + + if duplicates: + message = '' + for duplicate in duplicates: + message += f'
  • Источники с номерами: {duplicate[1]} ссылаются на один и тот же источник: {duplicate[0]};
  • \n' + result_str += (f'Повторяющиеся источники:' + f'') result_str += ''' Если возникли проблемы, попробуйте сделать следующее: ''' return answer(False, result_str) @@ -125,11 +139,29 @@ def add_references(self, k, prev_ref, array_of_references, ref_sequence): array_of_references.add(k) return prev_ref + def checking_duplicate_sources(self) -> list: + """Функция нахождения дубликатов в источниках""" + counter = Counter([text.lower() for text in self.literature_reference_text]) + + duplicates = [] + for text, count in counter.items(): + if count >= 2: + positions_duplicates = [i + 1 for i, text_in_ref in enumerate(self.literature_reference_text) if text == text_in_ref.lower()] + + if positions_duplicates: + duplicates.append(( + self.literature_reference_text[positions_duplicates[0]], + positions_duplicates + )) + + return duplicates + + def find_start_paragraph(self): start_index = 0 for i in range(len(self.file.paragraphs)): text_string = self.file.paragraphs[i].to_string().lower().split('\n')[1] - if re.fullmatch(f'{self.name_pattern}', text_string): + if re.fullmatch(f'{self.name_pattern}', text_string): start_index = i break return start_index @@ -143,6 +175,7 @@ def count_sources_vkr(self, header): break # if re.search(f"дата обращения", child["text"].lower()): literature_counter += 1 + self.literature_reference_text.append(child["text"]) return literature_counter def count_sources(self): @@ -166,6 +199,7 @@ def count_sources(self): for ind in range(first_string + 1, last_string): if re.match(f"{literature_counter + 1}.", one_page[ind]): literature_counter += 1 + self.literature_reference_text.append(one_page[ind]) return literature_counter def search_literature_start_pdf(self):