Как обработать как целое число, так и строку из raw_input? - PullRequest
3 голосов
/ 22 января 2012

Все еще пытаюсь понять 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 ]

6 голосов
/ 22 января 2012

Позвольте мне ответить на ваш вопрос другим вопросом:
Действительно ли необходимо смешивать буквы и цифры?
Разве они не могут быть просто строками?

Ну, давайте пройдем долгий путь и посмотрим, что делает программа:

  1. Отображение главного меню
  2. Запрос / получение ввода пользователя
    • Если действительно: хорошо
    • Если нет: напечатайте сообщение об ошибке и повторите
  3. Теперь у нас есть правильный ввод
    • Если это буква:выполнить специальное задание
    • Если это число: вызвать правильную функцию рисования

Точка 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как следует из названия, сохраняйте порядок своих предметов (посмотрите официальный документ ).Итак, у нас есть:

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()

Остерегайтесь того, что вы должны разработать свои действия так, чтобы они все имели одинаковую подпись (в любом случае они должны быть такими, они все действия!).Возможно, вы захотите использовать вызываемые элементы в качестве действий: экземпляры класса с __call__ реализованы.Создание базового Action класса и наследование от него будет идеальным здесь.

2 голосов
/ 22 января 2012

Мне не совсем понятно, о чем вы здесь спрашиваете. raw_input() всегда возвращает тип str. Если вы хотите автоматически преобразовать пользовательский ввод в int или другой (простой) тип, вы можете использовать функцию input(), которая делает это.

Вы выбрали, чтобы пользователь мог вводить букву или цифру, вы также можете назначить опции «буквы» для номера в меню. Или вы можете воспользоваться преимуществами try / except, например ::10000

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 голосов
/ 22 января 2012

Полагаю, ваш код можно немного упростить:

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
1 голос
/ 22 января 2012

Как я могу использовать целое число и строку вместе?Почему я не могу установить в строку, чем целое число?

Ну, форматирование строки довольно полезная вещь:

>>> 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"
0 голосов
/ 22 января 2012

Вы можете просто поместить «опции письма» в блоке исключений. Этот блок выполняется, если входные данные не могут быть преобразованы в целое число, например если это письмо.


Однако хорошо сделать ваши блоки try как можно меньше. Так что лучше сделать это:

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

Затем вы можете проверить, был ли выбор int с type(choice) == int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...