-2

All of this code functions perfectly when run alone. However, when i choose the standings option after i have run the new and fixture option the code throws an error. Any assistance on this matter would be greatly appreciated.

main():

       print ("Welcome to Tournament Tracker")
       print ("would you like to begin a new tournament (new), input the results of a fixture (fixture) or view the tournament standings(standings)")
       #allows the user to choose from several options including accesing an old tournament or creating a new one.
       response = input()
       #defines a variable "response" which will be checked against predefined, suggested responses using a slection statement
       if response == "new":
       #selection statment checks if variable "response" is = "new" and, if true, executes the following code
                  print ("enter in the name of the tournament")
                  tournamentName = input()
                  #creates variable tournamentName and sets it to user input
                  with  open(tournamentName + ".txt",mode="w",encoding = "utf-8") as tournamentfile:
                             pass
                  #creates file "tournamentName + ".txt""
                  print ("enter in the number of teams in the tournament")
                  numberOfTeams = int(input())
                  allPoints = int(0)
                  awayPoints = int(0)
                  #initalises the two variables "allPoints" and "awayPoints" to be written to text file
                  counter = int(0)
                  #initialises temporary variable counter to be used for iteration
                  while counter < numberOfTeams:
                  # while loop executes the following code unless the condition "counter" < "number of teams"
                             counter = counter +1
                             #one is added to the counter to ensure that the condition "counter" < "number of teams" will be met
                             print ("enter in the name of team {0}".format(counter))
                             teamName = input()
                             #asks the user for the name of each team linked to variable counter
                             print ("Team {0} is {1}".format(counter,teamName))
                             with open(teamName + "Points.txt", mode="w",encoding="utf-8") as allPointsfile:
                                        allPointsfile.write(str(allPoints))
                             #creates a txt file based on the variable "teamName", with "Points.txt" appended to it,
                             #inputted by the user and writes the variable "allPoints" to it 
                             with open(teamName + "AwayPoints.txt", mode = "w",encoding = "utf-8") as awayPointsfile:
                                        awayPointsfile.write(str(awayPoints))
                             #creates a txt file based on the variable "teamName", with "AwayPoints.txt" appended to it,
                             #inputted by the user and writes the variable "awayPoints" to it 
                             with open(tournamentName + ".txt", mode="a",encoding="utf-8") as tournamentfile:
                                        tournamentfile.write(teamName +"\n")
                                        tournamentfile.write(str(allPoints) + "\n")
                                        tournamentfile.write(str(awayPoints) + "\n")
                             #creates a txt file based on the variable "tournamentName", with ".txt" appended to it,
                             #inputted by the user and writes the variables "teamName", "allPoints" and "awayPoints" to it,
                             #each on a new line 
                  print("You may now add the results of fixtures")
                  main()
                  #informs the user that the next recommended option should be to input the results of a fixture
                  #and then calls the main function to give the user access to the all the options again 
       elif response == "fixture":
       #selection statment checks if variable "response" is = "fixture" and, if true,then executes the following code
                  print ("enter in the name of the tournament")
                  tournamentName = input() 
                  print ("enter in the name of the first (home) team")
                  teamOne = str(input())
                  print ("enter in the name of the second (away) team")
                  teamTwo = str(input())
                  print ("enter in the number of goals scored by the first team in their home fixture")
                  teamOneScore = input()
                  print("enter in the number of goals scored by the second team in the same fixture")
                  teamTwoScore = input()
                  #initialises variables "tournamentName", "teamOne", "teamOne", "teamOneScore" and "teamTwoScore"
                  if teamOneScore > teamTwoScore:
                  #selection statment checks if the variable "teamOneScore" > "teamTwoScore" and if true, executes the following code
                            with open(teamOne + "Points.txt", mode="r",encoding="utf-8") as allTeamOnePointsfile:
                                        allTeamOnePoints = allTeamOnePointsfile.read()
                                        if allTeamOnePoints == '':
                                            allTeamOnePoints  = 0
                                        allTeamOnePoints = int(allTeamOnePoints) + int(3)
                            #opens the file " teamOne (variable) + "Points.txt"" in read mode and reads the file. If statement checks if the file is empty
                            #and sets the value read, defined as "allTeamOnePoints" to 0 to avoid an error. Then adds 3 to "allTeamOnePoints"
                            with open(teamOne + "Points.txt", mode="w",encoding="utf-8") as allTeamOnePointsfile:
                                        allTeamOnePointsfile.write(str(allTeamOnePoints))
                            #opens the file " teamOne (variable) + "Points.txt"" in write mode and writes the variable "allTeamOnePoints" to the file. 
                                        print("{0} now has {1} points".format(teamOne,allTeamOnePoints))
                            #outputs the team name and the total number of points that team has
                            with open(teamTwo + "Points.txt", mode="r",encoding="utf-8") as allTeamTwoPointsfile:
                                        allTeamTwoPoints = allTeamTwoPointsfile.read()
                                        if allTeamTwoPoints == '':
                                            allTeamTwoPoints  = 0
                            #opens the file " teamTwo (variable) + "Points.txt"" in read mode and reads the file. If statement checks if the file is empty
                            #and sets the value read, defined as "allTeamTwoPoints" to 0 to avoid an error.
                                        print("{0} now has {1} points".format(teamTwo,allTeamTwoPoints))
                            #outputs the total points for teamTwo 
                            with open(tournamentName + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                                        tournamentList1 = tournamentFile.readlines()
                                        tournamentList = [elem.strip("\n")for elem in tournamentList1]
                                        #open the file "tournamentName (variable) + ".txt"" and reads it, with each line defined as a different element of an array
                                        #then strips the ""\n"" from the end of each element and defines the variable "tournamentList"
                                        index = 0
                                        #initialises temporary variable "index"
                                        noOfTeams = int(len(tournamentList))
                                        #initialises variable "noOfTeams" as the length of the arrray "tournamentList"
                                        while index < noOfTeams:
                                        #while loop checks if  temporary variable "index" < "noOfTeams"
                                                   if teamOne == tournamentList[index]:
                                                              tournamentList[index]= teamOne
                                                              tournamentList[index+1] = allTeamOnePoints
                                                              index = index +1
                                                   #selection statement checks if the variable "teamOne" is equal to the index'th element of the array "tournamentList"
                                                   #sets variable "teamOne" to the index'th element of array "tournamentList" if the previous condition is true
                                                   #sets variable "allTeamOnePoints" to the index'th element of array "tournamentList" if the previous condition is true
                                                   #adds 1 to index to allow for iteration
                                                   elif teamOne != tournamentList[index]:
                                                              index = index +1
                                                   #selection statement checks if the variable "teamOne" is equal to the index'th element of the array "tournamentList"
                                                   #adds 1 to index to allow for iteration

                                        index2 = 0
                                        #initialises temporary variable "index"
                                        while index2 < noOfTeams:
                                                   if teamTwo == tournamentList[index2]:
                                                              tournamentList[index2] = teamTwo
                                                              tournamentList[index2+1] = allTeamTwoPoints
                                                              index2 = index2 +1
                                                   #selection statement checks if the variable "teamTwo" is equal to the index2'th element of the array "tournamentList"
                                                   #sets variable "teamTwo" to the index'th element of array "tournamentList" if the previous condition is true
                                                   #sets variable "allTeamTwoPoints" to the index'th element of array "tournamentList" if the previous condition is true
                                                   #adds 1 to index2 to allow for iteration
                                                   elif teamTwo != tournamentList[index2]:
                                                              index2 = index2 +1
                                                   #selection statement checks if the variable "teamTwo" is equal to the index'th element of the array "tournamentList"
                                                   #adds 1 to index2 to allow for iteration
                            with open(tournamentName + ".txt", mode = "w", encoding = "utf-8") as tournamentFile:
                                        for counter in range (len(tournamentList)):
                                        #for loop executes the following code the once for each element in array "tournamentList"
                                                   tournamentFile.write(str(tournamentList[counter]) + "\n")
                            #writes variable "tournamentList" to "tournamentName + ".txt"" using for loop 
                                        main()
                                        #calls back the function "main()"



                  elif teamOneScore == teamTwoScore:
                  #the following code is very similar to the above code. Please see above code for documentation.
                            with open(teamOne + "Points.txt", mode="r",encoding="utf-8") as allTeamOnePointsfile:
                                        allTeamOnePoints = allTeamOnePointsfile.read()
                                        if allTeamOnePoints == '':
                                            allTeamOnePoints  = 0
                                        allTeamOnePoints = int(allTeamOnePoints) + int(1)
                            with open(teamOne + "Points.txt", mode="w",encoding="utf-8") as allTeamOnePointsfile:
                                        allTeamOnePointsfile.write(str(allTeamOnePoints))
                                        print("{0} now has {1} points".format(teamOne,allTeamOnePoints))
                            with open(teamTwo + "Points.txt", mode="r",encoding="utf-8") as allTeamTwoPointsfile:
                                        allTeamTwoPoints = allTeamTwoPointsfile.read()
                                        if allTeamTwoPoints == '':
                                            allTeamTwoPoints  = 0
                                        allTeamTwoPoints = int(allTeamTwoPoints) + int(1)
                            with open(teamTwo + "Points.txt", mode="w",encoding="utf-8") as allTeamTwoPointsfile:
                                        allTeamTwoPointsfile.write(str(allTeamTwoPoints))
                                        print("{0} now has {1} points".format(teamTwo,allTeamTwoPoints))
                            with open(teamTwo + "AwayPoints.txt",mode = "r",encoding="utf-8") as awayPointsfile:
                                        awayPoints = awayPointsfile.read()
                                        if awayPoints == '':
                                            awayPoints  = 0
                                        awayPoints = int(awayPoints) + int(1)
                            with open(teamTwo + "AwayPoints.txt",mode = "w",encoding="utf-8") as awayPointsfile:
                                        awayPointsfile.write(str(awayPoints))
                            with open(tournamentName + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                                         tournamentList1 = tournamentFile.readlines()

                                         tournamentList = [elem.strip("\n")for elem in tournamentList1]

                                         index = 0
                                         noOfTeams = int(len(tournamentList))
                                         while index < noOfTeams:
                                                   if teamOne == tournamentList[index]:
                                                              tournamentList[index]= teamOne
                                                              tournamentList[index+1] = allTeamOnePoints
                                                              index = index+1
                                                   elif teamOne != tournamentList[index]:
                                                              index = index +1
                                         index2 = 0
                                         while index2 < noOfTeams:
                                                   if teamTwo == tournamentList[index2]:
                                                              tournamentList[index2] = teamTwo
                                                              tournamentList[index2+1] = allTeamTwoPoints
                                                              tournamentList[index2+2] = awayPoints
                                                              index2 = index2+1
                                                   elif teamTwo != tournamentList[index]:
                                                              index2 = index2 +1
                            with open(tournamentName + ".txt", mode = "w", encoding = "utf-8") as tournamentFile:
                                        for counter in range (len(tournamentList)):
                                                   tournamentFile.write(str(tournamentList[counter]) + "\n")
                                                   print (tournamentList)
                                        main()



                  elif teamOneScore < teamTwoScore:
                  #the following code is very similar to the above code. Please see above code for documentation.
                             with open(teamTwo + "Points.txt", mode="r",encoding="utf-8") as allTeamTwoPointsfile:
                                        allTeamTwoPoints = allTeamTwoPointsfile.read()
                                        if allTeamTwoPoints == '':
                                            allTeamTwoPoints  = 0
                                        allTeamTwoPoints = int(allTeamTwoPoints) + int(3)
                             with open(teamTwo + "Points.txt", mode="w",encoding="utf-8") as allTeamTwoPointsfile:
                                        allTeamTwoPointsfile.write(str(allTeamTwoPoints))
                                        print("{0} now has {1} points".format(teamTwo,allTeamTwoPoints))
                             with open(teamTwo + "AwayPoints.txt",mode = "r",encoding="utf-8") as awayPointsfile:
                                        awayPoints = awayPointsfile.read()
                                        if awayPoints == '':
                                            awayPoints  = 0
                                        awayPoints = int(awayPoints) + int(3)
                             with open(teamTwo + "AwayPoints.txt",mode = "w",encoding="utf-8") as awayPointsfile:
                                        awayPointsfile.write(str(awayPoints))
                             with open(teamOne + "Points.txt", mode="r",encoding="utf-8") as allTeamOnePointsfile:
                                        allTeamOnePoints = allTeamOnePointsfile.read()
                                        if allTeamOnePoints == '':
                                            allTeamOnePoints  = 0
                                        print("{0} now has {1} points".format(teamOne,allTeamOnePoints))
                             with open(tournamentName + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                                         tournamentList1 = tournamentFile.readlines()

                                         tournamentList = [elem.strip("\n")for elem in tournamentList1]

                                         index = 0
                                         noOfTeams = int(len(tournamentList))
                                         while index < noOfTeams:
                                                   if teamOne == tournamentList[index]:
                                                              tournamentList[index]= teamOne
                                                              tournamentList[index+1] = allTeamOnePoints
                                                              index = index+1
                                                   elif teamOne != tournamentList[index]:
                                                              index = index +1
                                         index2 = 0
                                         while index2 < noOfTeams:
                                                   if teamTwo == tournamentList[index2]:
                                                              tournamentList[index2] = teamTwo
                                                              tournamentList[index2+1] = allTeamTwoPoints
                                                              tournamentList[index2+2] = awayPoints
                                                              index2 = index2 + 1
                                                   elif teamTwo != tournamentList[index2]:
                                                              index2 = index2 +1
                             with open(tournamentName + ".txt", mode = "w", encoding = "utf-8") as tournamentFile:

                                        for counter in range (len(tournamentList)):
                                                   tournamentFile.write(str(tournamentList[counter]) + "\n")
                                                   print (tournamentList)
                                        main()

       elif response == "standings":
       #selection statment checks if variable "response" is = "fixture" and, if true,then executes the following code
                  results()

def results():
           print ("enter in the name of the tournament you would like to access")
           tournamentName1 = input()
           #creates variable "tournamentName" and sets it equal to user input
           with open (tournamentName1 + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                      tournamentTeam1 = tournamentFile.readlines()[::3]
                      tournamentTeams1 = [elem.strip("\n")for elem in tournamentTeam1]
           #opens the file "tournamentName + ".txt"" and reads every third line into a list. Then strips ""\n"" from every element
           #defines the variable "tournamentTeams" as an array of al teams in the tournament
           with open (tournamentName1 + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                      tournamentPoint1 = tournamentFile.readlines()[1::3]
                      tournamentPoints1 = [elem.strip("\n")for elem in tournamentPoint1]
           #opens the file "tournamentName + ".txt"" and reads every third line starting from the second element
           #into a list. Then strips ""\n"" from every element
           #defines the variable "tournamentPoints" as an array with all the total points for each team
           with open (tournamentName1 + ".txt", mode = "r", encoding = "utf-8") as tournamentFile:
                      tournamentAwayPoint1 = tournamentFile.readlines()[2::3]
                      tournamentAwayPoints1 = [elem.strip("\n")for elem in tournamentAwayPoint1]
           #opens the file "tournamentName + ".txt"" and reads every third line starting from the third element
           #into a list. Then strips ""\n"" from every element
           #defines the variable "tournamentAwayPoints" as an array with all the total away points for each team
                      order = []
                      #defines temporary array order as an empty array
                      pos = 0
                      #defines temporary variable "pos" as equal to 0
                      for count in range(len(tournamentTeams1)):
                           order.append(count)
                           #creates an array of indexes of the teams
                      for count in range(len(tournamentTeams1)-1):
                           if (tournamentPoints1[order[pos]] < tournamentPoints1[order[pos+1]]):
                                 #compares the scores of two consecutive teams and switches them
                                 temp = order[pos]
                                 #temporary variable stores the index of the team
                                 order[pos] = order[pos+1]
                                 order[pos+1] = temp
                                 #switches the order of the teams
                           elif (tournamentPoints1[order[pos]] == tournamentPoints1[order[pos+1]] and tournamentAwayPoints1[order[pos]] <tournamentAwayPoints1[order[pos+1]]):
                                 #if the score is equal, we compare the away score
                                 temp = order[pos]
                                 order[pos] = order[pos+1]
                                 order[pos+1] = temp
                                 #same logic as prior
                           pos = pos +1
                           #adds 1 to variable "pos" in order to allow for iteration
                      index3 = 0
                      #defines temporary variable index as equal to 0
                      print()
                      for count in range(len(order)):
                          index3 = index3 + 1
                          print('{0}: {1} (score {2}) (away score {3})'.format(index3,tournamentTeams1[order[count]],tournamentPoints1[order[count]],tournamentAwayPoints1[order[count]]))
                      print("Congratulations to team {0} for winning the tournament!".format(tournamentTeams1[order[pos]]))
                      #print outs the winning team of the tournament

the exact error message:

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    main()
  File "/Users/MunshiMuhammed/Desktop/Coursework Coding Folder/Actually done coursework m8 (2).py", line 47, in main
    main()
  File "/Users/MunshiMuhammed/Desktop/Coursework Coding Folder/Actually done coursework m8 (2).py", line 129, in main
    main()
  File "/Users/MunshiMuhammed/Desktop/Coursework Coding Folder/Actually done coursework m8 (2).py", line 244, in main
    results()
  File "/Users/MunshiMuhammed/Desktop/Coursework Coding Folder/Actually done coursework m8 (2).py", line 296, in results
    print("Congratulations to team {0} for winning the tournament!".format(tournamentTeams1[order[pos]]))
IndexError: list index out of range

The text file that is being read from in the results function: (the first line the team name, the second is the home points and the third is the away points. the next line is the next team) 3 0 0 4 3 0

These are the print statements asked for (tournamentTeams1, order and pos) ['3', '4'] [1, 0] 1 1: 4 (score 3) (away score 0) ['3', '4'] [1, 0] 1 2: 3 (score 0) (away score 0) Congratulations to team 3 for winning the tournament!

Once again, this function only works if it is accessed after a restart of the idle.

  • That's a lot of code and very little details on what error you're getting. – NPE Dec 24 '14 at 11:11
  • That's quite a bit of code to wade through... You'll get a better response here if you can create a [MCVE](http://stackoverflow.com/help/mcve). But in the mean time, you should paste the __exact__ error message into your question. – PM 2Ring Dec 24 '14 at 11:11
  • Also, there are some odd things in your code, like `int(0)` and `str(input())`. 0 is already an `int` so there's no point converting it to `int`. Similarly, `input()` (in Python 3) returns a `str` so there's no point converting the return from `input()` to `str`. I notice that your `main()` calls itself, and while that's perfectly legal it's generally not a great way to structure a Python program. – PM 2Ring Dec 24 '14 at 11:16
  • I haven't analyzed your code closely enough to know if this is an issue for you, but do you realize that each invocation of `main()` will create its own variables? So when you call `main()` from within `main()` the new `main()` will have read access to the old `main()`'s objects, but if you try to write to those objects you'll actually create new objects local to the new `main()`. You can get around that by using the `global` keyword, but it's generally better to re-organize your code to avoid using globals, when practical. – PM 2Ring Dec 24 '14 at 11:20
  • Sorry, this is my first post here and i'm still a beginner to python. I have pasted the exact error message now. – Muhammed Munshi Dec 24 '14 at 11:59
  • Can you try sticking print(tournamentTeams1), print(order) and print(pos) on separate rows just above the print("Congratulations to team {0} for winning the...) at the end of your code, and update the question with the output? Also useful would be the first few lines of whatever file it is you're reading in the results function. – zehnpaard Dec 25 '14 at 03:26
  • thank you very much zehnpaard, the print statements and file have been added. – Muhammed Munshi Dec 26 '14 at 12:26
  • hmm, it looks like the results of the print statements that you updated is for the case where you're not encountering an error? The output we need is what gets printed when you encounter the error. – zehnpaard Dec 27 '14 at 14:28

1 Answers1

0

As mentioned in the comments, that's a lot of code to wade through.

To get better responses MCVE is key. Take a look at the error message, and you see that it's occurring in the results function. So you should try to replicate the error with just that function, plus some minimal data. If you can't, you need to check what inputs are going into the function (which is what inserting the print statements were about). Then figure out what bits of your code was producing those weird inputs, and try to isolate that bit of the code. Repeat the process until you've narrowed down the area of code where the problem is likely to lie. Then post the bit of the code, along with the inputs and outputs. Welcome to the wonderful world of debugging!

All that said, I did go through the code, and I think I know what's going wrong. When you call main() recursively, you are actually calling it without closing the tournamentName file, and then you are trying to access that same file in the results() function. Below is the problematic recursive call to main(), in the 'fixtures' part of your code.

with open(tournamentName + ".txt", mode = "w", encoding = "utf-8") as tournamentFile:
    for counter in range (len(tournamentList)):
    #for loop executes the following code the once for each element in array "tournamentList"
        tournamentFile.write(str(tournamentList[counter]) + "\n")
        #writes variable "tournamentList" to "tournamentName + ".txt"" using for loop 
    main() #Notice the indentation!

The indentation means the tournamentName.txt file is going to already be accessed in write mode, so you are getting an empty file when you try accessing it from the results() function. Your results() function throws an IndexError at the final line if the tournamentName.txt file is empty.

The immediate solution is to take the recursive call to main() outside of the with open(...), i.e. it should look like:

with open(tournamentName + ".txt", mode = "w", encoding = "utf-8") as tournamentFile:
    #Your for loop remains here
main() #At this point tournamentName.txt is closed, available for results() to access

You need to update it in all three places of your code where this occurs.

On the other hand, as @pm-2ring states, recursive calls to main() is probably not the best idea. I would strongly recommend restructuring your code so that the main function becomes a loop that looks like below.

def main():
    print("Welcome to Tournament Tracker")
    while True:
        response = input("would you like to begin a new tournament (new), input the results of a fixture (fixture) or view the tournament standings(standings)\n")
        if response == "new":
            create_new_tournament()
        elif response == "fixture":
            add_fixtures()
        elif response == "standings":
            print_results()
            return

I noticed four other big issues with your code:

  1. Your results() function has a bug where the team with the lowest score ends up at the end of the order list, while it should be the team with the highest score.
  2. Your main() function is way way too long. Splitting it into pieces will help a lot with what I wrote at the start - small functions make it easy to isolate the part of the code that is causing problems, and make it easy to post small code snippets onto stackoverflow.
  3. Your comments describe what the code is doing too literally, and don't give enough details on what the intended effects are. After you write short functions, you should explain what inputs those functions expect, and what output they are supposed to produce. Often, that's all the commenting you need in Python (assuming you're careful with function and variable names!)
  4. Your code has a lot of duplication, especially in the 'fixtures' section. You need to try hard not to copy and paste code, because that makes debugging/updating much harder - you might fix one bit of the code but forget an identical section.
Community
  • 1
  • 1
zehnpaard
  • 6,003
  • 2
  • 25
  • 40
  • thank you very much. I had limited time to do this (it was for a practise controlled assessment) so i had to try to economise time as much as possible. That said, i will use these valuable tips in the future. – Muhammed Munshi Dec 28 '14 at 13:24