COMPUTER PROGRAMMING 1 (PYTHON) • PROBLEM SOLVING & MINI-PROJECTS

Building Grade Tracker — I can build a grade tracker that computes averages and letter grades using lists and functions.

Combine Python lists and functions to create a practical tool that calculates averages and assigns letter grades automatically.

Historical Context & Motivation

Before computers existed, teachers recorded every grade by hand in paper grade books. They added columns of numbers with pencil, divided totals by the number of assignments, and looked up letter grades on a printed chart. One arithmetic mistake could change a student's entire report card. As schools grew larger, the need for reliable, automated grading tools became unavoidable.

1960s
Mainframe Grade Processing
Universities began using mainframe computers and punch cards to store student records and compute grade point averages for thousands of students at once.
1979
VisiCalc — The First Spreadsheet
The first electronic spreadsheet let teachers enter grades into rows and columns on personal computers, automatically recalculating averages when data changed.
1991
Python Is Released
Guido van Rossum released Python, a language designed to be readable and beginner-friendly — perfect for building small, useful tools like grade trackers.
2010s
Learning Management Systems
Platforms like Canvas and Google Classroom automate grade tracking at scale, but they rely on the same fundamental logic: store scores in a list, compute an average, and map that average to a letter grade.

At their core, all of these systems solve the same problem: how do you take a collection of numeric scores, find a meaningful average, and translate it into a letter grade? In this lesson, you will build that exact system from scratch in Python, using lists to store data and functions to organize your logic into reusable pieces.

Core Principles & Definitions

Before writing any code, you need to understand the building blocks that make a grade tracker possible. Every program that processes a collection of data and produces a result follows a pattern: gather the data, process it, and present the output. Our grade tracker uses three core programming concepts to accomplish this.

1

Lists

A list is an ordered, mutable collection of items stored in a single variable. In Python, you create one with square brackets: grades = [88, 92, 75, 100]. Lists let you store as many scores as you need without creating separate variables for each one.
2

Functions

A function is a named block of code that performs a specific task and can be called as many times as you want. You define one with def and can pass data into it through parameters and get data back with return.
3

Conditional Logic

An if/elif/else chain lets your program choose different actions depending on a condition. You use this to decide whether a numeric average becomes an A, B, C, D, or F.
4

Built-in Functions: sum() and len()

Python provides sum() to add up all items in a list and len() to count how many items are in it. Dividing the sum by the length gives you the arithmetic mean — the average.
✦ KEY TAKEAWAY
Think of a list like a backpack: you can stuff any number of assignments into it, and it keeps them organized in order. A function is like a recipe card — it tells you exactly what to do with those assignments (add them up, divide, label the result). By combining backpacks and recipe cards, you build a complete system without repeating yourself.

Visual Overview of the Grade Tracker

The diagram below shows the complete data flow of our grade tracker. Data enters as individual scores, gets stored in a list, flows through two functions, and exits as both a numeric average and a letter grade. Understanding this pipeline before you code helps you see how each piece connects to the next.

The data flows left to right: raw scores enter, get stored in a Python list, pass through calculate_average(), and then through get_letter_grade() to produce the final output. The dashed box at the bottom shows common list operations you will use.

Notice how each box in the diagram represents a distinct responsibility. The list holds data, one function does math, and another function applies grading rules. This separation is a design principle called modular design — each piece does one job well, making your code easier to read, test, and modify later.

How the Math and Logic Work

The grade tracker relies on two core operations: computing an arithmetic mean and mapping that mean to a letter grade. Let's formalize both so you understand exactly what your code will do under the hood.

ARITHMETIC MEAN (AVERAGE)
average = sum(grades) ÷ len(grades) = (g₁ + g₂ + … + gₙ) ÷ n
Where g₁, g₂, …, gₙ are individual scores and n is the total number of scores. Python's sum() adds all items, and len() counts them.

In Python, the average calculation becomes a single line: average = sum(grades) / len(grades). The division operator / always returns a float in Python 3, so an average of 355 ÷ 4 yields 88.75 rather than the integer 88. This matters for precise grading.

LETTER GRADE MAPPING
A: avg ≥ 90 | B: 80 ≤ avg < 90 | C: 70 ≤ avg < 80 | D: 60 ≤ avg < 70 | F: avg < 60
This is a standard 10-point grading scale. Each range is exclusive at the top and inclusive at the bottom. In Python, you implement this with an if/elif/else chain that checks conditions from highest to lowest.
⚠️ Why Check From Highest to Lowest?
Python evaluates if/elif conditions in order and stops at the first one that is True. By checking avg >= 90 first, you guarantee a score of 95 immediately returns "A" without accidentally falling into a lower bracket. If you checked avg >= 60 first, every score above 60 would be labeled "D"!

There is one important edge case to handle: what if the list is empty? Dividing by zero causes a ZeroDivisionError in Python. A well-written function should check if len(grades) == 0 before performing the division and return a helpful message or a default value instead of crashing.

Detailed Code Breakdown

Now let's look at the complete grade tracker program and break down each function. The diagram below shows the full code structure with annotations. After studying it, you should be able to type this program from scratch.

The complete grade tracker program on the left, with annotation cards on the right explaining each section. Note the three clear sections: two function definitions and the main program that ties them together.
Key lines from the grade tracker and the concepts they demonstrate
Line / BlockPurposeKey Python Concept
def calculate_average(grades):Defines a function that accepts a list of numbersFunction definition, parameter
if len(grades) == 0:Prevents a ZeroDivisionError on an empty listGuard clause, error prevention
return total / countSends the computed average back to the callerReturn statement, float division
if average >= 90:Starts the letter grade decision chain from highestConditional, comparison operator
f"Average: {avg:.2f}"Formats the average to two decimal places for displayf-string, format specifier

Worked Example: Running the Grade Tracker

Let's trace through the program step by step using a concrete set of five quiz scores: 88, 92, 75, 100, and 67. By following the data through each function call, you'll see exactly how Python executes the code.

Tracing the Grade Tracker with Five Scores
1
Step 1 — Create the ListWe start by storing our scores in a list: grades = [88, 92, 75, 100, 67]. Python allocates memory for these five integers and stores them in order. Each element has an index: grades[0] is 88, grades[4] is 67.
grades = [88, 92, 75, 100, 67]
2
Step 2 — Call calculate_average(grades)Python enters the calculate_average function. It first checks if the list is empty — len(grades) returns 5, so we skip the guard clause. Next, sum(grades) adds 88 + 92 + 75 + 100 + 67 = 422. Then len(grades) gives 5. The function returns 422 ÷ 5.
avg = 84.4
3
Step 3 — Call get_letter_grade(84.4)Python enters get_letter_grade with average = 84.4. It checks: is 84.4 ≥ 90? No. Is 84.4 ≥ 80? Yes! Python immediately returns "B" and does not check the remaining conditions.
letter = "B"
4
Step 4 — Print the ResultsThe two print() statements use f-strings to display the results. The format specifier :.2f rounds the average to two decimal places for clean output.
Output: Average: 84.40 and Letter Grade: B
💡 Try Modifying the Data
What happens if you change the 67 to a 93? The new sum would be 448, the new average would be 89.6, and the letter grade would still be a B (since 89.6 < 90). Change it to a 95 and the average becomes 90.0 — now it's an A! Experimenting with different inputs is one of the best ways to build intuition about how your program works.

Strengths, Limitations & Design Choices

Our grade tracker is functional, but every program involves trade-offs. Understanding what your design does well and where it falls short helps you think like a real software developer. Below is a comparison of the strengths and limitations of our current approach.

Design strengths vs. limitations of the basic grade tracker
StrengthsLimitations
Modular — each function has one clear job, making it easy to test and debugOnly supports a simple average (no weighted categories like homework vs. exams)
Handles empty lists gracefully with a guard clauseGrades are hardcoded — there's no user input loop to enter scores dynamically
Works with any number of scores — list can grow or shrinkGrading scale is fixed at the standard 10-point scale; some schools use different thresholds
Uses Python built-ins (sum, len) so the code is concise and readableNo data persistence — scores are lost when the program ends (no file saving)
Clean f-string output is user-friendly and formattedDoes not validate input — negative numbers or non-numeric values could cause errors
✦ KEY TAKEAWAY
A first version of a program doesn't need to be perfect — it needs to work correctly for the core case. Professional developers call this a minimum viable product (MVP). Our grade tracker is an MVP: it solves the central problem (averaging grades and assigning letters) and gives you a solid foundation to add features like input validation, weighted averages, or file saving later.

Connection to Advanced Concepts

The grade tracker you've built uses fundamental Python patterns that appear everywhere in more advanced programming. Below is a comparison showing how each concept in your tracker maps to more sophisticated techniques you'll encounter as you continue learning.

How today's concepts connect to advanced programming
Grade Tracker ConceptAdvanced VersionWhere You'll See It
List of gradesDictionaries mapping student names to grade listsMulti-student grade books, databases
Functions with return valuesClasses with methods (object-oriented programming)AP Computer Science, game development
if/elif/else for letter gradesDictionary lookups or strategy patternsScalable applications, config-driven grading
Hardcoded listReading from CSV files or databasesData science, web applications
print() for outputGraphical user interfaces (GUIs) or web dashboardsTkinter, Flask, full-stack development

One powerful extension to try is adding a while loop that lets users type in grades one at a time and type "done" to finish. This turns your static program into an interactive tool. Another next step is using a dictionary to store multiple students' grades, so a single run of the program can track an entire class. These extensions build directly on the list and function skills you've practiced today.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain in your own words why we check if average >= 90 before elif average >= 80 in the get_letter_grade() function. What would go wrong if the conditions were reversed, checking from lowest to highest?
PROBLEM 2 — BASIC CALCULATION
Given grades = [78, 85, 92, 64, 91], manually trace through the calculate_average() function. What is the sum, the count, the average, and the resulting letter grade?
PROBLEM 3 — INTERMEDIATE
A student has grades [70, 85, 90, 60] and wants to know what score they need on a fifth assignment to earn at least a B (average ≥ 80). Write the math to solve this, then describe how you could modify the grade tracker to answer this question programmatically.
PROBLEM 4 — APPLIED
Your teacher uses a weighted grading system: homework is worth 30% of the final grade, quizzes are worth 30%, and exams are worth 40%. A student has a homework average of 95, a quiz average of 80, and an exam average of 72. Write a function weighted_average(hw, quiz, exam) that computes the weighted average, then compute the student's letter grade.
PROBLEM 5 — CRITICAL THINKING
A teacher wants to drop each student's lowest grade before computing the average. Write a function called drop_lowest(grades) that returns a new list with the lowest score removed, without modifying the original list. Then explain why it's important not to modify the original list and how your existing calculate_average() function can work with the result of drop_lowest().

Lesson Summary

In this lesson, you built a complete grade tracker in Python by combining three fundamental concepts. You used a list to store multiple scores in a single variable, applied Python's built-in sum() and len() functions to compute an arithmetic mean, and wrote an if/elif/else chain to map that average to a letter grade on a standard 10-point scale.

The key design principle was modular design: separating your logic into a calculate_average() function and a get_letter_grade() function so each piece has one clear job. You also learned to include a guard clause for empty lists and to check conditions from highest to lowest to avoid logical errors. These same patterns — storing data in collections, processing it with reusable functions, and presenting clean output — are the foundation of every real-world application, from learning management systems to data science pipelines.

Varsity Tutors • Computer Programming 1 (Python) • Building Grade Tracker