【问题标题】:Multiple User Input with Try Except Python使用除 Python 之外的 Try 的多用户输入
【发布时间】:2021-10-14 19:36:10
【问题描述】:

我的任务是创建一个 python 程序,该程序将询问用户输入并计算每月还款额,这是我必须解决的公式:Formula。这样做并不太难,但是作为奖励,导师要求尝试使用户输入“牢不可破”,这意味着如果输入了预期之外的任何值,它不会破坏程序。我认为这可以通过 Try except 轻松完成,这就是我所做的,但是我相信我的代码可以以更简洁的方式编写,而不是对每个输入都使用 Try except,如下所示:

err = "Please enter a number only!!"
while True:
    try:
        A = int(input("How much were you loaned? "))
    except ValueError:
        print(err)
        continue
    else:
        break
while True:
    try:
        R = float(input("At what monthly rate interest? ")) / 100
    except ValueError:
        print(err)
        continue
    else:
        break
while True:
    try:
        N = int(input("And how many years is the loan for? "))
    except ValueError:
        print(err)
        continue
    else:
        break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly") 

我觉得也许用户输入可以放入一个 For 循环,或者可能所有这些都放入一个 Try except 块?在考虑之后,我将所有输入放入一个 Try except 块中,但是一旦您未能正确输入用户输入的预期数据,它就会立即回到开头,而不是您所在的问题。这不是我想要的。看看:

err = "Please enter a number only!!"
while True:
    try:
        A = int(input("How much were you loaned? "))
        R = float(input("At what monthly rate interest? ")) / 100
        N = int(input("And how many years is the loan for? "))
    except ValueError:
        print(err)
        continue
    else:
        break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly")

您认为我可以如何修改此代码以使其更简洁、更短且更高效,而无需对每个用户输入都进行尝试?

【问题讨论】:

  • 任何时候您编写几乎相同的代码块,解决方案是将该块移动到一个函数中,并使用指定每个原始块的唯一详细信息的参数调用它。
  • 尝试只通过while循环。写while True and if type(A)==int and type(R)==float and type(N)==int: break else: continue。我随便写的,用适当的缩进写????

标签: python user-input try-except


【解决方案1】:

对其进行模块化,并使用一个通用函数来处理输入和循环,直到用户输入所要求的内容。

def get_num(prompt="Enter number: "):
    """
    (str) -> num
    Outputs a prompt and loops until a valid number is
    entered by the user, at which point that value is
    returned and the function terminates
    """
    while True:
        num = input(prompt)
        try:
            num = float(num)
            return num
        except:
            print("Must enter a valid number")

def do_calc():
    """(None) -> None
    Get user input, perform calculations and output results
    """
    A = int(get_num("How much were you loaned? "))
    R = get_num("At what monthly rate interest? ") / 100
    N = int(get_num("And how many years is the loan for? "))
    RA = R * A
    RN = 1 - (1 + R) ** -N
    P = RA / RN
    print(f"You will pay £{round(P, 2)} yearly or £{P/12:.2f} monthly")

do_calc()

使用 Python 3 中的 f-string 非常好用且优雅——只需将值或计算插入花括号内即可。根据评论中的建议,您可能希望使用显示的圆形函数或格式选项显示两位小数。

命名变量的更 Pythonic 方式是

  • 金额而不是A
  • 率而不是R
  • num_years 而不是 N 等等。

【讨论】:

  • +1 用于推荐 f 字符串。作为对这一点的补充:您仍然可以在 f 字符串中包含格式化语句。例如:f"{P/12:.2f}" 将打印P/12 的值,格式为带有两位小数的浮点数。
  • @Antimon 谢谢,我已将其添加为改进。
【解决方案2】:

提取函数中的重复过程,以及所有相关输入。
我在最终输出中添加了一些格式以避免过多的小数

def get_value(message, func, denominator = 1):
   try_again = True
   v = None
   while try_again:
      try:
         v = func(input(message))/denominator
      except ValueError:
         print("Please enter a number only!!")
      else:
         try_again= False   
   return v

A = get_value("How much were you loaned? ", int)
R = get_value("At what monthly rate interest? ", float, denominator=100.0)
N = get_value("And how many years is the loan for? ", int)

RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £ {:.2f} yearly or £ {:.2f} monthly".format(P, P / 12)) 

【讨论】:

  • 您可以通过直接从try 块中直接returning 大大简化此操作。不需要vtry_againelse 块:只是一个无限的while True 循环,直到没有ValueError 被引发。
  • 另外,不要尝试在try 块中包含除法;您已经介绍了 OP 原始代码中没有的除零错误的可能性。让get_value 担心返回intfloat,并让调用者在适当的时候将返回值除以100。
  • @chepner 分母不是用户输入。我认为可以安全地假设没有调用指定 denominator=0 的函数
  • 假设不存在这样做的选项会更安全。 get_value 的工作应该是解析和验证用户输入,而不是使用该输入进行额外处理。
  • 你真的认为get_value("...", float, denominator=100.0) 是对get_value("...", float) / 100.0 的改进吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
相关资源
最近更新 更多