diff --git a/.gitignore b/.gitignore index c7724d5..df62900 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.env *_site/ *.log +package-lock.json +node_modules \ No newline at end of file diff --git a/README.md b/README.md index 5c5e9c6..afd38e3 100644 --- a/README.md +++ b/README.md @@ -29,113 +29,137 @@ for the benefit of the entire student community. ## Programmes Click to expand the list of courses for each programme. +
👇 N1SOF - Software Engineering and Management Bachelor's Programme -### Term 1: +### Term 1 -- [DIT043 - Object-Oriented Programming](/exams/DIT043) -- [DIT023 - Mathematical Foundations for Software Engineering](/exams/DIT023) -- [DIT046 - Requirements and User Experience](/exams/DIT046) +- [DIT043 - Object-Oriented Programming](./exams/DIT043) 5 exams. +- [DIT023 - Mathematical Foundations for Software Engineering](./exams/DIT023) 9 exams. +- [DIT046 - Requirements and User Experience](./exams/DIT046) 5 exams. *** -### Term 2: +### Term 2 -- [DIT033 - Data Management](/exams/DIT033) -- [DIT182 - Data Structures and Algorithms](/exams/DIT182) -- [DIT185 - Software Analysis and Design](/exams/DIT185) +- [DIT033 - Data Management](./exams/DIT033) 9 exams. +- [DIT182 - Data Structures and Algorithms](./exams/DIT182) 0 exams. +- [DIT185 - Software Analysis and Design](./exams/DIT185) 3 exams. *** -### Term 3: +### Term 3 -- [DIT345 - Fundamentals of Software Architecture](/exams/DIT345) -- [DIT342 - Web Development](/exams/DIT342) -- [DIT348 - Software Development Methodologies](/exams/DIT348) +- [DIT345 - Fundamentals of Software Architecture](./exams/DIT345) 5 exams. +- [DIT342 - Web Development](./exams/DIT342) 10 exams. +- [DIT348 - Software Development Methodologies](./exams/DIT348) 0 exams. *** -### Term 4: +### Term 4 -- [DIT633 - Development of Embedded and Real-Time Systems](/exams/DIT633) -- [DIT636 - Software Quality and Testing](/exams/DIT636) +- [DIT633 - Development of Embedded and Real-Time Systems](./exams/DIT633) 4 exams. +- [DIT636 - Software Quality and Testing](./exams/DIT636) 5 exams. *** -### Term 5: +### Term 5 -- [DIT822 - Software engineering for AI systems](/exams/DIT822) +- [DIT822 - Software engineering for AI systems](./exams/DIT822) 5 exams. *** -### Term 6: +### Term 6 + +- [DIT822 - Software engineering for AI systems](./exams/DIT822) 5 exams. -- [DIT822 - Software engineering for AI systems](/exams/DIT822) +***
👇 N2SOF - Software Engineering and Management Master's Programme -- [DIT431 - High Performance Parallel Programming](/exams/DIT431) +### + +- [DIT431 - High Performance Parallel Programming](./exams/DIT431) 1 exams. + +***
👇 N1COS - Datavetenskapligt program -- [DIT093 - Algorithms](/exams/DIT093) -- [DIT185 - Software Analysis and Design](/exams/DIT185) -- [DIT342 - Web Development](/exams/DIT342) -- [DIT348 - Software Development Methodologies](/exams/DIT348) -- [DIT401 - Operating Systems](/exams/DIT401) +### + +- [DIT342 - Web Development](./exams/DIT342) 10 exams. +- [DIT348 - Software Development Methodologies](./exams/DIT348) 0 exams. +- [DIT185 - Software Analysis and Design](./exams/DIT185) 3 exams. +- [DIT401 - Operating Systems](./exams/DIT401) 1 exams. +- [DIT093 - Algorithms](./exams/DIT093) 1 exams. + +***
👇 N2ADS - Applied Data Science Master's Programme -- [DIT033 - Data Management](/exams/DIT033) -- [DIT046 - Requirements and User Experience](/exams/DIT046) -- [DIT093 - Algorithms](/exams/DIT093) -- [DIT182 - Data Structures and Algorithms](/exams/DIT182) -- [DIT401 - Operating Systems](/exams/DIT401) -- [DIT431 - High Performance Parallel Programming](/exams/DIT431) -- [DIT822 - Software engineering for AI systems](/exams/DIT822) +### + +- [DIT822 - Software engineering for AI systems](./exams/DIT822) 5 exams. +- [DIT046 - Requirements and User Experience](./exams/DIT046) 5 exams. +- [DIT401 - Operating Systems](./exams/DIT401) 1 exams. +- [DIT431 - High Performance Parallel Programming](./exams/DIT431) 1 exams. +- [DIT182 - Data Structures and Algorithms](./exams/DIT182) 0 exams. +- [DIT033 - Data Management](./exams/DIT033) 9 exams. +- [DIT093 - Algorithms](./exams/DIT093) 1 exams. + +***
👇 N2COS - Computer Science Master's Programme -- [DIT093 - Algorithms](/exams/DIT093) -- [DIT401 - Operating Systems](/exams/DIT401) -- [DIT431 - High Performance Parallel Programming](/exams/DIT431) +### + +- [DIT401 - Operating Systems](./exams/DIT401) 1 exams. +- [DIT431 - High Performance Parallel Programming](./exams/DIT431) 1 exams. +- [DIT093 - Algorithms](./exams/DIT093) 1 exams. + +***
+
👇 NONE - Courses that have yet to be assigned to any programmes -- [DAT050 - Objektorienterad programmering](/exams/DAT050) -- [DAT060 - Logic in Computer Science](/exams/DAT060) -- [DAT105 - Computer Architecture](/exams/DAT105) -- [DAT246 - Empirical Software Engineering](/exams/DAT246) -- [DAT400 - High Performance Parallel Programming](/exams/DAT400) -- [DAT555 - Programmeringsteknik: Python](/exams/DAT555) -- [DIT440 - Introduction to Functional Programming](/exams/DIT440) -- [DIT670 - Computer Networks](/exams/DIT670) -- [DIT792 - Grundläggande Datorteknik](/exams/DIT792) -- [DIT852 - Introduction to Data Science](/exams/DIT852) -- [DIT962 - Datastrukturer](/exams/DIT962) -- [DIT980 - Diskret matematik för Datavetare](/exams/DIT980) -- [DIT984 - Diskret matematik för Datavetare](/exams/DIT984) -- [EDA093 - Operating Systems](/exams/EDA093) -- [EDA387 - Computer Networks](/exams/EDA387) -- [EDA452 - Grundläggande daterteknik](/exams/EDA452) -- [TDA384 - Principles of concurrent programming](/exams/TDA384) -- [TDA548 - Grundläggande programvarutveckling](/exams/TDA548) -- [TDA555 - Introduction to functional programming](/exams/TDA555) -- [TIN093 - Algorithms](/exams/TIN093) +### + +- [DAT050 - Objektorientered programmering](./exams/DAT050) 2 exams. +- [DAT060 - Logic in Computer Science](./exams/DAT060) 2 exams. +- [DAT105 - Computer Architecture](./exams/DAT105) 2 exams. +- [DAT246 - Empirical Software Engineering](./exams/DAT246) 2 exams. +- [DAT400 - High Performance Parallel Programming](./exams/DAT400) 1 exams. +- [DAT555 - Programmeringsteknik](./exams/DAT555) 2 exams. +- [DIT440 - Introduction to Functional Programming](./exams/DIT440) 2 exams. +- [DIT670 - Computer Networks](./exams/DIT670) 1 exams. +- [DIT792 - Grundläggande Datorteknik](./exams/DIT792) 1 exams. +- [DIT852 - Introduction to Data Science](./exams/DIT852) 2 exams. +- [DIT962 - Datastrukturer](./exams/DIT962) 2 exams. +- [DIT980 - Diskret matematik för Datavetare](./exams/DIT980) 1 exams. +- [DIT984 - Diskret matematik för Datavetare](./exams/DIT984) 1 exams. +- [EDA093 - Operating Systems](./exams/EDA093) 1 exams. +- [EDA387 - Computer Networks](./exams/EDA387) 2 exams. +- [EDA452 - Grundläggunde daterteknik](./exams/EDA452) 1 exams. +- [TDA384 - Principles of concurrent programming](./exams/TDA384) 2 exams. +- [TDA548 - Grundlöggande programvarutveckling](./exams/TDA548) 2 exams. +- [TDA555 - Introduction to functional programming](./exams/TDA555) 2 exams. +- [TIN093 - Algorithms](./exams/TIN093) 2 exams. + +***
diff --git a/courses/createReadme.js b/courses/createReadme.js deleted file mode 100644 index 4aa26f5..0000000 --- a/courses/createReadme.js +++ /dev/null @@ -1,31 +0,0 @@ -const fs = require("fs"); -const programmeMD = require("./modules/programmeMD"); -const courseTools = require("./modules/courseTools"); - -const programmes = require("./programmes.json"); -let courses = require("./courses.json"); - -const priorityProgrammes = ["N1SOF", "N2SOF"]; - - -function main() { - const courseProgrammes = courseTools.getCourseProgrammes(courses); - - courses = courseTools.stealCourseNames(courses); - - let readme = fs.readFileSync("./courses/static/header.md", "utf-8"); - - const [programmeMDs, coursesInProgrammes] = programmeMD.getProgrammeMDs(programmes, courses, courseProgrammes) - - let orderedProgrammeMDs = programmeMD.sortProgrammeMDs(programmeMDs, priorityProgrammes); - - orderedProgrammeMDs.forEach(programmeCode => { - readme += programmeMDs[programmeCode] - }); - - readme += programmeMD.getNoneMD(courses, coursesInProgrammes); - - fs.writeFileSync("./README.md", readme, "utf-8"); -} - -main(); \ No newline at end of file diff --git a/courses/modules/courseTools.js b/courses/modules/courseTools.js deleted file mode 100644 index 91f3a55..0000000 --- a/courses/modules/courseTools.js +++ /dev/null @@ -1,34 +0,0 @@ -const fs = require("fs"); - - -function stealCourseNames(courses) { - trackedCourses = fs.readdirSync("./exams/", "utf-8"); - - trackedCourses.forEach(course => { - if (courses[course] == undefined && !fs.existsSync(`./exams/${course}/.gitignore`)) { - let courseReadme = fs.readFileSync(`./exams/${course}/README.md`, "utf-8"); - courseReadme = courseReadme.split("\n")[0].split("-"); - courseReadme.shift(); - courses[course] = {"name": courseReadme.join("-").trim(), "credits": null, "level": null, "programmes": []}; - } - }); - - return courses; -} - -function getCourseProgrammes(courses) { - let programmes = {"NONE": []}; - - for (const courseCode in courses) { - const course = courses[courseCode]; - - course.programmes.forEach(programme => { - if (programmes[programme] == undefined) programmes[programme] = []; - programmes[programme].push(courseCode); - }); - } - - return programmes; -} - -module.exports = { getCourseProgrammes, stealCourseNames }; \ No newline at end of file diff --git a/courses/modules/programmeMD.js b/courses/modules/programmeMD.js deleted file mode 100644 index 10e622e..0000000 --- a/courses/modules/programmeMD.js +++ /dev/null @@ -1,132 +0,0 @@ -const fs = require("fs"); - -// Replace {{variable}}s -function replaceVariables(originalString, data) { - return originalString.replace(/\{\{(\w+)\}\}/g, function (variable, variableName) { - if (data.hasOwnProperty(variableName)) { - return data[variableName]; - } else { - return variable; - } - }); -} - -// Create the markdown section for each programme. -function getProgrammeMDs(programmes, courses, courseProgrammes) { - const programmeSource = fs.readFileSync("./courses/static/programme.md", "utf-8"); // The skeleton of the md. - - let programmeMDs = {}; - - let coursesInProgrammes = [] - - for (const programmeCode in courseProgrammes) { - const programme = programmes[programmeCode]; - if (programme === undefined) continue; // If the programme is not tracked (e.g. Not from the IT Faculty) then skips - - let courseList = courseProgrammes[programmeCode]; - courseList = courseList.filter(course => fs.existsSync(`./exams/${course}`)); // Only tracks courses that have their directories - - coursesInProgrammes = coursesInProgrammes.concat(courseList); - - const stuctureFilePath = `./courses/programmeOrders/${programmeCode}.json`; // The programme's structure - - let sectionStrings = []; - - // Check for defined terms - if (fs.existsSync(stuctureFilePath)) { - const programmeOrderRaw = fs.readFileSync(stuctureFilePath, "utf-8"); - const programmeOrder = JSON.parse(programmeOrderRaw); - - let processedCourses = []; // To keep track of processed courses - - Object.keys(programmeOrder).forEach(term => { - let termCoursesStrings = []; - programmeOrder[term].forEach(course => { - if (courseList.includes(course) && fs.existsSync(`./exams/${course}`)) { - termCoursesStrings.push(`- [${course} - ${courses[course].name}](/exams/${course})\n`); - processedCourses.push(course); // Mark course as processed - } - }); - - if (termCoursesStrings.length > 0) { - sectionStrings.push(`### ${term}:\n\n${termCoursesStrings.join('')}`); - } - }); - - // Process courses not in any terms - const unlistedCourses = courseList.filter(course => !processedCourses.includes(course)).sort(); - if (unlistedCourses.length > 0) { - let unlistedCoursesString = unlistedCourses.map(course => `- [${course} - ${courses[course].name}](/exams/${course})\n`).join(''); - sectionStrings.push(`### Not in any terms:\n\n${unlistedCoursesString}`); - } - } else { - // File doesn't exist - courseList = courseList.sort(); - if (courseList.length > 0) { - let coursesString = courseList.map(course => `- [${course} - ${courses[course].name}](/exams/${course})\n`).join(''); - sectionStrings.push(coursesString); - } - } - - // Join all sections with `***` only if more than one section exists - let programmeCourses = sectionStrings.length > 1 ? sectionStrings.join("\n***\n\n") : sectionStrings.join(""); - - if (programmeCourses) { - const programmeMD = replaceVariables(programmeSource, { - "programmeCode": programmeCode, - "programmeName": programme.name, - "courses": programmeCourses - }); - - programmeMDs[programmeCode] = `\n${programmeMD}`; - } - } - - return [programmeMDs, coursesInProgrammes]; -} - -function getNoneMD(courses, courseProgrammes) { - const programmeSource = fs.readFileSync("./courses/static/programme.md", "utf-8"); // The skeleton of the md. - - let trackedProgrammlessCourses = []; - for (const course in courses) { - if (!courseProgrammes.includes(course) && fs.existsSync(`./exams/${course}`)) trackedProgrammlessCourses.push(course); - } - - if (trackedProgrammlessCourses.length == 0) return ""; - - let programmeCourses = ""; - - trackedProgrammlessCourses.forEach(courseCode => { - const course = courses[courseCode]; - programmeCourses += `- [${courseCode} - ${course.name}](/exams/${courseCode})\n`; - }); - - const NoneMD = replaceVariables(programmeSource, { - "programmeCode": "NONE", - "programmeName": "Courses that have yet to be assigned to any programmes", - "courses": programmeCourses - }); - - return NoneMD; -} - -// Sort all programme markdowns based and also apply priority. -function sortProgrammeMDs(programmeMDs, priorityProgrammes) { - const allProgrammes = Object.keys(programmeMDs); - const prioritized = [], others = []; - - allProgrammes.forEach(key => { - if (priorityProgrammes.includes(key)) { - prioritized.push(key); - } else { - others.push(key); - } - }); - - others.sort(); - - return [...prioritized, ...others]; -} - -module.exports = { sortProgrammeMDs, getProgrammeMDs, getNoneMD}; \ No newline at end of file diff --git a/courses/programmeOrders/N1SOF.json b/courses/programmeOrders/N1SOF.json deleted file mode 100644 index 07098b3..0000000 --- a/courses/programmeOrders/N1SOF.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Term 1": [ - "DIT043", - "DIT023", - "DIT046", - "DIT094" - ], - "Term 2": [ - "DIT033", - "DIT182", - "DIT185", - "DIT113" - ], - "Term 3": [ - "DIT345", - "DIT342", - "DIT348", - "DIT356" - ], - "Term 4": [ - "DIT633", - "DIT636", - "DIT639" - ], - "Term 5": [ - "DIT038", - "DIT822", - "DIT826", - "DIT828" - ], - "Term 6": [ - "DIT836", - "DIT822", - "DIT837" - ] -} \ No newline at end of file diff --git a/courses/static/header.md b/courses/static/header.md deleted file mode 100644 index 139e6ad..0000000 --- a/courses/static/header.md +++ /dev/null @@ -1,20 +0,0 @@ -

SKIP – Past Exams Repository

-

- -


- -Welcome to the official `GitHub` repository that gathers **examination materials** for programmes at the **IT Faculty** of [Gothenburg University](https://www.gu.se/). - -### What's Inside - -Our repository currently features a sample of past exams, providing insights into the types of assessments you can expect during your studies. These materials are here to help you prepare effectively, understand the course expectations, and excel in your academic journey. - -### Explore and Contribute - -As we move forward into the academic year of **2023/2024**, our primary focus will be to continuously expand this repository. We are committed to adding old exams for the current study periods, ensuring that you have access to the most up-to-date and relevant assessment materials to support your learning. - -Feel free to explore, **contribute**, and make the most of this repository as you strive for excellence in your studies. Your feedback and contributions are highly encouraged and appreciated as we work together to enhance this resource for the benefit of the entire student community. - -## Programmes - -Click to expand the list of courses for each programme. \ No newline at end of file diff --git a/descriptionCreator/README.md b/descriptionCreator/README.md new file mode 100644 index 0000000..25494a6 --- /dev/null +++ b/descriptionCreator/README.md @@ -0,0 +1,32 @@ +# Description Creator + +This program creates the description for the past exams repo of SKIP + +To run this program use the command `npm run createDescription`! + +# Static files +The static files follow a strict format in order to build the proper markdown file in the end. + +The main file is the `structure.md` file, this defines how everything is to be chained together. + +The program understands variables and markdown file references. Both ust be defined between double curly brackets. +If there are multiple markdown files of the same name that needs to be chained together than it should be refferred to as `.mds`. During these the program will import the variable named the same + an `s` character into data so they can be referred to as variables + +for example if you say `programme.mds` then the variables under `programmes` will be available in data (if previous variables don't confict with the current variable, they'll still be available too.) + +## Variables +``` +"programmes": + "programmeCode", "prorammeName":, "language", "terms": + "termName", "courses": + "courseCode", "courseName", "courseCredit", "courseLevel", "courseDirectory", "courseExamCount" +``` + +# Settings +The following settings can be set currently. +- priorityProgrammes - Ordered list of programmes that should be prioritized +- extraCourses - List the courses that are not in any programmes +- emptyCourses - List courses that are defined and have no exams +- extraProgrammes - List programmes that are not defined +- emptyProgrammes - List programmes without courses +- termifyProgrammes - Split courses by terms if the programme terms are defined \ No newline at end of file diff --git a/courses/courses.json b/descriptionCreator/data/courses.json similarity index 98% rename from courses/courses.json rename to descriptionCreator/data/courses.json index 43b18fd..d13d1da 100644 --- a/courses/courses.json +++ b/descriptionCreator/data/courses.json @@ -1,4 +1,5 @@ { + "$schema": "../schemas/courses.json", "DIT837": { "name": "Bachelor Thesis in Software Engineering and Management", "credits": 15, @@ -189,7 +190,7 @@ "name": "Network Security", "credits": 7.5, "level": "master", - "programmes": ["N2COS", "N2ADS", "N1COS", "NDATM"] + "programmes": ["N2COS", "N2ADS", "N1COS"] }, "DIT075": { "name": "Mobile Computing: Design and Implementation", @@ -213,7 +214,7 @@ "name": "Language-Based Security", "credits": 7.5, "level": "master", - "programmes": ["N2COS", "N2ADS", "N2SOM", "N1COS", "NDATM"] + "programmes": ["N2COS", "N2ADS", "N2SOM", "N1COS"] }, "DIT407": { "name": "Introduction to Data science and AI", @@ -315,7 +316,7 @@ "name": "Distributed Systems, Advanced Course", "credits": 7.5, "level": "master", - "programmes": ["N2COS", "N2ADS", "N2SOM", "N1COS", "NDATM"] + "programmes": ["N2COS", "N2ADS", "N2SOM", "N1COS"] }, "DIT240": { "name": "Distributed Systems", @@ -423,7 +424,7 @@ "name": "Computer Architecture", "credits": 7.5, "level": "master", - "programmes": ["N2COS", "N2ADS", "N2SEM", "N2GDT", "N2SOM", "N1COS", "NDATM"] + "programmes": ["N2COS", "N2ADS", "N2SEM", "N2GDT", "N2SOM", "N1COS"] }, "DIT743": { "name": "Computational Methods in Bioinformatics", diff --git a/descriptionCreator/data/programmeOrders.json b/descriptionCreator/data/programmeOrders.json new file mode 100644 index 0000000..47b1996 --- /dev/null +++ b/descriptionCreator/data/programmeOrders.json @@ -0,0 +1,57 @@ +{ + "$schema": "../schemas/programmeOrders.json", + "N1SOF": [ + { + "name": "Term 1", + "courses": [ + "DIT043", + "DIT023", + "DIT046", + "DIT094" + ] + }, + { + "name": "Term 2", + "courses": [ + "DIT033", + "DIT182", + "DIT185", + "DIT113" + ] + }, + { + "name": "Term 3", + "courses": [ + "DIT345", + "DIT342", + "DIT348", + "DIT356" + ] + }, + { + "name": "Term 4", + "courses": [ + "DIT633", + "DIT636", + "DIT639" + ] + }, + { + "name": "Term 5", + "courses": [ + "DIT038", + "DIT822", + "DIT826", + "DIT828" + ] + }, + { + "name": "Term 6", + "courses": [ + "DIT836", + "DIT822", + "DIT837" + ] + } + ] +} \ No newline at end of file diff --git a/courses/programmes.json b/descriptionCreator/data/programmes.json similarity index 76% rename from courses/programmes.json rename to descriptionCreator/data/programmes.json index 2ddf821..f25fcad 100644 --- a/courses/programmes.json +++ b/descriptionCreator/data/programmes.json @@ -1,50 +1,51 @@ { + "$schema": "../schemas/programmes.json", "N2ADS": { "name": "Applied Data Science Master's Programme", - "lang": "en" + "language": "en" }, "N2COS": { "name": "Computer Science Master's Programme", - "lang": "en" + "language": "en" }, "N1COS": { "name": "Datavetenskapligt program", - "lang": "se" + "language": "se" }, "N2DGL": { "name": "Digital Leadership Master's Programme", - "lang": "en" + "language": "en" }, "N2GDT": { "name": "Game Design & Technology Master's Programme", - "lang": "en" + "language": "en" }, "T2HAI": { "name": "Human-centered Artificial Intelligence Master's Programme", - "lang": "en" + "language": "en" }, "S2ITL": { "name": "International Master's Programme in Information Technology and Learning", - "lang": "en" + "language": "en" }, "N2LKI": { "name": "Lärande, kommunikation och informationsteknologi, Magisterprogram", - "lang": "se" + "language": "se" }, "H2LTG": { "name": "Master in Language Technology", - "lang": "en" + "language": "en" }, "N1SOF": { "name": "Software Engineering and Management Bachelor's Programme", - "lang": "en" + "language": "en" }, "N2SOF": { "name": "Software Engineering and Management Master's Programme", - "lang": "en" + "language": "en" }, "N1SYD": { "name": "Systemvetenskap: samhällets digitalisering, kandidatprogram", - "lang": "se" + "language": "se" } } \ No newline at end of file diff --git a/descriptionCreator/main.js b/descriptionCreator/main.js new file mode 100644 index 0000000..c27ee5a --- /dev/null +++ b/descriptionCreator/main.js @@ -0,0 +1,19 @@ +import * as fs from "fs"; + +import { checkReference } from './modules/checkReferences.js'; +import { processData } from './modules/processData.js'; +import { settings } from './modules/settings.js'; + +/** + * Main function of the Description creator + * @param {{[x: string]: any}} settings + */ +function main(settings) { + let programmes = processData(settings); + + fs.writeFileSync("./exams.json", JSON.stringify(programmes,null,2), "utf-8"); + + fs.writeFileSync("./README.md", checkReference("structure.md", programmes), "utf-8"); +} + +main(settings); \ No newline at end of file diff --git a/descriptionCreator/modules/checkReferences.js b/descriptionCreator/modules/checkReferences.js new file mode 100644 index 0000000..517e785 --- /dev/null +++ b/descriptionCreator/modules/checkReferences.js @@ -0,0 +1,31 @@ +import * as fs from "fs"; + +function checkmds(file, data) { + file = file.replace(/{{(\w+?)\.md}}/g, (match, filename) => { + return checkReference(`${filename}.md`, data); + }); + + return file.replace(/{{(\w+?)\.mds}}/g, (match, filename) => { + let elements = [] + + data[`${filename}s`].forEach(determinor => { + elements.push(checkReference(`${filename}.md`, {...data, ...determinor})); + }); + return elements.join("\n"); + }); +} + +function checkvar(file, data) { + return file = file.replace(/{{(\w+?)}}/g, (match, variableName) => { + return data[variableName]; + }) +} + +export function checkReference(path, data) { + let file = fs.readFileSync(`./descriptionCreator/static/${path}`).toString(); + + file = checkmds(file, data); + file = checkvar(file, data); + + return file; +} \ No newline at end of file diff --git a/descriptionCreator/modules/processData.js b/descriptionCreator/modules/processData.js new file mode 100644 index 0000000..faee2c7 --- /dev/null +++ b/descriptionCreator/modules/processData.js @@ -0,0 +1,193 @@ +import * as fs from 'fs'; + +import courses from "../data/courses.json" assert {type: "json"}; +import programmes from "../data/programmes.json" assert {type: "json"}; +import programmeOrders from "../data/programmeOrders.json" assert {type: "json"}; + +// List courses that are defined and have no exams +function checkEmptyCourses(settings) { + for (const course in courses) { + if (!fs.existsSync(`./exams/${course}`)) { + delete courses[course]; + } + } +} + +// List the courses that are not in any programmes +function checkExtraCourses(settings) { + const courseList = fs.readdirSync("./exams/"); + for (const course of courseList) { + if (!courses[course]) { + if (fs.existsSync(`./exams/${course}/README.md`)) { + const courseDescription = fs.readFileSync(`./exams/${course}/README.md`).toString(); + + const regexPattern = new RegExp(`${course} - (\\p{L}((\\p{L}| )*\\p{L}))`, "u"); + + const match = courseDescription.match(regexPattern); + const courseName = match ? match[1] : "Unkown course"; + courses[course] = { name: courseName, credits: null, level: null, programmes: [] }; + } + } + } +} + +function countExams(settings) { + for (const course in courses) { + if (fs.existsSync(`./exams/${course}`)) { + const directories = fs.readdirSync(`./exams/${course}`, { withFileTypes: true }); + + const examCount = directories.filter(directory => directory.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(directory.name)).length; + + + courses[course].exams = examCount; + } else { + courses[course].exams = 0; + } + } +} + +function populateProgrammes(settings) { + for (const programme in programmeOrders) { + if (!programmes[programme]) { + programmes[programme] = {name: null, language: null}; + } + programmes[programme].courses = []; + for (const term in programmeOrders[programme]) { + programmeOrders[programme][term].courses = programmeOrders[programme][term].courses.filter(course => courses[course]); + + programmeOrders[programme][term].courses.forEach(course => { programmes[programme].courses.push(course); }); + + if (programmeOrders[programme][term].courses.length == 0) { + delete programmeOrders[programme][term]; + } + } + } + for (const course in courses) { + for (const programme of courses[course].programmes) { + if (!programmes[programme]) {programmes[programme] = {name: null, la5nguage: null}} + if (!programmes[programme].courses) {programmes[programme].courses = []} + if (!programmes[programme].courses.includes(course)) { + if (!programmeOrders[programme]) { programmeOrders[programme] = []; } + const terms = programmeOrders[programme].map(term => term.name); + if (!terms.includes("")) {programmeOrders[programme].push({"name": "", courses: []})} + const term = programmeOrders[programme].findIndex(term => term.name == ""); + programmeOrders[programme][term].courses.push(course); + programmes[programme].courses.push(course); + } + } + } +} + +function checkExtraProgrammes(settings) { + for (const programme in programmes) { + if (!programmes[programme].name) { + delete programmes[programme]; + } + } +} + +function checkForEmptyProgrammes(settings) { + for (const programme in programmes) { + if (!programmes[programme].courses) { + delete programmes[programme]; + } + } +} + +function checkEmptyProgrammes(settings) { + const priority = settings.priorityProgrammes; + priority.forEach(programme => { + if (!programmes[programme]) programmes[programme] = {name: null, language: null, courses: [], terms: []}; + }); +} + +const orderedProgrammes = []; +function orderProgrammes(settings) { + const priority = settings.priorityProgrammes; + priority.forEach(programme => { + if (programmes[programme]) { orderedProgrammes.push({programmeCode: programme, ...programmes[programme]}); } + }); + + const remaining = Object.keys(programmes).filter(programme => !priority.includes(programme) && programme != "NONE").sort(); + remaining.forEach(programme => { + orderedProgrammes.push({programmeCode: programme, ...programmes[programme]}); + }); + + if (settings.extraCourses) { + orderedProgrammes.push({programmeCode: "NONE", ...programmes.NONE}); + } + + orderedProgrammes.forEach(programme => { + programme.terms = programmeOrders[programme.programmeCode]; + }); +} + +function checkProgrammelessCourses(settings) { + const courseArrays = Object.values(programmes).map(programme => programme.courses); + + const inProgramme = courseArrays.reduce((allCourses, currentCourses) => { + return allCourses.concat(currentCourses); + }, []); + + for (const course in courses) { + if (!inProgramme.includes(course)) { + if (!programmes.NONE) { programmes.NONE = {name: `${settings.courseNotAssigned}`, language: null, courses: []}; } + programmes.NONE.courses.push(course); + } + } + if (settings.extraCourses) { + programmeOrders.NONE = [{name: "", courses: programmes.NONE.courses}] + } +} + +function putInCourses(settings) { + orderedProgrammes.forEach(programme => { + if (programme.terms != undefined) { + programme.terms.forEach(term => { + term.courses = term.courses.map(course => [course, courses[course]]); + }); + } + }); +} + +export function processData(settings) { + delete courses.$schema; + delete programmes.$schema; + delete programmeOrders.$schema; + + if (!settings.emptyCourses) { checkEmptyCourses(settings); } + if (settings.extraCourses) { checkExtraCourses(settings); } + countExams(); + + populateProgrammes(settings); + if (!settings.extraProgrammes) { checkExtraProgrammes(settings); } + if (!settings.emptyProgrammes) { checkForEmptyProgrammes(settings); } + if (settings.emptyProgrammes) { checkEmptyProgrammes(settings); } + + checkProgrammelessCourses(settings); + + orderProgrammes(settings); + + putInCourses(settings); + + const cleaned = { + programmes: orderedProgrammes.map(({programmeCode, name, language, terms}) => ({ + programmeCode, + programmeName: name, + programmeLanguage: language, + terms: terms.map(({name, courses}) => ({ + termName: name, + courses: courses.map(([courseCode, {name, credits, level, exams}]) => ({ + courseCode, + courseName: name, + courseCredit: credits, + courseLevel: level, + courseExamCount: exams, + courseDirectory: `./exams/${courseCode}` + })) + })) + })) + }; + + return cleaned; +} \ No newline at end of file diff --git a/descriptionCreator/modules/settings.js b/descriptionCreator/modules/settings.js new file mode 100644 index 0000000..2e60ff8 --- /dev/null +++ b/descriptionCreator/modules/settings.js @@ -0,0 +1,26 @@ +import schema from "../schemas/settings.json" assert {type: "json"}; +import userSettings from "../settings.json" assert {type: "json"}; + +const defaultSettings = ((schema) => { + const defaultSettings = {}; + const propertiesInSchema = schema.properties; + for (let propertyKey in propertiesInSchema) { + if (propertiesInSchema.hasOwnProperty(propertyKey)) { + if ("default" in propertiesInSchema[propertyKey]) { + defaultSettings[propertyKey] = propertiesInSchema[propertyKey].default; + } else { + console.log(`Schema error! ${propertyKey} is undefined!`); + defaultSettings[propertyKey] = undefined; + } + } + } + return defaultSettings; +})(schema); + +delete defaultSettings.$schema; +delete userSettings.$schema; + +export let settings = { + ...defaultSettings, + ...userSettings +}; \ No newline at end of file diff --git a/descriptionCreator/schemas/courses.json b/descriptionCreator/schemas/courses.json new file mode 100644 index 0000000..ee9e84a --- /dev/null +++ b/descriptionCreator/schemas/courses.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Schema for defining courses with their details", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "Path to the JSON schema definition", + "default": "./schemas/courses.json" + } + }, + "patternProperties": { + "^[A-Za-z]{3}[0-9]{3}$": { + "description": "Code for the Course (e.g. 'ABC123')", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the course" + }, + "credits": { + "type": "number", + "description": "Credits awarded for completing the course" + }, + "level": { + "type": "string", + "enum": ["bachelor", "master"], + "description": "Level of the course (bachelor / master)" + }, + "programmes": { + "type": "array", + "description": "List of programme codes associated with the course", + "items": { + "type": "string", + "pattern": "^[A-Za-z0-9]{5}$", + "description": "Code for the programme (alphanumeric, 5 characters)" + } + } + }, + "required": ["name", "credits", "level", "programmes"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["$schema"] +} \ No newline at end of file diff --git a/descriptionCreator/schemas/programmeOrders.json b/descriptionCreator/schemas/programmeOrders.json new file mode 100644 index 0000000..871b512 --- /dev/null +++ b/descriptionCreator/schemas/programmeOrders.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Schema for defining the list of courses per term for each programme", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "Path to the JSON schema definition", + "default": "./schemas/programmeOrders.json" + } + }, + "patternProperties": { + "^[A-Za-z0-9]{5}$": { + "description": "Code for the programme (alphanumeric, 5 characters)", + "type": "array", + "items": { + "type": "object", + "description": "Details of a specific term within the programme", + "properties": { + "name": { + "type": "string", + "description": "Name of the term (e.g., 'Term 1')" + }, + "courses": { + "type": "array", + "description": "Ordered list of course codes for this term", + "items": { + "type": "string", + "pattern": "^[A-Za-z]{3}[0-9]{3}$", + "description": "Code for the course (e.g., 'ABC123')" + } + } + }, + "required": ["name", "courses"], + "additionalProperties": false + } + } + }, + "required": ["$schema"], + "additionalProperties": false +} \ No newline at end of file diff --git a/descriptionCreator/schemas/programmes.json b/descriptionCreator/schemas/programmes.json new file mode 100644 index 0000000..b7072a7 --- /dev/null +++ b/descriptionCreator/schemas/programmes.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Schema for defining programme details", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "Relative path to the JSON schema definition", + "default": "./schemas/programmes.json" + } + }, + "patternProperties": { + "^[A-Za-z0-9]{5}$": { + "description": "Code for the programme (alphanumeric, 5 characters)", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the programme" + }, + "language": { + "type": "string", + "enum": ["en", "se"], + "description": "Language of the programme ('en' for English, 'se' for Swedish)" + } + }, + "required": ["name", "language"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["$schema"] +} \ No newline at end of file diff --git a/descriptionCreator/schemas/settings.json b/descriptionCreator/schemas/settings.json new file mode 100644 index 0000000..7c255cf --- /dev/null +++ b/descriptionCreator/schemas/settings.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Schema for defining setting details", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "Relative path to the JSON schema definition", + "default": "./schemas/settings.json" + }, + "priorityProgrammes": { + "type": "array", + "description": "Ordered list of programmes that should be prioritized", + "items": { + "type": "string", + "pattern": "^[A-Za-z0-9]{5}$", + "description": "Code for the programme (alphanumeric, 5 characters)" + }, + "default": [] + }, + "extraCourses" : { + "type": "boolean", + "description": "List the courses that are not in any programmes", + "default": false + }, + "emptyCourses": { + "type": "boolean", + "description": "List courses that are defined and have no exams", + "default": false + }, + "extraProgrammes": { + "type": "boolean", + "description": "List programmes that are not defined", + "default": false + }, + "emptyProgrammes": { + "type": "boolean", + "description": "List programmes without courses", + "default": false + }, + "termifyProgrammes": { + "type": "boolean", + "description": "Split courses by terms if the programme terms are defined", + "default": true + }, + "courseNotAssigned": { + "type": "string", + "description": "The name of the fake programme that contains courses not in any programmes", + "default": "Courses that have yet to be assigned to any programmes" + } + }, + "additionalProperties": false, + "required": ["$schema"] +} \ No newline at end of file diff --git a/descriptionCreator/settings.json b/descriptionCreator/settings.json new file mode 100644 index 0000000..2e27782 --- /dev/null +++ b/descriptionCreator/settings.json @@ -0,0 +1,5 @@ +{ + "$schema": "./schemas/settings.json", + "priorityProgrammes": ["N1SOF", "N2SOF"], + "extraCourses": true +} \ No newline at end of file diff --git a/descriptionCreator/static/course.md b/descriptionCreator/static/course.md new file mode 100644 index 0000000..230d3c4 --- /dev/null +++ b/descriptionCreator/static/course.md @@ -0,0 +1 @@ +- [{{courseCode}} - {{courseName}}]({{courseDirectory}}){{examCount.md}} \ No newline at end of file diff --git a/descriptionCreator/static/examCount.md b/descriptionCreator/static/examCount.md new file mode 100644 index 0000000..f64be1b --- /dev/null +++ b/descriptionCreator/static/examCount.md @@ -0,0 +1 @@ + {{courseExamCount}} exams. \ No newline at end of file diff --git a/descriptionCreator/static/footer.md b/descriptionCreator/static/footer.md new file mode 100644 index 0000000..e69de29 diff --git a/descriptionCreator/static/header.md b/descriptionCreator/static/header.md new file mode 100644 index 0000000..26c4127 --- /dev/null +++ b/descriptionCreator/static/header.md @@ -0,0 +1,31 @@ +

SKIP – Past Exams Repository

+

+ +


+ +Welcome to the official `GitHub` repository that gathers **examination +materials** for programmes at the **IT Faculty** of [Gothenburg +University](https://www.gu.se/). + +### What's Inside + +Our repository currently features a sample of past exams, providing insights +into the types of assessments you can expect during your studies. These +materials are here to help you prepare effectively, understand the course +expectations, and excel in your academic journey. + +### Explore and Contribute + +As we move forward into the academic year of **2023/2024**, our primary focus +will be to continuously expand this repository. We are committed to adding old +exams for the current study periods, ensuring that you have access to the most +up-to-date and relevant assessment materials to support your learning. + +Feel free to explore, **contribute**, and make the most of this repository as +you strive for excellence in your studies. Your feedback and contributions are +highly encouraged and appreciated as we work together to enhance this resource +for the benefit of the entire student community. + +## Programmes + +Click to expand the list of courses for each programme. \ No newline at end of file diff --git a/courses/static/programme.md b/descriptionCreator/static/programme.md similarity index 77% rename from courses/static/programme.md rename to descriptionCreator/static/programme.md index d492339..05a8813 100644 --- a/courses/static/programme.md +++ b/descriptionCreator/static/programme.md @@ -1,5 +1,6 @@ +
👇 {{programmeCode}} - {{programmeName}} +{{term.mds}} -{{courses}} -
+ \ No newline at end of file diff --git a/descriptionCreator/static/structure.md b/descriptionCreator/static/structure.md new file mode 100644 index 0000000..f7805fa --- /dev/null +++ b/descriptionCreator/static/structure.md @@ -0,0 +1,3 @@ +{{header.md}} +{{programme.mds}} +{{footer.md}} \ No newline at end of file diff --git a/descriptionCreator/static/term.md b/descriptionCreator/static/term.md new file mode 100644 index 0000000..a18a3b5 --- /dev/null +++ b/descriptionCreator/static/term.md @@ -0,0 +1,6 @@ + +### {{termName}} + +{{course.mds}} + +*** \ No newline at end of file diff --git a/exams.json b/exams.json new file mode 100644 index 0000000..a74cf58 --- /dev/null +++ b/exams.json @@ -0,0 +1,493 @@ +{ + "programmes": [ + { + "programmeCode": "N1SOF", + "programmeName": "Software Engineering and Management Bachelor's Programme", + "programmeLanguage": "en", + "terms": [ + { + "termName": "Term 1", + "courses": [ + { + "courseCode": "DIT043", + "courseName": "Object-Oriented Programming", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT043" + }, + { + "courseCode": "DIT023", + "courseName": "Mathematical Foundations for Software Engineering", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 9, + "courseDirectory": "./exams/DIT023" + }, + { + "courseCode": "DIT046", + "courseName": "Requirements and User Experience", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT046" + } + ] + }, + { + "termName": "Term 2", + "courses": [ + { + "courseCode": "DIT033", + "courseName": "Data Management", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 9, + "courseDirectory": "./exams/DIT033" + }, + { + "courseCode": "DIT182", + "courseName": "Data Structures and Algorithms", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 0, + "courseDirectory": "./exams/DIT182" + }, + { + "courseCode": "DIT185", + "courseName": "Software Analysis and Design", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 3, + "courseDirectory": "./exams/DIT185" + } + ] + }, + { + "termName": "Term 3", + "courses": [ + { + "courseCode": "DIT345", + "courseName": "Fundamentals of Software Architecture", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT345" + }, + { + "courseCode": "DIT342", + "courseName": "Web Development", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 10, + "courseDirectory": "./exams/DIT342" + }, + { + "courseCode": "DIT348", + "courseName": "Software Development Methodologies", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 0, + "courseDirectory": "./exams/DIT348" + } + ] + }, + { + "termName": "Term 4", + "courses": [ + { + "courseCode": "DIT633", + "courseName": "Development of Embedded and Real-Time Systems", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 4, + "courseDirectory": "./exams/DIT633" + }, + { + "courseCode": "DIT636", + "courseName": "Software Quality and Testing", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT636" + } + ] + }, + { + "termName": "Term 5", + "courses": [ + { + "courseCode": "DIT822", + "courseName": "Software engineering for AI systems", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT822" + } + ] + }, + { + "termName": "Term 6", + "courses": [ + { + "courseCode": "DIT822", + "courseName": "Software engineering for AI systems", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT822" + } + ] + } + ] + }, + { + "programmeCode": "N2SOF", + "programmeName": "Software Engineering and Management Master's Programme", + "programmeLanguage": "en", + "terms": [ + { + "termName": "", + "courses": [ + { + "courseCode": "DIT431", + "courseName": "High Performance Parallel Programming", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT431" + } + ] + } + ] + }, + { + "programmeCode": "N1COS", + "programmeName": "Datavetenskapligt program", + "programmeLanguage": "se", + "terms": [ + { + "termName": "", + "courses": [ + { + "courseCode": "DIT342", + "courseName": "Web Development", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 10, + "courseDirectory": "./exams/DIT342" + }, + { + "courseCode": "DIT348", + "courseName": "Software Development Methodologies", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 0, + "courseDirectory": "./exams/DIT348" + }, + { + "courseCode": "DIT185", + "courseName": "Software Analysis and Design", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 3, + "courseDirectory": "./exams/DIT185" + }, + { + "courseCode": "DIT401", + "courseName": "Operating Systems", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT401" + }, + { + "courseCode": "DIT093", + "courseName": "Algorithms", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT093" + } + ] + } + ] + }, + { + "programmeCode": "N2ADS", + "programmeName": "Applied Data Science Master's Programme", + "programmeLanguage": "en", + "terms": [ + { + "termName": "", + "courses": [ + { + "courseCode": "DIT822", + "courseName": "Software engineering for AI systems", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT822" + }, + { + "courseCode": "DIT046", + "courseName": "Requirements and User Experience", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 5, + "courseDirectory": "./exams/DIT046" + }, + { + "courseCode": "DIT401", + "courseName": "Operating Systems", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT401" + }, + { + "courseCode": "DIT431", + "courseName": "High Performance Parallel Programming", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT431" + }, + { + "courseCode": "DIT182", + "courseName": "Data Structures and Algorithms", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 0, + "courseDirectory": "./exams/DIT182" + }, + { + "courseCode": "DIT033", + "courseName": "Data Management", + "courseCredit": 7.5, + "courseLevel": "bachelor", + "courseExamCount": 9, + "courseDirectory": "./exams/DIT033" + }, + { + "courseCode": "DIT093", + "courseName": "Algorithms", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT093" + } + ] + } + ] + }, + { + "programmeCode": "N2COS", + "programmeName": "Computer Science Master's Programme", + "programmeLanguage": "en", + "terms": [ + { + "termName": "", + "courses": [ + { + "courseCode": "DIT401", + "courseName": "Operating Systems", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT401" + }, + { + "courseCode": "DIT431", + "courseName": "High Performance Parallel Programming", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT431" + }, + { + "courseCode": "DIT093", + "courseName": "Algorithms", + "courseCredit": 7.5, + "courseLevel": "master", + "courseExamCount": 1, + "courseDirectory": "./exams/DIT093" + } + ] + } + ] + }, + { + "programmeCode": "NONE", + "programmeName": "Courses that have yet to be assigned to any programmes", + "programmeLanguage": null, + "terms": [ + { + "termName": "", + "courses": [ + { + "courseCode": "DAT050", + "courseName": "Objektorientered programmering", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DAT050" + }, + { + "courseCode": "DAT060", + "courseName": "Logic in Computer Science", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DAT060" + }, + { + "courseCode": "DAT105", + "courseName": "Computer Architecture", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DAT105" + }, + { + "courseCode": "DAT246", + "courseName": "Empirical Software Engineering", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DAT246" + }, + { + "courseCode": "DAT400", + "courseName": "High Performance Parallel Programming", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/DAT400" + }, + { + "courseCode": "DAT555", + "courseName": "Programmeringsteknik", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DAT555" + }, + { + "courseCode": "DIT440", + "courseName": "Introduction to Functional Programming", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DIT440" + }, + { + "courseCode": "DIT670", + "courseName": "Computer Networks", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/DIT670" + }, + { + "courseCode": "DIT792", + "courseName": "Grundläggande Datorteknik", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/DIT792" + }, + { + "courseCode": "DIT852", + "courseName": "Introduction to Data Science", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DIT852" + }, + { + "courseCode": "DIT962", + "courseName": "Datastrukturer", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/DIT962" + }, + { + "courseCode": "DIT980", + "courseName": "Diskret matematik för Datavetare", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/DIT980" + }, + { + "courseCode": "DIT984", + "courseName": "Diskret matematik för Datavetare", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/DIT984" + }, + { + "courseCode": "EDA093", + "courseName": "Operating Systems", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/EDA093" + }, + { + "courseCode": "EDA387", + "courseName": "Computer Networks", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/EDA387" + }, + { + "courseCode": "EDA452", + "courseName": "Grundläggunde daterteknik", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 1, + "courseDirectory": "./exams/EDA452" + }, + { + "courseCode": "TDA384", + "courseName": "Principles of concurrent programming", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/TDA384" + }, + { + "courseCode": "TDA548", + "courseName": "Grundlöggande programvarutveckling", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/TDA548" + }, + { + "courseCode": "TDA555", + "courseName": "Introduction to functional programming", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/TDA555" + }, + { + "courseCode": "TIN093", + "courseName": "Algorithms", + "courseCredit": null, + "courseLevel": null, + "courseExamCount": 2, + "courseDirectory": "./exams/TIN093" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..eb9b8db --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "createDescription": "node ./descriptionCreator/main.js" + }, + "type": "module" +}