pythonfunctioninput

How do I get rid of these side effects arising from my input statements in my python codebase?


Currently, my program is failing some tests because my input statements keeps appearing in the output during testing. However, it doesn't appear when testing with my jupiter notebook. Any hint on how to solve my issue. The problem is in my main() function: codebase:


Other codes

#define main logics in main function        
def main():
    #create a lists of data structure to store player's salaries and overall rates 
    salary_dataset = [[1, 2, 3, 4], [1000, 700, 500, 400], [80, 60, 45, 30]]
    #initialize a list to store player information
    player_data = []
    #get information of 3 players or until the input is 'end'
    for _ in range(3):
        #initialize variables to store player's profile
        player_id = input("Enter player ID (type 'end' to finish): ")
        #check if user wants to end input
        if player_id.lower() == 'end':
            break #exit loop if user enters 'end'
        #validate player id
        if len(player_id) != 2 or not player_id.isdigit():
            print("invalid player Id. Please enter a 2-digit number.")
            continue    
            
        name = input("Enter player name: ")
        dob = input("Enter player D.o.B (YYYY-MM-DD): ")
        
        #validate D.O.B format 
        try: #use try-except block to prevent the program from crashing if a user enters date incorrectly
            datetime.strptime(dob, "%Y-%m-%d") 
        except ValueError:
            print("Invalid data format. Please use YYYY-MM-DD.")
            continue  
        
        #initialize each player's data input
        skills_set = [0, 0, 0, 0, 0, 0]
    
        #Gather the six skills input
        for idx in range(len(skills_set)):
            skills_set[idx] = validate_input("Enter players data (0-5 only): ")
            
        #calculate overall rate, salary range, and age and store in variables
        overall_rate_per_player = calculate_rating(skills_set)
        salary_range = calculate_salary(overall_rate_per_player, salary_dataset)
        age = calculate_age(dob)
        
        #append player information to the player_data list
        player_data.append({
            'UID': player_id,
            'Name': name,
            'D.o.B': dob,
            'Age': age,
            'Score': overall_rate_per_player,
            'Salary Range': salary_range
        })
        

    #sort player data list of dictionaries base on the 'UID' key and display table using tabulate
    table = [[p['UID'], p['Name'], p['D.o.B'], p['Age'], p['Score'],
    p['Salary Range']] for p in sorted(player_data, key=lambda x: x['UID'])]
    #print the table
    print(tabulate(table, tablefmt='grid'))
    
    write_to_file(table)
        
#call the main function        
if __name__ == "__main__":
    main()  
    advanced()

my output:

Enter player ID (type 'end' to finish): Enter player name: Enter player D.o.B (YYYY-MM-DD): Enter players data (0-5 only): Enter players data (0-5 only): Enter players data (0-5 only): Enter players data (0-5 only): Enter players data (0-5 only): Enter players data (0-5 only): Enter player ID (type 'end' to finish): +----+--------------+------------+----+-----+------+
| 10 | Lionel Messi | 1987-06-24 | 36 | 100 | 1000 |
+----+--------------+------------+----+-----+------+
File not found: PlayerData.txt

expected output:

Expected output 
10  Lionel Messi  1987-06-24     36      100            1000

I want my output to be same as expected output.


Solution

  • It's a bit tricky to run automated tests for code that asks for keyboard input.

    One common solution is to rearrange your code so that all the keyboard input is handled separately, and then your main function just accepts those inputs as fixed arguments.

    Maybe something like this:

    player_name = input("Enter player name:")
    player_id = input("Enter player ID:")
    player_dob = input("Enter player DOB:")
    
    result = get_player_data(player_name, player_id, player_dob)
    

    Then you could write a simple automated test that calls your function with predefined inputs:

    result = get_player_data("Lionel Messi", 10, "1987-06-24")