from pathlib import Path
import json
import re
import requests
import time
import os
dictionary_filename = 'efremova.txt'
dictionary_forms_filename = 'odict.csv'
json_filename = 'data.json'
def if_exist_dictionary(func):
def wrapper(*original_args, **original_kwargs):
file = Path(dictionary_filename)
if not file.is_file():
print('Файл {} не существует. Программа не может быть выполнена'.format(dictionary_filename))
return
func(*original_args, **original_kwargs)
return wrapper
def if_exist_json(func):
def wrapper(*original_args, **original_kwargs):
file = Path(json_filename)
if not file.is_file():
print('Файл {} не существует. Его нужно сгенерировать первоначально'.format(json_filename))
return
func(*original_args, **original_kwargs)
return wrapper
def if_exist_dictionary_forms(func):
def wrapper(*original_args, **original_kwargs):
file = Path(dictionary_forms_filename)
if not file.is_file():
print('Файл {} не существует. Функция не может быть выполнена'.format(dictionary_filename))
return
func(*original_args, **original_kwargs)
return wrapper
def function_execution_time(func):
def wrapper(*original_args, **original_kwargs):
start = time.time()
func(*original_args, **original_kwargs)
end = time.time()
print('Время выполнения функции: {}\n'.format(time.strftime('%H:%M:%S', time.gmtime(end - start))))
return wrapper
def index_of(string, substring):
try:
index = string.index(substring)
except ValueError:
index = -1
return index
def save_json(dictionary):
file = Path(json_filename)
action = 'обновлен' if file.is_file() else 'создан'
with open(json_filename, 'w', encoding='utf8') as outfile:
json.dump(dictionary, outfile, ensure_ascii=False, indent=4)
print('Файл {} {}'.format(json_filename, action))
def read_json():
file = Path(json_filename)
with open(file, encoding='utf8') as f:
dictionary = json.loads(f.read())
print('Файл {} открыт'.format(json_filename))
return dictionary
@function_execution_time
def remove_all_temporary_files():
def remove(filename):
if Path(json_filename).is_file():
os.remove(json_filename)
print('Файл {} удален'.format(json_filename))
else:
print('Файл {} не существует'.format(json_filename))
remove(json_filename)
print('Временных файлов больше нет')
@function_execution_time
@if_exist_dictionary
def generated_json():
file = Path(dictionary_filename)
with open(file, encoding='utf8') as f:
lines = f.read().splitlines()
dictionary = {}
for line in lines:
word = line.split(' ', 1)[0]
definition = line.split(' ', 1)[1]
if not bool(re.match(r'(ж|м|ср|мн)\.(.*)$', definition) or re.match(r'(1\.|I) (ж|м|ср|мн)\.(.*)$', definition)):
continue
dictionary[word] = {'definition': definition}
if word[-2:] in ['ая', 'ее', 'ие', 'ий', 'ое', 'ой', 'ые', 'ый', 'ье', 'ьи', 'ья', 'яя']:
dictionary[word]['answerIsProbablyNotNoun'] = 'null'
if bool(re.match(r'(мн)\.(.*)$', definition) or re.match(r'(1\.|I) (мн)\.(.*)$', definition)):
dictionary[word]['answerNeedToIncludePlural'] = 'null'
save_json(dictionary)
@function_execution_time
@if_exist_json
def statistics():
dictionary = read_json()
count = 0
count_check = 0
count_need_check = 0
count_need_check_404 = 0
count_need_check_noun = 0
count_need_check_not_noun = 0
count_plural_check = 0
count_plural_need_check = 0
count_plural_check_need_include = 0
count_plural_check_include = 0
count_plural_check_exclude = 0
count_with_capital_letter = 0
for word, entry in dictionary.items():
count += 1
if 'answerIsProbablyNotNoun' in entry:
count_check += 1
if entry['answerIsProbablyNotNoun'] == 'null':
count_need_check += 1
if entry['answerIsProbablyNotNoun'] not in ['null', 'noun', 'not noun']:
count_need_check_404 += 1
if entry['answerIsProbablyNotNoun'] == 'noun':
count_need_check_noun += 1
if entry['answerIsProbablyNotNoun'] == 'not noun':
count_need_check_not_noun += 1
if 'answerNeedToIncludePlural' in entry:
count_plural_check += 1
if entry['answerNeedToIncludePlural'] == 'null':
count_plural_need_check += 1
if entry['answerNeedToIncludePlural'] == 'include':
count_plural_check_include += 1
if entry['answerNeedToIncludePlural'] == 'need include':
count_plural_check_need_include += 1
if entry['answerNeedToIncludePlural'] == 'exclude':
count_plural_check_exclude += 1
if word != word.lower():
count_with_capital_letter += 1
print('Всего существительных по Ефремовой: {}'.format(count))
print('Подозрительные (возможно не сущ.):')
print('\tвсего: {}'.format(count_check))
print('\tне проверенные на сайтах: {}'.format(count_need_check))
print('\tпроверено: {}'.format(count_check - count_need_check))
print('\tиз них с ошибкой 404 и др.: {}'.format(count_need_check_404))
print('\tопределено как сущ.: {}'.format(count_need_check_noun))
print('\tопределено как не сущ.: {}'.format(count_need_check_not_noun))
print('Слова во множественном числе по Ефремовой:')
print('\tвсего: {}'.format(count_plural_check))
print('\tнужно проверить: {}'.format(count_plural_need_check))
print('\tпроверено: {}'.format(count_plural_check - count_plural_need_check))
print('\tрекомендуется включить: {}'.format(count_plural_check_need_include))
print('\tвключаем: {}'.format(count_plural_check_include))
print('\tисключаем: {}'.format(count_plural_check_exclude))
print('Слова с большой буквы по Ефремовой:')
print('\tвсего: {}'.format(count_with_capital_letter))
@function_execution_time
@if_exist_json
def print_list_of_words(key, answer, invert=False):
def print_word():
print(word)
print('{} = {}'.format(key, entry[key]))
print('-------------------------')
dictionary = read_json()
count = 0
for word, entry in dictionary.items():
if key in entry:
if not invert:
if entry[key] in answer:
print_word()
count += 1
else:
if entry[key] not in answer:
print_word()
count += 1
print('Слов: {}'.format(count))
@if_exist_json
def print_list_of_words_capital():
dictionary = read_json()
count = 0
for word, entry in dictionary.items():
if word != word.lower():
print(word)
count += 1
print('Слов: {}'.format(count))
def check_word_in_wiktionary(word, html):
answer = None
if 'title="существительное">Существительное' in html:
answer = 'noun'
if 'Существительное.' in html:
answer = 'noun'
if 'title="выступает в роли существительного">субстантивир.' in html:
answer = 'noun'
if 'Существительное' in html and 'Прилагательное' not in html:
answer = 'noun'
if 'Существительное, одушевлённое, тип склонения по ' in html:
answer = 'noun'
if 'title="прилагательное">Прилагательное' in html:
answer = 'not noun'
if 'title="причастие">Причастие' in html:
answer = 'not noun'
if 'title="причастие">причастие' in html:
answer = 'not noun'
if 'title="наречие">Наречие' in html:
answer = 'not noun'
if 'title="деепричастие">деепричастие' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Прилагательное' in html:
answer = 'not noun'
if 'Существительное' not in html and 'прилагательного' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Местоименное прилагательное' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Притяжательное местоимение' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Притяжательное прилагательное' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Числительное' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Порядковое числительное' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Местоимение' in html:
answer = 'not noun'
if 'Существительное' not in html and 'Указательное местоимение' in html:
answer = 'not noun'
return answer
def check_word_in_academic(word, html):
answer = None
regexp = r'<\/strong> — сущ\.(.*?)<\/p>\n
' \
r'Словарь синонимов<\/a><\/p>'
if re.search(re.escape(word) + regexp, html, re.S):
answer = 'noun'
return answer
def check_word_in_goldlit(word, html):
answer = None
if 'Морфологический разбор слова: {}'.format(word) not in html:
return '404'
if 'Часть речи: прилагательное
' in html:
answer = 'not noun'
if 'Часть речи: местоимение-существительное
' in html:
answer = 'not noun'
if 'Часть речи: числительное' in html:
answer = 'not noun'
if 'Часть речи: наречие' in html:
answer = 'not noun'
if 'Часть речи: деепричастие' in html:
answer = 'not noun'
if 'Часть речи: причастие' in html:
answer = 'not noun'
if 'Часть речи: порядковое числительное' in html:
answer = 'not noun'
if 'Часть речи: существительное
' in html:
answer = 'noun'
return answer
def check_word_in_morfologija(word, html):
answer = None
if 'Часть речи: прилагательное' in html:
answer = 'not noun'
if 'Часть речи: наречие' in html:
answer = 'not noun'
if 'Часть речи: местоимение' in html:
answer = 'not noun'
if 'Часть речи: наречие' in html:
answer = 'not noun'
if 'Часть речи: деепричастие' in html:
answer = 'not noun'
if 'Часть речи: поряд. числительное' in html:
answer = 'not noun'
if 'Часть речи: местоим. прил.' in html:
answer = 'not noun'
if 'Часть речи: существительное' in html:
answer = 'noun'
return answer
def check_word_in_site(word, url, function_check_html):
answer = None
response = requests.get(url + word.lower())
if response.status_code == 200:
answer_from_html = function_check_html(word, response.text)
if answer_from_html is not None:
answer = answer_from_html
else:
answer = str(response.status_code)
print('word = {}'.format(word))
print('answer = {}'.format(answer))
print('-------------------------')
return answer
@function_execution_time
@if_exist_json
def check_words_on_site(url, function_check_html):
dictionary = read_json()
i = 0
for word, entry in dictionary.items():
if 'answerIsProbablyNotNoun' in entry and entry['answerIsProbablyNotNoun'] not in ['noun', 'not noun']:
try:
answer = check_word_in_site(word, url, function_check_html)
except requests.exceptions.ConnectionError:
print("Ошибка: ConnectionError")
time.sleep(1)
save_json(dictionary)
except requests.exceptions.Timeout:
print("Ошибка: Timeout")
time.sleep(10)
save_json(dictionary)
if answer is not None:
dictionary[word]['answerIsProbablyNotNoun'] = answer
i += 1
if i % 100 == 0:
save_json(dictionary)
save_json(dictionary)
print('Проверка слов на {} завершена'.format(url))
def check_plural_word_in_wiktionary(word, html):
answer = None
if '{} — Викисловарь'.format(word) in html:
answer = 'need include'
if 'формы ед. ч. не используются' in html:
answer = 'include'
else:
if '— Викисловарь'.format(word) in html:
answer = 'exclude'
return answer
def check_plural_word_in_goldlit(word, html):
answer = None
if 'Начальная форма: {}'.format(word.upper()) in html:
answer = 'include'
return answer
def check_plural_in_academic(word, html):
answer = None
regexp = r'<\/strong> — сущ\.(.*?)<\/p>\n
' \
r'Словарь синонимов<\/a><\/p>'
if re.search(re.escape(word) + regexp, html, re.S):
answer = 'include'
return answer
@function_execution_time
@if_exist_json
def check_plural_words_on_site(url, function_check_html):
dictionary = read_json()
i = 0
for word, entry in dictionary.items():
if 'answerNeedToIncludePlural' in entry and entry['answerNeedToIncludePlural'] not in ['exclude']:
try:
answer = check_word_in_site(word, url, function_check_html)
except requests.exceptions.ConnectionError:
print("Ошибка: ConnectionError")
time.sleep(1)
save_json(dictionary)
except requests.exceptions.Timeout:
print("Ошибка: Timeout")
time.sleep(10)
save_json(dictionary)
if answer in ['need include','include', 'exclude']:
dictionary[word]['answerNeedToIncludePlural'] = answer
i += 1
if i % 100 == 0:
save_json(dictionary)
save_json(dictionary)
print('Проверка слов на {} завершена'.format(url))
@function_execution_time
@if_exist_json
def define_words_as_nouns():
dictionary = read_json()
for word, entry in dictionary.items():
if 'answerIsProbablyNotNoun' in entry and entry['answerIsProbablyNotNoun'] not in ['noun', 'not noun']:
dictionary[word]['answerIsProbablyNotNoun'] = 'noun'
save_json(dictionary)
print('Все оставшиеся слова определены как сущестуительные')
statistics()
@function_execution_time
@if_exist_json
@if_exist_dictionary_forms
def check_words_in_plural():
file = Path(dictionary_forms_filename)
with open(file) as f:
dictionary_forms = f.read().splitlines()
print('Файл {} открыт'.format(dictionary_forms_filename))
dictionary = read_json()
for word, entry in dictionary.items():
if 'answerNeedToIncludePlural' in entry and entry['answerNeedToIncludePlural'] not in ['include', 'exclude']:
is_initial_form = False
is_as_form = False
index_initial_form = -1
index_as_form = -1
for index, line in enumerate(dictionary_forms):
if index_of(line, word + ',') == 0:
is_initial_form = True
if index_initial_form == -1:
index_initial_form = index
if index_of(line, ',' + word + ',') >= 0:
is_as_form = True
if index_initial_form != -1 and index_as_form == index_initial_form:
index_as_form = index
if index_as_form == -1:
index_as_form = index
if line.endswith(',' + word):
is_as_form = True
if index_initial_form != -1 and index_as_form == index_initial_form:
index_as_form = index
if index_as_form == -1:
index_as_form = index
answer = None
if is_initial_form:
answer = 'need include'
if not is_initial_form and is_as_form:
answer = 'exclude'
if is_initial_form and is_as_form and index_as_form != index_initial_form:
answer = 'exclude'
print(word)
if answer is not None:
print('answer = {}'.format(answer))
dictionary[word]['answerNeedToIncludePlural'] = answer
print('-------------------------')
save_json(dictionary)
print('Проверка слов во множественном числе завершена')
statistics()
@if_exist_dictionary
def main():
menu = [
{'text': 'Очистить временные файлы', 'function': remove_all_temporary_files},
{'text': 'Сгенерировать файл {}'.format(json_filename), 'function': generated_json},
{'text': 'Статистика', 'function': statistics},
{'text': 'Список непроверенных подозрительных слов', 'function': print_list_of_words,
'params': {'key': 'answerIsProbablyNotNoun', 'answer': ['null']}},
{'text': 'Список проверенных подозрительных слов с ошибкой 404 и др.', 'function': print_list_of_words,
'params': {'key': 'answerIsProbablyNotNoun', 'answer': ['null', 'noun', 'not noun'], 'invert': True}},
{'text': 'Список непроверенных слов во мн. числе', 'function': print_list_of_words,
'params': {'key': 'answerNeedToIncludePlural', 'answer': ['null']}},
{'text': 'Список рекомендуемых к включению слов во мн. числе', 'function': print_list_of_words,
'params': {'key': 'answerNeedToIncludePlural', 'answer': ['need include']}},
{'text': 'Список включаемых проверенных слов во мн. числе', 'function': print_list_of_words,
'params': {'key': 'answerNeedToIncludePlural', 'answer': ['include']}},
{'text': 'Список невключаемых проверенных слов во мн. числе', 'function': print_list_of_words,
'params': {'key': 'answerNeedToIncludePlural', 'answer': ['exclude']}},
{'text': 'Список слов с большой буквы', 'function': print_list_of_words_capital},
{'text': 'Проверить подозрительные слова на wiktionary.org', 'function': check_words_on_site,
'params': {'url': 'https://ru.wiktionary.org/wiki/', 'function_check_html': check_word_in_wiktionary}},
{'text': 'Проверить подозрительные слова на dic.academic.ru', 'function': check_words_on_site,
'params': {'url': 'https://dic.academic.ru/searchall.php?SWord=',
'function_check_html': check_word_in_academic}},
{'text': 'Проверить подозрительные слова на goldlit.ru', 'function': check_words_on_site,
'params': {'url': 'https://goldlit.ru/component/slog?words=', 'function_check_html': check_word_in_goldlit}},
{'text': 'Проверить подозрительные слова на morfologija.ru', 'function': check_words_on_site,
'params': {'url': 'http://www.morfologija.ru/словоформа/', 'function_check_html': check_word_in_morfologija}},
{'text': 'Оставшиеся непроверенные слова определить как существительные', 'function': define_words_as_nouns},
{'text': 'Проверить слова во мн. числе', 'function': check_words_in_plural},
{'text': 'Проверить слова во мн. числе на wiktionary.org', 'function': check_plural_words_on_site,
'params': {'url': 'https://ru.wiktionary.org/wiki/', 'function_check_html': check_plural_word_in_wiktionary}},
{'text': 'Проверить слова во мн. числе на dic.academic.ru', 'function': check_plural_words_on_site,
'params': {'url': 'https://dic.academic.ru/searchall.php?SWord=',
'function_check_html': check_plural_in_academic}},
{'text': 'Проверить слова во мн. числе на goldlit.ru', 'function': check_plural_words_on_site,
'params': {'url': 'https://goldlit.ru/component/slog?words=', 'function_check_html': check_plural_word_in_goldlit}},
]
while True:
for index, item in enumerate(menu):
print('{} - {}'.format(index + 1, item['text']))
try:
command = int(input('Введите номер команды (нажмите Enter для выхода): '))
except ValueError:
break
if command > len(menu) or command < 0:
break
if 'params' not in menu[command - 1]:
menu[command - 1]['function']()
else:
menu[command - 1]['function'](**menu[command - 1]['params'])
input("Нажмите Enter для продолжения...")
def test():
check_word_in_site('стуаввввввлья', 'https://goldlit.ru/component/slog?words=', check_plural_word_in_goldlit)
if __name__ == '__main__':
main()