Проверка строки на опрелеленные символы
Пользователь вводит строку и мы должны сравнить все символы в строке со списком разрешенных символов. Если все символы разрешены то возвращаем True, если нет то False. Не очень понимаю как это можно реализовать.
def secure_eval(action):
is_true = 0
allowed = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '*', '/']
for i in range(len(action)):
if allowed in action[i]:
is_true=1
else:
is_true=0
break
if is_true:
return eval(action)
else:
return "Я не могу выполнить данную команду"
Ошибка:
line 9, in secure_eval
if allowed in action[i]:
TypeError: 'in <string>' requires string as left operand, not list
Ответы (2 шт):
Разобрались с вами в комментариях, что проблем было две:
- Когда встречается символ, которого нет среди разрешенных нужно сразу прерывать работу функции, поскольку последующие разрешенные элементы будут перезаписывать значение переменной
is_true - Оператор
inприменим сразу к целому списку, поэтому нет необходимости писать вложенные циклы.
С учетом вышесказанного должен был получиться следующий код:
def secure_eval(action):
is_true = 0
allowed = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '*', '/']
for i in range(len(action)):
if action[i] in allowed:
is_true = 1
else:
is_true = 0
break
if is_true:
return eval(action)
else:
return "Я не могу выполнить данную команду"
И хотя этот код работает, в образовательных целях покажу вам, как можно было решить эту задачу более оптимально:
allowed = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '*', '/']
def secure_eval(action):
if not any([letter for letter in action if letter not in allowed]):
return eval(action)
return "Я не могу выполнить данную команду"
Поскольку речь о множествах, то наиболее эффективно решать эту задачу можно через множества, а именно через метод .issuperset(), возвращающий истину, если одно множество является надмножеством для другого.
def secure_eval(action):
return eval(action) if set('0123456789+-*/').issuperset(action) else "Я не могу выполнить данную команду"
При этом остается вероятность ошибки вычисления выражения, если оно, например, такое: 1++1-22--.
Чтобы не получить неожиданную ошибку, я бы предложил обработать ошибки внутри функции:
def secure_eval2(action):
try:
if not set('0123456789+-*/').issuperset(action):
raise SyntaxError
return eval(action)
except Exception:
return "Я не могу выполнить данную команду"
Тест функции secure_eval2():
for txt in "1+2-3*4", "4+5-A+1", "1++1-22--":
print(f'{txt} = {secure_eval2(txt)}')
1+2-3*4 = -9
4+5-A+1 = Я не могу выполнить данную команду
1++1-22-- = Я не могу выполнить данную команду
Функция secure_eval() на таком тестовом наборе данных выдает ошибку, а secure_eval2() отрабатывает штатно.