3.2 🔗 Chains - собери свою цепь

💰 Сэкономил на токенах - чилю на Мальдивах 🏝🤩

Допустим, наш сервис анализирует отзывы пользователей, а эмоциональные отзывы порой содержат много ненужных символов.

Например:

!!!!!КРУТО!!!!!

Где снаряды?????????

Чтобы не переплачивать лишнего за чьи-то эмоции, давайте напишем функцию для text_clean_chain, которая будет убирать избыточные знаки.

text_clean_chain = TransformChain(input_variables=["text"],
                                  output_variables=["output_text"],
                                  transform=del_additional_signs)

# Или вариант с LCEL

text_clean_chain = del_additional_signs | prompt | llm

Задача: Напишите функцию del_additional_signs, которая удаляет вопросительные и восклицательные знаки в начале слов, оставляет только один (если такой присутствует) в конце слов переданной строки и возвращает "чистую" строку.

 

Подсказка 🤫 Зачем писать самому, если можно спросить ChatGPT?

Failed test #3 of 5. Wrong answer

Почему ошибка выдается? Вроде все символы удаляются.

@Артем_Летин, обратите внимание на символы в начале строки. Может быть комбинация из знаков вопроса и восклицательных.

@Петр_Михайлов, в начале строки символы удаляются, но ошибка остается. Нужно обрабатывать случаи, когда текст не в одну строку?

@Артем_Летин, Все в одну строчку. В вашем последнем решении не все символы в начале строки будут удалены. Проверьте случай, когда у вас есть и восклицательный и вопросительный знаки в начале строки.

@Петр_Михайлов, Добавил вопросительный знак в начало строки. Запустил код. Знаки удалились. Но ошибка осталась.

@Артем_Летин, попробуйте проверить ваше решение такой строкой "!?Проверка!!!"

@Петр_Михайлов, спасибо! Теперь понятно. Все получилось

Failed test #3 of 5. Wrong answer
Если не сложно, не могли бы подсказать в чем могла бы быть ошибка?

@Дамир_Красильников, строка !?Что такое?????, у вас первый восклицательный знак не удаляется

@Никита_Тенишев
код выдаёт 

Что! такое?

Но всё равно Failed test #3 of 5. Wrong answer

" ...удаляет вопросительные и восклицательные знаки в начале слов, оставляет только один..."

Для этого "только один" есть правило что там должен быть '?' не зависимо от порядка?

Какой иной правильный ответ на тот тест?

@Grigorii_Tarasov, для этого теста входная строка !?Что такое?????, правильный ответ на этот тест Что такое?. Восклицательный знак не нужен, потому что его нет после слова Что

Failed test #4 of 5. Wrong answer 

Подскажите, пожалуйста, куда копать?)

@Dmitry_Krapukhin, Тестовая строка "В ожидании ответа...". В вашем случае точки удалятся, но этого не нужно

@Никита_Тенишев, Спасибо) Просто в описании задачи написано только про "вопросительные и восклицательные знаки", наверное стоит добавить это в условие задачи)

Вы решили сложную задачу, поздравляем! Вы можете помочь остальным учащимся в комментариях, отвечая на их вопросы, или сравнить своё решение с другими.

 

При этом: Вы получили: 0 баллов из 2

@Олег_Хасьянов, это интерфейс Степика иногда подвисает - надо перезагрузить страницу.

RegEx... сколько ими пользуюсь, но все равно, их отладка много времени отнимает.

@Михаил_Чернышев, я пользуюсь regex101.com - там как-то попроще

Комментарий закреплён

Вариант от GPT-3.5 :)

Python 3
import re

def del_additional_signs(string: str) -> str:
    cleaned_string = re.sub(r'(^|[^\w])[\?!]+', r'\1', string)
    return cleaned_string

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

@Никита_Тенишев, а как выглядел промпт? Я от GPT-3.5 адекватного решения добиться не смог, пришлось переписывать за ним =)

две строки. Но можно через или, как у Никиты Тенишева  re.sub(r'(^|[^\w])[\?!]+', r'\1', string) 

Кстати, с кодом помог https://chat.langchain.com/ промпт: how to remove symbols (!, ?) from the beginning of the string using regular expressions (re) in python.
Шпоргалка по регуляркам: https://habr.com/ru/articles/349860/

символ ^  -- выражение относится к началу строки. 

Python 3
import re

def del_additional_signs(string: str) -> str:
    text = re.sub(r'([!?])\1+', r'\1', string)
    text = re.sub(r'^[!?]+', '', text)
    return text

# не изменяйте фрагмент кода ниже
string = input()
#string = "!?Проверка!!!"
print(del_additional_signs(string))

import re 
def del_additional_signs(input_string):
    # Удаляем вопросительные и восклицательные знаки в начале слов
    result = re.sub(r'(^|\s)[!?]+', r'\1', input_string)
    # Оставляем только один вопросительный или восклицательный знак в конце слов
    result = re.sub(r'([!?])+(?=\s|$)', r'\1', result)
    return result
    
# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Python 3
import re 
def del_additional_signs(input_string):
    # Удаляем вопросительные и восклицательные знаки в начале слов
    result = re.sub(r'(^|\s)[!?]+', r'\1', input_string)
    # Оставляем только один вопросительный или восклицательный знак в конце слов
    result = re.sub(r'([!?])+(?=\s|$)', r'\1', result)
    return result
    
# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Без регулярок:

Python 3
def del_additional_signs(string: str) -> str:
    r = ""
    prev = "s"
    for i in string:
        if (i == "?" or i == "!") and (prev == i or prev == " " or r == ""):
            continue
        
        r += i
        prev = i
    return r

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Не люблю делать сложные регулярки, предпочитаю разбивать на шаги - так проще понять чо происходит

Python 3
import re

def del_additional_signs(string: str) -> str:
    cleaned_str = re.sub(r'[!|?]+\b', '', string)
    cleaned_str = re.sub(r'\b!+', '!', cleaned_str)
    cleaned_str = re.sub(r'\b\?+', '?', cleaned_str)
    return cleaned_str

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

def del_additional_signs(string: str) -> str:
    # Используем list comprehension для обработки каждого слова в строке
    cleaned_words = [''.join([char for char in word if char not in ['?', '!']]) if word[-1] not in ['?', '!'] 
                     else ''.join([char for char in word[:-1] if char not in ['?', '!']]) + word[-1]
                     for word in string.split()]
    return ' '.join(cleaned_words)

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Python 3
def del_additional_signs(string: str) -> str:
    # Используем list comprehension для обработки каждого слова в строке
    cleaned_words = [''.join([char for char in word if char not in ['?', '!']]) if word[-1] not in ['?', '!'] 
                     else ''.join([char for char in word[:-1] if char not in ['?', '!']]) + word[-1]
                     for word in string.split()]
    return ' '.join(cleaned_words)

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))
+
Python 3
import re

def del_additional_signs(string: str) -> str:
    cleaned_sentence = re.sub(r'([!?])\1+', r'\1', string)
    cleaned_sentence = re.sub(r'^[!?]+', '', cleaned_sentence)
    cleaned_sentence = re.sub(r'([!?])$', r'\1', cleaned_sentence)
    return cleaned_sentence.strip()

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Локальная модель "limarp-miqu-1-70b-Q5_K_M.gguf" справилась с первого раза. Модели поменьше не справились вообще.

Python 3
import re

def del_additional_signs(string):
    # Define the regular expression pattern to match punctuation marks at the beginning and end of words
    pattern = r'(\?|\!){2,}|\A[\?\!]|[^\w\s]\Z'
    # Use re.sub() with the defined pattern to replace multiple punctuation marks with a single one at the end of words and remove them from the beginning
    string = re.sub(pattern, lambda match: '.' if match.group(0)[-1] == '.' else match.group(0)[-1], string)
    # Remove leading punctuation marks and convert to uppercase
    string = re.sub(r'^[\?\!]', '', string)
    string = re.sub(r' [\?\!]', ' ', string)
    return string

string = input()
print(del_additional_signs(string))

 Решение с двумя регулярками

Python 3
import re

def del_additional_signs(string: str) -> str:
    # your code here
    string = re.sub(r'([?!])+', r'\1', string)
    string = re.sub(r'(^[?!])','', string)
    return string

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Вариант от того, кому было лень вспоминать регулярки

Python 3
def del_additional_signs(string: str) -> str:
    
    while string[0] in '!?':
            string = string[1:]
    k = 1
    while k < len(string):
        if string[k - 1] in '!?' and string[k - 1] == string[k]:
            string = string[:k]+string[k+1:]
        else:
            k += 1
    return string

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

а вот костыль)

Python 3
def del_additional_signs(string: str) -> str:
       # Разделяем строку на слова
    words = string.split()

    # Обрабатываем каждое слово
    for i in range(len(words)):
        # Удаляем вопросительные и восклицательные знаки в начале слова
        words[i] = words[i].lstrip('?!')
    for i in range(len(words)):
        
        if  words[i][-1]  == '!':
            words[i] = words[i].rstrip('?!') + '!'
        elif words[i][-1]  == '?':
            words[i] = words[i].rstrip('?!') + '?'
        else:
            words[i] = words[i]
    # Склеиваем слова с одним вопросительным или восклицательным знаком в конце
    string = ' '.join(words)
      
    return string

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

как вариант, от HumanGPT -)

Python 3
import re
def del_additional_signs(string: str) -> str:
    string_post = re.findall(r'[\w.]+[!?]?', string)
    return ' '.join(string_post)

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))

Решение не от чатаГПТ :))

Python 3
import re
def del_additional_signs(string: str) -> str:
    string = " ".join(re.findall("[^!?\s]+[!?]?", string))
    return string

# не изменяйте фрагмент кода ниже
string = input()
print(del_additional_signs(string))