To iterate through a .txt table in python

Question:

Student ID, Assignment, Score
123456, Zany Text, 100
123456, Magic 9 Ball, 60
123456, Nim Grab, 80
123456, Dungeon Crawl, 78
123456, Ultimate TODO List, 90
654321, Zany Text, 48

This is the content of the .txt file, I need to iterate through this text and get the average Score of all the students (and do some other stuff, but ill figure that out later).

Tried putting all the content in a 2d tuple, which worked but i couldnt reference any of the elements in the list inside the list – print(tup[1][1]) gave error list index out of range but print(tup[1]) did not.

my code-

infile=open("scores.txt", "r")
total=0
i=0
tup=[]
for i in range (7):
    tup.append([])
tup[0].append(infile.readline().split(","))
b=''
for i in range(1, len(tup)):
    tup[i].append(infile.readline().split(","))
for i in range(0,len(tup)):
    for j in range(len(tup[i])):
        print(tup[i][j], end=' ')
    print()
Asked By: Prerak Jain

||

Answers:

  1. You don’t need to "pre-allocate" lists in python: if you want to add new elements, simply call tup.append.
  2. You’ll want to strip off the end ‘n’ from .readline() using strip.
  3. You can iterate over elements of a list using for item in list:

infile=open("scores.txt", "r")
table = []
table.append(infile.readline().strip().split(","))
for _ in range(16):
    table.append(infile.readline().strip().split(","))
for row in table:
    for col in row:
        print(col, end=' ')
    print()
total = sum(int(row[-1]) for row in table[1:] if row[-1])
print(total)
Answered By: Jack Reilly

The file appears to be in CSV format. Change your file from .txt to .csv . Now you can use csv library to get your desired outcome.

import csv

# opening the CSV file
with open('score.csv', mode='r')as file:

 # reading the CSV file
 csvFile = csv.reader(file)
 # removing Headers from the file
 header = next(csvFile)
 # displaying the contents of the CSV file

 avg_score = 0
 total_score = 0
 total_row = 0

 for lines in csvFile:
    total_score += int(lines[2])
    total_row += 1

 avg_score = total_score/total_row
 print(avg_score)

Hope this helps. Happy Coding 🙂

Answered By: louis joseph

It should be something like:

# read the file
content = []
with open("scores.txt", "r") as infile:
    for line in infile:
        if not line.isspace():  # skip empty lines
            content.append(line.strip().split(','))

# print the content 
for row in content:
    for element in row:
         print(el, end=' ')
    print()

mean = sum([float(x[-1]) for x in content[1:]])/(len(content)-1)
print(mean)

So you have made a several mistakes here:

  1. You open the file without closing it later
  2. You predefine length of your file – this is not needed and not healthy
  3. You separate first line read from the file and the rest – I understand why you would like to do that. But as you treat header and the rest of the content the same way there is no actual need to do that. It is better to read everything the same way and treat the header later.
  4. Finally, to calculate mean it is better to create a list comprehension of the numerical value of the last column (hence [-1] index) starting from the second row (hence the [1:])
  5. One small thing. When reading files, there is always the need to check valid inputs. I’ve added the treatment for trailing empty lines as an example.
Answered By: igrinis