Grades ProjectPoints Project

Files and lists of tuples

In the introductory lecture on files we saw that very often when we read data from a file we end up working with a list of tuples. In today's lecture we are going to look at a few more examples of programs that read lists of tuples from files and manipulate those lists of tuples.

In an earlier lecture on tuples we also saw that list comprehensions are a very common tool to use when processing lists of tuples. Today's example programs will show some more examples of list comprehensions as a means of processing and transforming lists of tuples.

First example: grading quizzes

For our first example program we will write a program to grade a collection of quizes. The problem starts with a text file that contains a list of quiz scores. Each line in the file takes the form

<name> <score>

In the first round of processing we will want to read this data from the file and organize it as a list of tuples:

(<name>,<score>)

Here is the portion of the program that constructs this list of tuples from the file.

data = []
with open("scores.txt") as f:
    for line in f.readlines():
        parts = line.split()
        data.append((parts[0],int(parts[1])))

The scores on this quiz are a little low, so the first thing we will want to do with these scores is apply a curve. To compute the curve we compute the average score on the quiz and then compute the difference between that average and a target value of 76.

sum = 0
for name, score in data:
    sum += score
average = sum/len(data)
print("Average for the exam is ",average)
curve = 76-average

Next, we construct a new version of the data list that has the scores adjusted by the curve amount. This is a natural opportunity to use a list comprehension:

curved = [(name,score + curve) for name,score in data]

Finally, we will want to convert each one of the scores to a letter grade using a standard scale. The first step in doing this is to define a function that converts a score to a letter grade:

def letterGrade(score):
    if score >= 90:
        grade = 'A'
    elif score >= 80:
        grade = 'B'
    elif score >= 70:
        grade = 'C'
    elif score >= 60:
        grade = 'D'
    else:
        grade = 'F'
    return grade

Using this function we can construct another list comprehension that converts the list of curved scores into a list of letter grades for each student.

grades = [(name,letterGrade(score)) for name,score in curved]

The last step is to print the results.

print("Name   Grade")
for name, grade in grades:
    print('{:8s} {}'.format(name,grade))

Second example: counting nearby points

The next example project involves a set of points in the plane. The points are stored in a data file, and each line of the data file has the format

<x coordinate> <y coordinate>

Here is the code to read these points from the text file. This code stores the list of points as a list of tuples.

points = []
with open('points.txt') as f:
    for line in f.readlines():
        parts = line.split()
        point = (float(parts[0]),float(parts[1]))
        points.append(point)

For each point in the data set we would like to count how many points are close to that point. To help us with this, I have constructed a function that takes a point and a list of points and computes how many of the points in the list are close to the given point.

import math
def count_close(point,points,cutoff = 5):
    """Count how many other points are within the cutoff
       distance of the given point. This function assumes
       that point is one of the points in the points list,
       and does not count the point itself."""
    count = 0
    for x,y in points:
        if math.sqrt((x-point[0])**2+(y-point[1])**2) <= cutoff:
            count += 1
    return count - 1

Using this function we can now set up a list comprehension that gives us the count of nearby points for each point in the original data set:

counts = [(point,count_close(point,points)) for point in points]

for point, n in counts:
    print(n," ",point)