CGPA CALCULATOR

CGPA Calculator
Free Online Tool

CGPA Calculator

Calculate your Cumulative Grade Point Average instantly. Add semesters, enter your courses, and see your CGPA update in real-time.

0.00
CGPA
Enter your courses to begin
Credits: 0
Semesters: 0
Courses: 0
Enter prior GPA (optional). If you already have a CGPA from previous terms, enter it along with the total credits completed to carry it forward.
Add a semester. Click “Add Semester” for each term you want to include. You can rename each semester freely.
Fill in your courses. Enter the course name, select a letter grade, and specify the number of credit hours for each course.
Add more courses or semesters as needed using the respective buttons. Your CGPA updates live as you type.
Read your result. The gauge at the top shows your live cumulative GPA, letter grade, total credits, and a per-semester breakdown.
`; }); // ── STATE ──────────────────────────────────────────────────────── let semCount=0; const sems=[]; // ── HELPERS ───────────────────────────────────────────────────── const gradeOpts=(sel='A')=>GRADES.map(g=>``).join(''); function semGPA(courses){ let pts=0,cr=0; courses.forEach(c=>{const g=GM[c.grade],n=parseFloat(c.credits)||0;if(g&&n>0){pts+=g.p*n;cr+=n;}}); return cr>0?{gpa:pts/cr,credits:cr}:{gpa:null,credits:0}; } function calcCGPA(){ let pts=0,cr=0; const eg=parseFloat(document.getElementById('prevGPA').value); const ec=parseFloat(document.getElementById('prevCredits').value); if(!isNaN(eg)&&!isNaN(ec)&&ec>0){pts+=eg*ec;cr+=ec;} sems.forEach(s=>s.courses.forEach(c=>{ const g=GM[c.grade],n=parseFloat(c.credits)||0; if(g&&n>0){pts+=g.p*n;cr+=n;} })); return cr>0?{gpa:pts/cr,credits:cr}:{gpa:null,credits:0}; } function letterDesc(gpa){ if(gpa===null)return{l:'—',d:'Enter your courses to begin',col:'var(--muted)'}; if(gpa>=3.7)return{l:'A',d:'Excellent — Outstanding performance',col:'#4ade80'}; if(gpa>=3.3)return{l:'A−',d:'Excellent — Above average work',col:'#86efac'}; if(gpa>=3.0)return{l:'B+',d:'Good — Noticeably above average',col:'#60a5fa'}; if(gpa>=2.7)return{l:'B',d:'Good — Above average performance',col:'#93c5fd'}; if(gpa>=2.3)return{l:'B−',d:'Good — Slightly above average',col:'#bfdbfe'}; if(gpa>=2.0)return{l:'C+',d:'Satisfactory — Average work',col:'#fbbf24'}; if(gpa>=1.7)return{l:'C',d:'Satisfactory — Average performance',col:'#fcd34d'}; if(gpa>=1.3)return{l:'C−',d:'Satisfactory — Below average',col:'#fde68a'}; if(gpa>=1.0)return{l:'D',d:'Poor — Minimal passing work',col:'#fb923c'}; if(gpa>0) return{l:'D−',d:'Poor — Barely passing',col:'#fdba74'}; return{l:'F',d:'Failing — Did not meet requirements',col:'#f87171'}; } // ── REFRESH ────────────────────────────────────────────────────── function refresh(){ // Per-semester GPAs const semResults=sems.map(s=>{ const r=semGPA(s.courses); const el=document.getElementById(`sgpa-${s.id}`); if(el) el.textContent=r.gpa!==null?`GPA: ${r.gpa.toFixed(2)}`:'GPA: —'; // Update GP cells s.courses.forEach((c,i)=>{ const el=document.getElementById(`gp-${s.id}-${i}`); if(el){ const g=GM[c.grade];const n=parseFloat(c.credits)||0; if(g&&n>0){el.textContent=(g.p*n).toFixed(2);el.className=`gp-cell ${g.cls}`;} else{el.textContent='—';el.className='gp-cell';} } }); // footer summary const sfEl=document.getElementById(`sfoo-${s.id}`); if(sfEl){ sfEl.innerHTML=`Semester GPA: ${r.gpa!==null?r.gpa.toFixed(2):'—'}Credits: ${r.credits}`; } return r; }); // Cumulative const {gpa,credits}=calcCGPA(); const totalCourses=sems.reduce((a,s)=>a+s.courses.length,0); // Gauge const CIRC=2*Math.PI*45; const pct=gpa!==null?Math.min(gpa/4,1):0; const fill=document.getElementById('gaugeFill'); fill.style.strokeDashoffset=CIRC*(1-pct); const col=gpa===null?'var(--muted)':gpa>=3.5?'#4ade80':gpa>=3.0?'#60a5fa':gpa>=2.0?'#fbbf24':gpa>=1.0?'#fb923c':'#f87171'; fill.style.stroke=col; document.getElementById('gaugeGPA').textContent=gpa!==null?gpa.toFixed(2):'0.00'; document.getElementById('gaugeGPA').style.color=col; const ld=letterDesc(gpa); document.getElementById('statLetter').textContent=ld.l; document.getElementById('statLetter').style.color=ld.col; document.getElementById('statDesc').textContent=ld.d; document.getElementById('metaCredits').textContent=credits; document.getElementById('metaSems').textContent=sems.length; document.getElementById('metaCourses').textContent=totalCourses; // Per-semester badges const bd=document.getElementById('semBadges'); bd.innerHTML=semResults.map((r,i)=>{ if(r.gpa===null)return''; const bg=r.gpa>=3?'rgba(74,222,128,.12)':r.gpa>=2?'rgba(251,191,36,.12)':'rgba(248,113,113,.12)'; const tc=r.gpa>=3?'#4ade80':r.gpa>=2?'#fbbf24':'#f87171'; return`S${i+1}: ${r.gpa.toFixed(2)}`; }).join(''); } // ── BUILD COURSE ROW ────────────────────────────────────────────── function courseRowHTML(sid,idx,c){ return` `; } // ── ADD SEMESTER ────────────────────────────────────────────────── function addSemester(){ semCount++; const id=semCount; const sem={id,name:'',courses:[ {name:'',grade:'A',credits:3},{name:'',grade:'A',credits:3}, {name:'',grade:'B+',credits:3},{name:'',grade:'B',credits:3}, ]}; sems.push(sem); const div=document.createElement('div'); div.className='sem-card';div.id=`sem-${id}`; div.innerHTML=`
${id}
GPA: —
${sem.courses.map((c,i)=>courseRowHTML(id,i,c)).join('')}
Course Name Grade Credits Grade Pts
`; document.getElementById('semsContainer').appendChild(div); // Events div.addEventListener('input',e=>{ const t=e.target; const sid=parseInt(t.dataset.sid),idx=parseInt(t.dataset.idx),f=t.dataset.f; const s=sems.find(s=>s.id===sid); if(s&&!isNaN(idx)&&f){s.courses[idx][f]=t.value;refresh();} if(t.dataset.stitle){const s2=sems.find(s=>s.id===parseInt(t.dataset.sid));if(s2)s2.name=t.value;} }); div.addEventListener('change',e=>{ const t=e.target; const sid=parseInt(t.dataset.sid),idx=parseInt(t.dataset.idx),f=t.dataset.f; const s=sems.find(s=>s.id===sid); if(s&&!isNaN(idx)&&f){s.courses[idx][f]=t.value;refresh();} }); div.addEventListener('click',e=>{ // Remove course const rc=e.target.closest('[data-rm-course]'); if(rc){ const sid=parseInt(rc.dataset.rmCourse),ci=parseInt(rc.dataset.ci); const s=sems.find(s=>s.id===sid); if(s&&s.courses.length>1){ s.courses.splice(ci,1); document.getElementById(`tbody-${sid}`).innerHTML=s.courses.map((c,i)=>courseRowHTML(sid,i,c)).join(''); refresh(); } return; } // Remove semester const rs=e.target.closest('[data-rm-sem]'); if(rs){ const sid=parseInt(rs.dataset.rmSem); const idx=sems.findIndex(s=>s.id===sid); if(idx!==-1)sems.splice(idx,1); div.remove();refresh(); return; } // Add course const ac=e.target.closest('[data-add-course]'); if(ac){ const sid=parseInt(ac.dataset.addCourse); const s=sems.find(s=>s.id===sid); if(s){ const ni=s.courses.length; s.courses.push({name:'',grade:'A',credits:3}); document.getElementById(`tbody-${sid}`).insertAdjacentHTML('beforeend',courseRowHTML(sid,ni,s.courses[ni])); refresh(); } } }); refresh(); } // ── GLOBAL LISTENERS ───────────────────────────────────────────── document.getElementById('prevGPA').addEventListener('input',refresh); document.getElementById('prevCredits').addEventListener('input',refresh); document.getElementById('addSemBtn').addEventListener('click',addSemester); document.getElementById('resetBtn').addEventListener('click',()=>{ if(!confirm('Reset all data?'))return; sems.length=0;semCount=0; document.getElementById('semsContainer').innerHTML=''; document.getElementById('prevGPA').value=''; document.getElementById('prevCredits').value=''; refresh(); addSemester(); }); // ── INIT ───────────────────────────────────────────────────────── addSemester();
Scroll to Top