Функция, не удовлетворяющая конкретному тестовому сценарию

#python #function #unit-testing

#python #функция #модульное тестирование

Вопрос:

Моя функция trim (S) проходит все тестовые примеры, кроме теста 2.

Предположим, что S является строкой. Возвращает строку, которая совпадает со строкой S, но без пробелов в начале или в конце строки. Например, trim(‘dog ‘) возвращает ‘dog’ . trim(‘cat in the hat’) возвращает ‘cat in the hat’ . Обратите внимание, что пробелы, которые не находятся в начале или конце, остаются такими, какие они есть. Пример 3: trim(«) и trim(‘ ‘) оба возвращают пустую строку. Вы не должны использовать рекурсию. Не используйте встроенные функции, которые обрезают, например rtrim() .

Какие-либо решения?

 def trim(S) :

    min_index = 0
    max_index = 0
    if S.isspace() == True:
      new_S = ''
      return new_S
    if len(S) == 0:
      new_S = ''
      return new_S
    for ch in S:
      if ch.isspace() == False and min_index == 0:
        min_index = S.index(ch)
    for ch in S:
      if ch.isspace() == False and S.index(ch) > max_index:
        max_index = S.index(ch)
    new_S = S[min_index:max_index 1]
    # print('new_S: ',new_S)
    print('min_index: ',min_index,'max_index: ', max_index)
    return new_S
# --------------------------------------------------------------
# Testing
# --------------------------------------------------------------
class myTests(unittest.TestCase):
 def test1(self):
  self.assertEqual(trim('    dog   '), 'dog')
 def test2(self):
  self.assertEqual(trim('    cat in the hat'), 'cat in the hat')
 def test3(self):
  self.assertEqual(trim(''), '')
 def test4(self):
  self.assertEqual(trim('      '), '')
 def test5(self):
  self.assertEqual(trim(' red green  blue  .'), 'red green  blue  .')


if __name__ == '__main__':
 unittest.main(exit=True)
 

Комментарии:

1. Вы добавляете много сложностей, пытаясь отслеживать начало букв и конец букв. Почему бы не запустить бесконечный цикл, который удаляет первый символ до тех пор, пока он не достигнет буквы, а затем прерывается. Выполните второй бесконечный цикл, удаляя последний символ, пока он не достигнет буквы, а затем прервется. Также ваши первые два if оператора могут быть объединены с or

Ответ №1:

Ошибка в последнем цикле. Вызов S.index(ch) внутри этого цикла не гарантирует, что он найдет последний пробел во входной строке. Если конечные символы ввода являются символами, которые также не являются уникальными в строке, то max_index они никогда не выйдут за пределы соответствующих индексов, просто потому S.index(ch) , что вернут индекс, указывающий на более раннее появление этого символа. Это, например, случай со вторым тестом, где последнее слово содержит символы, которые все встречались ранее в строке. Последним уникальным символом является буква «e» в позиции 13, и поэтому max_index в конечном итоге будет всего 13, а это не то, что вы хотите.

Для этого последнего цикла вам действительно следует выполнить итерацию в обратном направлении, начиная с конца строки, ища первый символ, не являющийся пробелом, который вы найдете при выполнении итерации.

Вот как это может работать:

 def trim(s):
    if not s or s.isspace():
        return ""
    for i, ch in enumerate(s):
        if not ch.isspace():
            break
    for j, ch in enumerate(s[::-1]):
        if not ch.isspace():
            break
    return s[i:len(s)-j]