Форум сайта python.su
PalromВот такая задача для практики дословно:
Ну так ждали от вас деталей задания, что можно засчитывать, что нельзя. Но судя по всему у вас их и нет. Скрипт ваш подойдёт только для этого конкретного списка, т.е. он бесполезен будет в большинстве случаев.
Но для сдачи наверное пойдёт.
with open("C:\\Users\\Владимир\\Desktop\\exercise28.txt", "w", encoding="utf-8" ) as file:
file.write("some line blablabla you dont need to catch this line try to catch me but not me I'm here, catch me!!!")
with open("C:\\Users\\Владимир\\Desktop\\exercise28.txt", "r") as file:
str_ = file.read()
word = str_.split()
s = "".join(word)
a = s.count("catchme")
l=[]
for i in range(a):
l.append("catch me")
print(a)
print(l)
Офлайн
VladimirDegТак это надо создать файл со множеством строк, а не с одной строкой только. В каждой строке файла должен быть текст, в котором может быть часть в виде “catch me”, а может и не быть ни одной такой части. И вот те строки, в которых есть хотя бы одна часть в виде “catch me”, нужно собрать в список, добавляя их в него целиком, а потом в конце вывести количество элементов этого списка.
Вот такая задача для практики дословно:
Отредактировано py.user.next (Июль 5, 2022 11:23:42)
Офлайн
py.user.nextТекст на строки разбил на свой вкус, т.к. хз как должно быть по заданию.
Берёшь каждую строку файла.
Ищешь в строке файла подстроку “catch me”.
Если подстрока найдена, то проверяешь символ слева от неё и символ справа от неё.
Если она подходит, добавляешь всю строку файла без изменений в результирующий список и переходишь к следующей строке файла.
Если она не подходит, то справа от подстроки в строке файла ищешь снова подстроку “catch me”.
Всё это повторяешь, пока строка не закончится.
Если строка закончилась, а в ней ничего подходящего не найдено, то просто переходишь к следующей строке и повторяешь это всё для неё.
В конце, когда все строки перебраны, выводишь результирующий список и длину этого списка.
with open("C:\\PythonProjects\\somefile.txt", "w", encoding="utf-8") as file: file.write("some line blablabla\nyou dont need to catch this line\n" "try to catch me but not me\nI'm here, catch me!!!") with open("C:\\PythonProjects\\somefile.txt", "r", encoding="utf-8") as file: str_ = file.read().splitlines() def find_word(textlist, word): res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: if not i[start - 1].isalpha() or start == 0: if not i[start + len(word)].isalpha(): res.append(i) count += 1 start = i.find(word, start + len(word)) return res, count print(find_word(str_, 'catch me'))
(['try to catch me but not me', "I'm here, catch me!!!"], 2)
Отредактировано Palrom (Июль 6, 2022 11:16:56)
Офлайн
Palromdef find_word(textlist, word): res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: if not i[start - 1].isalpha() or start == 0: if not i[start + len(word)].isalpha(): res.append(i) count += 1 start = i.find(word, start + len(word)) return res, count
>>> def find_word(textlist, word): ... res = [] ... count = 0 ... for i in textlist: ... start = i.find(word) ... while start >= 0: ... if not i[start - 1].isalpha() or start == 0: ... if not i[start + len(word)].isalpha(): ... res.append(i) ... count += 1 ... start = i.find(word, start + len(word)) ... return res, count ... >>> find_word(['they catch me there'], 'catch me') (['they catch me there'], 1) >>> >>> find_word(['catch me there'], 'catch me') (['catch me there'], 1) >>> >>> find_word(['they catch me'], 'catch me') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 8, in find_word IndexError: string index out of range >>>
PalromПри start, которая равна нулю, что будет проверяться сначала?if not i[start - 1].isalpha() or start == 0:
# i[start - 1] => i[0 - 1] => i[-1]
Отредактировано py.user.next (Июль 6, 2022 12:01:23)
Офлайн
Мдэ. Попробую починить, но мне кажется это будет уже нежизнеспособный уродец, глубиной с Марианскую впадину. Нужен другой подход наверно. Спасибо за разбор.
UPD. Перелопатил всё.
def find_word(textlist, word): punct = r' !#$%&"()*+,-./:;<=>?@[\]^_`{|}~' + "'" res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: if start == 0: if len(i) == len(word): res.append(i) count += 1 elif len(i[start:start + len(word) + 1]) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 elif i[start - 1] in punct: if len(i[start:start + len(word) + 1]) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 elif i[-1] == word[-1]: res.append(i) count += 1 start = i.find(word, start + len(word)) return res, count
teststring = [' !catch me! catch melon catch mecatch me catchme! '] print(find_word(teststring, 'catch me'))
([' !catch me! catch melon catch mecatch me catchme! '], 1) # нашёл вот это: !catch me!
teststring = ['catching me @catch me catch me11 catch me% '] print(find_word(teststring, 'catch me'))
(['catching me @catch me catch me11 catch me% ', 'catching me @catch me catch me11 catch me% '], 2) # нашёл вот это: @catch me, catch me%
Отредактировано Palrom (Июль 6, 2022 17:30:41)
Офлайн
Снабдил принтами, чтобы было понятно, как я до этого докатился и что код делает на каждой строке:
str_ = ['some line blablabla', 'you dont need to catch this line', 'try to catch me but not me', "I'm here, catch me!!!"] def find_word(textlist, word): punct = r' !#$%&"()*+,-./:;<=>?@[\]^_`{|}~' + "'" res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: if start == 0: print('слово начинается с начала строки и...') if len(i) == len(word): print('строка и есть слово.', 'УСПЕХ') res.append(i) count += 1 elif len(i[start:start + len(word) + 1]) > len(word): print('строка больше искомого слова и..') if i[start + len(word)] in punct: print('после искомого слова идёт пунктуация.', 'УСПЕХ') res.append(i) count += 1 else: print('сразу после искомого слова идёт буква.') elif i[start - 1] in punct: print('слово начинается с пунктуации и...') if len(i[start:start + len(word) + 1]) > len(word): print('строка больше искомого слова и...') if i[start + len(word)] in punct: print('после искомого слова идёт пунктуация.', 'УСПЕХ') res.append(i) count += 1 else: print('сразу после искомого слова идёт буква.') elif i[-1] == word[-1]: print('строка заканчивается искомым словом.', 'УСПЕХ') res.append(i) count += 1 else: print('перед искомым словом идёт буква.') start = i.find(word, start + len(word)) return res, count
print(find_word(str_, 'line'))
(['some line blablabla', 'you dont need to catch this line'], 2)
Отредактировано Palrom (Июль 6, 2022 18:17:27)
Офлайн
PalromКод получился нечитаемый, из-за этого его понадобилось ещё снабжать принтами. А код должен быть читаемым без всяких принтов. Ни принтов, ни комментариев не должно быть. Комментарии пишутся только тогда, когда хочешь объяснить причину написания такой-то строки. Если пишешь комментарий, чтобы объяснить, как работает строка, значит эта строка плохо написана и её нужно переписать так, чтобы поясняющий комментарий не требовался. Лучший комментарий - это тот, которого нет, и без которого и так всё понятно сходу.
Снабдил принтами, чтобы было понятно, как я до этого докатился и что код делает на каждой строке:
PalromЧто делает проверкаif len(i[start:start + len(word) + 1]) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 elif i[-1] == word[-1]: res.append(i) count += 1
PalromЗачем она нужна вообще?elif i[-1] == word[-1]:
if len(i[start:start + len(word) + 1]) > len(word):
word_with_right_char = i[start:start + len(word) + 1] if len(word_with_right_char) > len(word):
PalromБылоelif i[start - 1] in punct:
elif i[start - 1] in punct:
char_left = i[start - 1] ... elif char_left in punct:
Отредактировано py.user.next (Июль 6, 2022 22:14:44)
Офлайн
py.user.nextСравнивает последние символы для надёжности. Ну по сути она лишняя, да. На секунду выпало из головы, что i.find(word) уже и так всё нашёл и сравнил. Уберу пожалуй.
Что делает проверкаЗачем она нужна вообще?elif i[-1] == word[-1]:
py.user.nextДа я бы с удовольствием, но проблема в том, что многие вычисления будут производиться где-то наверху кода, при создании объекта, и тогда, когда это может быть недопустимо. Это сработает здесь:
лучше раздай всем вычислениям имена, а потом работай только с этими именами
py.user.nextИ здесь:word_with_right_char = i[start:start + len(word) + 1] if len(word_with_right_char) > len(word):
py.user.nextИ этот положительный пример подталкивает вроде как создать и “char_right” для этой конструкции:char_left = i[start - 1] elif i[start - 1] in punct:
if i[start + len(word)] in punct:
def find_word(textlist, word): punct = r' !#$%&"()*+,-./:;<=>?@[\]^_`{|}~' + "'" res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: word_with_right_char = i[start:start + len(word) + 1] char_left = i[start - 1] if start == 0: if len(i) == len(word): res.append(i) count += 1 elif len(word_with_right_char) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 elif char_left in punct: if len(word_with_right_char) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 else: res.append(i) count += 1 start = i.find(word, start + len(word)) return res, count
Отредактировано Palrom (Июль 7, 2022 12:15:20)
Офлайн
PalromДальше там повторяется
Вот так будет выглядеть с правками:def find_word(textlist, word): punct = r' !#$%&"()*+,-./:;<=>?@[\]^_`{|}~' + "'" res = [] count = 0 for i in textlist: start = i.find(word) while start >= 0: word_with_right_char = i[start:start + len(word) + 1] char_left = i[start - 1] if start == 0: if len(i) == len(word): res.append(i) count += 1 elif len(word_with_right_char) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 elif char_left in punct: if len(word_with_right_char) > len(word): if i[start + len(word)] in punct: res.append(i) count += 1 else: res.append(i) count += 1 start = i.find(word, start + len(word)) return res, count
len(word_with_right_char)
start + len(word)
PalromДелай их много, делай их повторно. Сделал один слой - сделай второй слой. Сделал второй слой - сделай третий слой. Читаемость должна повышаться. Код должен читаться, как художественная книга, - образы должны возникать из имён. Типа образ “правый символ” или образ “длина строки” или образ “слово шаблон”. А вот это типа “два плюс три плюс пять” - это не образ, а набор логических конструкций.
но приём возьму на вооружение
Офлайн