我无法让“if”命令正常工作

时间:2014-10-31 02:05:04

标签: python python-2.7 if-statement python-2.x addition

我正在尝试添加两个数字,即使它们包含“ - ”或“。”,但我的if命令在某种程度上是错误的,这里是代码:

def add():
    print "\nAddition"
    print " "
    print "What is your first number?"
    preadd1=raw_input(prompt)
    print "What is your second number?"
    preadd2=raw_input(prompt)
    if preadd1.isdigit() and preadd2.isdigit():
        add1=int(preadd1)
        add2=int(preadd2)
        add_answer= add1+add2
        print " "
        print add_answer
        add()
    elif preadd1=="pike" or preadd2=="pike":
        pike()
    elif "-" in preadd1 or "." in preadd1 or "-" in preadd2 or "." in preadd2 and preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit():
        add1=float(preadd1)
        add2=float(preadd2)
        add_answer=add1+add2
        print ""
        print add_answer
        add()
    else:
        print "\nPlease enter two numbers."
        add()
add()

当我输入像“-sf”这样的非数字时,它会返回错误:

ValueError: could not convert string to float: -sf

这对我来说毫无意义,因为我确定preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit()

请帮忙。

5 个答案:

答案 0 :(得分:2)

您的问题中有太多代码:

让我们将您的代码示例缩减为您实际关注的内容:

preadd1 = "-sf"
preadd2 = "3"

if "-" in preadd1 or "." in preadd1 or "-" in preadd2 or "." in preadd2 and preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit():
    print "Shouldn't get here!"

我对你的问题的看法:

这是你的表达:

if "-" in preadd1 or "." in preadd1 or "-" in preadd2 or "." in preadd2 and preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit():

你的字符串中有一个-,所以整个表达式都是真的。

真正的解决方案:

您应该查看这个问题,了解各种正确的方法来测试字符串是否可以转换为浮点数:Checking if a string can be converted to float in Python

答案 1 :(得分:2)

不要试图预测适合float转化的文字,而只是去做并处理后果。

另请参阅:EAFP

说明概念的不完整摘要:

while True:
    try:
        text = raw_input()
        val = float(text)
        break
    except ValueError as e:
        continue

答案 2 :(得分:0)

尝试将raw_input()包裹在int()中。您需要捕获错误,以便它不会进入if

答案 3 :(得分:0)

正如Bill所说,你的if语句是短路,这意味着只要or对中的第一个语句是True,整个语句就会立即评估到True。我觉得我还应该注意到,根据文档,andor之前进行了评估,这也可能导致一些问题。您可以通过一些放置好的括号来解决这个问题,但如果我可以提出替代方案:

#!/usr/bin/env python

def add():
    print "\nAddition\n"
    print "What is your first number?"
    prompt=""
    preadd1=raw_input(prompt)
    print "What is your second number?"
    preadd2=raw_input(prompt)
    add1=toint(preadd1)
    add2=toint(preadd2)
    add1f=tofloat(preadd1)
    add2f=tofloat(preadd2)
    if (add1 is not None) and (add2 is not None):
        add_answer=add1+add2
        print " "
        print add_answer
        add()
    elif (add1f is not None) and (add2f is not None):
        add_answer=add1+add2
        print ""
        print add_answer
        add()
    elif preadd1=="pike" or preadd2=="pike":
        pike()
    else:
        print "\nPlease enter two numbers."
        add()

def toint(x):
    try:
        return int(x)
    except ValueError:
        return None

def tofloat(x):
    try:
        return float(x)
    except ValueError:
        return None

if __name__ == "__main__":
    add()

函数toint()tofloat()首先尝试将输入转换为相应的类型。如果ValueError块中出现try(意味着输入不是有效intfloat),则except块会捕获错误,而是返回None

我还想指出,这不一定是递归的最佳用法,但因为我认为这只是一个"学习语言"我把它留在我的代码中的项目类型。在这种情况下,使用while循环而不是递归可能会更好。

修改:编辑代码以包含elif语句,因为我们不知道pike()中的内容。 Kudos @BillLynch。

答案 4 :(得分:0)

您当前的问题是无法理解Python如何理解if语句中的条件。您希望 Python评估所有or,然后继续and,但这不是Python的工作方式。

您认为自己写的是什么:

 ("-" in preadd1 or "." in preadd1 or "-" in preadd2 or "." in preadd2)
 and 
 (preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() 
 and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit())

Python看到了什么:

 ("-" in preadd1)
 or 
 ("." in preadd1)
 or 
 ("-" in preadd2)
 or (
 "." in preadd2 and  preadd1.replace("-","").isdigit() and preadd1.replace(".","").isdigit() 
 and preadd2.replace("-","").isdigit() and preadd2.replace(".","").isdigit()
 )

看着这种方式,你会看到Python在决定整个条件为True并继续使用缩进块之前从未读过第一个条件("-" in preadd1)。

您可以使用括号正确绑定运算符并获得所需的结果。但是你应该对那个广泛的测试感到困扰,以确定字符串是否可以转换为浮点数。最重要的是,它应该被分解为一个函数或方法,其名称可以指示您正在做什么,但在Python中执行类似的操作更为典型:

 try:
      fl1 = float(preadd1)
 except:
      fl1 = None

 try:
     fl2 = float(preadd2)
 except:
     fl2 = None

 if fl1 is not None and fl2 is not None:
     # Do your float logic here
 else:
     # Do your non-float logic here