需要 python 帮助:在函数之间传递字典时遇到问题 [关闭]

问题描述 投票:0回答:0
# Define constants
MIN_COMPETITORS = 3
MAX_FIS_POINTS = 999


# Define f-value for each discipline for FIS points calculation
AC = 1360
DH = 1250
SG = 1190
GS = 1010
SL = 730


def main():
    """ Call program functions """
    # Call read startlist file function and read discipline file function 
    competitors = read_startlist_file()
    read_discipline_file()
    exit_program = False
    # Keep returning to menu until the user choose to quit
    while not exit_program:
        # Call get menu options function
        choice = get_menu_options()
        # Call desired function based on user input
        if choice == 1:
            competitors = view_startlist(competitors)
        elif choice == 2:
            get_discipline()
        elif choice == 3:
            add_competitor(competitors)
        elif choice == 4:
            remove_competitor(competitors)
        elif choice == 5:
            start_from_scratch(competitors)
        else:
            exit_program = True
    # Call program exit function
    program_exit()

           
def display_title():
    """ Display title of the program """
    print('~' * 17)
    print("Start List Editor")
    print('~' * 17)


def get_menu_options():
    """ Presents the user with a menu of options to select from and prompts user for their input """
    # Call display title function
    display_title()
    # Show menu options
    menu_options = ['View Startlist', 'Select Race Discipline', 'Add Competitor', 'Remove Competitor', 'Start From Scratch', 'Quit']
    print("\nPlease select from the following options:\n")
    for i, option in enumerate(menu_options):
        print(f'{i + 1:>9}. {option}')
    # Get input from user
    choice = input('\n>>> ')
    # Validate user input
    while choice not in ['1', '2', '3', '4', '5', '6']:
        print('\nInvalid option.')
        choice = input('\n>>> ')
    return int(choice)


def get_discipline():
    """ Get the discipline of the race for the startlist and convert to an f-value """
    # Show disciplines
    print()
    print('~' * 16)
    print("AC DH SG GS SL")
    print('~' * 16)

    # Initialize flag variable to false
    valid_input = False
    # Begin Loop
    while not valid_input:
        # Get discipline
        discipline = input("\nPlease select the discipline for the race: ")
        if discipline == 'AC' or discipline == 'DH' or discipline == 'SG' or discipline == 'GS' or discipline == 'SL':
            valid_input = True
            print("Thank you. The discipline has been recorded.\n")
        else:
            print("Invalid Input. Please enter either AC , DH, SG , GS, or SL\n")
    # Convert discipline to f-value
    if discipline == 'AC':
        f_value = AC
    elif discipline == 'DH':
        f_value = DH
    elif discipline == 'SG':
        f_value = SG
    elif discipline == 'GS':
        f_value = GS
    else:
        f_value = SL
    # Pass f-value to write discipline file function
    write_discipline_file(f_value)
    return f_value

   
def view_startlist(competitors):
    """ Displays all the competitors currently on the startlist """
    if competitors:
        # Sort competitors dictionary by ascending FIS points order
        competitors = dict(sorted(competitors.items(), key=lambda x: float(x[1])))
        # Displays contents of the startlist
        print()
        print('=' * 43)
        print(f"{'Rank':<6} {'Name':<25} {'FIS Points':<10}")
        print('=' * 43)
        print()
        # Table row
        for i, (name, (fis_points)) in enumerate(competitors.items()):
            print(f"{i+1:<6} {name:<20} {fis_points:>15}")
        # Spacing
        print()
    else:
        print("The Startlist is currently empty.")
        # spacing
        print()


def start_from_scratch(competitors):
    """ Clear any existing startlist and input entire startlist of competitors """
    print("\nPlease provide the following information for the startlist...\n")
    # Create an empty dictionary for the startlist to be stored in
    competitors = {}
    # Initialize flag variable to false
    valid_input = False
    # Begin Loop
    while not valid_input:
        # Get user input for number of competitors
        num_competitors = input("How many competitors will be on the startlist?: ")
        # Format spacing
        print()
        if num_competitors.isdigit() and int(num_competitors) >= MIN_COMPETITORS:
            valid_input = True
        else:
            print("The startlist must contain at least 3 competitors. Please enter an integer value greater than or equal to 3.\n")
    # Go through loop of getting info for all competitors
    for i in range(int(num_competitors)):
        # Reset flag variable to false
        valid_input = False
        # Begin loop
        while not valid_input:
            # Get competitor name 
            competitor = input(f"Please enter competitor {i +1}'s name: ")
            names = competitor.split()
            if len(names) == 2 and all(name.isalpha() for name in names):
                valid_input = True
            else:
                print("Invalid input. Please enter the first AND last name of the competitor, using letters only.")
        # Reset flag variable to false
        valid_input = False
        # Begin loop
        while not valid_input:
            try:
                fis_points = float(input(f"Please enter competitor {i +1}'s FIS points: "))
                # Format spacing
                print()
                if 0 <= fis_points <= MAX_FIS_POINTS:
                    valid_input = True
                else:
                    print("Invalid input. Please enter a float value between 0 and 999.\n")
            except ValueError:
                print("Invalid input. Please enter a float value between 0 and 999.\n")
        # Add competitor to dictionary
        competitors[competitor] = fis_points
    # Pass new competitors dictionary to write startlist file function
    print(competitors)
    write_startlist_file(competitors)
    return competitors


def add_competitor(competitors):
    """ Prompts the user to add a competitor to the startlist """
    # Initialize flag variable to false
    valid_input = False
    # Begin Loop
    while not valid_input:
        # Get competitor name 
        competitor = input(f"\nPlease enter the competitor's name: ")
        names = competitor.split()
        if len(names) == 2 and all(name.isalpha() for name in names):
            valid_input = True
        else:
            print("Invalid input. Please enter the first AND last name of the competitor, using letters only.\n")
    # Reset flag variable to false
    valid_input = False
    # Begin loop
    while not valid_input:
        try:
            fis_points = float(input(f"Please enter the competitor's FIS points: "))
            if 0 <= fis_points <= MAX_FIS_POINTS:
                valid_input = True
            else:
                print("Invalid input. Please enter a float value between 0 and 999.\n")
        except ValueError:
            print("Invalid input. Please enter a float value between 0 and 999.\n")
    # Format spacing
    print()
    # Add competitor to dictionary
    competitors[competitor] = fis_points
    # Pass new competitors dictionary to write startlist file function
    write_startlist_file(competitors)
    return competitors


def remove_competitor(competitors):
    """ Prompts the user to remove a competitor from the startlist """
    # Initialize flag variable to false
    valid_input = False
    # Begin Loop
    while not valid_input:
        # Get competitor name 
        competitor = input(f"\nPlease enter the competitor's name you would like to remove: ")
        names = competitor.split()
        if len(names) == 2 and all(name.isalpha() for name in names):
            valid_input = True
        else:
            print("Invalid input. Please enter the first AND last name of the competitor, using letters only.\n")    
    # Notify user if competitor is not on the list
    if competitor not in competitors:
        print(f"{competitor} is not on the startlist.\n")
    else:
        # Remove the desired competitor
        competitors.pop(competitor)
        print(f"{competitor} was removed from the startlist.\n")


def read_startlist_file():
    """ Reads in the entire contents of the text file and stores each item as an element in a dictionary. Returns that dictionary. """
    competitors = {}
    try:
        # read competitor list from startlist file
        with open('startlist.txt', 'r') as in_file:
            for line in in_file:
                key, value = line.strip().split(':')
                competitors[key] = str(value)
    # Handle exceptions
    except FileNotFoundError:
        print("\nCannot find the file or the file does not exist. Creating a new file...please run the program again.")
        write_startlist_file(competitors)
    except IOError:
        print("\nError reading file. Aborting program...")
    else:
        return competitors
    finally:
        # Close file
        in_file.close()
    

def read_discipline_file():
    """ Reads in the contents of the text file and stores as a variable. Returns that variable. """
    try:
        # read competitor list from startlist file
        with open('discipline.txt', 'r') as in_file:
            f_value = in_file.read()
    # Handle exceptions
    except FileNotFoundError:
        print("\nCannot find the file or the file does not exist. Creating a new file...please run the program again.")
        write_discipline_file(f_value)
    except IOError:
        print("\nError reading file. Aborting program...")
    else:
        return f_value
    finally:
        # Close file
        in_file.close()


def write_startlist_file(competitors):
    """ Opens 'startlist.txt' text file and writes the competitor list to that file """
    # Sort competitors dictionary by ascending FIS points order
    competitors = dict(sorted(competitors.items(), key=lambda x: float(x[1])))
    try:
        # writes competitors to a file
        out_file = open('startlist.txt', 'w')
        for key, value in competitors.items():
            out_file.write(f"{key}:{value}\n")
    # Handle exceptions
    except IOError:
        print('Error writing to file')
    except ValueError:
        print('Invalid data:', line)
    finally:
        # Close the file
        out_file.close()


def write_discipline_file(f_value):
    """ Opens 'discipline.txt' text file and writes the f-value to that file """
    # Convert f-value to a string
    var_string = str(f_value)
    try:
        # writes competitors to a file
        with open('discipline.txt', 'w') as file:
            file.write(var_string)
    # Handle exceptions
    except IOError:
        print("Error writing to file")
    except ValueError:
        print("Invalid data:", line)
    finally:
        # Close the file
        file.close()


def program_exit():
    """ Prompts the user if they would like to exit the program and validates the choice, then calls the write_startlist_file and
        write_discipline_file functions and passes the dictionary of competitors and list of the disciplines' f-value """
    exit_list = input('\nAre you sure you want to exit? (y/n)\n>>> ')
    if exit_list == 'y':
        # Exit program
        print("\nThank you. Please navigate to race_simulation.py to simulate the race.")
        # Call write grocery list file function
        # write_startlist_file(competitors)
        # Call write discipline file function [Removed] **causes issues**
    else:
        # Return to options menu
        print()
        main()

        
# Run program
if __name__ == '__main__':
    main()

当我运行程序时,一切正常,所有内容都写入两个文本文件“startles.txt”和“discipline.txt”。但是,当我从菜单选项调用 start_from_scratch() 函数并继续完成所有必需的输入时,它将新的 startles 字典写入 'startles.txt' 但是之后,当我从菜单选项调用 view_startlist() 函数时它说它是空的并且没有收到新的更新字典。真的很困惑为什么会这样?

python function dictionary return
© www.soinside.com 2019 - 2024. All rights reserved.