input(this is what the file mygrades.txt contains)
CS1:5.75
#
CS 2: 5.5
Mathematik 1:5.75
@!
Econ 1: 5.5
Physics:6
Chemistry:5.75
!#
@
output : 5.70
Code:
import os
def get_average_grade(path):
grades = []
filesize = os.path.getsize("C:\\Users\Documents\mygrades.txt")
if not os.path.exists(path):
return None
with open("C:\\Users\Documents\mygrades.txt", "r") as f:
filesize = os.path.getsize("C:\\Users\Documents\mygrades.txt")
if filesize == 0: # not entirely correct because it might contain "#@$%$^&^&*^" for example which means no grade but wont return 0.0
return 0.0
else:
for line in f.readlines():
if ":" in line:
searchforcolon = line.find(":")
number1 = float(line[searchforcolon 1:])
grades.append(number1)
average = sum(grades)/len(grades)
return average
print(get_average_grade("C:\\Users\Documents\mygrades.txt"))
CodePudding user response:
The following articulation of your code would do the job. I assume that you want to round the average to second lower decimal:
v = []
with open(PATH_TO_FILE, "r") as f:
for l in f.readlines():
if ":" in l:
v.append(float(l.split(":")[1].strip()))
print(f'{int(100 * sum(v)/len(v))/100:.2f}' if len(v) > 0 else None)
CodePudding user response:
It seems that you want something like this:
import os
def get_average_grade(path):
if not os.path.exists(path):
return None
grades = []
with open(path) as file:
for line in file:
if ':' in line:
_, grade = line.strip().split(':')
if ''.join(grade.strip().split('.', maxsplit=1)).isnumeric():
grades.append(float(grade))
return (grades and round(sum(grades) / len(grades), 2)) or 0.0
print(get_average_grade('myfile.txt'))
First of you weren't using the path
argument properly in your function, you had to put it everywhere you used the path.
This function works pretty simply, first check if the path exists and if it doesn't return None. Then define a list and open the file (use for line in f
instead of for line if f.readlines()
). Then check if semicolon is in the line and split by that semicolon instead of trying to find its index, that will return a list that will contain text before and after each semicolon in that line. So extract the grade by using unpacking, then check if it can be converted to float and if that is not possible simply continue (you may want to somehow alert the user if couldn't convert to a float though). Then there is a simple short-circuiting which first checks if grades list is empty and if it is then it return 0.0
(so no grades were found), otherwise it return the average rounded to 2 decimal places