Overview
Objectives for today's lab:
- Become familiar with File I/O
- Learn to parse multiple kinds of information from a line of text
Grade Report
- You will be writing a program that computes weighted final grades
for 201 students and the class average.
- For this task, you'll be provided a file, grades.txt, containing the
students' names, and each assignment's weight and grade.
- Your program will produce a file named grade_report.txt that contains
the name of each student, their course score and their letter grade
for the course and finally the class average.
- The student grade file, grades.txt, has the following content:
Alice 0.03 74 0.03 79 0.03 72 0.03 69 0.03 81 0.03 75 0.03 73 0.03 70 0.08 75 0.08 73 0.25 82 0.25 71 0.10 28
Bob 0.03 84 0.03 79 0.03 87 0.03 90 0.03 85 0.03 82 0.03 86 0.03 83 0.08 87 0.08 89 0.25 82 0.25 84 0.10 30
Charlie 0.03 66 0.03 63 0.03 89 0.03 65 0.03 57 0.03 70 0.03 64 0.03 67 0.08 65 0.08 62 0.25 70 0.25 61 0.10 27
Lisa 0.03 91 0.03 99 0.03 89 0.03 90 0.03 100 0.03 100 0.03 98 0.03 95 0.08 85 0.08 100 0.25 94 0.25 92 0.10 34
Getting Started
- Since you will be reusing the code you wrote last week for the
functions lab, you'll want to make a copy of your lab5.py file and
just edit it. Call this copy lab6.py and put it in your lab6
directory.
- To get a copy of the grades.txt file, use the following command:
cp /afs/umbc.edu/users/s/l/slupoli/pub/labCode201/grades.txt .
You'll be reusing all of the functions you wrote last week for
this program. Only main() requires modification to handle:
- getting information on multiple students.
So you will still have:
- main()
- findCourseScore(courseDataList) - This function gets passed a list
of assignment weights and scores, arranged with the assignment's
weight followed by its score in the next position. This function
is to calculate and return the course score.
- findLabScore(rawlabScore) - This function takes the raw lab
score as shown in the file in the range of 0 - 30 and calculates
a final lab score in the range of 0 - 100. See the more detailed
instructions later in the lab.
- findLetterGrade(courseScore) - this function takes a numeric grade,
and returns a string, either 'A', 'B', 'C', 'D', or 'F'
What we are about to do (overall)
- Just listen for now to get the BIG PICTURE!
- Recall that in order to iterate through each line in a file we use
the following code :
infile = open("infilename.txt", "r")
for line in infile:
#do something with the variable line
infile.close()
- To write a string to a file we use the following code :
outfile = open("outfilename.txt", "w")
outfile.write("Some string")
outfile.close()
- In this case, when we read a line from the grades file, there
are multiple pieces of data on one line.
- To be usable, we'll need to separate the data. We can use the string
split() method.
- The split() method will return a list of strings that
represent each piece of text that is separated by blank space in the
original string.
- For example observe the following code :
>>> aLine = 'Lisa 0.03 91'
>>> aLine.split()
['Lisa', '0.03', '91']
If we store the result of the string split in a variable,
we can easily delete the student's name from the front of the list
leaving a list of weights and scores.
This still isn't quite what we need for our findCourseScore function,
although we're close. We'll need to change the list of strings into
a list of floats before we can pass it to our function.
Step 0 - File open/close
- To begin (and end) any type of file IO program, we need to open and close the file.
- Within the main in lab6.py, (also pictured below), create the code to open and close both:
- grades.txt for input (infile)
- grade_report.txt for output (outfile)
.. header, functions, etc...
def main():
#open files for input and output
.. rest of the orginal code here
#close files
main()
Step 1 - Iterating through a file
- In the previous lab, there was only one student's data that was read in. (Lisa's). In this lab there will
be many student's data that will be read in, but thankfully they all have the same data pattern as before.
Because of this we need to add a for loop that will read the data from the file grades.txt.
- Remember to indent the orginal code inside the new loop!!
.. header, functions, etc...
def main():
#open files for input and output
#create for loop to read all data from a file
.. rest of the orginal code here (INDENTED!!!)
#close files
main()
Step 2 - Splitting up the line of data read in
- Data from a file is read in line by line.
Alice 0.03 74 0.03 79 0.03 72 0.03 69 0.03 81 0.03 75 0.03 73 0.03 70 0.08 75 0.08 73 0.25 82 0.25 71 0.10 28
Bob 0.03 84 0.03 79 0.03 87 0.03 90 0.03 85 0.03 82 0.03 86 0.03 83 0.08 87 0.08 89 0.25 82 0.25 84 0.10 30
Charlie 0.03 66 0.03 63 0.03 89 0.03 65 0.03 57 0.03 70 0.03 64 0.03 67 0.08 65 0.08 62 0.25 70 0.25 61 0.10 27
Lisa 0.03 91 0.03 99 0.03 89 0.03 90 0.03 100 0.03 100 0.03 98 0.03 95 0.08 85 0.08 100 0.25 94 0.25 92 0.10 34
In order to use it and place the data we need into courseDataList (list) already created in our previous lab, you must:
- "Split" the line read in from the file, and that new set of data is placed into "courseDataList".
- Splitting will break up every individual item (called tokens) into a list of strings.
(Almost just like what we had last lab!!)
.. header, functions, etc...
def main():
#open files for input and output
#create for loop to read all data from a file
#split line into 'tokens', reuse courseDataList
courseDataList = line.split()
.. rest of the orginal code here (INDENTED!!!)
#close files
main()
Step 3 - Getting the name out of our courseDataList
.. header, functions, etc...
def main():
#open files for input and output
#create for loop to read all data from a file
#split line into 'tokens', reuse courseDataList
#create a variable called "name"
#grab the name from the list and place into "name".
#remove the "name" from the list using it's index number
.. rest of the orginal code here
#close files
main()
Step 4 - Converting courseDataList from Strings to Floats
- Again, our courseData list is not just right. But,:
- the name has been removed
- But the remaining data is all strings!!
- Remember, our findCourseScore requires a list of weights and scores in FLOATS!
- Within another loop that will travse the entire list:
- convert the courseDataList into floats (indented!! Since in another loop)
.. header, functions, etc...
def main():
#open files for input and output
#create for loop to read all data from a file
courseDataList = []
#split line into 'tokens', reuse courseDataList
#create a variable called "name"
#grab the name from the list and place into "name".
#remove the "name" from the list using it's index number
#create loop to travel through all of courseDataList
#type cast here to convert all elements from strings to float
.. rest of the orginal code here
#close files
main()
Step 5 - On your own!!
- We can't do everything for you!!
- But here's what's left. You need to find where it belongs.
- pass the float list of course data to findCourseScore
- with the information received from findCourseScore
- get the score (code already completed)
- using score, get the letter grade (extra credit last week, might already have)
- and write all information to a file
- Within the loop, Keep a running total of scores to find the class average
- At the very end, but before closing the file, write the class average to the file
- Remember to check "grade_report.txt" since there will not be output to the screen!
- Here is what the grade_report.txt file should look like:
Alice: 77.21 - C
Bob: 85.86 - B
Charlie: 68.14 - D
Lisa: 95.49 - A
Class average: 81.68
Bonus Task
Alice: 77.21 - C
Bob: 85.86 - B
Charlie: 68.14 - D
Lisa: 95.49 - A
Class average: 81.68
A: 1
B: 1
C: 1
D: 1
F: 0
Challenge Problem
- Write a challenge6.py file that will append the grades.txt file with
a new student's name and grades.
- You should do error checking on the input to insure that:
- The weights should add up to 1.00
- Grades should be in the following ranges:
- Assignment grades (HWs & Projs): 0 - 115
- Exam grades: 0 - 105
- Lab grade: 0 - 34