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 这样的专门库,这些库提供了更强大、更安全的数学运算支持。

相关推荐
糕冷小美n7 小时前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥7 小时前
Technical Report 2024
java·服务器·前端
沐墨染7 小时前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion7 小时前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks7 小时前
前端将死,Agent 永生
前端·人工智能·ai编程
问道飞鱼8 小时前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建
爱上妖精的尾巴8 小时前
8-10 WPS JSA 正则表达式:贪婪匹配
服务器·前端·javascript·正则表达式·wps·jsa
Aliex_git9 小时前
浏览器 API 兼容性解决方案
前端·笔记·学习
独泪了无痕9 小时前
useStorage:本地数据持久化利器
前端·vue.js
程序员林北北10 小时前
【前端进阶之旅】JavaScript 一些常用的简写技巧
开发语言·前端·javascript