# 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() 函数时它说它是空的并且没有收到新的更新字典。真的很困惑为什么会这样?