0

以下是我在Python 2.7中构建的一个简单的Mils to Degrees转换计算器的(半)完成版本,作为学习练习。我是Python新手,仍然在努力解决问题。前提是,用户选择将mils转换成度,反之亦然。用户输入所选单位的方位角并将其转换为另一个单位。如果用户选择一个无效的菜单选项,他会被通知。如果他输入范围之外的方位角(1-360度,密耳为1-6400),他将被通知并且必须重新开始。问题是,如果用户输入一个无效的方位角,比如365度,他会被踢回菜单。 有没有办法返回到if/else循环中的上一步?我搜索了论坛和文档,它似乎不可能。另外,由于我是Python的新手,如何使此代码更高效? 我是否需要如果elif语句在函数定义中,还是可以将它们组合在一起而不会产生错误或冗余输出?我没有成功这样做。所有的投入都欢迎和赞赏。Python转换计算器循环/代码效率

#Mil-Deg.py 
#Simple Mils/Degrees Conversion Calculator 
#6 JAN 2013 

#Note: 6400 mils/360 degrees in a circle. 17.78 mils to one degree. 

import sys 
import math 
import winsound 

#Define menu function 
def menu():      

    print 
    print " Mils/Degrees Conversion Calculator" 
    print "-" * 38 
    print 
    print "Options: " 
    print "1. Degrees to Mils" 
    print 
    print "2. Mils to Degrees" 
    print 
    print "3. Quit" 
    print "-" * 20 
    print 
    return input ("Choose your option: ") 
    print 

#Define mils to degrees function  
def m2d(a): 
    if a <= 6400 and a >= 1: #get user input within given range  
     b = 17.78 
     c = round((a/b),0) #convert and round to nearest degree 
     if c > 359 or c < 1: #change 0 degrees to 360    
      c = 360 
      #Output 
      print 
      print a, "mils =", int (c), "degrees"  
     else: 
      print 
      print a, "mils =", int (c), "degrees" 
    elif a > -1 and a < 1:  #change 0 mils to 6400 
     a = 6400 
     b = 17.78 
     c = round((a/b), 0) #math, same as above 
     if c > 359 or c < 1: #0 to 360, same as above    
      c = 360 
      #Output 
      print 
      print 6400, "mils =", int (c), "degrees" 
     else: 
      print 
      print a, "mils =", int (c), "degrees" 
    else: 
     #warning, mulligan 
     winsound.Beep(440, 500) 
     print 
     print "*** There are only 6400 mils in a circle. Try again. ***" 
    print 
    print "-" * 38 
    print 

#define degrees to mils function   
def d2m(b): 
    if b <= 360 and b > 0:   #get user input within given range 
     a = 17.78 
     c = round((b * a),0)  #convert and round to nearest mil 
     if c >= 6400:    #set limit to 6400 mils 
      c = 6400 
      #Output 
      print 
      print b, "degrees =", int (c), "mils" 
     else: 
      print 
      print b, "degrees =", int (c), "mils" 
    elif b > -1 and b < 1:   #change 0 to 360 degrees 
     b = 360 
     a = 17.78 
     c = round((b * a),0)  #math, same as above 
     if c >= 6400: 
      c = 6400 
      #Output 
      print 
      print 360, "degrees =", int (c), "mils" 
     else: 
      print 
      print b, "degrees =", int (c), "mils" 
    else: 
     #warning 
     winsound.Beep(440, 500) 
     print 
     print "*** There are only 360 degrees in a circle. Try again. ***" 
    print 
    print "-" * 38 
    print 


#Begin program 
loop = 1 
choice = 0 
while loop == 1: 
    choice = menu()     #Menu function call 
    if choice == 1:     #If user chooses degrees to mils: 
     #Output 
     print 
     print "Enter your azimuth in degrees (1 - 360)" 
     print 
     d2m(input("Degrees: "))  #function call 

    elif choice == 2:    #If user chooses mils to degrees: 
     #Output 
     print 
     print "Enter your azimuth in mils (1 - 6400)" 
     print 
     m2d(input("Mils: "))  #function call 

    elif choice == 3:    #If user chooses quit, exit program 
     loop = 0 

    elif choice != 1 and choice != 2 and choice != 3: #if user makes invalid menu choice: 
     #warning 
     winsound.Beep(440, 500) 
     print 
     print 
     print 
     print choice, "is not a valid choice." 
     print 
     print "Please choose from the available options." 
     print 
     print 

print 
print "-" * 38 
print 
print "Thank you for using Mil-Deg.py" 
print 
print 
+0

'如果-else'不是一个循环,尝试'while'循环这里。 –

+0

你的'return'语句后面有'print',它永远不会被执行。你还应该使用'raw_input',它比'input'安全得多。 'raw_input'将接受输入并将其转换为一个字符串。 –

+0

@AshwiniChaudhary,谢谢。我有一点C经验。我应该意识到这一点。我尝试过,但我把它放在函数定义而不是执行块,它导致了一个无限循环。现在,我把它放在正确的地方,它按预期工作。谢谢。 – Betastate

回答

0

我清理你的代码了一下,做了以下修改:

  1. 固定打印报表
  2. 固定的方法名。方法名称应该是描述性的。字符可以自由输入,所以不要小心输入完整的单词。
  3. 你的方法是打印输出和复制逻辑,所以我清理它们只是返回值而已。这样你可以在以后的其他程序中使用这些方法。
  4. 添加了一个辅助方法来检查用户的输入(再次停止重复/复制粘贴相同的代码)。
  5. 我使用了字符串的format函数,以便于打印计算。

下面是结果:

import sys 
import math 
import winsound 

#Define menu function 
def menu():      
    '''This function prints the main menu''' # this is a docstring for your method 
    print "\nMils/Degrees Conversion Calculator" 
    print "-" * 38 
    print "\nOptions: " 
    print "1. Degrees to Mils\n" 
    print "2. Mils to Degrees\n" 
    print "3. Quit\n" 
    print "-" * 20 
    print "\n" 


#Define mils to degrees function  
def mils_to_degrees(a): # use method names that make sense 
    '''This function takes mils and converts them into degrees''' 
    b = 17.78 
    c = round((a/b),0) #convert and round to nearest degree 
    if c > 359 or c < 1: #change 0 degrees to 360    
     c = 360 
    return (a,int(c)) 

#define degrees to mils function   
def degrees_to_mils(b): 
    '''This method converts degrees to mils''' 
    a = 17.78 
    if b == 0: 
     b = 360 
    c = round((b * a),0)  #math, same as above 
    if c > 6400:    #set limit to 6400 mils 
     c = 6400 
    return (b,c) 

def check_input(user_input): 
    '''Checks if the input is a number''' 
    try: 
     converted_number = int(user_input) 
    except ValueError: 
     return -1 
    return converted_number 

#Begin program 
loop = True 
while loop: 
    menu() 
    choice = int(raw_input("Choose your option: ")) 
    if choice not in [1,2,3]: 
     winsound.Beep(440, 500) 
     print choice, "is not a valid choice.\n" 
     print "Please choose from the available options.\n" 
     menu() 
     choice = int(raw_input('Choose your option: ')) 

    if choice == 1: 
     print "\nEnter your azimuth in degrees (0 - 360)\n" 
     degrees = check_input(raw_input('Degrees: ')) 
     if degrees > 360 or degrees < 0: 
      print 'Please enter a value between 0 and 360' 
     else: 
      result = degrees_to_mils(degrees) # function call 
      print '{} degrees = {} mils'.format(*result) 
      print "-" * 38 

    elif choice == 2:    #If user chooses mils to degrees: 
     print "\nEnter your azimuth in mils (1 - 6400)\n" 
     mils = check_input(raw_input('Mils: ')) 
     if mils > 6400 or mils < 1: 
      print 'Please enter a value between 1 and 6400' 
     else: 
      result = mils_to_degrees(mils)  #function call 
      print '{} mils = {} degrees'.format(*result) 
      print "-" * 38 

    elif choice == 3: 
     loop = False 

print "\n" 
print "-" * 38 
print "\nThank you for using Mil-Deg.py\n\n" 
+0

哇。这是对我原来的代码的巨大改进。我相信这对你来说很容易,但你已经给了我很多东西来学习和吸收。非常感谢,伙计。我非常感谢帮助! – Betastate

0

由于阿什维尼在评论中提到,你if-else条件块并不是一个真正的循环,所以用while循环应该回答你的问题的程序流程的一部分。

就elif的和普通的优雅而言,可以考虑this method of handling multiple options using a dictionary of functions;在这里少数选项当然不是必需的,但它可能会给你一些练习Python如何处理字典和函数的类。

在风格上,我建议使用换行符转义序列\n而不是所有这些无关的打印语句。

+0

卡梅隆,while循环确实解决了上述问题。我仍在处理其余的建议。我需要再读几遍字典。感谢您的建议。我很感激。 – Betastate