Emily is a very smart girl.

Over the years, she has earned high grades and high accolades from peers and teachers alike in all of her honors and advanced high school classes.

She has gotten so used to overperform academically that she decided to take 5 AP classes in her 10th grade.

Almost a year went by and she now thinks, after struggling constantly to find the time to do so many assignments and extra curricular activities, that she might have been too ambitious. And to top it all, she now faces the 5 AP tests.

Three of her AP classes (AP Calculus, AP Chemistry and AP Biology) are crucial for her focus area in the years ahead. She will have to earn 94% or more of the total possible points in each of these.

The other two (AP French and AP History) are not as important but she still must earn 85% or more in each.

With these percents dancing in her head, she sits down in front of the computer a few weeks before taking the tests.

She wants to figure out how many points she has to earn in each of the tests to achieve her goal.

She writes down a list of points she earned during the year in each assignment of each class. She stores this in a python list of lists (with the first element of the list representing the assignment scores for AP Biology, the second the scores for AP Calculus,

then AP Chemistry, AP French and the last element representing the scores for AP History, i.e. she organizes the classes in alphabetical order)

pointsEarned = [[382, 710, 805, 615, 377, 255, 256, 30, 70, 316, 372, 173], [17, 23, 50, 200, 19, 56, 83, 91, 77, 9, 0], [26, 530, 60, 18, 547, 53, 529, 671, 90, 140, 208, 19, 329, 242, 233], [55, 77, 82, 60], [408, 800, 5, 306, 2, 703, 311, 163, 760, 742, 640, 574, 301, 565]]

Similarly the points possible in each assignment of each class are stored in the list of lists

pointsPossible = [[999, 947, 839, 689, 491, 758, 652, 156, 123, 731, 455, 526],

[20, 30, 50, 250, 20, 70, 100, 100, 100, 10, 10], [87, 648, 609, 65, 554, 150, 736, 837, 368, 147, 223, 438, 475, 893, 349],

[100,100,100,100], [949, 936, 7, 404, 191, 899, 964, 393, 914, 805, 706, 619, 529, 734]] The maximum possible points of each test go in the list

testsPossible = [50517, 1500, 58913,500, 9946]

and the minimum percent goal for each test goes into the list

percentsMin = [94,94,94,85,85]

Emily then computed the lowest 5 test scores that she needs to meet her goals using the following python code

# Loop through the integers between 0 and testMax# and exit when you have reached pointsNeeded def pointsNeeded(self, pointsEarned, pointsPossible, testMax, percentMin): totalPoss = 0 totalEarned = 0 # compute total possible points (from assignments and test) # and total earned points (just from assignments) for i in range(len(pointsPossible)): totalPoss += pointsPossible[i] totalEarned += pointsEarned[i] # take into account the max possible test points # when computing the total possible points totalPoss += testMax # if the totalEarned points equals the desired percent # Emily can skip the final test if (percentMin*totalPoss) == (100*totalEarned): return 0 # Loop through the max test possible points and quit as soon as # it is higher or equal than the minimum number of points needed for i in range(testMax + 1): if 100*i >= (percentMin*totalPoss - 100*totalEarned): return i # The score needed in the test is higher than the maximum possible points of # the test return -1def testsMin(self,pointsEarned,pointsPossible,testsMax,percentsMin): goalTestsScores = [] for i in range(len(pointsEarned)): goalTestsScores.append(self.pointsNeeded(pointsEarned[i],pointsPossible[i],testsMax[i],percentsMin[i])) return goalTestsScores

Notice that there are 3 possible cases:

a) She already has enough points in a class to achieve her desired percent. She can basically skip the test. That is the case above where a 0 is returned.

b) She needs to have some value between 1 and testMax in the test. That is the second return (return i) above. There is a loop through the testMax points until we hit or surpass

the points needed.

c) Finally it might be the case that she is so far behind in the class that even having the maximum score in the test will not allow her to reach the desired percent. That is the final return above (return -1).

After writing this code Emily realized she could have just computed the points needed directly. She rewrote the points needed function like this

# Compute the points needed directly def pointsNeeded(self, pointsEarned, pointsPossible, testMax, percentMin): totalPoss = 0 earned = 0 for i in range(len(pointsPossible)): totalPoss += pointsPossible[i] earned += pointsEarned[i] totalPoss += testMax # the 99 is needed to round up by 1 pointsNeeded = (percentMin*totalPoss+99)/100 - earned # We might need more points than testMax if pointsNeeded > testMax: return -1 # The number of points earned can be larger than what we need # i.e. we dont even have to take the final test if pointsNeeded < 0: return 0 return pointsNeeded

The only slightly tricky part is the fact she adds 99 to round up the score. Why is this needed?

Suppose percentMin = 70, totalPass = 66, earned = 44.

Then (70*66/100)=46 since this is integer division.

pointsNeeded = 46-44=2.

That is with 44+2=46 Emily would get 70% of 66. But is that true? 46/66= 0.696969... not 0.7.So indeed Emily would need 3 points not 2.

This is because 70*66/100 = 46.2 not 46. We want to round up and

(70*66 + 99)/100 = 47

which gives the 3 points needed.

When Emily runs her code she gets

We see that Emily needs to score 50050 out of 50517 in Biology's final test, 1500 out of 1500 (a perfect score!) in Calculus, 57868 out of 58913 in Chemistry, 491 out of 500 in French and in History 9867 out of 9946.CLASS 0 points earned in assignments [382, 710, 805, 615, 377, 255, 256, 30, 70, 316, 372, 173] total points earned in assignments 4361 max assignment points [999, 947, 839, 689, 491, 758, 652, 156, 123, 731, 455, 526] max points in test 50517 max possible points (assignments and tests) 57883 minimum test score to get 94% of the total possible points: 50050 CLASS 1 points earned in assignments [17, 23, 50, 200, 19, 56, 83, 91, 77, 9, 0] total points earned in assignments 625 max assignment points [20, 30, 50, 250, 20, 70, 100, 100, 100, 10, 10] max points in test 1500 max possible points (assignments and tests) 2260 minimum test score to get 94% of the total possible points: 1500 CLASS 2 points earned in assignments [26, 530, 60, 18, 547, 53, 529, 671, 90, 140, 208, 19, 329, 242, 233] total points earned in assignments 3695 max assignment points [87, 648, 609, 65, 554, 150, 736, 837, 368, 147, 223, 438, 475, 893, 349] max points in test 58913 max possible points (assignments and tests) 65492 minimum test score to get 94% of the total possible points: 57868 CLASS 3 points earned in assignments [55, 77, 82, 60] total points earned in assignments 274 max assignment points [100, 100, 100, 100] max points in test 500 max possible points (assignments and tests) 900 minimum test score to get 85% of the total possible points: 491 CLASS 4 points earned in assignments [408, 800, 5, 306, 2, 703, 311, 163, 760, 742, 640, 574, 301, 565] total points earned in assignments 6280 max assignment points [949, 936, 7, 404, 191, 899, 964, 393, 914, 805, 706, 619, 529, 734] max points in test 9946 max possible points (assignments and tests) 18996 minimum test score to get 85% of the total possible points: 9867 =======================

She will need quite a bit of luck to achieve her goals.

We end this post with Emily's complete code