#python #python-3.x
#python #python-3.x
Вопрос:
Я пытаюсь решить проблему, которая стимулирует движения робота. Робот начинается с позиции (0, 0, ‘N’). Команда задается в виде списка строк. функция ‘turn’ превращается из N в E, из S в W и обратно в N. Функция перемещения перемещается в определенном направлении: N, S по оси y и E, W по оси x. N: y 1 S: y-1 W: x-1 E: x 1
Часть, с которой у меня возникают проблемы, заключается в том, что при попытке использовать ярлыки в функции. Использование ‘turnleft’ вместо [‘turn’, ‘turn’, ‘turn’], ‘turnright’ вместо ‘turn’
def macro_interpreter(code, macros):
при вызове функции:
print(macro_interpreter(['turnleft', 'turnright'], {'turnleft': ['turn', 'turn', 'turn'], 'turnright' : ['turn'], 'bigleftturn' : ['move', 'move', 'turnleft', 'move', 'move'], 'bigrightturn' : ['move', 'move', 'turnright', 'move', 'move']}))
определение термина дано в словаре.
Мой код выполняется только для первой команды, а затем завершается, он игнорирует второй код в списке
def macro_interpreter(code, macros):
x,y,index = 0, 0, 0
state = ['N', 'E', 'S', 'W']
for command in code:
if command in macros:
return macro_interpreter(macros[command], macros)
else:
if command == 'move':
if state[index] == 'N':
y = 1
elif state[index] == 'E':
x = 1
elif state[index] == 'S':
y -= 1
elif state[index] == 'W':
x -= 1
elif command == 'turn':
try:
index = index 1
except IndexError:
index = 0
return (x, y, state[index])
Комментарии:
1. каков ваш ожидаемый результат?. насколько я могу видеть
turn
, он отсутствует в вашем макросе (при втором запуске) и'move'
также не был частью возвращаемых кодов, поэтому другие условия в этом блоке никогда не будут выполняться…. а также увеличение числа никогда не приведет к увеличениюIndexError
, скорее, попытка получить доступ к списку с отсутствующим индексом приведет.
Ответ №1:
Если вы всегда нажимаете один else
оператор в цикле поверх code
команд, то вы никогда не будете повторять, потому command not in macros
что .
После первой итерации, code == ['turn', 'turn', 'turn']
, но macros
не содержит ключа "turn"
Если вы хотите сделать это более правильно, то вы можете передать x, y и «состояние индекса направления» в качестве параметров функции, затем увеличить / изменить их в рекурсивном вызове, а не только изменять локальные переменные функции и всегда перезапускать их обратно на (0,0, 0).
Кроме того, вам нужно заменить это try except на index = (index 1) % len(state)
, потому что при увеличении числа ошибка IndexError не будет обнаружена
Итак, что-то вроде этого
state = ['N', 'E', 'S', 'W']
def macro_interpreter(code, macros, x=0,y=0,index=0):
# TODO: check if x or y have gone outside "the board"
# TODO: return to break from recursion
for command in code:
if command in macros:
return macro_interpreter(macros[command], macros,x,y,index)
else:
if command == 'move':
if state[index] == 'N':
return macro_interpreter(code[1:], macros,x,y=y 1,index)
Ответ №2:
Есть некоторые поправки, которые я внес в ваш код, чтобы правильно поддерживать рекурсию. Этот код будет делать то, чего вы хотите достичь.
def macro_interpreter(code, macros, x=0, y=0, index=0):
state = ['N', 'E', 'S', 'W']
for command in code:
if command in macros:
x, y, curr_state = macro_interpreter(macros[command], macros, x, y, index)
# update new index with new state value
index = state.index(curr_state)
else:
if command == 'move':
if state[index] == 'N':
y = 1
elif state[index] == 'E':
x = 1
elif state[index] == 'S':
y -= 1
elif state[index] == 'W':
x -= 1
elif command == 'turn':
index = (index 1)%len(state)
return (x, y, state[index])
Теперь, если я запущу ваш тестовый пример
>> print macro_interpreter(['turnleft', 'turnright'], {'turnleft': ['turn', 'turn', 'turn'], 'turnright' : ['turn'], 'bigleftturn' : ['move', 'move', 'turnleft', 'move', 'move'], 'bigrightturn' : ['move', 'move', 'turnright', 'move', 'move']})
Output:- (0, 0, 'N')
Я надеюсь, что это поможет вам.
Ответ №3:
Строка
return macro_interpreter (macros etc.
будет делать именно это. Он покинет цикл for и вернется из внешнего вызова. Конец истории.
Ответ №4:
Я подозреваю, что это потому, что вы возвращаете
macro_interpreter(macros[command], macros)
Это просто завершает работу функции после запуска рекурсивного кода. Ты увидишь, если изменишься
return macro_interpreter(macros[command], macros)
Для
print macro_interpreter(macros[command], macros)
что код будет печатать то, что вы хотите, чтобы он делал. Как вы хотите на самом деле обрабатывать выходные данные, зависит от вас.