как присоединить многоточие ("...") к концу сокращенного предложения? Python
Ваша задача состоит в том, чтобы урезать предложение до длины, которая не превышает заданное количество символов.
Если данное предложение уже достаточно короткое, Вам не нужно ничего с ним делать. В случае, если его нужно урезать, отсутствующая часть должна быть обозначена присоединением многоточия ("...") к концу сокращенного предложения.
Сокращенное предложение может содержать целые слова и пробелы. Оно не должно содержать ни усеченных слов, ни конечных пробелов. Многоточие было учтено при расчете разрешенного количества символов, поэтому оно не засчитывается в счет заданной длины.
Входные данные: Два аргумента:
однострочное предложение в виде строка максимальная длина усеченного предложения в виду int Выходные данные: Урезанное предложение с многоточием (если требуется) в виде одной строки.
Примеры:
cut_sentence("Hi my name is Alex", 4) == "Hi..."
cut_sentence("Hi my name is Alex", 8) == "Hi my..."
cut_sentence("Hi my name is Alex", 18) == "Hi my name is Alex"
cut_sentence("Hi my name is Alex", 20) == "Hi my name is Alex"
Мой код:
def cut_sentence(line: str, length: int) -> str:
list_ = [str(x) for x in line.split()]
len_word = 0
res_word = ''
lst2 = []
if len(line) == 0 or length == 1:
return '...'
elif len(line) - (length + 3) > 0:
for i in list_:
if len(res_word) > length-2:
break
lst2.append(i)
res_word = ' '.join(lst2)
res_word += '...'
else:
return f'{line[:length]}'
return res_word
Где ошибаюсь?
Ответы (2 шт):
Давайте тестировать:
# ваш код
...
# тест
for i in range(10):
print(i, cut_sentence('a b c d e', i))
0 # нет многоточия 1 ... # должно быть a... 2 a... 3 a... # должно быть a b... 4 a... # должно быть a b... 5 a... # должно быть a b с... 6 a b c # нет многоточия 7 a b c d # нет многоточия 8 a b c d # нет многоточия 9 a b c d e
Большая часть тестов провалилась, к сожалению.
P.S. Мой ответ не указывает конкретную причину ошибок. Он указывает на то что ошибок много. Возможно, вы не внимательно прочитали условие.
P.P.S. Регулярное выражение r'\S\s' совпадает с парой символов - "непробелом" и "пробелом". Между ними находится позиция по которой можно разрезать строку. Из всех таких позиций нужно выбрать самую дальнюю, но не больше заданной длины. Если таких нет, значит первый разрез слишком далеко или разрезов нет вообще. В этом случае надо вернуть только многоточие:
def cut_sentence(line: str, length: int) -> str:
if len(line) <= length:
return line
cuts = (m.start() + 1 for m in re.finditer(r'\S\s', line))
cut = max(filter(lambda c: c <= length, cuts), default=0)
return f'{line[:cut]}...'
Как альтернативный вариант. Поскольку интересуют нас в качестве разделителя только пробелы, то можно просто искать пробел слева от нужной позиции (плюс место под искомый пробел, поэтому в срезе длина+1) и обрезать строку по нему. Если пробел не найден - обрезается вся строка. Если длины достаточно для всей строки - ничего не делаем.
def cut_sentence(line: str, length: int) -> str:
if len(line) <= length:
return line
return line[:max(line[:length+1].rfind(' '), 0)] + '...'
assert cut_sentence("Hi my name is Alex", 4) == "Hi..."
assert cut_sentence("Hi my name is Alex", 8) == "Hi my..."
assert cut_sentence("Hi my name is Alex", 18) == "Hi my name is Alex"
assert cut_sentence("Hi my name is Alex", 20) == "Hi my name is Alex"
Чем код короче, тем сложнее в нём что-то напутать.
Ну и хорошая практика - писать проверки вычислительного кода в виде assert-ов. Если что-то не так с функцией - вы сразу это заметите.