There's a few things wrong with your code. This maybe should be migrated to Code Review, but I'll write my answer here for now.
I will keep this as close to your version as I can so that you see how to get from where you are to a working example without needing a ton of stuff you might not have learned yet. First let's look at yours one part at a time.
file =open('grades1.in.txt').read().split('\n')
Your file
is going to be a list of strings, where each string is a line in your input file. Note that if you have empty lines in your input, some of the lines in this list will be empty strings. This is important later.
for scores in file:
name_numbers = (scores.split('_'))
Works fine to split the name part of the line from the scores part of the line, so we'll keep it, but what are you doing with it here? Right now you are overwriting name_numbers
with each new line in the file and never doing anything with it, so we are going to move this into your function and make better use of it.
def averages():
No arguments? We'll work on that.
for numbers in file:
Keep in mind your file
is a list, where each entry in the list is one line of your input file, so this numbers in file
doesn't really make sense. I think this is where you first go wrong. You want to look at the numbers in each line after you split it with scores.split('_')
, and for that we need to index the result of the split. When you split your first line, you get something like:
split_line = ['Anne Adema', '', '', '', '', '', '', '', '', '', '', '', '6.5 5.5 4.5']
The first element (split_line[0]
) is the name, and the last element (split_line[-1]
) are the numbers, but you still have to split those out too! To get a list of numbers, you actually have to split it and then interpret each string as a number. You can do this pretty easily with a list comprehension (best way to loop in Python) like this:
numbers = [float(n) for n in split_line[-1].split(' ')]
This reads something like: first split the last element of the line at spaces to get ['6.5', '5.5', '4.5']
(note they're all strings), and then convert each value in that list into a floating-point number, and finally save this list of floats as numbers
. OK, moving on:
sum=0
numbers = split("\n") # already talked about this
for num in numbers:
sum = sum + int(num)
averages = sum/NUMBER_OF_GRADES
sum
is a keyword in Python, and we never want to assign something to a keyword, so something's wrong here. You can actually just call sum(my_list)
on any list (actually any iterable) my_list
to get the sum of all of the values in the list. To take the average, you just want to divide this sum by the length of the list, which you can get with len(my_list)
.
print ('% has an average grade of %.1') %(name, averages)
There are some cool newer ways to print formatted text, one of which I will show in the following, but if you are supposed to use this way then I say stick with it. That said, I couldn't get this line to work for me, so I went with something I know better.
Rewriting it into something that works:
def averages(line):
if line is '':
return # skips blank lines!
name_numbers = line.split('_') # now we split our line
name = name_numbers[0]
numbers = [float(n) for n in name_numbers[-1].split(' ')]
average = sum(numbers) / len(numbers)
print('{} has an average grade of {:.2}'.format(name, average))
And running it on your data:
file =open('grades1.in.txt').read().split('\n')
for line in file:
averages(line) # call the function on each line
# Anne Adema has an average grade of 5.5
# Bea de Bruin has an average grade of 7.2
# Chris Cohen has an average grade of 7.3
# Dirk Dirksen has an average grade of 4.6
With the result shown in the comments below the function call. One more note, you never close your file, and in fact you never save off the file handle to close it. You can get rid of any headaches around this by using the context manager syntax in Python:
with open('grades1.in.txt', 'r') as a_file:
for line in a_file:
averages(line)
This automatically handles closing the file, and will even make sure to do so if you run into an error in the middle of the block of code that executes within the context manager. You can loop through a_file
because it basically acts as an iterable that returns the next line in the file each time it is accessed.