+ 3.5_08
This commit is contained in:
parent
233a3e8134
commit
3922323b1b
166
mod_oop/3.5_08_morph.py
Normal file
166
mod_oop/3.5_08_morph.py
Normal file
@ -0,0 +1,166 @@
|
||||
"""
|
||||
https://stepik.org/lesson/701990/step/8?unit=702091
|
||||
|
||||
Ваша задача написать программу поиска слова в строке. Задача усложняется тем, что слово должно определяться в разных его формах. Например, слово:
|
||||
программирование
|
||||
может иметь следующие формы:
|
||||
программирование, программированию, программированием, программировании, программирования, программированиям, программированиями, программированиях
|
||||
|
||||
Для решения этой задачи необходимо объявить класс Morph (морфология), объекты которого создаются командой:
|
||||
mw = Morph(word1, word2, ..., wordN)
|
||||
где word1, word2, ..., wordN - возможные формы слова.
|
||||
|
||||
В классе Morph реализовать методы:
|
||||
add_word(self, word) - добавление нового слова (если его нет в списке слов объекта класса Morph);
|
||||
get_words(self) - получение кортежа форм слов.
|
||||
|
||||
Также с объектами класса Morph должны выполняться следующие операторы сравнения:
|
||||
mw1 == "word" # True, если объект mv1 содержит слово "word" (без учета регистра)
|
||||
mw1 != "word" # True, если объект mv1 не содержит слово "word" (без учета регистра)
|
||||
И аналогичная пара сравнений:
|
||||
"word" == mw1
|
||||
"word" != mw1
|
||||
|
||||
После создания класса Morph, формируется список dict_words из объектов этого класса, для следующих слов с их словоформами:
|
||||
- связь, связи, связью, связей, связям, связями, связях
|
||||
- формула, формулы, формуле, формулу, формулой, формул, формулам, формулами, формулах
|
||||
- вектор, вектора, вектору, вектором, векторе, векторы, векторов, векторам, векторами, векторах
|
||||
- эффект, эффекта, эффекту, эффектом, эффекте, эффекты, эффектов, эффектам, эффектами, эффектах
|
||||
- день, дня, дню, днем, дне, дни, дням, днями, днях
|
||||
|
||||
Затем, прочитайте строку из входного потока командой:
|
||||
text = input()
|
||||
Найдите все вхождения слов из списка dict_words (используя операторы сравнения) в строке text (без учета регистра, знаков пунктуаций и их словоформы). Выведите на экран полученное число.
|
||||
"""
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
sys.stdin.reconfigure(encoding="utf-8")
|
||||
|
||||
|
||||
def run_test(request, expected, num=0, count=0):
|
||||
test_id = "" if num == 0 else f" #{num}" + (f"of {count}" if count else "")
|
||||
|
||||
p = subprocess.run(
|
||||
[sys.executable, __file__],
|
||||
input=f"{request}\n",
|
||||
encoding="utf-8",
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
if p.stderr:
|
||||
print("StdErr:\n", p.stderr, file=sys.stderr)
|
||||
p.check_returncode()
|
||||
|
||||
answer = (p.stderr + p.stdout).strip()
|
||||
assert (
|
||||
answer == expected
|
||||
), f"""\nFailed test{test_id}. Wrong answer
|
||||
|
||||
This is a sample test from the problem statement!
|
||||
|
||||
Test input:
|
||||
{request}
|
||||
|
||||
Correct output:
|
||||
{expected}
|
||||
|
||||
|
||||
Your code output:
|
||||
{answer}
|
||||
"""
|
||||
|
||||
|
||||
def stdin_tests():
|
||||
tests = [
|
||||
("Мы будем устанавливать связь завтра днем.", "2"),
|
||||
("Завтра после полудня мы установим контакт.", "0"),
|
||||
("Напишите формулу L1-нормы вектора.", "2"),
|
||||
("Ф:о@рм-у-л.а за формулой, д.е.н.ь за днем", "4"),
|
||||
]
|
||||
for i, test in enumerate(tests):
|
||||
run_test(*test, i, len(tests))
|
||||
|
||||
|
||||
if sys.argv[-1] == "test":
|
||||
stdin_tests()
|
||||
exit()
|
||||
# ---------
|
||||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class Morph:
|
||||
def __init__(self, *words):
|
||||
self.words = set(map(str.lower, words))
|
||||
# тесты просят сохранять порядок и дубликаты для get_words
|
||||
# но только для исходных данных
|
||||
# немножко возражаю, хочу set!
|
||||
self.words_for_tests = list(map(str.lower, words))
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}({', '.join(map(repr, self.words))})"
|
||||
|
||||
def add_word(self, word):
|
||||
l0 = len(self)
|
||||
self.words.add(word.lower())
|
||||
if len(self) > l0:
|
||||
self.words_for_tests.append(word.lower())
|
||||
|
||||
def get_words(self):
|
||||
return tuple(self.words_for_tests)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.words)
|
||||
|
||||
def __radd__(self, other):
|
||||
return self + other
|
||||
|
||||
def __add__(self, other):
|
||||
if hasattr(other, "words"):
|
||||
return self.__class__(*self.words, *other.words)
|
||||
if isinstance(other, str):
|
||||
return self.__class__(*self.words, *other.split())
|
||||
return NotImplemented
|
||||
|
||||
def __contains__(self, other):
|
||||
return self == other
|
||||
|
||||
def __eq__(self, other):
|
||||
if hasattr(other, "words"):
|
||||
return self.words == other.words
|
||||
if isinstance(other, str):
|
||||
return other.lower() in self.words
|
||||
return NotImplemented
|
||||
|
||||
def __lt__(self, other):
|
||||
if hasattr(other, "words"):
|
||||
return self.words < other.words
|
||||
if isinstance(other, str):
|
||||
return other.lower() in self.words
|
||||
return NotImplemented
|
||||
|
||||
def __gt__(self, other):
|
||||
if hasattr(other, "words"):
|
||||
return self.words > other.words
|
||||
if isinstance(other, str):
|
||||
return False
|
||||
return NotImplemented
|
||||
|
||||
|
||||
data = """\
|
||||
- связь, связи, связью, связей, связям, связями, связях
|
||||
- формула, формулы, формуле, формулу, формулой, формул, формулам, формулами, формулах
|
||||
- вектор, вектора, вектору, вектором, векторе, векторы, векторов, векторам, векторами, векторах
|
||||
- эффект, эффекта, эффекту, эффектом, эффекте, эффекты, эффектов, эффектам, эффектами, эффектах
|
||||
- день, дня, дню, днем, дне, дни, дням, днями, днях\
|
||||
"""
|
||||
sanitizer = str.maketrans({k: "" for k in "–?!,.:;()+-*^%$#@№/\\<>"})
|
||||
dict_words = [*map(lambda x: Morph(*x.translate(sanitizer).split()), data.split("\n"))]
|
||||
all_words = sum(dict_words, Morph())
|
||||
|
||||
text = input() # эту строчку не менять
|
||||
|
||||
words = [*map(lambda x: x.translate(sanitizer), text.split())]
|
||||
print(sum(word in all_words for word in words))
|
Loading…
Reference in New Issue
Block a user