Взаимодействие с пользователем через циклы while / выход из двух циклов while

Здравствуйте, товарищи программисты.

Я довольно новичок в Python и вообще в программировании, и я не знаю, как обрабатывать пользовательский ввод лучше всего. Мой друг предложил циклы while, и они работали достаточно хорошо, но теперь у меня серьезная проблема.

Программа спрашивает пользователя, какой из трех способов вычисления числа Пи он хочет. После его/ее выбора, т.е. способ вычисления Pi с использованием многоугольника, который удваивает количество углов после каждой итерации, он спрашивает, сколько цифр хочет видеть пользователь или сколько петель нужно рассчитать и т. д. Я также добавил код, который проверяет, что написал пользователь , например если пользователя просят ввести y или n, но он набирает b, программа напоминает ему об этом и спрашивает снова.

Этот стиль привел к появлению циклов, внутренних циклов, внутренних циклов, и теперь он больше похож на HTML-код, чем на Python, и его немного сложно понять...

Взглянем:

#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

prgrm_ctrl_main_while_start = 0
while prgrm_ctrl_main_while_start == 0:

    print "Please select the type of algorithm you want to calculate Pi."
    usr_ctrl_slct_algrthm = raw_input("'p' to use polygons, 'm' to use the Monte-Carlo algorithm or 'c' for the Chudnovsky algorithm: ")
    print " "
    if usr_ctrl_slct_algrthm == 'p':

        #import libraries
        import time
        from mpmath import *

        #starting values 
        n_corners = mpf(8)                                                                  
        counter = 0                                                                         
        while_loop_check_itertions = 0
        while while_loop_check_itertions == 0:

            print "Pi will be calculated more precisely the more iterations you select but it'll also take longer!"
            loops = int(input("Please select number of iterations (1 - 10.000.000): "))
            print " "
            if  1 <= loops <=  10000000:
                loops = loops - 1
                decimals = int(input("Please select the amount of decimals you want to see: "))
                print " "
                decimals = decimals + 1
                starttime = time.clock()


                mp.dps = decimals                                                                           


                while counter <= loops:                                                             
                    counter = counter + 1                                                           

                    n_corners = mpf(n_corners) * mpf(2)                                                 

                    circle = mpf(360)                                                           
                    alpha = mpf(circle) / mpf(n_corners)                                    
                    beta = mpf(alpha) / mpf(2)                                              
                    radiansBeta = mpf(mp.radians(beta))                             
                    opp_leg = mpf(mp.sin(radiansBeta))                                                                                                      
                    edge_lngth = mpf(opp_leg) * mpf(2)                                                                                          
                    circmfrnce = mpf(n_corners) * mpf(edge_lngth)                                                       
                    pi = mpf(circmfrnce) / mpf(2)                                                                                           

                    print "Pi: ", mpf(pi)
                    print "Time to calculate: ", time.clock() - starttime, "seconds"
                    print " "
                    prgrm_ctrl_p_algrthm_while_start = 0
                    while prgrm_ctrl_p_algrthm_while_start == 0:
                        usr_ctrl_slct_p_algrthm = raw_input("Would you like to try this algorithm again? (y/n): ")
                        print " "
                        if usr_ctrl_slct_p_algrthm == 'y':
                            usr_ctrl_slct_p_algrthm_slction = 0
                            break
                        elif usr_ctrl_slct_p_algrthm == 'n':
                            usr_ctrl_slct_p_algrthm_slction = 1
                            break
                        else:
                            print "You must either type 'y' or 'n'!"
                            continue
                    if usr_ctrl_slct_p_algrthm_slction == 0:
                        continue
                    else:
                        usr_ctrl_slct_diffrt_algrthm_while_start = 0
                        while usr_ctrl_slct_diffrt_algrthm_while_start == 0:
                            usr_ctrl_slct_diffrt_algrthm = raw_input("Do you want to use another algorithm? (y/n): ")
                            print " "
                            if usr_ctrl_slct_diffrt_algrthm == 'y':
                                usr_ctrl_slct_diffrt_algrthm_slction = 0
                                break
                            elif usr_ctrl_slct_diffrt_algrthm == 'n':
                                print "See you next time!"
                                print " "
                                usr_ctrl_slct_diffrt_algrthm_slction = 1
                                break
                            else:
                                print "You must either type 'y' or 'n'!"
                                continue
                        if usr_ctrl_slct_diffrt_algrthm_slction == 0:               #The program gets to this line and in case of the user selecting 'y' should continue in the first while-loop
                            continue
                        else:                                                       #if the user says 'n' the program should interrupt and stop, in the best case it should close the command line (in my case IDLE)
                            break                                                   #instead of doing all this the code gets executed again in the 2nd while loop not the 1st
        """NOTE: I also know the lines above continue or quit the 2nd while-loop"""

            elif loops < 1:
                print "Please select at least one iteration!"
                while_loop_check_algrthm_slct = 0
                while while_loop_check_algrthm_slct == 0:
                    usr_ctrl_slct_algrthm_p_try_agn = raw_input("Do you want to try it again? (y/n): ")
                    print " "
                    if usr_ctrl_slct_algrthm_p_try_agn == 'y':
                        usr_ctrl_slct_algrthm_p_try_agn_slction = 0
                        break
                    elif usr_ctrl_slct_algrthm_p_try_agn == 'n':
                        usr_ctrl_slct_algrthm_p_try_agn_slction = 1
                        break
                    else:
                        print "You must either type 'y' or 'n'!"
                        continue
                if usr_ctrl_slct_algrthm_p_try_agn_slction == 1:
                    break
                else:
                    continue
            else:
                print "The maximum amount of iterations is 10 million!"
                while_loop_check_algrthm_slct = 0
                while while_loop_check_algrthm_slct == 0:
                    usr_ctrl_slct_algrthm_p_try_agn = raw_input("Do you want to try it again? (y/n): ")
                    print " "
                    if usr_ctrl_slct_algrthm_p_try_agn == 'y':
                        usr_ctrl_slct_algrthm_p_try_agn_slction = 0
                        break
                    elif usr_ctrl_slct_algrthm_p_try_agn == 'n':
                        usr_ctrl_slct_algrthm_p_try_agn_slction = 1
                        break
                    else:
                        print "You must either type 'y' or 'n'!"
                        continue
                if usr_ctrl_slct_algrthm_p_try_agn_slction == 1:
                    break
                else:
                    continue

Я прокомментировал строки, которые произведены...

Я не могу решить проблему с циклом main-while, поэтому я спрашиваю вас, как я могу это решить. Есть ли лучший способ обработки пользовательского ввода и проверки его правильности? Я застрял в точке, где мне хотелось бы пойти, потому что я не могу представить никакого другого решения.

Надеюсь, вы можете мне помочь, и спасибо за чтение этого длинного кода! Я ценю это! :)

голофокс


person Community    schedule 27.08.2015    source источник


Ответы (2)


Моя первая мысль - упростить вещи, посмотрите этот "псевдокод":

while True: #select algorithm type
    #code: ask for algorithm
    if answer not in "pmc":
        #some message
        continue #non-valid algorithm selected, ask again
    #...
    if answer == 'p':
        while True: #select iteration range
            #code: ask for iteration
            if answer_not_in_range:
                #some message
                continue #non-valid iteration value, ask again
            #...
            #perform calculation upon valid selections
            #...
            #calculation ends
            #code: ask for try again with other iteration (algorithm stays same)
            if answer != "yes":
                break #break out of "iteration" loop
            #else loop continues asking for new iteration
    #code: ask for try again with other algorithm
    if answer != "yes":
        break #"algorithm" loop ends, program ends
person rolika    schedule 27.08.2015
comment
Это выглядит великолепно. Я попытаюсь когда-нибудь переписать свой код. Я дам вам знать, если это сработает :) - person ; 28.08.2015
comment
Привет, @rolika, надеюсь, ты это читаешь... Я не вижу твой код после '#...'. Вы хотите узнать количество итераций ДО того, как будет выбран какой-либо тип алгоритма? Потому что обычно я сначала спрашиваю о типе алгоритма с 'if answer == 'p': #code, который оставляет меня с той же проблемой. Или как вы додумались спросить пользователя о типе используемого алгоритма? - person ; 31.08.2015
comment
Кажется, я забыл, что if answer == 'p'... Поместите его после первого #... и сделайте отступ для всего второго цикла while. - person rolika; 31.08.2015
comment
О, чувак, код работает отлично! Спасибо, мужик. Но мне все еще нужно выяснить, как я могу проверить правильность ввода пользователя. (Потому что кажется, что '!=' не работает. Например, когда программа запрашивает тип алгоритма, и я ввожу p, она печатает, что ввод был неправильным, и запрашивает снова ?!) Совместимы ли эти операторы с python 2? - person ; 31.08.2015
comment
@holofox, попробуй if answer not in "pmc": вместо серий or - person rolika; 01.09.2015
comment
Ух ты! Теперь он работает отлично. Рад, что рядом есть такие люди, как ты! Спасибо за вашу помощь, вы спасли мою школьную работу. - person ; 01.09.2015

Как говорит Роберт Россни в ответ на другой вопрос :

Моим первым побуждением было преобразовать вложенный цикл в функцию и использовать return для выхода.

person Cody Piersall    schedule 27.08.2015