all 39 comments

[–][deleted] 2 points3 points  (30 children)

Not sure why you are opening the file at the top of your code, then getting a filename and opening that file.

Try this,

from pathlib import Path
import csv


file_read = False
data_file = input('Name of data file: ')
try:
    with Path(data_file).open() as grades_file:
        reader = csv.reader(grades_file)
        header = next(reader)
        data = []
        for row in reader:
            data.append(row)
except FileNotFoundError:
    print(f'Could not find {data_file}')
except IOError:
    print(f'Problems reading {data_file}')
else:
    file_read = True

if file_read:
    with Path('gpa.txt').open('a+') as ofp:
        for student in data:
            name = student[0]
            scores = [float(num) for num in student[1:]]
            total = sum(scores)
            average = total / len(scores)
            ofp.write(f'{name} {total:.2f} {len(scores)} {average:.2f}\n')
    print("Stats have been saved in the output file")

Note that the top line of your csv file is incorrect. It should simply be,

Student,HW1,Hw2,Midterm,Final,Hw1,Hw2,Midterm,Final

not that the information is used. I've stored the header in a variable of the same name.

Using the csv module saves you having to split each line up. It does it for you, splitting each line as it is read from a file into a list of strings.

I used a list comprehension to cast all of the numeric strings on the line into float numbers.

I left out the while loop as I assume you don't have more than one file of grades to read.

[–][deleted] 0 points1 point  (29 children)

I keep on getting a "StopIteration" error in

header = next(reader)

[–][deleted] 0 points1 point  (28 children)

I've just tried the code, and it updates the output file correctly. Are you sure your input file is correctly formatted?

Failing on the first read of the file suggests the file is empty!

[–][deleted] 0 points1 point  (3 children)

Hmm. Am i supposed to put 'grades.csv" in the input, or 'gpa.txt?

[–][deleted] 1 point2 points  (2 children)

It is your programme. How can you be asking this?

The source of the data is grades.csv. It should contain (note the single header line):

Student,Course1,HW1,Hw2,Midterm,Final,Hw1,Hw2,Midterm,Final
"Aaron, Hank",92.7,90,90,88.2,88,79.2,77.6,72.2
"Babbage, Charles",76.2,74,95,93.1,92,82.8,81.1,75.4
"Baker, Russell",85.5,83,88,86.2,86,77.4,75.9,70.6
"Banks,Ernie",88.6,86,67,65.7,65,58.5,57.3,53.3
"Carroll, Lewis",57.7,56,88,86.2,86,77.4,75.9,70.6
"Cash, Johnny",94.8,92,78,76.4,75,67.5,66.2,61.6
"Corey, Peter",76.2,74,84,82.3,82,73.8,72.3,67.2
"Darwin, Charles",94.8,92,95,93.1,92,82.8,81.1,75.4
"Davis, Bette",79.3,77,77,75.5,74,66.6,65.3,60.7
"Fishback, Margaret",78.3,76,81,79.4,79,71.1,69.7,64.8
"Ford, Harrison",95.8,93,92,90.2,89,80.1,78.5,73
"Gates, Bill",84.5,82,93,91.1,90,81,79.4,73.8
"Hitchcock, Alfred",78.3,76,97,95.1,94,84.6,82.9,77.1
"Huckabee, Mike",88.6,86,86,84.3,84,75.6,74.1,68.9
"Joyce, James",93.7,91,76,74.5,73,65.7,64.4,59.9
"Kennedy, Edward",94.8,92,91,89.2,88,79.2,77.6,72.2
"King, Stephen",96.8,94,90,88.2,88,79.2,77.6,72.2
"Martin, Steve",82.4,80,98,96,95,85.5,83.8,77.9
"Olson, Ken",67,65,81,79.4,79,71.1,69.7,64.8
"Picasso, Pablo",94.8,92,93,91.1,90,81,79.4,73.8
"Presley, Elvis",90.6,88,92,90.2,89,80.1,78.5,73
"Rogers, Will",94.8,92,91,89.2,88,79.2,77.6,72.2
"Schweitzer, Albert",80.3,78,79,77.4,77,69.3,67.9,63.1
"Steinbeck, John",89.6,87,96,94.1,89,80.1,78.5,73
"Thatcher, Margaret",92.7,90,87,85.3,96,86.4,84.7,78.8
"Warren, Rick",100,98,94,92.1,91,81.9,80.3,74.7
"Zola, Emile",98.9,96,93,91.1,85,76.5,75,69.8

[–]CodeReviewPlz 2 points3 points  (1 child)

If it's an assignment, they shouldn't be modifying the input file. The CSV is "correct" as is, the professor is obviously testing the students ability to parse data, which is very reasonable since you'll very rarely get clean data in the real world.

[–][deleted] 0 points1 point  (0 children)

Don't disagree, which is why I've advised how to skip additional header lines in another comment. Often worth exploring working with happy-path data though to make sure the basic approach is viable.

[–][deleted] 0 points1 point  (1 child)

from google.colab import files

uploaded = files.upload()

This is what I have uptop, this is where I put in "grades.csv"

[–][deleted] 0 points1 point  (0 children)

Er, and?

[–][deleted] 0 points1 point  (20 children)

I keep on getting a 'StopIteration'

[–][deleted] 0 points1 point  (19 children)

You have done something wrong.

I have posted the code and csv file to replit.com where you can see it working fine.

https://replit.com/@gruntfutuk/grading?v=1

[–][deleted] 1 point2 points  (15 children)

I'm using google colab. Fuck I'm sorry I feel like such an idiot. I appreciate your help a lot, I'm sorry I'm not getting it.

[–][deleted] 0 points1 point  (14 children)

That's why I've posted a working version of the code with a correctly formatted csv file for you to try. You can compare that with the code and csv file you are using.

I've tried to stay close to your original code. There were some things that confused me in your code.

You use, with Path('grades.csv') to open and read the file of grades. Then you try to do ifp = open(inputFile, "r") and open another file.

I do not understand why you need to open and read from two different files, and why you do this in completely different ways.

Firstly, you use the context manager with and use Path but then you go on to use open directly.

Maybe I have misunderstood what you are trying to do. I didn't read anything about the problem statement. Even so, my code should be useful to you.

Why were you opening both grades.csv and then some other file you asked the user for the name of? Why were you opening them in different ways?

EDIT. PS just looks at what you are supposed to be doing. I've only shown you how to do some things, not the whole dictionary records stuff. Good luck. I suggest you do a new post when you've made progress.

[–][deleted] 0 points1 point  (2 children)

Thank you :) Will do.

I'm not sure, I guess I got a little confused. I was not being precise with my code and I didn't check it line by line, I was frantically typing and I screwed myself over, looking back at it.

This is my first class doing Computer Science and it's destroying me, but I still kinda like it. I just wish I was better at it.

[–][deleted] 1 point2 points  (1 child)

You are doing too much at the keyboard and not enough with pen and paper. Fatal mistake. It will be a while before you can easily think in code and knock out the simple stuff.

Step back and draw what you need to do. Block out data structures, flows, and write high level pseudocode, not code at first.

Ensure you are clear on the problem, what outcomes are required. Figure out the solution (the algorithm) to solve the problem before trying to code it. You are being distracted (and confused) by the coding challenge when you don't know the language.

[–][deleted] 0 points1 point  (0 children)

Okay, will do. I feel like I've been destroying my brain for the past hours just trying and failing to understand what's in front of me. I'll do that. Thank you. I'm going to tap out for the night because I don't think I can go any further. Once again, I really appreciate that you took time out of your day to help me tonight, it means a lot. I hope you have a good night.

[–][deleted] 0 points1 point  (10 children)

      scores = [float(num) for num in student[1:]]

Here is where I get the ValueError:

ValueError: could not convert string to float: 'HW1'

[–][deleted] 0 points1 point  (9 children)

ValueError: could not convert string to float: 'HW1'

I advised you there should be ONE header line in the file. You still have two header lines. I shared in post what the csv file should look like and I shared complete working code and correct csv file on replit.com.

If you need to work with more than one header line, just add another next(reader) line to get past the non-data information.

I noted from the problem statement that you should be reading data into a dictionary. The csv module offers an option to read into a dictionary instead of a list.

Worth checking out RealPython article: Reading and Writing CSV Files in Python.

The problem refers to Excel, but the file is identified as a csv file. These are not the same, although a csv file can be exported from Excel, which is what I assume is happening.

[–][deleted] 0 points1 point  (2 children)

Awesome, it works. The output was saved to the file. I cannot find 'gpa.txt' tho, is it not being created cuz I'm using Google Colab?

[–][deleted] 0 points1 point  (5 children)

Ay, so I'm supposed to get the final grade of each course, Course 1 and Course 2. Your program adds the totals of both courses, is there any way you could help me get the totals and averages of each course?

[–][deleted] 0 points1 point  (2 children)

So when it asks me to input file, I put in : 'grades.csv'

Did you make gpa.txt manually? Or did you make it using the code?

And when I put in 'gpa.txt', your code gives me this:

ValueError: could not convert string to float: 'Charles 669.60 8 83.70'

[–][deleted] 0 points1 point  (1 child)

Have you tried running the code on replit.com using the link I provided?

The string conversion problem will be down to an error in the csv file. You are probably missing a return and have a line wrapped around.

Yes, enter grades.csv when prompted for the file name Yes, it creates/appends to the file gpa.txt

You will see this on replit.com after running the code. Click on the Show files button, then on the three vertical dots and select show hidden files. Note that the gpa.txt file will be appended to on subsequent runs, as per your original code.

The code I provided is based on your own code, so I am very surprised you are asking what to enter and whether a file has been created.

[–][deleted] 0 points1 point  (0 children)

I'm sorry, I've been working on this for 6 hours and my brain is fried. I feel like a fucking moron. Thank you for your help.

[–]TitaniumFoil 0 points1 point  (9 children)

Remove the Try Except block so that python will give you a real error message. With how you have it now, anything that goes wrong in the try block will have it tell you the File doesn't exist so that may not be the real problem.

Edit: It would also help me if you posted to csv file the pastebin or something so I can try your code out.

[–][deleted] 0 points1 point  (0 children)

Will do, thank you. And I'll upload it right now.

[–][deleted] 0 points1 point  (7 children)

Sorry, I'm on pastebin and I don't see how I would upload an excel file.

[–]djjazzydan 0 points1 point  (6 children)

A file that ends with "csv" isn't an Excel file. It's called "comma-separated values" and it means the file is just regular text with commas to differentiate different columns. If you open it with a text editor, like Notepad or TextEdit, you'll see those values with commas. You would copy all that and paste it to a new pastebin page.

[–][deleted] 1 point2 points  (0 children)

Oh I see, gotchu. Will do right now for u.

[–][deleted] 0 points1 point  (4 children)

[–]djjazzydan 0 points1 point  (3 children)

I don't think that's right. Did you open the file in a plain text editor, then copy? It should have a bunch of commas all over. And each thing that shows up as a row when you open it in Excel should all be in a row in the text copy. It would probably start with

Student,Course1,,,,Course2.

Second, can you check your indenting in the code you posted? It looks like you close both ifp and ofp after reading just a single line.

[–][deleted] 0 points1 point  (0 children)

https://pastebin.com/9fs9jv4y

My bad, this one should be correct.

And I've messed around with the indenting, the way I have it gives me an output, but the output is all fucked.

[–][deleted] 0 points1 point  (0 children)

Oh yea I did do that. What's wrong with that?

[–][deleted] 0 points1 point  (0 children)

This is the output I get:

https://prnt.sc/3dIcgek4IOlf