Skip to content

Commit

Permalink
see #92 add grade distributions [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
rtholmes committed Sep 13, 2018
1 parent 64bacd7 commit 894bd1c
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/portal/frontend/html/cs310/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<ons-list id="AdminGradesList">
<ons-list-header>Grade Overview</ons-list-header>
<div id="gradesListTable" style="width:100%;"></div>
<div id="gradesSummaryTable" style="width:100%;"></div>
<div id="gradesListTableNone" class="noResultsRow">
No Results
</div>
Expand Down
202 changes: 200 additions & 2 deletions packages/portal/frontend/src/app/views/AdminGradesTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class AdminGradesTab {

// NOTE: this could consider if studentListTable has children, and if they do, don't refresh
document.getElementById('gradesListTable').innerHTML = ''; // clear target
document.getElementById('gradesSummaryTable').innerHTML = ''; // clear target

UI.showModal('Retrieving grades.');
const delivs = await AdminDeliverablesTab.getDeliverables(this.remote);
Expand Down Expand Up @@ -132,11 +133,208 @@ export class AdminGradesTab {

if (st.numRows() > 0) {
UI.showSection('gradesListTable');
UI.showSection('gradesSummaryTable');
UI.hideSection('gradesListTableNone');
} else {
UI.showSection('gradesListTable');
UI.hideSection('gradesListTableNone');
UI.hideSection('gradesListTable');
UI.hideSection('gradesSummaryTable');
UI.showSection('gradesListTableNone');
}

this.renderSummary(grades, delivs, students);
}

private renderSummary(grades: GradeTransport[], delivs: DeliverableTransport[], students: StudentTransport[]): void {
Log.trace("AdminGradesTab::renderSummary(..) - start");

const headers: TableHeader[] = [
{
id: 'delivId',
text: 'Deliv Id',
sortable: true,
defaultSort: true,
sortDown: false,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: 'avg',
text: 'Average',
sortable: true, // Whether the column is sortable (sometimes sorting does not make sense).
defaultSort: false, // Whether the column is the default sort for the table. should only be true for one column.
sortDown: false, // Whether the column should initially sort descending or ascending.
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: 'median',
text: 'Median',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '009',
text: '0-9',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '1019',
text: '10-19',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '2029',
text: '20-29',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '3039',
text: '30-39',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '4049',
text: '40-49',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '5059',
text: '50-59',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '6069',
text: '60-69',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '7079',
text: '70-79',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '8089',
text: '80-89',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '9099',
text: '90-99',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
},
{
id: '100',
text: '100',
sortable: true,
defaultSort: false,
sortDown: true,
style: 'padding-left: 1em; padding-right: 1em;'
}

];

// for (const deliv of delivs) {
// const col = {
// id: deliv.id,
// text: deliv.id,
// sortable: true,
// defaultSort: false,
// sortDown: true,
// style: 'padding-left: 1em; padding-right: 1em;'
// };
// headers.push(col);
// }

const st = new SortableTable(headers, '#gradesSummaryTable');

// this loop couldn't possibly be less efficient
const gradeMap: {[delivId: string]: number[]} = {};

for (const grade of grades) {
if (grade !== null && typeof grade.score !== 'undefined' && typeof grade.score === 'number') {
if (typeof gradeMap[grade.delivId] === 'undefined') {
gradeMap[grade.delivId] = [];
}
gradeMap[grade.delivId].push(grade.score);
}
}

const inBin = function(list: number[], lower: number, upper: number): number {
const total = list.reduce(function(accumulator, currentValue) {
if (currentValue >= lower && currentValue <= upper) {
accumulator++;
}
return accumulator;
}, 0);
return total;
};

for (const delivId of Object.keys(gradeMap)) {

const delivGrades: number[] = gradeMap[delivId];

const num = delivGrades.length;
if (num > 0) {
const total = delivGrades.reduce(function(accumulator, currentValue) {
return accumulator + currentValue;
});
const avg = Number((total / num).toFixed(2));

delivGrades.sort((a, b) => a - b);
const lowMiddle = Math.floor((num - 1) / 2);
const highMiddle = Math.ceil((num - 1) / 2);
const median = (delivGrades[lowMiddle] + delivGrades[highMiddle]) / 2;

const row: TableCell[] = [
{value: delivId, html: delivId},
{value: avg + '', html: avg + ''},
{value: median + '', html: median + ''}
];

for (let i = 0; i < 10; i++) {
const lower = i * 10;
const upper = lower + 9;
const numInBin = inBin(delivGrades, lower, upper);
Log.info('inBin( [..], ' + lower + ', ' + upper + '; #: ' + numInBin);
row.push({value: numInBin + '', html: numInBin + ''});
}
const numPerfect = inBin(delivGrades, 100, 100);
row.push({value: numPerfect + '', html: numPerfect + ''});
st.addRow(row);
}
}

st.generate();
}

public static async getGrades(remote: string): Promise<GradeTransport[]> {
Expand Down

0 comments on commit 894bd1c

Please sign in to comment.