TypeScript Tutorial
TypeScript Project: Grade Calculator
Convert numeric scores to letter grades, compute an average, and print a report.
What you will build
A grade calculator takes numeric scores, maps each one to a letter, then prints a report with an average. The letter boundaries live in one function so the table and the average never disagree about what 89 means. Scores sit in a number[].
Demo scores are hardcoded. Use Try it in TypeScript and/typescript/try. The Python and C++ try pages will not compile this.
Numeric score to letter
Walk the scale from the top. 90 and up is A, 80 is B, 70 is C, 60 is D, anything below is F. A score outside 0 through 100 still gets a letter here; you can clamp or reject those in practice. The return type isstring.
Example
function letterFrom(score: number): string {
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
}
return "F";
}
console.log(91 + " " + letterFrom(91));
console.log(84 + " " + letterFrom(84));
console.log(59 + " " + letterFrom(59));Output is A, then B, then F. 90 is the first A; 89 is still a B.
Average of an array
Sum the scores, then divide by length. TypeScript number keeps the fraction. An empty array has no average; return 0 and let the caller print a message.
Example
function average(scores: number[]): number {
if (scores.length === 0) {
return 0;
}
let sum = 0;
for (const s of scores) {
sum = sum + s;
}
return sum / scores.length;
}
const scores: number[] = [];
scores.push(91);
scores.push(84);
scores.push(76);
console.log(average(scores));Compile at /typescript/try with Try it in TypeScript. The average of 91, 84, and 76 is 83.666… until you set precision with toFixed.
GPA-style points
A GPA-style average maps letters to 4.0, 3.0, 2.0, 1.0, and 0.0, then averages those points. That is not the same as averaging the raw percents. Both numbers are useful; this project prints each.
Example
function letterFrom(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
if (score >= 60) return "D";
return "F";
}
function pointsFrom(letter: string): number {
if (letter === "A") return 4.0;
if (letter === "B") return 3.0;
if (letter === "C") return 2.0;
if (letter === "D") return 1.0;
return 0.0;
}
console.log(pointsFrom(letterFrom(91)));
console.log(pointsFrom(letterFrom(84)));91 becomes A and 4.0. 84 becomes B and 3.0.
Complete grade report
Print every score with its letter, then the percent average and the GPA-style average, both with two decimal places. Names are optional here; the array is scores only so the arithmetic stays obvious.
Example
function letterFrom(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
if (score >= 60) return "D";
return "F";
}
function pointsFrom(letter: string): number {
if (letter === "A") return 4.0;
if (letter === "B") return 3.0;
if (letter === "C") return 2.0;
if (letter === "D") return 1.0;
return 0.0;
}
const scores: number[] = [];
scores.push(91);
scores.push(84);
scores.push(76);
scores.push(68);
scores.push(95);
console.log("Score Letter");
let sum = 0;
let pointSum = 0;
for (const s of scores) {
const letter = letterFrom(s);
console.log(String(s).padStart(5) + " " + letter);
sum = sum + s;
pointSum = pointSum + pointsFrom(letter);
}
console.log("Average percent: " + (sum / scores.length).toFixed(2));
console.log("GPA-style: " + (pointSum / scores.length).toFixed(2));Five rows print first. The percent average is 82.80. The GPA-style average uses A, B, C, D, A which is (4+3+2+1+4) / 5 = 2.80.
Common mistakes
- Testing F first with
score < 60and then usingifinstead ofelse iffor the rest. A 95 is less than nothing in a broken chain and can fall through. Start from A and go down, or use exclusive ranges. - Calling
letterFromin the report and a second copy of the scale in the GPA function. One function for the letter; one function from letter to points. - Dividing by
lengthwithout checking for an empty array. Guard that case. - Printing averages without
toFixed(2). Then 82.8 and 2.8 look unfinished next to a grade table.
Practice
- Change the 68 to 88 and confirm the letter becomes B and both averages rise.
- Add a sixth score of 100 with
pushand confirm an extra A row appears. - Treat scores below 0 or above 100 as invalid instead of a letter, and count how many A grades appear.
Last project: a shopping cart with a receipt and a money total.