1

My program creates a list of stations, with some information about them. I have three edit functions set up: edit_mp (), edit_name () and edit_clear (). These three can only be called from a menu at the beginning of the edit_station () function. edit_mp () is currently taking user input and then jumps into the middle of the edit_clear ().

I have two types of objects: a Station object which stores some information and a Subdivision object which stores the list of stations and a sorted list of one feature of those stations.

I tried adding extra checks into the function, which has demonstrated that the function stops right after the "New milepost is"-line and confirming the input.upper (). It should move on to the if-else-loop immediately, but the print statements I put into the if are not working and the else doesn't call edit_station_menu (). Instead, I get the "Please enter a whole number" statement and the siding length prompt from edit_clear ().

def edit_station():
    global n
    global mp_edit
    n = 0
    mp_edit = input("Enter milepost of station to edit.")
    while n <= len(sub_list[i].stations):
        if sub_list[i].stations[n].mp == float(mp_edit):
            edit_station_menu()
        elif n < len(sub_list[i].stations):
            n += 1
        else:
            print("Milepost not found.  Enter 1 to try again, or any other key to return.")
            choice = input()
            if choice == "1":
                edit_station()
            else:
                display_sub()

def edit_station_menu():
    global n
    global mp_edit
    sta = sub_list[i].stations[n]
    def edit_mp():
        print("STATION SELECTED: " + sta.name)
        mp = input("Station milepost: ")
        try:
            mp = float(mp)
        except ValueError:
            print("Please enter a valid milepost number (numerals and decimals only).")
            edit_mp()
        else:
            print("New milepost is " + str(mp) + ". Is this correct? Y/N")
            correct = input()
            if correct.upper() == "Y":
                sub_list[i].mp.remove(mp_edit)
                print("Original milepost removed.")
                sta.mp = mp
                sub_list[i].mp.append(sta.mp)
                print("New milepost added.")
                if sub_list[i].ascend_dir == "W" or sub_list[i].ascend_dir == "S":
                    sub_list[i].mp.sort()
                else:
                    sub_list[i].mp.sort()
                    sub_list[i].mp.reverse()
                edit_station_menu()
            else:
                print("Ready to move on, nothing has changed.")
                input()
                edit_mp()

    def edit_name():
        print("STATION SELECTED: " + sta.name)
        name = input("Enter new station name: ").upper()
        print("New station name is " + name + ". Is this correct? Y/N")
        correct = input()
        if correct.upper() == "Y":
            sta.name = name
            edit_station_menu()
        else:
            edit_name()

    def edit_clear():
        def edit_sdglen():
            sdglen = input("Enter siding length: ")
            try:
                sta.sdglen = int(sdglen)
            except ValueError:
                print("Please enter a whole number.")
                edit_sdglen()
            else:
                edit_station_menu()

        def edit_maxtoclear():
            maxtoclear = input("Maximum length that can clear main line at this station: ")
            try:
                sta.clearlen = int(maxtoclear)
            except ValueError:
                print("Please enter a whole number.")
                edit_maxtoclear()
            else:
                sta.canclear = True
                edit_station_menu()

        print("STATION SELECTED: " + sta.name)
        sdg = input("Does this station have a designated passing siding? Y/N")
        if sdg.upper() == "Y":
            edit_sdglen()
        else:
            sta.sdglen = 0
            canclear = input("Can a train clear main track at this station? Y/N")
            if canclear.upper() == "Y":
                edit_maxtoclear()
            else:
                sta.canclear = False
                sta.clearlen = 0
                edit_station_menu()




    print("STATION SELECTED: " + sta.name)
    print("1. Edit MP")
    print("2. Edit name")
    print("3. Edit clearing information")
    print("4. Any other key to return to subdivision")
    choice = input()
    if choice == "1":
        edit_mp()
    elif choice == "2":
        edit_name()
    elif choice == "3":
        edit_clear()
    else:
        display_sub()

My output

SOUTHWARD | ALASKA DIVISION                                   |    NORTHWARD
MP        | STATIONS                          | SDG   | CLEAR | CLEAR LENGTH
29.4      | MOOSE PASS                        | 990   | False | 0
18.4      | CROWN POINT                       | 3704  | False | 0
12.0      | DIVIDE                            | 1920  | False | 0
3.4       | SEWARD                            | 0     | True  | 15000
1. Add Station
2. Edit Station
Any other key to save and return.
2
Enter milepost of station to edit.18.4
STATION SELECTED: CROWN POINT
1. Edit MP
2. Edit name
3. Edit clearing information
4. Any other key to return to subdivision
1
STATION SELECTED: CROWN POINT
Station milepost: 25.4
New milepost is 25.4. Is this correct? Y/N
y
Please enter a whole number.
Enter siding length:

First, the program displays the station list as created, then it prompts whether to add a station or edit an existing one. I put in the wrong milepost at Crown Point, so I select edit, put in the milepost that has been assigned to Crown Point and edit it. After asking me whether this is correct the program is supposed to execute the if-else-part after the prompt and either * correct milepost in station and change itself in list of mileposts (necessary for sorting) * or tell me I didn't change a thing and go back to the menu. Instead, it's going all the way down to edit_clear () on the except ValueError-statement.

h4z3
  • 5,265
  • 1
  • 15
  • 29
Alan
  • 33
  • 2
  • Using recursion is not the way to go here. You might want to read: [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Matthias Sep 23 '19 at 13:19
  • Thanks! That will help I think for the individual pieces, but the main problem I'm trying to solve is that even with correct input the code is going to a step that's not even part of the same function, and I can't identify where it is interpreting to do that. The mp editing should have nothing to do with the siding length, and yet the two are somehow linked in a way I haven't been able to find. – Alan Sep 23 '19 at 16:30

1 Answers1

0

However, edit_mp() is currently taking user input and then jumping into the middle of the edit_clear() function.

No.

You're deep into recursion.

What happens is: edit_station_menu executes edit_clear, which eventually executes edit_station_menu which executes edit_mp

When edit_mp exits, edit_station_menu exits as well (because there's no more things to do):

        if choice == "1":
            edit_mp()
        elif choice == "2":
            edit_name()
        elif choice == "3":
            edit_clear()
        else:
            display_sub()
        #edit_station_menu exits here because there's nothing more

So now we get when we first executed that particular edit_station_menu - that is, "into the middle of edit_clear() function".

h4z3
  • 5,265
  • 1
  • 15
  • 29
  • Hm. So where is it going into the edit_clear() function? It's not supposed to do that unless the user chose 3 on the edit_station_menu() function. – Alan Sep 23 '19 at 13:11
  • In the example you posted we don't see your claim that edit_clear is accesses, I only explained how it works for the example you described. Moreover, you edited your code in the meantime, reorganising indentations and removing contents of edit_clear, making your description of the code behaviour even more different than your code! – h4z3 Sep 23 '19 at 13:25
  • Okay, it wasn't you who messed up your code in the question. I'll edit the code back – h4z3 Sep 23 '19 at 13:32