collection data types the program' overall logic is captured in the main(functiondef main()if len(sys argv= or sys argv[ in {"- ""--help"}print("usage{ file [file filen]]formatsys argv[ ])sys exit(usernames set(users {for filename in sys argv[ :]for line in open(filenameencoding="utf ")line line rstrip(if lineuser process_line(lineusernamesusers[(user surname lower()user forename lower()user id)user print_users(usersif the user doesn' provide any filenames on the command lineor if they type "-hor "--helpon the command linewe simply print usage message and terminate the program for each line readwe strip off any trailing whitespace ( \nand process only nonempty lines this means that if the data file contains blank lines they will be safely ignored we keep track of all the allocated usernames in the usernames set to ensure that we don' create any duplicates the data itself is held in the users dictionarywith each user (member of the staffstored as dictionary item whose key is tuple of the user' surnameforenameand idand whose value is named tuple of type user using tuple of the user' surnameforenameand id for the dictionary' keys means that if we call sorted(on the dictionarythe iterable returned will be in the order we want ( surnameforenameid)without us having to provide key function def process_line(lineusernames)fields line split(":"username generate_username(fieldsusernamesuser user(usernamefields[forename]fields[middlename]fields[surname]fields[id]return user since the data format for each record is so simpleand because we've already stripped the trailing whitespace from the linewe can extract the fields simply by splitting on the colons we pass the fields and the usernames set to the generate_username(functionand then we create an instance of the user named