Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to the 120 credits on repeated courses #280

Merged
merged 3 commits into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Array [
"College-AG-Physical and Life Sciences",
"College-AG-Quantitative Literacy",
"College-AG-Social Sciences and Humanities",
"College-AG-Total Academic Credits",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snapshot is updated as expected, since there are no longer part of the requirement json any more. Since it's before launch, no migration is necessary. For more background, see #222

"College-AG-Written and Oral Expression",
"College-AG-Written Expression",
"College-AS-(PBS-AS) or (MQR-AS)",
Expand All @@ -22,8 +21,6 @@ Array [
"College-AS-Liberal Arts",
"College-AS-Mathematics & Quantitative Reasoning (MQR-AS)",
"College-AS-Physical & Biological Sceiences (PBS-AS)",
"College-AS-Total Academic Credits",
"College-BU-Total Academic Credits",
"College-EN-Advisor-Approved Electives",
"College-EN-Chemistry",
"College-EN-Computing",
Expand All @@ -38,12 +35,10 @@ Array [
"College-HE-9 Credits In HE Outside Major",
"College-HE-Human Ecology Credits",
"College-HE-Technical Communication",
"College-HE-Total Academic Credits",
"College-IL-Core Requirements",
"College-IL-Distribution Requirements",
"College-IL-First-Year Writing Seminars",
"College-IL-ILR Advance Writing",
"College-IL-Total Academic Credits",
"College-UNI-Physical Education",
"College-UNI-Swim Test",
"Major-AEM-AEM Concentration Requirement",
Expand Down
21 changes: 1 addition & 20 deletions src/requirements/data/checkers-common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Course } from '../types';
import { CREDITS_COURSE_ID, FWS_COURSE_ID } from './constants';
import { FWS_COURSE_ID } from './constants';

/**
* @param courseName name of the course (as a code)
Expand Down Expand Up @@ -31,14 +31,6 @@ export const courseMatchesCode = (course: Course, code: string): boolean =>
export const courseMatchesCodeOptions = (course: Course, codeOptions: readonly string[]): boolean =>
codeOptions.some(code => ifCodeMatch(`${course.subject} ${course.catalogNbr}`, code));

/**
* @param course course object with useful information retrived from Cornell courses API.
* @returns true if the course is AP/IB equivalent course or credit
*/
export const courseIsAPIB = (course: Course): boolean =>
[CREDITS_COURSE_ID, FWS_COURSE_ID].includes(course.crseId) ||
['AP', 'IB', 'CREDITS'].includes(course.subject);

/**
* Almost colleges have FWS requirements. Instead of writing them from scratch each time, call this
* function.
Expand All @@ -51,17 +43,6 @@ export const courseIsFWS = (course: Course): boolean =>
course.titleLong.includes('FWS:') ||
(course.catalogSatisfiesReq?.includes('First-Year Writing Seminar') ?? false);

/**
* Used for total academic credit requirements for all colleges except EN and AR
* @param course course object with useful information retrived from Cornell courses API.
* @returns true if the course is not PE or 10** level
*/
export const courseIsAllEligible = (course: Course): boolean =>
course.crseId === CREDITS_COURSE_ID ||
(!courseIsAPIB(course) &&
!ifCodeMatch(course.subject, 'PE') &&
!ifCodeMatch(course.catalogNbr, '10**'));

/**
* This function returns a checker that checks whether a course satisfy a single requirement by
* checking whether the course code appears in the includes array.
Expand Down
14 changes: 0 additions & 14 deletions src/requirements/data/colleges/ag.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import { Course, CollegeOrMajorRequirement } from '../../types';
import { includesWithSingleRequirement } from '../checkers-common';

const totalAcademicCreditsRequirement: CollegeOrMajorRequirement = {
name: 'Total Academic Credits',
description:
'120 academic credits are required for graduation. ' +
'A minimum of 100 credits must be in courses for which a letter grade was recieved. ' +
'PE courses do not count.',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11561',
checker: (course: Course): boolean => !['PE'].includes(course.subject),
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
};

const calsCreditsRequirement: CollegeOrMajorRequirement = {
name: 'CALS Credits',
description:
Expand Down Expand Up @@ -220,7 +207,6 @@ const calsWrittenExpressionRequirement: CollegeOrMajorRequirement = {
};

const calsRequirements: readonly CollegeOrMajorRequirement[] = [
totalAcademicCreditsRequirement,
calsCreditsRequirement,
calsIntroductoryLifeSciencesOrBiologyRequirement,
calsPhysicalAndLifeSciencesRequirement,
Expand Down
17 changes: 1 addition & 16 deletions src/requirements/data/colleges/as.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
import { Course, CollegeOrMajorRequirement } from '../../types';
import {
courseIsFWS,
includesWithSingleRequirement,
courseIsAllEligible,
} from '../checkers-common';
import { courseIsFWS, includesWithSingleRequirement } from '../checkers-common';

const casRequirements: readonly CollegeOrMajorRequirement[] = [
{
name: 'Total Academic Credits',
description:
'120 academic credits are required' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11570#credit-req',
checker: courseIsAllEligible,
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
},
{
name: 'A&S Credits',
description:
Expand Down
15 changes: 1 addition & 14 deletions src/requirements/data/colleges/bu.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import { CollegeOrMajorRequirement } from '../../types';
import { courseIsAllEligible } from '../checkers-common';

const businessRequirements: readonly CollegeOrMajorRequirement[] = [
{
name: 'Total Academic Credits',
description:
'120 academic credits are required' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11715',
checker: courseIsAllEligible,
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
},
];
const businessRequirements: readonly CollegeOrMajorRequirement[] = [];

export default businessRequirements;
13 changes: 0 additions & 13 deletions src/requirements/data/colleges/he.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import { Course, CollegeOrMajorRequirement } from '../../types';
import { courseIsAllEligible } from '../checkers-common';

const humanEcologyRequirements: readonly CollegeOrMajorRequirement[] = [
{
name: 'Total Academic Credits',
description:
'120 academic credits are required' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits',
source:
'http://courses.cornell.edu/content.php?catoid=41&navoid=11600#Cornell_Credit_Requirements',
checker: courseIsAllEligible,
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
},
{
name: 'Human Ecology Credits',
description:
Expand Down
12 changes: 0 additions & 12 deletions src/requirements/data/colleges/il.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@ import {
courseIsFWS,
includesWithSingleRequirement,
includesWithSubRequirements,
courseIsAllEligible,
} from '../checkers-common';

const ilrRequirements: readonly CollegeOrMajorRequirement[] = [
{
name: 'Total Academic Credits',
description:
'120 academic credits are required' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11587',
checker: courseIsAllEligible,
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
},
{
name: 'Core Requirements',
description:
Expand Down
2 changes: 1 addition & 1 deletion src/requirements/decorated-requirements.json

Large diffs are not rendered by default.

128 changes: 123 additions & 5 deletions src/requirements/reqs-functions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import store from '../store';
import { CREDITS_COURSE_ID, FWS_COURSE_ID } from './data/constants';
import buildRequirementFulfillmentGraphFromUserData from './requirement-graph-builder-from-user-data';
import {
CourseTaken,
Expand All @@ -8,6 +9,121 @@ import {
GroupedRequirementFulfillmentReport,
} from './types';

type FulfillmentStatistics = {
readonly id: string;
readonly requirement: RequirementWithIDSourceType;
readonly courses: readonly (readonly CourseTaken[])[];
} & RequirementFulfillmentStatistics;

/**
* @param course course object with useful information retrived from Cornell courses API.
* @returns true if the course is AP/IB equivalent course or credit
*/
const courseIsAPIB = (course: CourseTaken): boolean =>
[CREDITS_COURSE_ID, FWS_COURSE_ID].includes(course.courseId) ||
['AP', 'IB', 'CREDITS'].includes(course.subject);

/**
* Used for total academic credit requirements for all colleges except EN and AR
* @param course course object with useful information retrived from Cornell courses API.
* @returns true if the course is not PE or 10** level
*/
const courseIsAllEligible = (course: CourseTaken): boolean =>
course.courseId === CREDITS_COURSE_ID ||
(!courseIsAPIB(course) && course.subject !== 'PE' && !course.number.startsWith('10'));

const getTotalCreditsFulfillmentStatistics = (
college: string,
courses: readonly CourseTaken[]
): FulfillmentStatistics | null => {
const requirementCommon = {
sourceType: 'College',
sourceSpecificName: college,
name: 'Total Academic Credits',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the name field be how the frontend would special case the 120 total academic credits?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's handled by completely remove them from the requirement json, and inject it as the first college requirement in the requirement menu.

courses: [],
subRequirementProgress: 'any-can-count',
fulfilledBy: 'credits',
minCount: 120,
} as const;
let requirement: RequirementWithIDSourceType;
switch (college) {
case 'AG':
requirement = {
...requirementCommon,
id: 'College-AG-total-credits',
description:
'120 academic credits are required for graduation. ' +
'A minimum of 100 credits must be in courses for which a letter grade was recieved. ' +
'PE courses do not count.',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11561',
};
break;
case 'AS':
requirement = {
...requirementCommon,
id: 'College-AS-total-credits',
description:
'120 academic credits are required. ' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits.',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11570#credit-req',
};
break;
case 'HE':
requirement = {
...requirementCommon,
id: 'College-HE-total-credits',
description:
'120 academic credits are required. ' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits.',
source:
'http://courses.cornell.edu/content.php?catoid=41&navoid=11600#Cornell_Credit_Requirements',
};
break;
case 'IL':
requirement = {
...requirementCommon,
id: 'College-IL-total-credits',
description:
'120 academic credits are required. ' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits.',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11587',
};
break;
case 'BU':
requirement = {
...requirementCommon,
id: 'College-BU-total-credits',
description:
'120 academic credits are required. ' +
'PE courses and courses numbered 1000-1099 do not count towards the 120 credits.',
source: 'http://courses.cornell.edu/content.php?catoid=41&navoid=11715',
};
break;
default:
return null;
}

let minCountFulfilled = 0;
if (college === 'AG') {
courses.forEach(course => {
if (course.subject !== 'PE') minCountFulfilled += course.credits;
});
} else {
courses.forEach(course => {
if (courseIsAllEligible(course)) minCountFulfilled += course.credits;
});
}

return {
id: requirement.id,
requirement,
courses: [],
fulfilledBy: 'credits',
minCountFulfilled,
minCountRequired: 120,
};
};

function computeFulfillmentStatisticsFromCourses(
coursesThatFulfilledRequirement: readonly (readonly CourseTaken[])[],
counting: 'courses' | 'credits',
Expand Down Expand Up @@ -163,12 +279,14 @@ export default function computeRequirements(
minors
);

type FulfillmentStatistics = {
readonly id: string;
readonly requirement: RequirementWithIDSourceType;
readonly courses: readonly (readonly CourseTaken[])[];
} & RequirementFulfillmentStatistics;
const collegeFulfillmentStatistics: FulfillmentStatistics[] = [];
const totalCreditsFulfillmentStatistics = getTotalCreditsFulfillmentStatistics(
college,
coursesTaken
);
if (totalCreditsFulfillmentStatistics != null) {
collegeFulfillmentStatistics.push(totalCreditsFulfillmentStatistics);
}
const majorFulfillmentStatisticsMap = new Map<string, FulfillmentStatistics[]>();
const minorFulfillmentStatisticsMap = new Map<string, FulfillmentStatistics[]>();
requirementFulfillmentGraph.getAllRequirements().forEach(requirement => {
Expand Down