compile_term_summaries.js
Examine the entire allstudents.json file, and extract a summary for each term. The following categories are summarized:
- citizenship
- ethnicity
- gender
- class size per year in program
- admits and graduations
- enrollment (requires
term_data/<term_key>/registration.json
) - support (requires
term_data/<term_key>/assignments.json
)
Numbers are broken down by department.subdivisons and department.plan_codes
Summary for previous and current academic year is stored in ./jekyll/_data/overview.json
Summary for each term is stored in ./jekyll/_data/term_data/<term_key>/term_summary.json
Table of Contents
- Setup
- Base Summary Structure
- Summarizing Categories
- Term Utilities
- Terms in Database
- Compile Term summaries for all terms
- Compile Academic Year Summary
/** department_summary.js
@overview generate json for use by gradphile overview pages
*/
Setup
Dependencies
var fs = require('fs');
var readYAML = require('read-yaml');
require('./logging')(__filename);
var bc = require("./bc_utilities.js");
Some Constants
const kAllAreasKey = "all";
const kAllPlansKey = "all";
Load Data for summary
reads in:
- department.yaml
- faculty.csv
- allstudents.json
and filter down to current faculty
const allstudents = bc.readJSON("./jekyll/_data/allstudents.json");
const allfaculty = bc.initializeFromCSVPathWithKey("./jekyll/_data/dept/faculty.csv", null);
const department = bc.initializeFromYAMLPath("./jekyll/_data/dept/department.yaml");
const current_faculty = allfaculty.filter(function(f) {
return (f.past_faculty != "yes");
})
Set Current Academic Year Terms
We are summarizing for current term and academic year, so we need term keys and codes for current term and current academic year.
We will approximate start of terms with some generic dates, which vary a little from specific term starts:
assume fall runs from 8/1 to 12/20
assume spring runs from 12/21 to 4/30
assume summer runs from 5/1 to 7/31
let now = new Date();
let month = now.getMonth() + 1;
let date = now.getDate();
let year = now.getFullYear();
let term = "fall";
let term_num = 9;
if (month == 12 && date >=21) {
term = "spring";
term_num = 1;
}
if (month <= 4) {
term = "spring";
term_num = 1;
}
if (month >= 5 && month <= 7) {
term = "summer";
term_num = 6;
}
const kCurrentTermKey = year +"_" + term;
const kCurrentTermCode = year +"/" + term_num;
const kThisYear = (term == "fall") ? year : (year - 1);
const kLastYear = kThisYear - 1;
Base Summary Structure
Each summary category defines a list of subkeys. Each subkey can be a summary number (eg summary.percentFemale) or a map of subcategories (for example, summary.gender[“F”] and gender[“M”]).
The getSummaryWithAreaAndPlanKeys function sets up the summary data structure, using the map of subkeys, to subdivide into “areas” across department.subdivisions and “plans” across department.plan_codes for degrees. Both summary.areas and summary.plans have “all” keys that accumulate across all students enrolled in that term. Note that plans[“all”] could be larger than areas[“all”], because a student can have multiple contemporaneous plans, but only belong to one area.
function getSummaryWithAreaAndPlanKeys(subKeys) {
let summary = { "areas" : {}, "plans" : {} };
summary.areas[kAllAreasKey]={};
department.subdivisions.forEach(function(area) {
summary.areas[area.abbr] = {};
});
summary.plans[kAllPlansKey] = {};
department.plan_codes.forEach(function(plan) {
summary.plans[plan] = {};
});
for (sk in subKeys) {
// console.log(sk + ": " + subKeys[sk]);
if ("Number" == subKeys[sk]) {
summary.areas[kAllAreasKey][sk] = 0;
department.subdivisions.forEach(function(area) {
summary.areas[area.abbr][sk] = 0;
});
summary.plans[kAllPlansKey][sk] = 0;
department.plan_codes.forEach(function(plan) {
summary.plans[plan][sk] = 0;
});
}
else if (Array.isArray(subKeys[sk])) {
summary.areas[kAllAreasKey][sk] = {}
subKeys[sk].forEach(function(k) {
summary.areas[kAllAreasKey][sk][k] = 0;
});
department.subdivisions.forEach(function(area) {
summary.areas[area.abbr][sk] = {};
subKeys[sk].forEach(function(k) {
summary.areas[area.abbr][sk][k] = 0;
});
});
summary.plans[kAllPlansKey][sk] = {}
subKeys[sk].forEach(function(k) {
summary.plans[kAllPlansKey][sk][k] = 0;
});
department.plan_codes.forEach(function(plan) {
summary.plans[plan][sk] = {};
subKeys[sk].forEach(function(k) {
summary.plans[plan][sk][k] = 0;
});
});
}
}
// console.log(summary);
return summary;
}
Summarizing Categories
The summarize_<category>
functions have the same general structure:
-
allocate the summary data structure with getSummaryWithAreaAndPlanKeys
-
load any required ancillary files
-
enumerate across the given student array
-
accumulate numbers for the student’s area
-
enumerate across the student’s current plans, and accumulate numbers for the student’s plan code
-
At the end, calculate any percentages that require knowing the totals and subtotals.
Class Size Summary
Sum the total number of students who are in their first year, or second year, etc. of study up to 8 years. Any student in the program for more than 8 years is counted in the 8 years bin. Incoming students (students who will be admitted in the next 12 months) are summed in the zero-year bin.
Depends on refactor_plans.js having updated allstudents.json with derived variables
const kClassSizeSubKeys = {
0: "Number",
1: "Number",
2: "Number",
3: "Number",
4: "Number",
5: "Number",
6: "Number",
7: "Number",
8: "Number"
};
const kMaxYear = 8;
function summarize_class_size(current_students,term_key){
// pass in array of students enrolled in a specific term
let class_size_summary = getSummaryWithAreaAndPlanKeys(kClassSizeSubKeys);
let term_months = termKey2Months(term_key) + 1;
// add 1 month to catch those who have entered this term
function getYear(admit_term_code) {
let admit_months = termCode2Months(admit_term_code);
let year = 0;
if ((term_months - admit_months) < 0) { year = 0; } // incoming
else {
year = Math.ceil((term_months - admit_months)/12);
if (year > kMaxYear) { year = kMaxYear; }
}
return year;
}
current_students.forEach(function(s){
let year = getYear(s.admit_term);
class_size_summary.areas[kAllAreasKey][year]++;
class_size_summary.areas[s.area][year]++;
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
let year = getYear(s.academic_plans[p].admit_term);
class_size_summary.plans[kAllPlansKey][year]++;
class_size_summary.plans[p][year]++;
});
});
return class_size_summary;
} // summarize_class_size
Class Enrollment and Registration summary
Here we determine the number of students who are not only enrolled, but also registered in the given term, and total number of hours taken across entire area or plan. Requires
const kEnrollmentSubKeys = {
"enrolled": "Number",
"registered": "Number",
"hours" : "Number"
};
function summarize_enrollment(current_students, term_key){
let class_enrolled_summary = getSummaryWithAreaAndPlanKeys(kEnrollmentSubKeys);
// load registration for given term
let registration = {};
let registration_path = __dirname +
"/jekyll/_data/term_data/"
+ term_key
+ "/registration.json";
if (fs.existsSync(registration_path)){
let registration = bc.readJSON(registration_path);
}
else {
console.log(term_key + " registration missing")
}
current_students.forEach(function(s){
class_enrolled_summary.areas[kAllAreasKey].enrolled++;
class_enrolled_summary.areas[s.area].enrolled++;
if (bc.notUndefinedAndNotNull(registration[s.fsuid])){
class_enrolled_summary.areas[kAllAreasKey].registered++;
class_enrolled_summary.areas[kAllAreasKey].hours += registration[s.fsuid].hours;
class_enrolled_summary.areas[s.area].registered++;
class_enrolled_summary.areas[s.area].hours += registration[s.fsuid].hours;
}
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
class_enrolled_summary.plans[kAllPlansKey].enrolled++;
class_enrolled_summary.plans[p].enrolled++;
if (bc.notUndefinedAndNotNull(registration[s.fsuid])){
class_enrolled_summary.plans[kAllPlansKey].registered++;
class_enrolled_summary.plans[kAllPlansKey].hours += registration[s.fsuid].hours;
class_enrolled_summary.plans[p].registered++;
class_enrolled_summary.plans[p].hours += registration[s.fsuid].hours;
}
});
});
return class_enrolled_summary;
} // summarize_enrollment
Demographics summary
Summarize the citizenship broadly divided into US & RA, Intl, and LAC students.
Depends on refactor_plans.js having updated allstudents.json with derived variables.
const kCitizenSubKeys = {
"US & RA" : "Number",
"LAC" : "Number",
"Intl" : "Number",
"total" : "Number",
"percentIntlNotLAC" : "Number",
"percentIntl" : "Number"
};
function summarize_citizenship(current_students, term_key){
// pass in array of students enrolled in a specific term
let citizen_summary = getSummaryWithAreaAndPlanKeys(kCitizenSubKeys);
current_students.forEach(function(s){
citizen_summary.areas[kAllAreasKey]["total"]++;
citizen_summary.areas[s.area]["total"]++;
if (s.residency == "usa") {
citizen_summary.areas[kAllAreasKey]["US & RA"]++;
citizen_summary.areas[s.area]["US & RA"]++;
}
else {
citizen_summary.areas[kAllAreasKey]["Intl"]++;
citizen_summary.areas[s.area]["Intl"]++;
}
if (s.lac) {
citizen_summary.areas[kAllAreasKey]["LAC"]++;
citizen_summary.areas[s.area]["LAC"]++;
}
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
citizen_summary.plans[kAllPlansKey]["total"]++;
citizen_summary.plans[p]["total"]++;
if (s.residency == "usa") {
citizen_summary.plans[kAllPlansKey]["US & RA"]++;
citizen_summary.plans[p]["US & RA"]++;
}
else {
citizen_summary.plans[kAllPlansKey]["Intl"]++;
citizen_summary.plans[p]["Intl"]++;
}
if (s.lac) {
citizen_summary.plans[kAllPlansKey]["LAC"]++;
citizen_summary.plans[p]["LAC"]++;
}
});
});
citizen_summary.areas[kAllAreasKey]["percentIntlNotLAC"] = 100
* (citizen_summary.areas[kAllAreasKey]["Intl"] - citizen_summary.areas[kAllAreasKey]["LAC"] )
/ citizen_summary.areas[kAllAreasKey]["total"] ;
citizen_summary.areas[kAllAreasKey]["percentIntl"] = 100
* citizen_summary.areas[kAllAreasKey]["Intl"]
/ citizen_summary.areas[kAllAreasKey]["total"] ;
department.subdivisions.forEach(function(area) {
citizen_summary.areas[area.abbr]["percentIntlNotLAC"] = 100
* (citizen_summary.areas[area.abbr]["Intl"] - citizen_summary.areas[area.abbr]["LAC"])
/ citizen_summary.areas[area.abbr]["total"] ;
citizen_summary.areas[area.abbr]["percentIntl"] = 100
* citizen_summary.areas[area.abbr]["Intl"]
/ citizen_summary.areas[area.abbr]["total"] ;
});
citizen_summary.plans[kAllAreasKey]["percentIntlNotLAC"] = 100
* (citizen_summary.plans[kAllAreasKey]["Intl"] - citizen_summary.plans[kAllAreasKey]["LAC"] )
/ citizen_summary.plans[kAllAreasKey]["total"] ;
citizen_summary.plans[kAllAreasKey]["percentIntl"] = 100
* citizen_summary.plans[kAllAreasKey]["Intl"]
/ citizen_summary.plans[kAllAreasKey]["total"] ;
department.plan_codes.forEach(function(plan) {
citizen_summary.plans[plan]["percentIntlNotLAC"] = 100
* (citizen_summary.plans[plan]["Intl"] - citizen_summary.plans[plan]["LAC"])
/ citizen_summary.plans[plan]["total"] ;
citizen_summary.plans[plan]["percentIntl"] = 100
* citizen_summary.plans[plan]["Intl"]
/ citizen_summary.plans[plan]["total"] ;
});
return citizen_summary;
} // citizen_summary
Gender summary
Summarize male, female, other (O), or unknown (?).
const kGenderOptions = [
"F",
"M",
"O",
"?"
];
const kGenderSubKeys = {
"gender" : kGenderOptions ,
"total" : "Number",
"percentFemale" : "Number"
};
function summarize_gender(current_students,term_key){
// pass in array of students enrolled in a specific term
let gender_summary = getSummaryWithAreaAndPlanKeys(kGenderSubKeys);
current_students.forEach(function(s){
gender_summary.areas[kAllAreasKey].total++;
gender_summary.areas[kAllAreasKey].gender[s.sex]++;
gender_summary.areas[s.area].gender[s.sex]++;
gender_summary.areas[s.area].total++;
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
gender_summary.plans[kAllPlansKey].total++;
gender_summary.plans[kAllPlansKey].gender[s.sex]++;
gender_summary.plans[p].gender[s.sex]++;
gender_summary.plans[p].total++;
});
});
gender_summary.areas[kAllAreasKey].percentFemale = 100
* gender_summary.areas[kAllAreasKey].gender["F"]
/ gender_summary.areas[kAllAreasKey].total;
department.subdivisions.forEach(function(area) {
gender_summary.areas[area.abbr].percentFemale = 100
* gender_summary.areas[area.abbr].gender["F"]
/ gender_summary.areas[area.abbr].total;
});
gender_summary.plans[kAllPlansKey].percentFemale = 100
* gender_summary.plans[kAllPlansKey].gender["F"]
/ gender_summary.plans[kAllPlansKey].total;
department.plan_codes.forEach(function(plan) {
gender_summary.plans[plan].percentFemale = 100
* gender_summary.plans[plan].gender["F"]
/ gender_summary.plans[plan].total;
});
return gender_summary;
} // gender_summary
Ethnicity summary
Accumulate totals of FSU-defined ethnicity, which are self-declared by the student.
Relies on refactor_plans.js to have determine if underrepresented minority, defines as residency is “usa” and ethnicity = AMIND, PACIF,HISPA, BLACK, or MULTIPLE.
const kEthnicityOptions = [
"WHITE",
"ASIAN",
"NOTSPEC",
"PACIF",
"AMIND",
"HISPA",
"BLACK",
"MULTIPLE",
];
const kEthnicitySubKeys = {
"ethnicity" : kEthnicityOptions,
"total" : "Number",
"urMinority" : "Number",
"percentMinority" : "Number"
};
function summarize_ethnicity(current_students, term_key){
// pass in array of students enrolled in a specific term
let ethnicity_summary = getSummaryWithAreaAndPlanKeys(kEthnicitySubKeys);
current_students.forEach(function(s){
ethnicity_summary.areas[kAllAreasKey].total++;
ethnicity_summary.areas[s.area].total++;
ethnicity_summary.areas[kAllAreasKey].ethnicity[s.ethnicity]++;
ethnicity_summary.areas[s.area].ethnicity[s.ethnicity]++;
if (s.minority) {
ethnicity_summary.areas[kAllAreasKey].urMinority++;
ethnicity_summary.areas[s.area].urMinority++;
}
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
ethnicity_summary.plans[kAllPlansKey].total++;
ethnicity_summary.plans[p].total++;
ethnicity_summary.plans[kAllPlansKey].ethnicity[s.ethnicity]++;
ethnicity_summary.plans[p].ethnicity[s.ethnicity]++;
if (s.minority) {
ethnicity_summary.plans[kAllPlansKey].urMinority++;
ethnicity_summary.plans[p].urMinority++;
}
});
});
ethnicity_summary.areas[kAllAreasKey].percentMinority = 100
* ethnicity_summary.areas[kAllAreasKey].urMinority
/ ethnicity_summary.areas[kAllAreasKey].total;
department.subdivisions.forEach(function(area) {
ethnicity_summary.areas[area.abbr].percentMinority = 100
* ethnicity_summary.areas[area.abbr].urMinority
/ ethnicity_summary.areas[area.abbr].total;
});
ethnicity_summary.plans[kAllPlansKey].percentMinority = 100
* ethnicity_summary.plans[kAllPlansKey].urMinority
/ ethnicity_summary.plans[kAllPlansKey].total;
department.plan_codes.forEach(function(plan) {
ethnicity_summary.plans[plan].percentMinority = 100
* ethnicity_summary.plans[plan].urMinority
/ ethnicity_summary.plans[plan].total;
});
return ethnicity_summary;
} // ethnicity_summary
Graduation Summary
Look at plans of every student.
- if a student started a plan, then they were admitted
- if a student left a plan, they either graduated or left (depending on plan.outcome)
- if a student neither left not started a plan, then they are continuing
const kGraduationSubKeys = {
"graduated": "Number",
"left": "Number",
"continued": "Number",
"admitted" : "Number"
};
function summarize_graduation(current_students, term_key){
let graduation_summary = getSummaryWithAreaAndPlanKeys(kGraduationSubKeys);
// load registration for given term
let registration = {};
let registration_path = __dirname
+ "/jekyll/_data/term_data/"
+ term_key
+ "/registration.json"
if (fs.existsSync(registration_path)) {
registration = bc.readJSON(registration_path);
}
else {
console.log(term_key + " registration missing")
}
let term_months = termKey2Months(term_key);
current_students.forEach(function(s){
let admit_flag = false;
let left_flag = false;
let outcome = "left";
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
let plan_admit_flag = false;
let plan_left_flag = false;
plan = s.academic_plans[p];
let admit_months = termCode2Months(plan.admit_term);
if (admit_months == term_months) {
admit_flag = true;
plan_admit_flag = true;
graduation_summary.plans[kAllPlansKey]["admitted"]++;
graduation_summary.plans[p]["admitted"]++;
}
if (bc.notUndefinedAndNotNull(plan.last_term)) {
let plan_last_months = termCode2Months(plan.last_term);
if (plan_last_months == term_months) {
left_flag = true;
plan_left_flag = true;
if (plan.outcome == "graduated") {
outcome = "graduated";
graduation_summary.plans[kAllPlansKey]["graduated"]++;
graduation_summary.plans[p]["graduated"]++;
}
else {
graduation_summary.plans[kAllPlansKey]["left"]++;
graduation_summary.plans[p]["left"]++;
}
}
}
if (!plan_admit_flag && !plan_left_flag) {
graduation_summary.plans[kAllAreasKey]["continued"]++;
graduation_summary.plans[p]["continued"]++;
}
}); // next plan
if (admit_flag) {
graduation_summary.areas[kAllAreasKey]["admitted"]++;
graduation_summary.areas[s.area]["admitted"]++;
}
if (left_flag){
if (outcome == "graduated") {
graduation_summary.areas[kAllAreasKey]["graduated"]++;
graduation_summary.areas[s.area]["graduated"]++;
}
else {
graduation_summary.areas[kAllAreasKey]["left"]++;
graduation_summary.areas[s.area]["left"]++;
}
}
if (!admit_flag && !left_flag) {
graduation_summary.areas[kAllAreasKey]["continued"]++;
graduation_summary.areas[s.area]["continued"]++;
}
});
return graduation_summary;
}
Support Summary
Run through the _data/term_data/<term_key>/assignments.csv
file, and summarize:
- number of TA, RA, and NFR
- of the RAs, how many are supported by fellowship
We check length of fields, because blank fields may be zero-length strings in the csv file.
const kSupportSubKeys = {
"TA" : "Number",
"RA" : "Number",
"NFR" : "Number",
"fellowship" : "Number"
};
function summarize_support(current_students, term_key){
let support_summary = getSummaryWithAreaAndPlanKeys(kSupportSubKeys);
// load assignments for given term
let assignments = {};
let assignments_path = __dirname +
"/jekyll/_data/term_data/"
+ term_key
+ "/assignments.csv";
if (fs.existsSync(assignments_path)) {
assignments = bc.initializeFromCSVPathWithKey(assignments_path, 'fsuid');
}
else {
console.log(term_key + " assignments missing")
}
current_students.forEach(function(s){
if (typeof assignments[s.fsuid] != "undefined") {
let appt = assignments[s.fsuid];
let appointment_type = "NFR";
let has_fellowship = false;
if (appt.appointment.length > 0){
appointment_type = appt.appointment;
if ("RA" == appt.appointment && appt.ra_type == "fellowship"){
has_fellowship = true;
}
support_summary.areas[kAllAreasKey][appointment_type] ++;
support_summary.areas[appt.area][appointment_type]++;
if (has_fellowship){
support_summary.areas[kAllAreasKey]["fellowship"]++;
support_summary.areas[appt.area]["fellowship"]++;
}
let plans = currentPlansInTerm(s,term_key);
plans.forEach(function(p) {
support_summary.plans[kAllPlansKey][appointment_type] ++;
support_summary.plans[p][appointment_type]++;
if (has_fellowship){
support_summary.plans[kAllPlansKey]["fellowship"]++;
support_summary.plans[p]["fellowship"]++;
}
});
}
}
});
return support_summary;
}
Term Utilities
const term_name = {
"1" : "spring",
"6" : "summer",
"9" : "fall"
};
function termCode2term(code) {
let parts = code.split("/");
return { "year": parts[0], "term" : parts[1] };
}
//--------------------------------------------------------------
function incrementTerm(term) {
if (term.term == 1) {
term.term = 6;
}
else if (term.term == 6) {
term.term = 9;
}
else if (term.term == 9) {
term.term = 1;
term.year++;
}
}
//--------------------------------------------------------------
function lessOrSameTerm(term1,term2) {
// term1 falls earlier than term2, or is same term
return ((term1.year < term2.year) || (term1.year == term2.year && term1.term <= term2.term));
}
//--------------------------------------------------------------
function termCode2Months(term_code) {
let parts = term_code.split("/");
return (parseInt(parts[0],10) * 12 + parseInt(parts[1],10));
}
//--------------------------------------------------------------
function termKey2Months(term_key) {
let parts = term_key.split("_");
let months = parseInt(parts[0],10) * 12;
if ("spring" == parts[1]){
months+=1;
}
if ("summer" == parts[1]){
months+=6;
}
if ("fall" == parts[1]){
months+=9;
}
return months;
}
//--------------------------------------------------------------
function enrolledInTerm(s,term_key) {
let admit_months = termCode2Months(s.admit_term);
let last_months = 999999;
if (bc.notUndefinedAndNotNull(s.last_term)) {
last_months = termCode2Months(s.last_term);
}
let term_months = termKey2Months(term_key);
return (admit_months <= term_months && term_months <= last_months);
}
//--------------------------------------------------------------
function currentPlansInTerm(s,term_key) {
let term_months = termKey2Months(term_key);
let plans = [];
for (var p in s.academic_plans) {
plan = s.academic_plans[p];
let admit_months = termCode2Months(plan.admit_term);
let plan_last_months = 999999;
if (bc.notUndefinedAndNotNull(plan.last_term)) {
plan_last_months = termCode2Months(plan.last_term);
}
if (admit_months <= term_months && term_months<= plan_last_months) {
plans.push(p);
}
}
return plans;
}
//--------------------------------------------------------------
function enrolledInTermOrFuture(s,term_key) {
// if enrolled now, or will be enrolled in next two terms (less than 12 months from this term)
let admit_months = termCode2Months(s.admit_term);
let last_months = 999999;
if (bc.notUndefinedAndNotNull(s.last_term)) {
last_months = termCode2Months(s.last_term);
}
let term_months = termKey2Months(term_key);
return (admit_months <= term_months && term_months <= last_months || (admit_months - term_months < 12));
}
Terms in Database
Find the earliest term in the database from the first admissions term.
let current_year = (new Date()).getFullYear();
let current_month = (new Date()).getMonth() + 1;
let current_semester = (current_month < 6) ? 1 : ((current_month < 9) ? 6 : 9);
let current_term = { "term": current_semester, "year" : current_year };
let this_current_term = { "term": current_semester, "year" : current_year };
let start_term = { "term": current_semester, "year" : current_year };
allstudents.reduce(function(acc,s) {
let term = termCode2term(s.admit_term);
if (term.year < acc.year) {
acc.year = term.year; acc.term = term.term;
}
else if (term.year == acc.year && term.term < acc.term) {
acc.term = term.term;
}
return acc;
},start_term);
Compile Term summaries for all terms
Compile Term summaries for all terms in the database, and save them to term_data/term_summary.
let term_summaries = {};
for (term = start_term; lessOrSameTerm(term,this_current_term); incrementTerm(term)) {
let term_key = term.year + "_" + term_name[term.term];
let current_students = allstudents.filter(function(s) {
return enrolledInTerm(s,term_key);
});
let current_and_incoming_students = allstudents.filter(function(s) {
return enrolledInTermOrFuture(s,term_key);
});
term_summaries[term_key] = {};
term_summaries[term_key].term = term_key;
term_summaries[term_key].support = summarize_support(current_students,term_key);
term_summaries[term_key].graduation = summarize_graduation(current_students,term_key);
term_summaries[term_key].ethnicity = summarize_ethnicity(current_students,term_key);
term_summaries[term_key].gender = summarize_gender(current_students,term_key);
term_summaries[term_key].citizenship = summarize_citizenship(current_students,term_key);
term_summaries[term_key].enrollment = summarize_enrollment(current_students,term_key);
term_summaries[term_key].class_size = summarize_class_size(current_and_incoming_students,term_key);
fs.writeFileSync(__dirname+"/jekyll/_data/term_data/" + term_key + "/term_summary.json", JSON.stringify(term_summaries[term_key], null,5));
}
Compile Academic Year Summary
Graduate Faculty Status summary
Set up a map of all faculty and areas, with counts of the 6 possible Graduate Status options. Just filter the faculty by the given area and GFS status, and return the size of the filtered array.
const kGFSOptions = [
"none",
"GFS",
"coDDS",
"coMDS",
"RGFS",
"GTS"
];
function summarize_GFS() {
let GFS_summary ={};
GFS_summary[kAllAreasKey] = {};
kGFSOptions.forEach(function(gfs_status){
GFS_summary[kAllAreasKey][gfs_status] = current_faculty.filter(function(f){
return(f.graduate_status == gfs_status);
}).length;
});
department.subdivisions.forEach(function(area) {
GFS_summary[area.abbr] = {};
kGFSOptions.forEach(function(gfs_status){
GFS_summary[area.abbr][gfs_status] = current_faculty.filter(function(f){
return(f.graduate_status == gfs_status && f.area == area.abbr);
}).length;
});
});
return GFS_summary;
} // summarize_GFS
Compile Academic Year Term Summaries
Compile summaries for terms of this academic year and last academic year, and save to _data/overview.json.
let summary =
{ "last_year" : { "label": kLastYear + "-" + (kLastYear+1),
"fall" : { "key": kLastYear + "_fall" },
"spring" : { "key": (kLastYear + 1) + "_spring" },
"summer" : { "key": (kLastYear + 1) + "_summer" }
},
"this_year" : { "label": kThisYear + "-" + (kThisYear+1),
"fall" : { "key": kThisYear + "_fall" },
"spring" : { "key": (kThisYear + 1) + "_spring" },
"summer" : { "key": (kThisYear + 1) + "_summer" }
},
"terms": {}
};
const kTermKeys = [
kLastYear + "_fall",
(kLastYear + 1) + "_spring" ,
(kLastYear + 1) + "_summer" ,
kThisYear + "_fall" ,
(kThisYear + 1) + "_spring",
(kThisYear + 1)+ "_summer"
];
kTermKeys.forEach(function(term_key) {
summary.terms[term_key] = term_summaries[term_key];
});
summary.gfs_faculty = summarize_GFS();
fs.writeFileSync(__dirname+"/jekyll/_data/overview.json", JSON.stringify(summary, null,5));