如何处理raw_input中的整数和字符串?

时间:2012-01-22 14:07:21

标签: python user-input

仍在尝试了解python。它与php如此不同。

我将选项设置为整数,问题出在我的菜单上我也需要使用字母。

如何将整数和字符串一起使用?
为什么我不能设置为字符串而不是整数?

def main(): # Display the main menu
    while True:
        print
        print "  Draw a Shape"
        print "  ============"
        print
        print "  1 - Draw a triangle"
        print "  2 - Draw a square"
        print "  3 - Draw a rectangle"
        print "  4 - Draw a pentagon"
        print "  5 - Draw a hexagon"
        print "  6 - Draw an octagon"
        print "  7 - Draw a circle"
        print
        print "  D - Display what was drawn"
        print "  X - Exit"
        print

        choice = raw_input('  Enter your choice: ')

        if (choice == 'x') or (choice == 'X'):
            break

        elif (choice == 'd') or (choice == 'D'):
            log.show_log()

        try:
            choice = int(choice)
            if (1 <= choice <= 7):

                my_shape_num = h_m.how_many()
                if ( my_shape_num is None): 
                    continue

                # draw in the middle of screen if there is 1 shape to draw
                if (my_shape_num == 1):
                    d_s.start_point(0, 0)
                else:
                    d_s.start_point()
                #
                if choice == 1: 
                    d_s.draw_triangle(my_shape_num) 
                elif choice == 2: 
                    d_s.draw_square(my_shape_num) 
                elif choice == 3:             
                    d_s.draw_rectangle(my_shape_num) 
                elif choice == 4:             
                    d_s.draw_pentagon(my_shape_num) 
                elif choice == 5:             
                    d_s.draw_hexagon(my_shape_num) 
                elif choice == 6:             
                    d_s.draw_octagon(my_shape_num) 
                elif choice == 7: 
                    d_s.draw_circle(my_shape_num)

                d_s.t.end_fill() # shape fill color --draw_shape.py-- def start_point

            else:
                print
                print '  Number must be from 1 to 7!'
                print

        except ValueError:
            print
            print '  Try again'
            print

5 个答案:

答案 0 :(得分:6)

让我用另一个问题回答你的问题:
是否真的有必要混合字母和数字?
他们不能只是所有字符串吗?

好吧,让我们走很长的路,看看该计划正在做什么:

  1. 显示主菜单
  2. 询问/接收用户输入
    • 如果有效:确定
    • 如果不是:打印错误信息并重复
  3. 现在我们有了一个有效的输入
    • 如果是一封信:做一项特殊任务
    • 如果是数字:请调用正确的绘图功能
  4. 第1点。让我们为此创建一个函数:

    def display_menu():
        menu_text = """\
      Draw a Shape
      ============
    
      1 - Draw a triangle
      2 - Draw a square
      D - Display what was drawn
      X - Exit"""
        print menu_text
    

    display_menu非常简单,因此无需解释它的作用,但我们稍后会看到将此代码放入单独函数中的优势。

    第2点。这将通过循环完成:

    options = ['1', '2', 'D', 'X']
    
    while 1:
        choice = raw_input('  Enter your choice: ')
        if choice in options:
            break
        else:
            print 'Try Again!'
    

    第3点。好吧,经过一番思考后,特殊任务可能不那么特别,所以让我们把它们放到一个函数中:

    def exit():
        """Exit"""  # this is a docstring we'll use it later
        return 0
    
    def display_drawn():
        """Display what was drawn"""
        print 'display what was drawn'
    
    def draw_triangle():
        """Draw a triangle"""
        print 'triangle'
    
    def draw_square():
        """Draw a square"""
        print 'square'
    

    现在让我们把它们放在一起:

    def main():
        options = {'1': draw_triangle,
                   '2': draw_square,
                   'D': display_drawn,
                   'X': exit}
    
        display_menu()
        while 1:
            choice = raw_input('  Enter your choice: ').upper()
            if choice in options:
                break
            else:
                print 'Try Again!'
    
        action = options[choice]   # here we get the right function
        action()     # here we call that function
    

    切换的关键在于options现在不再是list而是dict,所以如果您只是像if choice in options那样迭代它,那么您的迭代就是在['1', '2', 'D', 'X'],但如果你options['X']你得到了退出功能(不是很棒!)。

    现在让我们再次改进,因为保持主菜单消息和options词典不太好,一年后我可能会忘记改变其中一个,我不会得到我想要的东西而我懒惰,我不想做同样的事情,等等...... 那么为什么不将options字典传递给display_manu并让display_menu使用__doc__中的文档字符串完成所有工作来生成菜单:

    def display_menu(opt):
        header = """\
      Draw a Shape
      ============
    
    """
        menu = '\n'.join('{} - {}'.format(k,func.__doc__) for k,func in opt.items())
        print header + menu
    

    对于OrderedDict,我们需要dict而不是options,因为OrderedDict顾名思义保留其项目的顺序(请查看{{ 3}})。所以我们有:

    def main():
        options = OrderedDict((('1', draw_triangle),
                               ('2', draw_square),
                               ('D', display_drawn),
                               ('X', exit)))
    
        display_menu(options)
        while 1:
            choice = raw_input('  Enter your choice: ').upper()
            if choice in options:
                break
            else:
                print 'Try Again!'
    
        action = options[choice]
        action()
    

    要注意你必须设计你的行动,以便他们都有相同的签名(他们应该是这样的,无论如何,他们都是行动!)。您可能希望将callables用作操作:已实现__call__的类的实例。创建基类Action类并从中继承将是完美的。

答案 1 :(得分:2)

我不清楚你在这里问的是什么。 raw_input()始终返回str类型。如果您想自动将用户输入转换为int或其他(简单)类型,您可以使用input()函数执行此操作。

您已选择让用户输入字母或数字,您可以在菜单中为“数字”选项分配数字。或者,您可以更好地利用try / except,例如:

try:
    choice = int(user_input)
    if choice == 1:
        # do something
    elif ...
except ValueError: # type(user_input) != int
    if choice == 'X' or choice == 'x':
        # do something
    elif ...
    else:
        print 'no idea what you want' # or print menu again

答案 2 :(得分:2)

我相信您的代码可以简化一下:

def main():
    while 1:
        print
        print "  Draw a Shape"
        print "  ============"
        print
        print "  1 - Draw a triangle"
        print "  2 - Draw a square"
        print "  3 - Draw a rectangle"
        print "  4 - Draw a pentagon"
        print "  5 - Draw a hexagon"
        print "  6 - Draw an octagon"
        print "  7 - Draw a circle"
        print
        print "  D - Display what was drawn"
        print "  X - Exit"
        print
        choice = raw_input('  Enter your choice: ').strip().upper()
        if choice == 'X':
            break
        elif choice == 'D':
            log.show_log()
        elif choice in ('1', '2', '3', '4', '5', '6', '7'):
            my_shape_num = h_m.how_many()
            if my_shape_num is None:
                continue
            elif my_shape_num == 1:
                d_s.start_point(0, 0)
            else:
                d_s.start_point()
            if choice == '1':
                d_s.draw_triangle(my_shape_num)
            elif choice == '2':
                d_s.draw_square(my_shape_num)
            elif choice == '3':
                d_s.draw_rectangle(my_shape_num)
            elif choice == '4':
                d_s.draw_pentagon(my_shape_num)
            elif choice == '5':
                d_s.draw_hexagon(my_shape_num)
            elif choice == '6':
                d_s.draw_octagon(my_shape_num)
            elif choice == '7':
                d_s.draw_circle(my_shape_num)
            d_s.t.end_fill()
        else:
            print
            print '  Invalid choice: ' + choice
            print

答案 3 :(得分:1)

  

我如何一起使用整数和字符串?为什么我不能设置为字符串而不是整数?

嗯,string formatting非常有用:

>>> a_string = "Hi, I'm a string and I'm"
>>> an_integer = 42
>>> another_string = "milliseconds old"
>>> we_are_the_champions = "%s %d %s" % (a_string, an_integer, another_string)
>>> we_are_the_champions
"Hi, I'm a string and I'm 42 milliseconds old"

你甚至可以将该整数抛出到字符串中:

>>> champions_are_here = "Hi, I'm a string and I'm even older, I'm %d milliseconds old" % 63
>>> champions_are_here
"Hi, I'm a string and I'm even older, I'm 63 milliseconds old"

答案 4 :(得分:0)

你可以把你的'字母选项'放在except块中。如果输入不能转换为整数,则执行该块,例如,如果是一封信。


然而,使try块尽可能小是一个很好的习惯。所以最好这样做:

try:
    choice = int(choice)
except ValueError:
    choice = choice.lower() # Now you don't have to check for uppercase input

然后,您可以检查选择是否为int type(choice) == int