【问题标题】:Turning raw_input into python expression将 raw_input 转换为 python 表达式
【发布时间】:2012-12-07 00:04:45
【问题描述】:

首先我正在使用线性编程包 PuLP

好的,我正在使用

通过 shell 收集用户输入
x = raw_input('-->')

现在用户将输入的信息是线性不等式形式(例如 2*a + 3*b

我现在无法通过以下方式获取输入并将其作为约束存储在 LP 中:

prob += x 

如果您对 python 文件中的信息进行硬编码,您只需添加:

prob += 2*a +3*b <= 4

对于这个例子

我得到的错误信息是:

TypeError:+= 不支持的操作数类型:'int' 和 'str'

有什么想法吗?

【问题讨论】:

  • 看看这个answer 有点类似的问题——那里使用的技术可以应用于您的问题。
  • 我解决这个问题的方法是:j="a" for i in constraints: i = i + " , \"" + j + "\"" print i k = eval(i) prob += k j += "a" prob 接受一个 python 表达式和一个唯一字符串的元组。

标签: python input typeerror


【解决方案1】:

尝试做:

x = float(raw_input('-->'))

我假设prob 是一个整数。 raw_input 将变量作为字符串返回,因此您希望将其转换为整数/浮点数。您收到错误是因为您试图“添加”一个字符串和一个整数;要么添加两个整数,要么连接两个字符串,但它们不能相互连接。因此,由于 x 必须是整数(或浮点数),请使用 float(obj) 或 int(obj)--- 你不知道 x 是浮点数还是整数,所以只需使用 @987654327 @。

要解析给定的不等式,请执行以下操作:

#assuming no spaces in the inequality are included; if the input isn't in the correct form, the program will NOT work correctly
ineq = input("What is the inequality? Input in the form: ax+by<=c: ")
a, b, c, sign, index = 0, 0, 0, '', 0 #multiple assignment
while ineq[index] != 'x': #until it reaches x, it will keep going
   a += int(ineq[index])
   if ineq[index] == 'x':
      break
   index += 1  # index = index + 1

index += 2 #to go through the 'x' and '+'

while ineq[index] != 'y':
   b += int(ineq[index])
   if ineq[index] == 'y':
      break
   index += 1

index += 1 #to go through the 'y'

if ineq[index] == '<' and ineq[index + 1] == '=':
   sign = '<='
elif ineq[index] == '>' and ineq[iddex + 1] == '=':
   sign = '>='
elif ineq[index] == '>':
   sign = '>'
else:
   sign = '<'

if sign == '<=' or sign == '>=':
   index += 2 #to go through the '>' or '<' and the '='
else:
   index += 1 #to go through the '>' or '<'

c = int(ineq[index:])
#code to solve the inequality

一种更简单、更快捷的方法是只提示用户输入“a”、“b”、“c”和“符号”的每个值。

【讨论】:

  • "现在用户输入的信息是线性不等式形式..."
  • 我得到 ValueError: invalid literal for int() with base 10: '3*a + 2*b
  • @minitech “我已经编写了一个方法,将用户定义的变量 a 和 b 存储到 LP 中。”您是否尝试解析(根据用户输入计算 a 和 b 的值)不等式?
  • +1,虽然您的答案不正确,但您发现问题的核心存在不一致。不幸的是,您的修复不是原始海报想要的。我不同意反对票,但对你来说就是这样。
  • @F3AR3DLEGEND:我想是的。 a 和 b 存在,输入将是一个线性方程 - 不能解析为 int 或 float。正如评论所证明的......
【解决方案2】:

因此,您的用户输入与您的代码内 python 示例之间存在根本区别:

在本例中,用户输入将是字符串文字"2*a + 3*b &lt;=4" 您无法将字符串文字附加到 prob,因为它需要一个约束或类似的对象——这就是您的错误的来源。

prob += x 

当您在 python 中评估相同的表达式时,您会注意到它缺少我在上面的语句周围有用地放置的引号。
这不是字符串文字,而是 python 表达式。纸浆的某些部分将其评估为约束对象,然后将该约束添加到问题中。

prob += 2*a +3*b <= 4



现在,完全忽略任意代码执行的可能性,解决问题的最简单方法是将用户输入评估为 python 代码,并让语言完成其余的工作:

exec("prob +="+x);

需要注意的是,除非此脚本完全供您个人使用,否则这是一个糟糕的想法。



从一般编程的角度来看,正确的解决方案是从字符串构造一个 LPConstraint 对象,然后将新构造的对象添加到 prob。

在理想情况下,您应该有一个用于 LPConstraint 的构造函数,该构造函数接受一个字符串,或者在库中的某个地方为您执行此操作的辅助方法。

我已经完成了(诚然所有 5 分钟......)一些阅读文档,但找不到任何此类方法。假设没有其他人运气好,您就只能自己解析字符串(以及随之而来的所有麻烦)并根据结果构建约束对象。



对于这样的问题,问题实际上是范围之一:

  • 你在哪里安装这个脚本?
  • 谁将使用它?
  • 它们会造成哪些潜在损害?

如果您正在创建要在高中或大学的计算机实验室中运行的 Python 脚本,看在上帝的份上,请不要使用 exec。

如果您出于自己的目的而创建要在您(也可能是您朋友的)机器上运行的 python 脚本,那么编写解析器就是在浪费您的时间和精力——您不会执行您自己的盒子上的恶意代码。

【讨论】:

  • 好的,我添加了一条关于 exec 不好的评论以及正确解决方案的外观。我认为手动解析字符串超出了这个问题的范围,我似乎找不到任何库函数来将字符串解析为 LPConstraint。感谢您提供反馈。
  • 嗯,这是我大学论文的一部分,我知道 exec() 很糟糕,但我只需要向我的论文主管证明该实现有效,如果被要求进行演示,我必须能够到。
  • 所以是的...使用exec的单行解决方案。
猜你喜欢
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2017-12-25
  • 2012-01-12
  • 2019-06-28
  • 1970-01-01
  • 2012-01-15
相关资源
最近更新 更多