Python 2.7.3中使用eval和list来求解数学表达式

在 Python 2.7.3 中,eval() 函数可以用来执行字符串形式的 Python 表达式,并返回表达式的值。这是一个在进行数学计算时非常有用的功能,尤其是当你需要处理由用户输入的或动态生成的表达式时。然而,使用 eval() 时需要特别小心,因为它也可以执行任意代码,可能导致安全问题。

这里是一个简单的例子,展示如何使用 eval() 来计算数学表达式,并且介绍如何安全地限制 eval() 所执行代码的环境。

1、问题背景

在 Python 2.7.3 中,我需要创建一个函数来进行以下操作:

  • 创建一个数学问题并将其作为字符串输出,其中主题是运算顺序。
  • 作为输出的第二部分,输出此问题的正确答案。
  • 作为其余输出,输出错误答案,但如果更改运算顺序(例如让减法先于乘法),则可以达到这些答案。

该函数不需要任何参数,但在问题过程中需要我们进行以下导入:

arduino 复制代码
import random
from random import choice

这样做是为了生成随机整数作为任何问题的数字,并选择问题中涉及的操作,例如 *,/,+,-。

2、解决方案

有两种解决这个问题的方法:

方法一

  1. 我通过交替将整数和操作添加到字符串来制作一个字符串(因此以整数结尾),然后在最后在字符串的某些位置加上括号。
  2. 我使用 eval() 来评估字符串并因此提供正确的答案。
  3. 我通过在不同的地方插入括号来制作该字符串的其他版本,以便返回不同的答案,然后我使用 eval() 对其进行求值以找到其他答案。

方法二

这类似于方法一,但将元素放入列表中。

  1. 将运算顺序提供为列表作为输入,例如正确的运算顺序为 [*,(,/),(+,-)],然后找到这些运算在列表中的位置,并对左右的整数执行运算,删除列表的 3 个部分,并用我们找到的答案替换它们。我们对整个列表的所有操作执行此操作,使用重复。
  2. 我通过输入一个运算顺序方面不同的列表来简单地获得不同的答案,从而使寻找错误答案的步骤变得更容易。

代码例子

方法一

python 复制代码
import random
from random import choice
​
def create_question():
  """Creates a math question as a string."""
​
  # Generate random integers and operations.
  integers = [random.randint(1, 10) for _ in range(5)]
  operations = choice(['+', '-', '*', '/'])
​
  # Create a string representation of the question.
  question = ""
  for i in range(len(integers)):
    question += str(integers[i])
    if i < len(integers) - 1:
      question += operations
​
  # Add parentheses to the string in random places.
  for _ in range(random.randint(1, 3)):
    index = random.randint(0, len(question) - 1)
    question = question[:index] + '(' + question[index:]
​
  return question
​
def evaluate_question(question):
  """Evaluates a math question string and returns the answer."""
​
  return eval(question)
​
def find_incorrect_answers(question):
  """Finds incorrect answers to a math question string."""
​
  incorrect_answers = []
​
  # Try adding parentheses to the string in different places.
  for i in range(len(question)):
    if question[i] in ['+', '-', '*', '/']:
      new_question = question[:i] + '(' + question[i:] + ')'
      incorrect_answers.append(evaluate_question(new_question))
​
  # Try changing the order of operations.
  for operation in ['+', '-', '*', '/']:
    new_question = question.replace(operation, '')
    incorrect_answers.append(evaluate_question(new_question))
​
  return incorrect_answers
​
# Test the function.
question = create_question()
print("Question:", question)
correct_answer = evaluate_question(question)
print("Correct answer:", correct_answer)
incorrect_answers = find_incorrect_answers(question)
print("Incorrect answers:", incorrect_answers)

方法二

python 复制代码
import random
from random import choice
​
def create_question():
  """Creates a math question as a string."""
​
  # Generate random integers and operations.
  integers = [random.randint(1, 10) for _ in range(5)]
  operations = choice(['+', '-', '*', '/'])
​
  # Create a list representation of the question.
  question = []
  for i in range(len(integers)):
    question.append(integers[i])
    if i < len(integers) - 1:
      question.append(operations)
​
  return question
​
def evaluate_question(question):
  """Evaluates a math question list and returns the answer."""
​
  # Find the indices of the operations.
  operation_indices = [i for i, op in enumerate(question) if op in ['+', '-', '*', '/']]
​
  # Evaluate the question using the correct order of operations.
  while operation_indices:
    # Find the index of the first operation.
    index = operation_indices[0]
​
    # Perform the operation.
    operation = question[index]
    left_operand = question[index - 1]
    right_operand = question[index + 1]
    result = eval(str(left_operand) + operation + str(right_operand))
​
    # Replace the operation and its operands with the result.
    question = question[:index - 1] + [result] + question[index + 2:]
​
    # Update the list of operation indices.
    operation_indices = [i - 1 for i in operation_indices if i > index]
​
  # Return the final result.
  return question[0]
​
def find_incorrect_answers(question):
  """Finds incorrect answers to a math question list."""
​
  incorrect_answers = []
​
  # Try changing the order of operations.
  for operation in ['+', '-', '*', '/']:
    new_question = question.copy()
​
    # Find the indices of the operations.
    operation_indices = [i for i, op in enumerate(new_question) if op in ['+', '-', '*', '/']]
​
    # Change the order of operations.
    while operation_indices:
      # Find the index of the first operation.
      index = operation_indices[0]
​
      # Perform the operation.
      operation = new_question[index]
      left_operand = new_question[index - 1]
      right_operand = new_question[index + 1]
      result = eval(str(left_operand) + operation + str(right_operand))
​
      # Replace the operation and its operands with the result.
      new_question = new_question[:index - 1] + [result] + new_question[index + 2:]
​
      # Update the list of operation indices.
      operation_indices = [i - 1 for i in operation_indices if i > index]
​
    # Evaluate the question.
    incorrect_answers.append(evaluate_question(new_question))
​
  return incorrect_answers
​
# Test the function.
question = create_question()
print("Question:", question)
correct_answer = evaluate_question(question)
print("Correct answer:", correct_answer)
incorrect_answers = find_incorrect_answers(question)
print("Incorrect answers:", incorrect_answers)

虽然 eval() 是一个强大的工具,能够动态执行字符串形式的代码,但它的使用需要谨慎,尤其是在处理用户输入的数据时。确保限制 eval() 的执行环境可以帮助防止潜在的安全风险。此外,对于复杂的数学表达式解析和计算,考虑使用像 NumPySymPy 这样的专门库,这些库提供了更强大、更安全的数学运算支持。

相关推荐
Traced back10 分钟前
在vue3项目中利用自定义ref实现防抖
前端·javascript·vue.js
木易66丶41 分钟前
Vue中el-tree结合vuedraggable实现跨组件元素拖拽
前端·笔记
黑客KKKing1 小时前
网络安全-web应用程序发展历程(基础篇)
前端·安全·web安全
长风清留扬1 小时前
小程序开发-页面事件之上拉触底实战案例
前端·javascript·css·ios·微信小程序·小程序·html
时间sk1 小时前
CSS——25.伪元素1(“::first-letter ,::first-line ”)
前端·javascript·css
DarkFallYou1 小时前
E10鸿蒙App
java·开发语言·前端
会跑的兔子1 小时前
鸿蒙路由通信(路由跳转/参数传递)
前端·华为·harmonyos
晚风予星1 小时前
Vue-Cli/Rsbuild动态代理IP地址无需重新启动/依靠热更新
前端·vue.js
low神1 小时前
在macOS上安装Flutter和环境配置
前端·flutter·react native·macos·前端框架
高 朗1 小时前
【Vue】MacOS从0开始创建一个前端Vue项目并集成AntDesignVue
前端·vue.js·macos·anti-design-vue