Home > database >  How to read names and grades from a csv file and write mean of them in another csv file?
How to read names and grades from a csv file and write mean of them in another csv file?

Time:10-15

I am a beginner in python, I want to read some names and grades from a csv file and write mean of grades in another csv file. I can read the grades from csv file, but I don't know how to write means in another csv file :( (Is there any way to write this code without the help of libraries like pandas?)

import csv
from os import name
from statistics import mean

with open(input_file_name) as f:
    reader = csv.reader(f)
    for row in reader:
        name = row[0]
        grades = row[1:]
        these_grades1 = list()
        for grade in grades:
            these_grades1.append(int(grade))
            mean1 = mean(these_grades1)

        #print(name,float(mean1))

    with open(output_file_name, 'w' , newline='') as new_f:
        writer = csv.writer(new_f)

        for row in reader:
            writer.writerow("%s,%s" % (name, float(mean1)))

        new_f.close()

names and grades:

marie,5,7,3,15
harry,3,9,4,20,9,1,8,16,0,5,2,4,7,2,1
john,19,10,19,6,8,14,3
sara,0,5,20,14
david,13,2,5,1,3,10,12,4,13,17,7,7
robert,1,9
james,0,16,16,13,19,2,17,8

correct output:

marie,7.5
harry,6.066666666666666
john,11.285714285714286
sara,9.75
david,7.833333333333333
robert,5.0
james,11.375

CodePudding user response:

There's a few things wrong with the code:

  • You keep overwriting mean1, meaning that the mean of each student is lost every time a new student is read. Use a list to keep track of the means already calculated (this is result in my code).
  • Not sure why you iterate over reader when printing the output
  • writerow takes a list as input, not a string (it will print very strangely if you use string)

Here is a fixed version:

import csv
from os import name

result = []
with open(input_file_name) as f:
    reader = csv.reader(f)
    for row in reader:
        name = row[0]
        grades = row[1:]
        for i, grade in enumerate(grades):
            grades[i] = int(grade)
        mean = sum(grades)/len(grades)
        result.append([name, mean])

with open(output_file_name, 'w' , newline='') as new_f:
    writer = csv.writer(new_f)
    for row in result:
        writer.writerow(row)

You can also do this without a list:

import csv
from os import name

with open(input_file_name) as f, open(output_file_name, 'w' , newline='') as new_f:
    reader = csv.reader(f)
    writer = csv.writer(new_f)
    for row in reader:
        name = row[0]
        grades = row[1:]
        for i, grade in enumerate(grades):
            grades[i] = int(grade)
        mean = sum(grades)/len(grades)
        writer.writerow([name, mean])

CodePudding user response:

This will give you appropriate result https://replit.com/@arvindDhakad/SilkyMarriedCleaninstall#main.py

import csv
from os import name
from statistics import mean

#open both file here
with open(input_file_name) as f, open(output_file_name, 'w' , newline='') as new_f:
    #initialize writer 
    writer = csv.writer(new_f)
    
    #initialize reader
    reader = csv.reader(f)

    for row in reader:
        name = row[0]
        grades = row[1:]
        these_grades1 = list()
        for grade in grades:
            these_grades1.append(int(grade))
            # you don't need to calculate mean here 
        
        # calculate mean
        mean1 = mean(these_grades1)

        # write to file
        writer.writerow([name, float(mean1)])

More pythonic version:

import csv
from statistics import mean

with open(input_file_name) as f, open(output_file_name, 'w',
                                      newline='') as new_f:
    #initialize writer
    writer = csv.writer(new_f)

    #initialize reader
    reader = csv.reader(f)
    writer.writerows([[row[0], mean(map(int, row[1:]))] for row in reader])
  • Related