Back to js-datatype-intermediate
07-school-report-card.js
JavaScript
1/**
2 * 📝 School Report Card Generator
3 *
4 * Sharma ji ke bete ka report card generate karna hai! Student ka naam aur
5 * subjects ke marks milenge, tujhe pura analysis karke report card banana hai.
6 *
7 * Rules:
8 * - student object: { name: "Rahul", marks: { maths: 85, science: 92, ... } }
9 * - Calculate using Object.values() and array methods:
10 * - totalMarks: sum of all marks (use reduce)
11 * - percentage: (totalMarks / (numSubjects * 100)) * 100,
12 * rounded to 2 decimal places using parseFloat(val.toFixed(2))
13 * - grade based on percentage:
14 * "A+" (>= 90), "A" (>= 80), "B" (>= 70), "C" (>= 60), "D" (>= 40), "F" (< 40)
15 * -
16 * - lowestSubject: subject name with lowest marks
17 * - passedSubjects: array of subject names where marks >= 40 (use filter)
18 * - failedSubjects: array of subject names where marks < 40
19 * - subjectCount: total number of subjects (Object.keys().length)
20 * - Hint: Use Object.keys(), Object.values(), Object.entries(),
21 * reduce(), filter(), map(), Math.max(), Math.min(), toFixed()
22 *
23 * Validation:
24 * - Agar student object nahi hai ya null hai, return null
25 * - Agar student.name string nahi hai ya empty hai, return null
26 * - Agar student.marks object nahi hai ya empty hai (no keys), return null
27 * - Agar koi mark valid number nahi hai (not between 0 and 100 inclusive),
28 * return null
29 *
30 * @param {{ name: string, marks: Object<string, number> }} student
31 * @returns {{ name: string, totalMarks: number, percentage: number, grade: string, highestSubject: string, lowestSubject: string, passedSubjects: string[], failedSubjects: string[], subjectCount: number } | null}
32 *
33 * @example
34 * generateReportCard({ name: "Rahul", marks: { maths: 85, science: 92, english: 78 } })
35 * // => { name: "Rahul", totalMarks: 255, percentage: 85, grade: "A",
36 * // highestSubject: "science", lowestSubject: "english",
37 * // passedSubjects: ["maths", "science", "english"], failedSubjects: [],
38 * // subjectCount: 3 }
39 *
40 * generateReportCard({ name: "Priya", marks: { maths: 35, science: 28 } })
41 * // => { name: "Priya", totalMarks: 63, percentage: 31.5, grade: "F", ... }
42 */
43export function generateReportCard(student) {
44 if(typeof student !== "object" || student === null){
45 return null
46 }
47 if( typeof student.name !== "string" || student.name.length === 0){
48 return null
49 }
50 if( typeof student.marks !== "object" || Object.keys(student.marks).length === 0){
51 return null
52 }
53 const marks = Object.values(student.marks)
54
55 const isNotValidMarks = marks.some(p => typeof p !== "number" || p < 0 || p > 100)
56
57 if(isNotValidMarks){
58 return null
59 }
60
61 const totalMarks = marks.reduce((accumulator, currentValue)=> accumulator + currentValue, 0);
62 const numSubjects = Object.entries(student.marks).length
63
64
65 const percentage = parseFloat(((totalMarks/(numSubjects*100))*100).toFixed(2))
66
67
68 function getGrade(percentage){
69 if (percentage >= 90) return "A+";
70 else if (percentage >= 80) return "A";
71 else if (percentage >= 70) return "B";
72 else if (percentage >= 60) return "C";
73 else if (percentage >= 40) return "D";
74 else return "F";
75 }
76
77 const grade = getGrade(percentage)
78 const SortedSubjects = Object.entries(student.marks).reduce((max, current)=> {
79 return current[1] > max[1] ? current: max
80 })
81 const highestSubject = SortedSubjects[0]
82
83 const reverseSortSubjects = Object.entries(student.marks).reduce((min, current)=>{
84 return current[1] < min[1] ? current : min
85 })
86 const lowestSubject = reverseSortSubjects[0]
87
88 const passedSubjects = Object.entries(student.marks).filter(([subject, mark]) => mark >= 40).map(([subject]) => subject);
89
90const failedSubjects = Object.entries(student.marks).filter(([subject, mark]) => mark < 40).map(([subject]) => subject);
91
92
93 return { name : student.name, totalMarks, percentage, grade, highestSubject, lowestSubject, passedSubjects, failedSubjects, subjectCount:numSubjects }
94}
95