python防呆等级测量

时间:2018-09-02 10:15:02

标签: python python-3.x list

def func(grades):
    first,*middle,last=grades
    try:
        avg=sum(middle)/len(middle)
        print(avg)
    except ZeroDivisionError:
        print("Atleast 3 grades must be inputed")
    except NameError:
        print("no letters are allowed in Grades")

func([50,60,60,60,70,90])
func([20,a,4,40])

您好,我正在使用此功能计算中级的平均成绩(不包括第一和最后一个成绩)。

我的问题是我如何才能改进此功能以使其“万无一失”(即,无论代码是什么输入而保持运行而不会崩溃)。

我尝试使用except:  克服它,但仍然NameError。 *答案中指出错误是由于功能外引起的,可以解决此错误吗?

3 个答案:

答案 0 :(得分:2)

您的document.GetElementsByTagName("div"); 与该函数无关,这是因为在初始化未定义的列表时,您正在尝试使用变量NameError

您似乎打算使用字符串进行测试:

a

但是,尽管如此,当您尝试对列表(而不是func([20, 'a', 4, 40]) :包含字符串)进行求和时,您的try..except仍然不会捕获抛出的TypeError 。如果输入的分数少于两个,您还应该抓住NameError

ValueError

如果传递了错误的数据类型,则会警告用户:

def func(grades):
    try:
        first,*middle,last=grades
        avg=sum(middle)/len(middle)
        print(avg)
    except (ZeroDivisionError, ValueError):
        print("At least 3 grades must be inputed")
    except TypeError:
        print("no letters are allowed in Grades")

答案 1 :(得分:1)

如果字符串在列表中,

sum将引发错误。因此,它忽略了try语句。您需要遍历列表,如果找到了字符串,则会引发错误。

def func(grades):
    try:
        first,*middle,last=grades
        for mid in middle:
            if isinstance(mid,str):raise ValueError
        avg=sum(middle)/len(middle)
        print(avg)
    except ZeroDivisionError:
        print("Atleast 3 grades must be inputed")
    except ValueError:
        print("no letters are allowed in Grades")

使用:

func([50,60,60,60,70,90])
func([20,"a",4,40])

输出:

62.5
no letters are allowed in Grades

如果您想忽略代码中的错误:

try:
    func([50,60,60,60,70,90])
    func([20,a,4,40])
except:  #ignore every error
    print("Invalid Data!")  #will continue/no crash

输出:

62.5
Invalid Data!

答案 2 :(得分:0)

正如注释中指出的那样:您正在向函数声明a(一个变量),但没有声明-因此NameError。这是在您在函数内部之前 发生的。您不能在其内部进行处理-您必须在函数调用周围对其进行处理:

try:
    calcfunc([20,a,4,40])  # a is the name of a variable that python does not know about
except NameError:
    print("Dont call stuff with variables that you did not declare!")

让我们徒然尝试使用自定义错误来完善代码,从而改进您的代码:

class InputTooShortError(ValueError):
    pass

class NotAnIntError(ValueError):
    pass

def calcfunc(grades):
    try:
        if len(grades) < 3:
            raise InputTooShortError()

        first,*middle,last=grades

        if not all(isinstance(p,int) for p in middle):
            raise NotAnIntError() 

        avg=sum(middle)/len(middle)
        print("Avg of {} = {}".format(middle,avg))
    except InputTooShortError:
        print("Atleast 3 grades must be inputed")
    except NotAnIntError:
        print("Your input contains non-numbers: {}".format(grades))
        correct = [first]+[p for p in middle if isinstance(p,int)]+[last]
        print("Using only {} as input:".format(correct))
        calcfunc(correct)

calcfunc([])
calcfunc([20,'a',4,40])       
calcfunc([50,60,60,60,70,90])

try:
    calcfunc([20,a,4,40]) 
except NameError:
    print("Dont call stuff with variables that you did not declare!")

输出:

# calcfunc([])
Atleast 3 grades must be inputed

# calcfunc([20,'a',4,40])
Your input contains non-numbers: [20, 'a', 4, 40]
Using only [20, 4, 40] as input:
Avg of [4] = 4.0

# calcfunc([50,60,60,60,70,90])
Avg of [60, 60, 60, 70] = 62.5

# calcfunc([20,a,4,40]) 
Dont call stuff with variables that you did not declare!

如果您将非列表输入作为输入,这仍然会崩溃。您可以使用

解决此问题
if not isInstance(grades,list):
    # create another error and handle it 

如果使用

,则可以允许各种迭代
from collections import Iterable

if not isinstance(e, Iterable):
    # do something