Ответы:
1: конечно, вместо того, чтобы что-то печатать, добавьте результат в список result.append('some value')
и не забудьте инициализировать список в начале кода result = []
и вернуть его как только функция завершена return result
- и, вероятно, не вызывайте функцию _print
, но что-то вроде bit_strings
.
ad 1: поскольку ваша функция рекурсивная, вам теперь также нужно захватить верните значение и добавьте его к результату при рекурсивном вызове функции, поэтому result += _print(string, index + 1)
2: обычно вы должны думать о крайних случаях и тестировать их отдельно, или группировать те, которые действительно проверяют один аспект вашего функция. Нет единого способа указать, как должен выглядеть тест - если бы он был, среда тестирования просто сгенерировала бы его для вас.
3: тот же ответ, что и для 2.
Ваш код становится :
def bit_strings(s, index):
result = []
if index == len(s):
result.append(''.join(s))
return result
if s[index] == "?":
# replace '?' by '0' and recurse
s[index] = '0'
result += bit_strings(s, index + 1)
# replace '?' by '1' and recurse
s[index] = '1'
result += bit_strings(s, index + 1)
# NOTE: Need to backtrack as string
# is passed by reference to the
# function
s[index] = '?'
else:
result += bit_strings(s, index + 1)
return result
# Driver code
if __name__ == "__main__":
x = "1??0?101"
xl = list(x) #don’t forget to convert to string
print(bit_strings(xl, 0))
Есть более эффективные способы сделать это, но я просто изменил ваш код в соответствии с вопросами и ответами.
Я переименовал string
в s
, поскольку string
немного сбивает с толку, напоминая другим о типе или затенении (встроенного) модуля.
Что касается модульного теста:
import unittest
from wildcard import bit_strings
class TestWildCard(unittest.TestCase):
def test_0_print(self):
print("Start wildCard _print test: \n")
# you only had one case here and it's a list now
result = ['101', '111']
# user assertEqual, not Equals
# you were passing in a string, but your code assumed a list, so list() added
self.assertEqual(bit_strings(list("1?1"), 0), result, "Results match")
При использовании среды, подобной PyCharm, он помогает вызывать файл test<something>.py
(т. Е. Иметь test
в имени), так что он помогает вам легче запускать модульные тесты.
Два альтернативных решения в соответствии с запросом в комментарии (одно еще рекурсивный, просто намного более краткий, другой не рекурсивный, но, возможно, немного расточительный со списками результатов - всего два быстрых):
from timeit import timeit
def unblank_bits(bits):
if not bits:
yield ''
else:
for ch in '01' if bits[0] == '?' else bits[0]:
for continuation in unblank_bits(bits[1:]):
yield ch + continuation
print(list(unblank_bits('0??100?1')))
def unblank_bits_non_recursive(bits):
result = ['']
for ch in bits:
if ch == '?':
result = [s+'0' for s in result] + [s+'1' for s in result]
else:
result = [s+ch for s in result]
return result
print(list(unblank_bits_non_recursive('0??100?1')))
print(timeit(lambda: list(unblank_bits('0??100?1'))))
print(timeit(lambda: list(unblank_bits_non_recursive('0??100?1'))))
Это решение не перемещается между списками и строками, так как нет нужно и не манипулирует вводом v alues. Как вы можете сказать, рекурсивный немного медленнее, но я предпочитаю его для удобства чтения. Вывод:
['00010001', '00010011', '00110001', '00110011', '01010001', '01010011', '01110001', '01110011']
['00010001', '01010001', '00110001', '01110001', '00010011', '01010011', '00110011', '01110011']
13.073874
3.9742709000000005
Обратите внимание, что ваше собственное решение работало примерно за 8 секунд с использованием той же настройки, поэтому предложенная мною «улучшенная версия» проще, но не быстрее, поэтому вы можете предпочесть последнее решение.