├── tutorial ├── 08 │ ├── 01.spec.js │ └── challenge-1.md ├── 09 │ └── challenge-2.md ├── 04 │ ├── 05.js │ ├── 03.js │ ├── 04.js │ ├── 02.js │ ├── 01.js │ ├── myFixed.js │ └── forEach.md ├── 07 │ ├── 07.js │ ├── 02.js │ ├── 06.js │ ├── 03.js │ ├── 01.js │ ├── 04.js │ ├── 05.js │ ├── suspectData.js │ └── reduce.md ├── 02 │ ├── 04.js │ ├── 03.js │ ├── 01.js │ ├── 05.js │ ├── 02.js │ ├── myBest.js │ └── sort.md ├── common │ └── array.js ├── 05 │ ├── 06.js │ ├── 02.js │ ├── 01.js │ ├── 05.js │ ├── 04.js │ ├── 03.js │ ├── find.md │ └── courses.js ├── 06 │ ├── 01.js │ ├── 02.js │ ├── 04.js │ ├── 03.js │ ├── 05.js │ ├── 06.js │ ├── concat.md │ └── courses2.js ├── 03 │ ├── 01.js │ ├── 07.js │ ├── 03.js │ ├── 06.js │ ├── 05.js │ ├── myCourses.js │ ├── 04.js │ ├── 02.js │ └── map.md ├── 00 │ ├── 04.js │ ├── 01.js │ ├── 03.js │ ├── 02.js │ ├── setup.md │ └── data.js ├── tutorial.md ├── 01 │ ├── 03.js │ ├── 01.js │ ├── 04.js │ ├── 02.js │ └── filter.md └── data │ ├── courses2.js │ ├── courses.js │ ├── students2.js │ └── students.js ├── .gitignore ├── CHANGELOG.md ├── package.json ├── README.md └── coderoad.json /tutorial/08/01.spec.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dev 3 | tutorial/.tmp.* 4 | -------------------------------------------------------------------------------- /tutorial/09/challenge-2.md: -------------------------------------------------------------------------------- 1 | ## Challenge 2 2 | coming soon 3 | 4 | It's time to get revenge. 5 | -------------------------------------------------------------------------------- /tutorial/08/challenge-1.md: -------------------------------------------------------------------------------- 1 | ## Challenge 1 2 | coming soon 3 | 4 | You'd better fix your name and scores back to the way they were. 5 | -------------------------------------------------------------------------------- /tutorial/04/05.js: -------------------------------------------------------------------------------- 1 | describe('05 log', () => { 2 | 3 | it('should pass', () => { 4 | expect(true).to.be.true; 5 | }); 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /tutorial/07/07.js: -------------------------------------------------------------------------------- 1 | describe('07 const likelySuspects', () => { 2 | 3 | it('should pass', () => { 4 | expect(true).to.be.true; 5 | }); 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /tutorial/02/04.js: -------------------------------------------------------------------------------- 1 | describe('04 function compareScore', () => { 2 | 3 | it('doesn\'t return 0 when b\'s score equals a\'s', () => { 4 | expect(compareScore({score: 3}, {score: 3})).to.equal(0); 5 | }); 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /tutorial/02/03.js: -------------------------------------------------------------------------------- 1 | describe('03 function compareScore', () => { 2 | 3 | it('doesn\'t return -1 when b\'s score is less than a\'s', () => { 4 | expect(compareScore({score: 5}, {score: 3})).to.equal(-1); 5 | }); 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /tutorial/common/array.js: -------------------------------------------------------------------------------- 1 | Array.prototype.concatAll = function() { 2 | var results = []; 3 | this.forEach(function(subArray) { 4 | subArray.forEach(function(item) { 5 | results.concat(item); 6 | }); 7 | }); 8 | return results; 9 | } 10 | -------------------------------------------------------------------------------- /tutorial/07/02.js: -------------------------------------------------------------------------------- 1 | const reduce = require('BASE/07-reduce.js'); 2 | 3 | describe('02 const total', () => { 4 | 5 | const total = reduce.__get__('total'); 6 | 7 | it('should add the numbers up', () => { 8 | expect(total).to.equal(54); 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/05/06.js: -------------------------------------------------------------------------------- 1 | describe('06 const decodedName', () => { 2 | 3 | const decodedName = find.__get__('decodedName'); 4 | 5 | it('should find 10 unknown students names', () => { 6 | expect(decodedName).to.equal('!findthebestrevenge!'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /tutorial/07/06.js: -------------------------------------------------------------------------------- 1 | describe('06 const likelySuspects', () => { 2 | 3 | const likelySuspects = reduce.__get__('likelySuspects'); 4 | 5 | it('should reduce down to a suspect name', () => { 6 | expect(likelySuspects).to.equal('Hack Kerr'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /tutorial/07/03.js: -------------------------------------------------------------------------------- 1 | describe('03 const averages', () => { 2 | 3 | const averages = reduce.__get__('averages'); 4 | 5 | it('should calculate the average of each class', () => { 6 | expect(averages).to.deep.equal([57, 67, 70, 70, 71, 62, 67, 73, 62, 57]); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /tutorial/02/01.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | const myBest = require('BASE/data/myBest.js'); 4 | 5 | describe('01 myBest data', () => { 6 | 7 | it('should be loaded in "data/myBest.js"', () => { 8 | expect(myBest).to.not.be.undefined; 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/05/02.js: -------------------------------------------------------------------------------- 1 | const find = require('BASE/05-find.js'); 2 | 3 | describe('02 const myClass', () => { 4 | 5 | const myClass = find.__get__('myClass'); 6 | 7 | it('should filter to "Web Security" class data', () => { 8 | expect(myClass).to.have.length(16); 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/06/01.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | const courses = require('BASE/data/courses2.js'); 4 | 5 | describe('01 load courses', () => { 6 | 7 | it('should be loaded in "data/courses2.js"', () => { 8 | expect(courses).to.not.be.undefined; 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/05/01.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | const courses = require('BASE/data/courses2.js'); 4 | 5 | describe('01 courses2 data', () => { 6 | 7 | it('should be loaded in "data/courses2.js"', () => { 8 | expect(courses).to.not.be.undefined; 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/03/01.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | const myCourses = require('BASE/data/myCourses.js'); 4 | 5 | describe('01 myCourses data', () => { 6 | 7 | it('should be loaded in "data/myCourses.js"', () => { 8 | expect(myCourses).to.not.be.undefined; 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/07/01.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | 3 | const suspectData = require('BASE/data/suspectData.js'); 4 | 5 | describe('01 suspectData', () => { 6 | 7 | it('should be loaded in "data/suspectData.js"', () => { 8 | expect(suspectData).to.not.be.undefined; 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/00/04.js: -------------------------------------------------------------------------------- 1 | describe('04 console.log', () => { 2 | 3 | it('should use `console.log` to log the name', () => { 4 | expect(spy).to.have.been.called(); 5 | }) 6 | 7 | it('should log `myName` to the console', () => { 8 | expect(spy).to.have.been.called.with('Ada Lovelace'); 9 | }); 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /tutorial/05/05.js: -------------------------------------------------------------------------------- 1 | describe('05 const unknownStudentNames', () => { 2 | 3 | const unknownStudentNames = find.__get__('unknownStudentNames'); 4 | 5 | it('should find 10 unknown students names', () => { 6 | const names = unknownStudentNames.join(''); 7 | expect(names).to.equal('!findthebestrevenge!'); 8 | }); 9 | 10 | }); 11 | -------------------------------------------------------------------------------- /tutorial/04/03.js: -------------------------------------------------------------------------------- 1 | describe('03 console.log', () => { 2 | 3 | if (process.env.TASK_POSITION !== '4') { 4 | it('should begin with an index', () => { 5 | expect(spy).to.have.been.called.with('1 A 95 Relational Databases'); 6 | expect(spy).to.have.been.called.with('10 C 77 Networks'); 7 | }); 8 | } 9 | 10 | }); 11 | -------------------------------------------------------------------------------- /tutorial/04/04.js: -------------------------------------------------------------------------------- 1 | describe('04 console.log', () => { 2 | 3 | if (process.env.TASK_POSITION !== '4') { 4 | it('should begin with an index', () => { 5 | expect(spy).to.have.been.called.with('1/10 A 95 Relational Databases'); 6 | expect(spy).to.have.been.called.with('10/10 C 77 Networks'); 7 | }); 8 | } 9 | 10 | }); 11 | -------------------------------------------------------------------------------- /tutorial/04/02.js: -------------------------------------------------------------------------------- 1 | require('BASE/04-forEach.js'); 2 | 3 | describe('02 console.log', () => { 4 | 5 | if (process.env.TASK_POSITION !== '4') { 6 | it('should be called 10 times', () => { 7 | expect(spy).to.have.been.called.with('A 95 Relational Databases'); 8 | expect(spy).to.have.been.called.with('C 77 Networks'); 9 | }); 10 | } 11 | 12 | }); 13 | -------------------------------------------------------------------------------- /tutorial/00/01.js: -------------------------------------------------------------------------------- 1 | const chai = require('chai'); 2 | const spies = require('chai-spies'); 3 | const expect = chai.expect; 4 | chai.use(spies); 5 | let spy = chai.spy.on(console, 'log'); 6 | 7 | describe('01 student data', () => { 8 | 9 | const students = require('BASE/data/students.js'); 10 | 11 | it('should be loaded in "data/students.js"', () => { 12 | expect(students).to.not.be.undefined; 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /tutorial/03/07.js: -------------------------------------------------------------------------------- 1 | describe('07 const scoresAndGrades', () => { 2 | 3 | const scoresAndGrades = map.__get__('scoresAndGrades'); 4 | 5 | it('should return an array of scores and grades', () => { 6 | expect(scoresAndGrades[0]).to.deep.equal({ 7 | grade: "A", 8 | score: 95 9 | }); 10 | expect(scoresAndGrades[9]).to.deep.equal({ 11 | grade: "C", 12 | score: 77 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /tutorial/06/02.js: -------------------------------------------------------------------------------- 1 | const concat = require('BASE/06-concat.js'); 2 | 3 | describe('02 const flattenedArray', () => { 4 | 5 | const flattenedArray = concat.__get__('flattenedArray'); 6 | 7 | it('should flatten the array', () => { 8 | expect(flattenedArray).to.have.length(4); 9 | }); 10 | 11 | it('should flatten the array', () => { 12 | expect(flattenedArray).to.deep.equal([1, 2, 3, 4]); 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /tutorial/05/04.js: -------------------------------------------------------------------------------- 1 | describe('04 const unknownStudentList', () => { 2 | 3 | const unknownStudentList = find.__get__('unknownStudentList'); 4 | 5 | it('should find 10 students', () => { 6 | expect(unknownStudentList).to.have.length(10); 7 | }); 8 | 9 | it('should find 10 unknown students across classes', () => { 10 | const names = unknownStudentList.map((student) => student.name).join(''); 11 | expect(names).to.equal('!findthebestrevenge!'); 12 | }); 13 | 14 | }); 15 | -------------------------------------------------------------------------------- /tutorial/00/03.js: -------------------------------------------------------------------------------- 1 | describe('03 const myName', () => { 2 | 3 | // __get__ grabs global myName 4 | const myName = setup.__get__('myName'); 5 | 6 | it('should exist', () => { 7 | expect(myName).to.not.be.undefined; 8 | }); 9 | 10 | it('should be a string', () => { 11 | expect(myName).to.be.a('string'); 12 | }); 13 | 14 | it('should have the correct value', () => { 15 | const result = 'Ada Lovelace'; 16 | expect(myName).to.deep.equal(result); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /tutorial/04/01.js: -------------------------------------------------------------------------------- 1 | const chai = require('chai'); 2 | const spies = require('chai-spies'); 3 | const expect = chai.expect; 4 | chai.use(spies); 5 | 6 | let myFixed = require('BASE/data/myFixed.js'); 7 | if (process.env.TASK_POSITION === '4') { 8 | myFixed = []; 9 | } 10 | 11 | let spy = chai.spy.on(console, 'log'); 12 | 13 | describe('01 myFixed data', () => { 14 | 15 | it('should be loaded in "data/myFixed.js"', () => { 16 | expect(myFixed).to.not.be.undefined; 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /tutorial/06/04.js: -------------------------------------------------------------------------------- 1 | describe('04 const students', () => { 2 | 3 | const students = concat.__get__('students'); 4 | 5 | it('should have 160 items', () => { 6 | expect(students).to.have.length(160); 7 | }); 8 | 9 | it('should result in a single array of student data', () => { 10 | expect(students[0]).to.deep.equal({ 11 | instructor: "Sean Quentin Lewis", 12 | title: "Relational Databases", 13 | name: "!f", 14 | grade: "D", 15 | score: 61 16 | }); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /tutorial/tutorial.md: -------------------------------------------------------------------------------- 1 | # Functional School 2 | A trip through functional programming in Javascript using common built-in Javascript array methods such as `map` & `reduce`. 3 | 4 | By the end, you should have an understanding of how to use array methods to manipulate semi-complex data. 5 | 6 | Level: Intermediate 7 | Keywords: javascript, functional 8 | Length: 1-2 hours 9 | 10 | 11 | @import('00/setup') 12 | @import('01/filter') 13 | @import('02/sort') 14 | @import('03/map') 15 | @import('04/forEach') 16 | @import('05/find') 17 | @import('06/concat') 18 | @import('07/reduce') 19 | -------------------------------------------------------------------------------- /tutorial/06/03.js: -------------------------------------------------------------------------------- 1 | describe('03 const doubleArray', () => { 2 | 3 | const doubleArray = concat.__get__('doubleArray'); 4 | 5 | it('should create an array of arrays', () => { 6 | expect(doubleArray).to.have.length(10); 7 | expect(doubleArray[0]).to.have.length(16); 8 | }); 9 | 10 | it('should create an array of arrays', () => { 11 | expect(doubleArray[0][0]).to.deep.equal({ 12 | instructor: "Sean Quentin Lewis", 13 | title: "Relational Databases", 14 | name: "!f", 15 | grade: "D", 16 | score: 61 17 | }); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /tutorial/07/04.js: -------------------------------------------------------------------------------- 1 | describe('04 const suspectScores', () => { 2 | 3 | it('should reduce to an array of suspect scores', () => { 4 | 5 | const suspectScores = reduce.__get__('suspectScores'); 6 | 7 | expect(suspectScores).to.deep.equal([{ 8 | name: 'Albert Gonzalez', 9 | scores: [35, 37, 73, 74, 94, 67, 39, 70, 56, 52] 10 | }, { 11 | name: 'Hack Kerr', 12 | scores: [85, 86, 92, 75, 83, 96, 94, 87, 89, 102] 13 | }, { 14 | name: 'Kevin Mitnick', 15 | scores: [72, 52, 47, 89, 47, 75, 81, 41, 40, 37] 16 | }]); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /tutorial/02/05.js: -------------------------------------------------------------------------------- 1 | describe('05 const mySorted', () => { 2 | 3 | const mySorted = sort.__get__('mySorted'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(mySorted).to.not.be.undefined; 7 | }); 8 | 9 | it('doesn\'t output an array', () => { 10 | expect(mySorted).to.be.an('array'); 11 | }); 12 | 13 | it('doesn\'t output exactly seven items', () => { 14 | expect(mySorted).to.have.length(7); 15 | }); 16 | 17 | it('isn\'t the right sorted data', () => { 18 | expect(mySorted[0].score).to.equal(93); 19 | expect(mySorted[6].score).to.equal(73); 20 | }); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /tutorial/02/02.js: -------------------------------------------------------------------------------- 1 | const sort = require('BASE/02-sort.js'); 2 | const compareScore = sort.__get__('compareScore'); 3 | 4 | describe('02 function compareScore', () => { 5 | 6 | it('doesn\'t exist', () => { 7 | expect(compareScore).to.not.be.undefined; 8 | }); 9 | 10 | it('isn\'t a Function', () => { 11 | expect(compareScore).to.be.a('function'); 12 | }); 13 | 14 | it('doesn\'t have two params', () => { 15 | expect(compareScore.length).to.equal(2); 16 | }); 17 | 18 | it('doesn\'t return 1 when b\'s score is more than a\'s', () => { 19 | expect(compareScore({ 20 | score: 3 21 | }, { 22 | score: 5 23 | })).to.equal(1); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /tutorial/07/05.js: -------------------------------------------------------------------------------- 1 | describe('05 const suspectStats', () => { 2 | 3 | it('should map over suspect data to find the score differences', () => { 4 | 5 | const suspectStats = reduce.__get__('suspectStats'); 6 | 7 | expect(suspectStats).to.deep.equal([{ 8 | name: 'Albert Gonzalez', 9 | scores: [35, 37, 73, 74, 94, 67, 39, 70, 56, 52], 10 | difference: -59 11 | }, { 12 | name: 'Hack Kerr', 13 | scores: [85, 86, 92, 75, 83, 96, 94, 87, 89, 102], 14 | difference: 233 15 | }, { 16 | name: 'Kevin Mitnick', 17 | scores: [72, 52, 47, 89, 47, 75, 81, 41, 40, 37], 18 | difference: -75 19 | }]); 20 | }); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /tutorial/06/05.js: -------------------------------------------------------------------------------- 1 | describe('05 const suspectData', () => { 2 | 3 | const suspectData = concat.__get__('suspectData'); 4 | 5 | it('should have 10 items', () => { 6 | expect(suspectData).to.have.length.below(31); 7 | }); 8 | 9 | it('should filter if the `indexOf` the suspects name is greater than -1', () => { 10 | const hackKerrData = suspectData.filter((suspect) => { 11 | return suspect.name === 'Hack Kerr'; 12 | }); 13 | expect(hackKerrData).to.have.length(10); 14 | expect(hackKerrData[0]).to.deep.equal({ 15 | title: 'Relational Databases', 16 | instructor: 'Sean Quentin Lewis', 17 | name: 'Hack Kerr', 18 | score: 85, 19 | grade: 'F' 20 | }); 21 | }); 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /tutorial/03/03.js: -------------------------------------------------------------------------------- 1 | describe('03 const myChanged', () => { 2 | 3 | const myChanged = map.__get__('myChanged'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(myChanged).to.not.be.undefined; 7 | }); 8 | 9 | it('isn\'t an array', () => { 10 | expect(myChanged).to.be.an('array'); 11 | }); 12 | 13 | it('doesn\'t change all D\'s to A\'s', () => { 14 | function filterD(student) { 15 | return student.grade === 'D'; 16 | } 17 | expect(myChanged.filter(filterD)).to.have.length(0); 18 | }); 19 | 20 | it('doesn\'t change all F\'s to A\'s', () => { 21 | function filterD(student) { 22 | return student.grade === 'F'; 23 | } 24 | expect(myChanged.filter(filterD)).to.have.length(0); 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /tutorial/00/02.js: -------------------------------------------------------------------------------- 1 | const setup = require('BASE/setup.js'); 2 | 3 | describe('02 const first', () => { 4 | 5 | // __get__ grabs global first 6 | const first = setup.__get__('first'); 7 | 8 | it('should exist', () => { 9 | expect(first).to.not.be.undefined; 10 | }); 11 | 12 | it('should be an object', () => { 13 | expect(first).to.be.an('object'); 14 | }); 15 | 16 | it('should take have property title', () => { 17 | expect(first).to.have.property('title'); 18 | }); 19 | 20 | it('should have the correct value', () => { 21 | var result = { 22 | "title": "Relational Databases", 23 | "instructor": "Sean Quentin Lewis", 24 | "name": "Ada Lovelace", 25 | "score": 91, 26 | "grade": "A" 27 | }; 28 | expect(first).to.deep.equal(result); 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /tutorial/03/06.js: -------------------------------------------------------------------------------- 1 | describe('06 function getGrade', () => { 2 | 3 | const getGrade = map.__get__('getGrade'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(getGrade).to.not.be.undefined; 7 | }); 8 | 9 | it('should be a function', () => { 10 | expect(getGrade).to.be.a('function'); 11 | }); 12 | 13 | it('should take a parameter', () => { 14 | expect(getGrade).to.have.length(1); 15 | }); 16 | 17 | 18 | }); 19 | 20 | describe('06 const mySlightlyChanged', () => { 21 | 22 | const mySlightlyChanged = map.__get__('mySlightlyChanged'); 23 | 24 | it('doesn\'t update grades correctly', () => { 25 | expect(mySlightlyChanged.map((x) => { 26 | return x.grade; 27 | })).to.deep.equal(['A', 'A', 'C', 'A', 'B', 'C', 'A', 'A', 'A', 'C']); 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## [1.1.0] - 2016-08-16 6 | - use new "writeFromFile" action in atom-coderoad@0.12 7 | 8 | ## [1.0.0] - 2016-08-15 9 | - update for mocha-coderoad v0.10 10 | - removed loaders in favor of new syntax 11 | - updated for es6 import/exports 12 | 13 | ## [0.5.0] - 2016-05-02 14 | - remove "chapters" 15 | 16 | ## [0.4.0] - 2016-04-23 17 | - updated for atom-coderoad@0.7 18 | 19 | ## [0.3.0] - 2016-04-01 20 | - update tutorial for changes to loaders in Atom-CodeRoad 21 | 22 | ## [0.1.7] - 2016-02-26 23 | - Hints for steps 1-7 24 | 25 | ##[0.1.9] - 2016-03-04 26 | - `@onPageComplete` messages 27 | 28 | ##[0.1.10] - 2016-03-07 29 | - Cursor position added (`::>`) 30 | -------------------------------------------------------------------------------- /tutorial/01/03.js: -------------------------------------------------------------------------------- 1 | describe('03 function isGoodGrade', () => { 2 | 3 | const isGoodGrade = filter.__get__('isGoodGrade'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(isGoodGrade).to.not.be.undefined; 7 | }); 8 | 9 | it('isn\'t a Function', () => { 10 | expect(isGoodGrade).to.be.a('function'); 11 | }); 12 | 13 | it('doesn\'t have any params', () => { 14 | expect(isGoodGrade.length).to.equal(1); 15 | }); 16 | 17 | it('doesn\'t return true when an items name matches "Ada Lovelace"', () => { 18 | const test = [{ 19 | grade: 'A' 20 | }, { 21 | grade: 'D' 22 | }, { 23 | grade: 'F' 24 | }, { 25 | grade: 'B' 26 | }]; 27 | expect(test.filter(isGoodGrade)).to.deep.equal([{ 28 | grade: 'A' 29 | }, { 30 | grade: 'B' 31 | }]); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /tutorial/05/03.js: -------------------------------------------------------------------------------- 1 | describe('03 function notInList', () => { 2 | 3 | const notInList = find.__get__('notInList'); 4 | 5 | it('should filter for student.name', () => { 6 | const regex = /[a-zA-Z]+\.name/; 7 | const str = notInList.toString(); 8 | expect(str.match(regex)).to.not.be.null; 9 | }); 10 | 11 | }); 12 | 13 | describe('03 const unknownStudent', () => { 14 | 15 | const unknownStudent = find.__get__('unknownStudent'); 16 | 17 | const otherStudents = ["Albert Gonzalez", "Brian Kernaghan", "Danielle Bunten Berry", "Donald Knuth", "Grace Hopper", "Hack Kerr", "James Gosling", "Ken Thompson", "Kevin Mitnick", "Linus Torvalds", "Niklaus Wirth", "Rebecca Heineman", "Tim Berners-Lee", "Xiao Tian", "Ying Cracker"]; 18 | 19 | it('should filter to "Web Security" class data', () => { 20 | expect(unknownStudent.name).to.equal('he'); 21 | }); 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /tutorial/02/myBest.js: -------------------------------------------------------------------------------- 1 | const myBest=[{ 2 | title:"Relational Databases", 3 | instructor:"Sean Quentin Lewis", 4 | name:"Ada Lovelace", 5 | score:91, 6 | grade:"A" 7 | },{ 8 | title:"3D Computer Graphics", 9 | instructor:"G.L. Webb", 10 | name:"Ada Lovelace", 11 | score:88, 12 | grade:"B" 13 | },{ 14 | title:"Web Security", 15 | instructor:"Sue Denim", 16 | name:"Ada Lovelace", 17 | score:81, 18 | grade:"B" 19 | },{ 20 | title:"Javascript Fundamentals", 21 | instructor:"Jay Kweerie", 22 | name:"Ada Lovelace", 23 | score:73, 24 | grade:"C" 25 | },{ 26 | title:"Algorithm Design", 27 | instructor:"Gale Shapely", 28 | name:"Ada Lovelace", 29 | score:93, 30 | grade:"A" 31 | },{ 32 | title:"Data Abstraction", 33 | instructor:"Aster Ricks", 34 | name:"Ada Lovelace", 35 | score:82, 36 | grade:"B" 37 | },{ 38 | title:"Data Structures", 39 | instructor:"Brodal Q.", 40 | name:"Ada Lovelace", 41 | score:88, 42 | grade:"B" 43 | }]; 44 | export default myBest; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coderoad-functional-school", 3 | "version": "1.1.3", 4 | "description": "Coderoad tutorial", 5 | "author": "Shawn McKay (http://shmck.com)", 6 | "contributers": [ 7 | "dimchez" 8 | ], 9 | "keywords": [ 10 | "coderoad", "tutorial", "functional" 11 | ], 12 | "main": "coderoad.json", 13 | "files": [ 14 | "coderoad.json", 15 | "tutorial" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/coderoad/coderoad-functional-school.git" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/coderoad/coderoad-functional-school/issues" 23 | }, 24 | "engines": { 25 | "node" : ">=4.0.0" 26 | }, 27 | "dependencies": { 28 | "chai": "3.5.0", 29 | "chai-spies": "0.7.1", 30 | "mocha": "3.0.2", 31 | "mocha-coderoad": "^0.10.0" 32 | }, 33 | "license": "MIT", 34 | "config": { 35 | "language": "JS", 36 | "dir": "tutorial", 37 | "testSuffix": ".js", 38 | "runner": "mocha-coderoad", 39 | "edit": true 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tutorial/03/05.js: -------------------------------------------------------------------------------- 1 | describe('05 function increaseScore', () => { 2 | 3 | const increaseScore = map.__get__('increaseScore'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(increaseScore).to.not.be.undefined; 7 | }); 8 | 9 | it('should be a function', () => { 10 | expect(increaseScore).to.be.a('function'); 11 | }); 12 | 13 | it('should take a parameter', () => { 14 | expect(increaseScore).to.have.length(1); 15 | }); 16 | 17 | it('shouldn\'t change scores under 95', () => { 18 | const test = { 19 | score: 82, 20 | grade: 'A', 21 | }; 22 | expect(increaseScore(test).score).to.equal(94); 23 | }); 24 | 25 | it('should change scores over 95 to 95', () => { 26 | const test = { 27 | score: 84, 28 | grade: 'A', 29 | }; 30 | expect(increaseScore(test).score).to.equal(95); 31 | }); 32 | 33 | }); 34 | 35 | describe('05 const mySlightlyChanged', () => { 36 | 37 | const mySlightlyChanged = map.__get__('mySlightlyChanged'); 38 | 39 | it('should cap scores at 95', () => { 40 | const scores = mySlightlyChanged.map((x) => x.score); 41 | expect(Math.max.apply(Math, scores)).to.equal(95); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /tutorial/06/06.js: -------------------------------------------------------------------------------- 1 | describe('06 const newSuspects', () => { 2 | 3 | const newSuspects = concat.__get__('newSuspects'); 4 | 5 | it('should have "Albert Gonzalez" in the list', () => { 6 | expect(newSuspects).to.contain('Albert Gonzalez'); 7 | }); 8 | 9 | it('should have "Kevin Mitnick" in the list', () => { 10 | expect(newSuspects).to.contain('Kevin Mitnick'); 11 | }); 12 | 13 | it('should have only 2 names', () => { 14 | expect(newSuspects).to.have.length(2); 15 | }); 16 | 17 | }); 18 | 19 | describe('06 const suspectData', () => { 20 | 21 | const suspectData = concat.__get__('suspectData'); 22 | 23 | it('should concat `newSuspects` onto `suspects`', () => { 24 | expect(suspectData).to.have.length(30); 25 | }); 26 | 27 | it('should filter if the `indexOf` the suspects name is greater than -1', () => { 28 | const kevin = suspectData.filter((x) => { 29 | return x.name === 'Kevin Mitnick'; 30 | }); 31 | expect(kevin).to.have.length(10); 32 | expect(kevin[0]).to.deep.equal({ 33 | grade: 'C', 34 | instructor: 'Sean Quentin Lewis', 35 | name: 'Kevin Mitnick', 36 | score: 72, 37 | title: 'Relational Databases' 38 | }); 39 | }); 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /tutorial/04/myFixed.js: -------------------------------------------------------------------------------- 1 | const myFixed = [{ 2 | title:"Relational Databases", 3 | instructor:"Sean Quentin Lewis", 4 | name:"Ada Lovelace", 5 | score:95, 6 | grade:"A" 7 | },{ 8 | title:"3D Computer Graphics", 9 | instructor:"G.L. Webb", 10 | name:"Ada Lovelace", 11 | score:95, 12 | grade:"A" 13 | },{ 14 | title:"Front End Web Development", 15 | instructor:"Moe Zaick", 16 | name:"Ada Lovelace", 17 | score:73, 18 | grade:"C" 19 | },{ 20 | title:"Web Security", 21 | instructor:"Sue Denim", 22 | name:"Ada Lovelace", 23 | score:93, 24 | grade:"A" 25 | },{ 26 | title:"Javascript Fundamentals", 27 | instructor:"Jay Kweerie", 28 | name:"Ada Lovelace", 29 | score:85, 30 | grade:"B" 31 | },{ 32 | title:"Data Science", 33 | instructor:"Ford Fulkerson", 34 | name:"Ada Lovelace", 35 | score:70, 36 | grade:"C" 37 | },{ 38 | title:"Algorithm Design", 39 | instructor:"Gale Shapely", 40 | name:"Ada Lovelace", 41 | score:95, 42 | grade:"A" 43 | },{ 44 | title:"Data Abstraction", 45 | instructor:"Aster Ricks", 46 | name:"Ada Lovelace", 47 | score:94, 48 | grade:"A" 49 | },{ 50 | title:"Data Structures", 51 | instructor:"Brodal Q.", 52 | name:"Ada Lovelace", 53 | score:95, 54 | grade:"A" 55 | },{ 56 | title:"Networks", 57 | instructor:"Van Emde Boas", 58 | name:"Ada Lovelace", 59 | score:77, 60 | grade:"C" 61 | }]; 62 | export default myFixed; 63 | -------------------------------------------------------------------------------- /tutorial/03/myCourses.js: -------------------------------------------------------------------------------- 1 | const myCourses=[{ 2 | title:"Relational Databases", 3 | instructor:"Sean Quentin Lewis", 4 | name:"Ada Lovelace", 5 | score:91, 6 | grade:"A" 7 | },{ 8 | title:"3D Computer Graphics", 9 | instructor:"G.L. Webb", 10 | name:"Ada Lovelace", 11 | score:88, 12 | grade:"B" 13 | },{ 14 | title:"Front End Web Development", 15 | instructor:"Moe Zaick", 16 | name:"Ada Lovelace", 17 | score:61, 18 | grade:"D" 19 | },{ 20 | title:"Web Security", 21 | instructor:"Sue Denim", 22 | name:"Ada Lovelace", 23 | score:81, 24 | grade:"B" 25 | },{ 26 | title:"Javascript Fundamentals", 27 | instructor:"Jay Kweerie", 28 | name:"Ada Lovelace", 29 | score:73, 30 | grade:"C" 31 | },{ 32 | title:"Data Science", 33 | instructor:"Ford Fulkerson", 34 | name:"Ada Lovelace", 35 | score:58, 36 | grade:"F" 37 | },{ 38 | title:"Algorithm Design", 39 | instructor:"Gale Shapely", 40 | name:"Ada Lovelace", 41 | score:93, 42 | grade:"A" 43 | },{ 44 | title:"Data Abstraction", 45 | instructor:"Aster Ricks", 46 | name:"Ada Lovelace", 47 | score:82, 48 | grade:"B" 49 | },{ 50 | title:"Data Structures", 51 | instructor:"Brodal Q.", 52 | name:"Ada Lovelace", 53 | score:88, 54 | grade:"B" 55 | },{ 56 | title:"Networks", 57 | instructor:"Van Emde Boas", 58 | name:"Ada Lovelace", 59 | score:65, 60 | grade:"D" 61 | }]; 62 | export default myCourses; 63 | -------------------------------------------------------------------------------- /tutorial/03/04.js: -------------------------------------------------------------------------------- 1 | describe('04 function increaseScore', () => { 2 | 3 | const increaseScore = map.__get__('increaseScore'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(increaseScore).to.not.be.undefined; 7 | }); 8 | 9 | it('should be a function', () => { 10 | expect(increaseScore).to.be.a('function'); 11 | }); 12 | 13 | it('should take a parameter', () => { 14 | expect(increaseScore).to.have.length(1); 15 | }); 16 | 17 | it('should try changing the `score` first before returning the changed object', () => { 18 | const regex = /return [a-zA-Z]+\.score/; 19 | const func = increaseScore.toString(); 20 | expect(func.match(regex)).to.be.null; 21 | }); 22 | 23 | it('should increment scores by 12 points', () => { 24 | const test = { 25 | score: 50, 26 | grade: 'D' 27 | }; 28 | expect(increaseScore(test).score).to.equal(62); 29 | }); 30 | 31 | }); 32 | 33 | describe('04 const mySlightlyChanged', () => { 34 | 35 | const mySlightlyChanged = map.__get__('mySlightlyChanged'); 36 | 37 | it('doesn\'t exist', () => { 38 | expect(mySlightlyChanged).to.not.be.undefined; 39 | }); 40 | 41 | it('isn\'t an array', () => { 42 | expect(mySlightlyChanged).to.be.an('array'); 43 | }); 44 | 45 | it('should increment scores by 12', () => { 46 | const scores = mySlightlyChanged.map((x) => x.score); 47 | expect(Math.min.apply(Math, scores)).to.equal(70); 48 | }); 49 | 50 | }); 51 | -------------------------------------------------------------------------------- /tutorial/03/02.js: -------------------------------------------------------------------------------- 1 | const map = require('BASE/03-map.js'); 2 | 3 | describe('02 function changeGrade', () => { 4 | 5 | const changeGrade = map.__get__('changeGrade'); 6 | 7 | it('doesn\'t exist', () => { 8 | expect(changeGrade).to.not.be.undefined; 9 | }); 10 | 11 | it('isn\'t a function', () => { 12 | expect(changeGrade).to.be.a('function'); 13 | }); 14 | 15 | it('should take a parameter', () => { 16 | expect(changeGrade).to.have.length(1); 17 | }); 18 | 19 | it('should try changing `course.grade` first before returning `course`', () => { 20 | const regex = /return [a-zA-Z]+\.grade/; 21 | const func = changeGrade.toString(); 22 | expect(func.match(regex)).to.be.null; 23 | }); 24 | 25 | it('doesn\'t return anything', () => { 26 | const test = { 27 | grade: 'D' 28 | }; 29 | expect(changeGrade(test)).to.not.be.undefined; 30 | }); 31 | 32 | it('should change grades from a D to an A', () => { 33 | const test = { 34 | grade: 'D' 35 | }; 36 | expect(changeGrade(test)).to.deep.equal({ 37 | grade: 'A' 38 | }); 39 | }); 40 | 41 | it('should change grades from a F to an A', () => { 42 | const test = { 43 | grade: 'F' 44 | }; 45 | expect(changeGrade(test)).to.deep.equal({ 46 | grade: 'A' 47 | }); 48 | }); 49 | 50 | it('should change grades from a B to an A', () => { 51 | const test = { 52 | grade: 'B' 53 | }; 54 | expect(changeGrade(test)).to.deep.equal({ 55 | grade: 'A' 56 | }); 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /tutorial/01/01.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | 3 | const students = require('BASE/data/students.js'); 4 | const filter = require('BASE/01-filter.js'); 5 | 6 | describe('01 function isAda', () => { 7 | 8 | const isAda = filter.__get__('isAda'); 9 | 10 | it('doesn\'t exist', () => { 11 | expect(isAda).to.not.be.undefined; 12 | }); 13 | 14 | it('isn\'t a Function', () => { 15 | expect(isAda).to.be.a('function'); 16 | }); 17 | 18 | it('doesn\'t take a parameter', () => { 19 | expect(isAda).to.have.length(1); 20 | }); 21 | 22 | it('doesn\'t return a boolean', () => { 23 | expect(isAda({name: 'Ada'})).to.be.a('boolean'); 24 | }); 25 | 26 | it('should match for name', () => { 27 | const regex1 = /\.name/; 28 | const regex2 = /\[.name.\]/; 29 | const string = isAda.toString(); 30 | const result = !!string.match(regex1) || !!string.match(regex2); 31 | expect(result).to.be.true; 32 | }); 33 | 34 | it('requires the full name "Ada Lovelace"', () => { 35 | const regex = /Ada Lovelace/; 36 | const string = isAda.toString(); 37 | expect(!!string.match(regex)).to.be.true; 38 | }); 39 | 40 | it('doesn\'t match student.name to "Ada Lovelace"', () => { 41 | const test = [{ 42 | name: 'Jane' 43 | }, { 44 | name: 'Joe' 45 | }, { 46 | name: 'Ada Lovelace' 47 | }]; 48 | expect(test.filter(isAda)).to.deep.equal([{ 49 | name: "Ada Lovelace" 50 | }]); 51 | }); 52 | 53 | }); 54 | -------------------------------------------------------------------------------- /tutorial/01/04.js: -------------------------------------------------------------------------------- 1 | describe('04 const myBest', () => { 2 | 3 | const myBest = filter.__get__('myBest'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(myBest).to.not.be.undefined; 7 | }); 8 | 9 | it('doesn\'t output an array', () => { 10 | expect(myBest).to.be.an('array'); 11 | }); 12 | 13 | it('doesn\'t output exactly seven items', () => { 14 | expect(myBest).to.have.length(7); 15 | }); 16 | 17 | it('isn\'t the right filtered data for "Ada Lovelace"', () => { 18 | expect(myBest).to.deep.equal([{ 19 | title: 'Relational Databases', 20 | instructor: 'Sean Quentin Lewis', 21 | name: 'Ada Lovelace', 22 | score: 91, 23 | grade: 'A' 24 | }, { 25 | title: '3D Computer Graphics', 26 | instructor: 'G.L. Webb', 27 | name: 'Ada Lovelace', 28 | score: 88, 29 | grade: 'B' 30 | }, { 31 | title: 'Web Security', 32 | instructor: 'Sue Denim', 33 | name: 'Ada Lovelace', 34 | score: 81, 35 | grade: 'B' 36 | }, { 37 | title: 'Javascript Fundamentals', 38 | instructor: 'Jay Kweerie', 39 | name: 'Ada Lovelace', 40 | score: 73, 41 | grade: 'C' 42 | }, { 43 | title: 'Algorithm Design', 44 | instructor: 'Gale Shapely', 45 | name: 'Ada Lovelace', 46 | score: 93, 47 | grade: 'A' 48 | }, { 49 | title: 'Data Abstraction', 50 | instructor: 'Aster Ricks', 51 | name: 'Ada Lovelace', 52 | score: 82, 53 | grade: 'B' 54 | }, { 55 | title: 'Data Structures', 56 | instructor: 'Brodal Q.', 57 | name: 'Ada Lovelace', 58 | score: 88, 59 | grade: 'B' 60 | }]); 61 | }); 62 | 63 | }); 64 | -------------------------------------------------------------------------------- /tutorial/00/setup.md: -------------------------------------------------------------------------------- 1 | ## Start 2 | Understanding the Data Set 3 | 4 | Over this tutorial series, we'll be changing and working with two different data sets. It'll be a big help to first understand what the data looks like. 5 | 6 | ```json 7 | var students = [ 8 | { 9 | "title": "Relational Databases", 10 | "instructor": "Sean Quentin Lewis", 11 | "name": "Ada Lovelace", 12 | "score": 91, 13 | "grade": "A" 14 | }, 15 | ... 16 | ] 17 | ``` 18 | 19 | Here we have an array of "student" objects. To get the first item in the array, you can use the array index. Array indexes start at 0. 20 | 21 | ```js 22 | console.log( 23 | 'first instructor', students[0].instructor 24 | ); 25 | // first instructor Sean Quentin Lewis 26 | ``` 27 | 28 | + Look in "data/students.js". This is the data we will be working with. Run save to continue. 29 | @test('00/01') 30 | @action(writeFromFile('data/students.js', '00/data.js')) 31 | 32 | + Set `first` to the first item in the `students` array. 33 | @test('00/02') 34 | @action(open('setup.js')) 35 | @action(set( 36 | ``` 37 | // Welcome to CodeRoad! 38 | const students = require('./data/students').default; 39 | 40 | var first = ::> 41 | ``` 42 | )) 43 | @hint('Get the first item in students using the array index') 44 | @hint('Access the title of `students[0]`') 45 | 46 | 47 | + Set `myName` to the "name" of the first student in the list. 48 | @test('00/03') 49 | @action(insert( 50 | ``` 51 | var myName = ::> 52 | ``` 53 | )) 54 | @hint('Get the first "name" in the students using the array index') 55 | @hint('Access the "name" of `first`') 56 | @hint('Try `first.name`') 57 | 58 | + Log your name to the console. 59 | @test('00/04') 60 | @action(insert( 61 | ``` 62 | 63 | console.log(::>); 64 | ``` 65 | )) 66 | @hint('Use `console.log`') 67 | @hint('Use `console.log(myName)`') 68 | 69 | 70 | @onPageComplete('Now we're ready to get started with `filter`ing our data.') 71 | -------------------------------------------------------------------------------- /tutorial/01/02.js: -------------------------------------------------------------------------------- 1 | describe('02 const myData', () => { 2 | 3 | const myData = filter.__get__('myData'); 4 | 5 | it('doesn\'t exist', () => { 6 | expect(myData).to.not.be.undefined; 7 | }); 8 | 9 | it('doesn\'t output an array', () => { 10 | expect(myData).to.be.an('array'); 11 | }); 12 | 13 | it('doesn\'t output exactly ten items', () => { 14 | expect(myData).to.have.length(10); 15 | }); 16 | 17 | it('isn\'t the right filtered data for "Ada Lovelace"', () => { 18 | expect(myData).to.deep.equal([{ 19 | title: 'Relational Databases', 20 | instructor: 'Sean Quentin Lewis', 21 | name: 'Ada Lovelace', 22 | score: 91, 23 | grade: 'A' 24 | }, { 25 | title: '3D Computer Graphics', 26 | instructor: 'G.L. Webb', 27 | name: 'Ada Lovelace', 28 | score: 88, 29 | grade: 'B' 30 | }, { 31 | title: 'Front End Web Development', 32 | instructor: 'Moe Zaick', 33 | name: 'Ada Lovelace', 34 | score: 61, 35 | grade: 'D' 36 | }, { 37 | title: 'Web Security', 38 | instructor: 'Sue Denim', 39 | name: 'Ada Lovelace', 40 | score: 81, 41 | grade: 'B' 42 | }, { 43 | title: 'Javascript Fundamentals', 44 | instructor: 'Jay Kweerie', 45 | name: 'Ada Lovelace', 46 | score: 73, 47 | grade: 'C' 48 | }, { 49 | title: 'Data Science', 50 | instructor: 'Ford Fulkerson', 51 | name: 'Ada Lovelace', 52 | score: 58, 53 | grade: 'F' 54 | }, { 55 | title: 'Algorithm Design', 56 | instructor: 'Gale Shapely', 57 | name: 'Ada Lovelace', 58 | score: 93, 59 | grade: 'A' 60 | }, { 61 | title: 'Data Abstraction', 62 | instructor: 'Aster Ricks', 63 | name: 'Ada Lovelace', 64 | score: 82, 65 | grade: 'B' 66 | }, { 67 | title: 'Data Structures', 68 | instructor: 'Brodal Q.', 69 | name: 'Ada Lovelace', 70 | score: 88, 71 | grade: 'B' 72 | }, { 73 | title: 'Networks', 74 | instructor: 'Van Emde Boas', 75 | name: 'Ada Lovelace', 76 | score: 65, 77 | grade: 'D' 78 | }]); 79 | }); 80 | 81 | }); 82 | -------------------------------------------------------------------------------- /tutorial/02/sort.md: -------------------------------------------------------------------------------- 1 | ## Sort 2 | Array -> sorted Array 3 | 4 | Your grades are filtered down to your name and good scores - but wouldn't it be better if your best grades were displayed first, at the top? Besides, your parents rarely read anything through. 5 | 6 | You can use the array method `sort` to arrange your data. Let's see how it works. 7 | 8 | ```js 9 | ['c', 'b', 'a'].sort(); 10 | //> ['a', 'b', 'c'] 11 | 12 | [3, 2, 1].sort(); 13 | //> [1, 2, 3] 14 | ``` 15 | 16 | But what about sorting scores inside of an object? 17 | 18 | ```js 19 | [{a: 3}, {a: 1}, {a: 2}].sort(); 20 | //> [{a: 3}, {a: 1}, {a: 2}] 21 | ``` 22 | 23 | That didn't work. Instead, you can write a custom `compareScore` function. 24 | 25 | A sort function takes two params, and compares the first to the second. It should return values saying where the second value should go in the array: 26 | 27 | * -1 : sort to a lower index (front) 28 | * 1 : sort to a higher index (back) 29 | * 0 : stay the same 30 | 31 | Alright, now time to sort your best grades to the top. 32 | 33 | First you'll need to write a sort condition function called `compareScore`. 34 | 35 | + look at the data we will work with next: `myBest`. Save to continue. 36 | @test('02/01') 37 | @action(writeFromFile('data/myBest.js', '02/myBest.js')) 38 | @open('data/myBest.js') 39 | 40 | + `compareScore` should return 1 if the first score is less than the second 41 | @test('02/02') 42 | @action(open('02-sort.js')) 43 | @action(set( 44 | ``` 45 | import myBest from './data/myBest'; 46 | // Array.sort(fn) 47 | 48 | function compareScore(a, b) { 49 | switch (true) { 50 | case b.score > a.score: 51 | // it should return 1 if b's score is more than a's 52 | return ::> 53 | case 'set condition here': 54 | // it should return -1 if b's score is less than a's 55 | 56 | default: 57 | // it should return 0 if b and a have the same score 58 | 59 | } 60 | } 61 | ``` 62 | )) 63 | + `compareScore` should return -1 if the first score is more than the second 64 | @test('02/03') 65 | @hint('set the second case to `b.score < a.score`') 66 | 67 | + `compareScore` should return 0 if the first score is the same as the second 68 | @test('02/04') 69 | @hint('no case is necessary, use the `default` case') 70 | 71 | + Set `mySorted` to the result of `myBest` sorted by `compareScore` 72 | @test('02/05') 73 | @action(insert( 74 | ``` 75 | // use the compare function to sort myBest 76 | const mySorted = myBest::> 77 | ``` 78 | )) 79 | @hint('try using `myBest.sort()`') 80 | 81 | @onPageComplete('In the next step we'll look at changing data with `map`') 82 | -------------------------------------------------------------------------------- /tutorial/05/find.md: -------------------------------------------------------------------------------- 1 | ## find 2 | Array -> first element that matches a condition 3 | 4 | Somehow your name has disappeared from the computer system. We'll have to `find` a way to get it back. 5 | 6 | You quickly put together a list of other students in class. If someone changed your name, it'll be the name that is not in that list. 7 | 8 | `find` works similar to `filter`, but returns only the first match. 9 | 10 | ```js 11 | const data = [1, 2, 3, 4, 5, 6]; 12 | 13 | function isEven(num) { 14 | return num % 2 === 0; 15 | } 16 | 17 | // returns all matching data to a condition 18 | data.filter(isEven); 19 | //> [2, 4, 6] 20 | 21 | // returns the first match 22 | data.find(isEven); 23 | //> [2] 24 | ``` 25 | 26 | Find is great for performantly matching unique values in data, such as an "id", or in our case: a name. 27 | 28 | + load "students" data. Save to continue. 29 | @test('05/01') 30 | @action(writeFromFile('data/myCourses2.js', '05/courses.js')) 31 | @action(open('data/myCourses2.js')) 32 | 33 | + `filter` to `courses` in the class titled "Web Security" 34 | @test('05/02') 35 | @action(open('05-find.js')) 36 | @action(set( 37 | ``` 38 | import courses from './data/myCourses2'; 39 | // Array.find(fn) 40 | 41 | // filter for the course title matching "Web Security" 42 | const myClass = courses.filter(::>); 43 | ``` 44 | )) 45 | @hint('create a `filter` function that takes a param `course`') 46 | @hint('return `true` if a condition matches, otherwise `false`') 47 | @hint('filter for `course.title === "Web Security"`') 48 | 49 | + `find` the name in `myClass` that isn't in the list of known students 50 | @test('05/03') 51 | @action(insert( 52 | ``` 53 | 54 | const otherStudents = ["Albert Gonzalez", "Brian Kernaghan", "Danielle Bunten Berry", "Donald Knuth", "Grace Hopper", "Hack Kerr", "James Gosling", "Ken Thompson", "Kevin Mitnick", "Linus Torvalds", "Niklaus Wirth", "Rebecca Heineman", "Tim Berners-Lee", "Xiao Tian", "Ying Cracker"]; 55 | 56 | ``` 57 | )) 58 | @action(insert( 59 | ``` 60 | // search for a student with a name 61 | // not matching students in `otherStudents` 62 | function notInList(::>) { 63 | 64 | } 65 | 66 | // find using `notInList` 67 | const unknownStudent = myClass.find(); 68 | ``` 69 | )) 70 | @hint('use `indexOf` to find what doesn't match') 71 | @hint('use `otherStudents.indexOf(x) === -1` to find what doesn't match') 72 | @hint('match for `student.name`') 73 | 74 | + `filter` down to students from courses without known names 75 | @test('05/04') 76 | @action(insert( 77 | ``` 78 | 79 | // filter using `notInList` 80 | const unknownStudentList = courses.filter(::>); 81 | ``` 82 | )) 83 | @hint('consider reusing a function') 84 | 85 | + `map` over the result to get only the `name` property 86 | @test('05/05') 87 | @action(insert( 88 | ``` 89 | 90 | // list only student names 91 | const unknownStudentNames = unknownStudentList.map(::>); 92 | ``` 93 | )) 94 | @hint('use `map` to return only the `student.name`') 95 | @hint('try this inside of your map call: `student => student.name`') 96 | 97 | + `join('')` the array of names to output the result as a string 98 | @test('05/06') 99 | @action(insert( 100 | ``` 101 | 102 | // use `.join('')` to join the array of strings 103 | const decodedName = unknownStudentNames::>; 104 | console.log(decodedName); 105 | ``` 106 | )) 107 | @hint('call `join` following `unknownStudentNames`') 108 | 109 | @onPageComplete('Very strange. In the next step, let's find out who wants revenge, and give it to him!') 110 | -------------------------------------------------------------------------------- /tutorial/01/filter.md: -------------------------------------------------------------------------------- 1 | ## Filter 2 | Array -> Array of items that match a condition 3 | 4 | You've hacked into the school's computer system, and just in time. The grades are in, but you're not too proud of your performance. That's okay, you have a plan: you're going to create a fake report card. 5 | 6 | It would be great if you could `filter` the scores that your parents will see. 7 | 8 | `filter` takes a matching condition function and only returns items that result in true. As an example, look at `isA` below: 9 | 10 | ```js 11 | function isA(x) { 12 | return x === 'a'; 13 | } 14 | ``` 15 | 16 | 17 | Like all of the methods in this chapter, `filter` is already part of the `Array.prototype`, so you can run it following any array. Each item in the array is passed into the params of the condition function, one by one. [Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). 18 | 19 | ```js 20 | const list = ['a', 'b']; 21 | list.filter(isA); 22 | 23 | // if isA(list[0]), add to output array 24 | // if isA(list[1]), add to output array 25 | // 26 | //> ['a'] 27 | ``` 28 | 29 | If your data was composed of objects, we could use dot notation to find matches. Checkout `isB` below. 30 | 31 | ```js 32 | function isB(x) { 33 | return x.item === 'b' 34 | } 35 | 36 | const list = [{item: 'a'}, {item: 'b'}]; 37 | list.filter(isB); 38 | //> [{item: 'b'}] 39 | ``` 40 | 41 | Where were we? Back to filtering our grades. 42 | 43 | There's too much student data in the computer system. We'll have to sort through it. Have a look at an example below: 44 | 45 | ```js 46 | console.log(students[0]); 47 | //> { course: 'Web Security', 48 | // instructor: 'Sue Denim', 49 | // name: 'Rebecca Heineman', 50 | // score: 93, 51 | // grade: 'A' } 52 | ``` 53 | 54 | + Write a filter condition function called `isAda` that returns true only if the name matches your name: "Ada Lovelace". 55 | @test('01/01') 56 | @action(open('01-filter.js')) 57 | @action(set( 58 | ``` 59 | import students from './data/students'; 60 | // Array.filter(fn) 61 | 62 | function isAda(student) { 63 | // return true if student name 64 | // matches "Ada Lovelace" 65 | ::> 66 | } 67 | ``` 68 | )) 69 | @hint('Some tasks have hints') 70 | @hint('Check if `student.name` matches "Ada Lovelace"') 71 | @hint('Use `===` to check equality') 72 | 73 | + Set `const myData` to filter with the `isAda` function. 74 | @test('01/02') 75 | @action(insert( 76 | ``` 77 | // run the function name in filter 78 | const myData = students.filter(::>); 79 | ``` 80 | )) 81 | @hint('Add a function to the `filter` call: `Array.filter(function() {})`') 82 | @hint('Pass `isAda` into your `filter` call') 83 | 84 | + Write a filter condition called `isGoodGrade` that will filter out any "D" or "F" grades. 85 | @test('01/03') 86 | @action(insert( 87 | ``` 88 | 89 | 90 | // return true if student.grade is not a "D" or "F" 91 | function isGoodGrade(student) { 92 | ::> 93 | } 94 | ``` 95 | )) 96 | @hint('match for `student.grade` that isn't "D" or "F"') 97 | @hint('use `!==` to check non-equality') 98 | @hint('Match for both: `student.grade !== "D" && student.grade !== "F"`') 99 | 100 | + Set `const myBest` to your scores, excluding any grades that are "D" or "F". 101 | 102 | @test('01/04') 103 | @action(insert( 104 | ``` 105 | // filter out "D"'s and "F"'s here 106 | const myBest = myData.filter(::>); 107 | 108 | ``` 109 | )) 110 | 111 | @onPageComplete('In the next step we'll look at how to `sort` data') 112 | -------------------------------------------------------------------------------- /tutorial/07/suspectData.js: -------------------------------------------------------------------------------- 1 | const suspectData = [{ 2 | title:"Relational Databases", 3 | instructor:"Sean Quentin Lewis", 4 | name:"Albert Gonzalez", 5 | score:35, 6 | grade:"F" 7 | }, { 8 | title:"Relational Databases", 9 | instructor:"Sean Quentin Lewis", 10 | name:"Hack Kerr", 11 | score:85, 12 | grade:"F" 13 | }, { 14 | title:"Relational Databases", 15 | instructor:"Sean Quentin Lewis", 16 | name:"Kevin Mitnick", 17 | score:72, 18 | grade:"C" 19 | }, { 20 | title:"3D Computer Graphics", 21 | instructor:"G.L. Webb", 22 | name:"Albert Gonzalez", 23 | score:37, 24 | grade:"F" 25 | }, { 26 | title:"3D Computer Graphics", 27 | instructor:"G.L. Webb", 28 | name:"Hack Kerr", 29 | score:86, 30 | grade:"F" 31 | }, { 32 | title:"3D Computer Graphics", 33 | instructor:"G.L. Webb", 34 | name:"Kevin Mitnick", 35 | score:52, 36 | grade:"F" 37 | }, { 38 | title:"Front End Web Development", 39 | instructor:"Moe Zaick", 40 | name:"Albert Gonzalez", 41 | score:73, 42 | grade:"C" 43 | }, { 44 | title:"Front End Web Development", 45 | instructor:"Moe Zaick", 46 | name:"Hack Kerr", 47 | score:92, 48 | grade:"C" 49 | }, { 50 | title:"Front End Web Development", 51 | instructor:"Moe Zaick", 52 | name:"Kevin Mitnick", 53 | score:47, 54 | grade:"F" 55 | }, { 56 | title:"Web Security", 57 | instructor:"Sue Denim", 58 | name:"Albert Gonzalez", 59 | score:74, 60 | grade:"C" 61 | }, { 62 | title:"Web Security", 63 | instructor:"Sue Denim", 64 | name:"Hack Kerr", 65 | score:75, 66 | grade:"F" 67 | }, { 68 | title:"Web Security", 69 | instructor:"Sue Denim", 70 | name:"Kevin Mitnick", 71 | score:89, 72 | grade:"B" 73 | }, { 74 | title:"Javascript Fundamentals", 75 | instructor:"Jay Kweerie", 76 | name:"Albert Gonzalez", 77 | score:94, 78 | grade:"A" 79 | }, { 80 | title:"Javascript Fundamentals", 81 | instructor:"Jay Kweerie", 82 | name:"Hack Kerr", 83 | score:83, 84 | grade:"F" 85 | }, { 86 | title:"Javascript Fundamentals", 87 | instructor:"Jay Kweerie", 88 | name:"Kevin Mitnick", 89 | score:47, 90 | grade:"F" 91 | },{ 92 | title:"Data Science", 93 | instructor:"Ford Fulkerson", 94 | name:"Albert Gonzalez", 95 | score:67, 96 | grade:"D" 97 | }, { 98 | title:"Data Science", 99 | instructor:"Ford Fulkerson", 100 | name:"Hack Kerr", 101 | score:96, 102 | grade:"A" 103 | }, { 104 | title:"Data Science", 105 | instructor:"Ford Fulkerson", 106 | name:"Kevin Mitnick", 107 | score:75, 108 | grade:"C" 109 | }, { 110 | title:"Algorithm Design", 111 | instructor:"Gale Shapely", 112 | name:"Albert Gonzalez", 113 | score:39, 114 | grade:"F" 115 | }, { 116 | title:"Algorithm Design", 117 | instructor:"Gale Shapely", 118 | name:"Hack Kerr", 119 | score:94, 120 | grade:"A" 121 | }, { 122 | title:"Algorithm Design", 123 | instructor:"Gale Shapely", 124 | name:"Kevin Mitnick", 125 | score:81, 126 | grade:"B" 127 | }, { 128 | title:"Data Abstraction", 129 | instructor:"Aster Ricks", 130 | name:"Albert Gonzalez", 131 | score:70, 132 | grade:"C" 133 | }, { 134 | title:"Data Abstraction", 135 | instructor:"Aster Ricks", 136 | name:"Hack Kerr", 137 | score:87, 138 | grade:"F" 139 | }, { 140 | title:"Data Abstraction", 141 | instructor:"Aster Ricks", 142 | name:"Kevin Mitnick", 143 | score:41, 144 | grade:"F" 145 | }, { 146 | title:"Data Structures", 147 | instructor:"Brodal Q.", 148 | name:"Albert Gonzalez", 149 | score:56, 150 | grade:"F" 151 | },{ 152 | title:"Data Structures", 153 | instructor:"Brodal Q.", 154 | name:"Hack Kerr", 155 | score:89, 156 | grade:"B" 157 | },{ 158 | title:"Data Structures", 159 | instructor:"Brodal Q.", 160 | name:"Kevin Mitnick", 161 | score:40, 162 | grade:"F" 163 | }, { 164 | title:"Networks", 165 | instructor:"Van Emde Boas", 166 | name:"Albert Gonzalez", 167 | score:52, 168 | grade:"F" 169 | }, { 170 | title:"Networks", 171 | instructor:"Van Emde Boas", 172 | name:"Hack Kerr", 173 | score:102, 174 | grade:"F" 175 | }, { 176 | title:"Networks", 177 | instructor:"Van Emde Boas", 178 | name:"Kevin Mitnick", 179 | score:37, 180 | grade:"F" 181 | }]; 182 | export default suspectData; 183 | -------------------------------------------------------------------------------- /tutorial/06/concat.md: -------------------------------------------------------------------------------- 1 | ## concat 2 | Array + Array -> Array 3 | 4 | Before we've been working on a structured set of student data. 5 | 6 | ```js 7 | // array of students 8 | [ 9 | { 10 | "title": "Relational Databases", 11 | "instructor": "Sean Quentin Lewis", 12 | "name": "Rebecca Heineman", 13 | "score": 71, 14 | "grade": "C" 15 | } 16 | // students in courses... 17 | ] 18 | ``` 19 | 20 | To be safe, let's now work on the original data set. Notice how it is structured differently. 21 | 22 | ```js 23 | // array of courses 24 | [ 25 | { 26 | "title": "Relational Databases", 27 | "instructor": "Sean Quentin Lewis", 28 | "students": [ 29 | { 30 | "name": "Rebecca Heineman", 31 | "score": 71, 32 | "grade": "C" 33 | } 34 | // students... 35 | ] 36 | } 37 | // courses... 38 | ] 39 | ``` 40 | 41 | In this data set, there is an array of students within an array of courses. So how can we recreate our original array of students from the courses? 42 | 43 | Weird things happen when you start combining arrays. We can use `concat` to bring sanity. 44 | 45 | ```js 46 | [1, 2] + [3, 4]; 47 | //> "1, 23, 4" 48 | 49 | [1, 2].push([3, 4]); 50 | //> 3 51 | 52 | [1, 2].join([3, 4]); 53 | //> "13, 42" 54 | 55 | [1, 2].concat([3, 4]); 56 | //> [1, 2, 3, 4] 57 | ``` 58 | 59 | Unfortunately, Javascript is missing a built in array method to concat multiple arrays together: let's call it `flatten` (sometimes called `concatAll`). 60 | 61 | `flatten` should loop over an array and `concat` each element. 62 | 63 | Let's look at an abstraction of what we need to do: 64 | 65 | ```js 66 | const start = [{ 67 | a: 1, 68 | c: [ 69 | { b: 1 } 70 | ] 71 | }, { 72 | a: 2, 73 | c: [ 74 | { b: 2 }, { b: 3 } 75 | ] 76 | }]; 77 | 78 | const middle = start.map(function(outer) { 79 | return outer.c.map(function(inner) { 80 | return { 81 | a: outer.a, 82 | b: inner.b 83 | }; 84 | }); 85 | }); 86 | //> [ [{ a: 1, b: 1 }], [{a: 2, b: 2}, {a: 2, b: 3}] ] 87 | 88 | const end = pre.flatten(); 89 | //> [{a: 1, b: 1}, {a: 2, b: 2}, {a: 2, b: 3}] 90 | ``` 91 | 92 | Back to business. 93 | 94 | We have a suspect in mind: a classmate named "Hack Kerr". He's a nice guy, and he's always been friendly to you - but there's something suspicious about him: his name. 95 | 96 | We'll test out flatten, then re-create our student array of data from the original course data. 97 | 98 | + load "courses" 99 | @test('06/01') 100 | @action(writeFromFile('data/courses2.js', '06/courses2.js')) 101 | @action(open('data/courses2.js')) 102 | 103 | + First, test out `flatten` on the `flattenedArray` 104 | @test('06/02') 105 | @action(open('06-concat.js')) 106 | @action(set( 107 | ``` 108 | import courses from './data/courses2'); 109 | // Array.concat(any) 110 | 111 | // Array.prototype can be used to create new Array methods 112 | Array.prototype.flatten = function() { 113 | return this.reduce((a, b) => a.concat(b), []); 114 | }; 115 | ``` 116 | )) 117 | @action(insert( 118 | ``` 119 | 120 | const numberedList = [[1, 2], [3, 4]]; 121 | 122 | // use `flatten` on `numberedList` 123 | const flattenedArray = numberedList::>; 124 | ``` 125 | )) 126 | @hint('call `.flatten()` on `numberedList`') 127 | 128 | 129 | + Now `map` over the courses array, and `map` over the students array inside of it. 130 | Return the fields: 131 | 132 | * title 133 | * instructor 134 | * name 135 | * grade 136 | * score 137 | @test('06/03') 138 | @action(insert( 139 | ``` 140 | 141 | // map over courses then 142 | // map over students inside of courses 143 | const doubleArray = courses.map((course) => { 144 | return course.students.map((student) => { 145 | return { 146 | // fill in the fields 147 | title: ::>'', 148 | instructor: '', 149 | name: '', 150 | score: '', 151 | grade: '' 152 | }; 153 | }); 154 | }); 155 | 156 | ``` 157 | )) 158 | @hint('pair `course.title`') 159 | @hint('pair `student.name`') 160 | 161 | + Use `flatten` to put all data into a single array. Set `students` to the result. 162 | @test('06/04') 163 | @action(insert( 164 | ``` 165 | // `flatten` doubleArray 166 | const students = doubleArray::>; 167 | ``` 168 | )) 169 | @hint('call `.flatten()` on `doubleArray`') 170 | 171 | + Use the `suspects` array to `filter` to only data matching the names in the `suspects` array 172 | @test('06/05') 173 | @action(insert( 174 | ``` 175 | 176 | const suspects = ["Hack Kerr"]; 177 | // filter to data matching `suspects` 178 | 179 | const suspectData = students::>; 180 | ``` 181 | )) 182 | 183 | + You just thought of two more suspects! Make a new variable called `newSuspects` and add it above `suspects`. 184 | 185 | ```js 186 | const newSuspects = ['Albert Gonzalez', 'Kevin Mitnick']; 187 | ``` 188 | 189 | `concat` the `newSuspects` onto the `suspects` list. 190 | @test('06/06') 191 | @hint('call `suspects.concat()` with `newSuspects`') 192 | 193 | @onPageComplete('In the next step, we'll look at using one of the most powerful methods: `reduce`') 194 | -------------------------------------------------------------------------------- /tutorial/04/forEach.md: -------------------------------------------------------------------------------- 1 | ## forEach 2 | Array -> run a function for each item 3 | 4 | You've updated your grades, but they're still in an array. It's time to loop over them and log them to the console. 5 | 6 | To open the console, go to *View* > *Developer* > *Toggle Developer Tools*. Or press *cmd+opt+I* on Mac, *ctrl+alt+I* on Windows. 7 | 8 | `forEach` has a lot in common with `map`, but there is a big difference. Understanding that difference is important for grasping the difference between: 9 | 10 | * **functional** & **imperative** programming 11 | * **pure** & **impure** functions 12 | 13 | Know it or not, you're probably already used to "imperative" programming. 14 | 15 | > **Imperative** programming describes the order of actions 16 | 17 | Imperative code tells the computer what to do, step by step. 18 | 19 | ```js 20 | let x = 1; // make a variable 21 | x = x + 1; // add one 22 | x = x + 1; // add another 23 | console.log(x); 24 | //> 3 25 | ``` 26 | 27 | > **Functional** programming describes the data transformation 28 | 29 | Functional programming is a lot like writing math equations. As in math, 1 + 1 always equals 2. 30 | 31 | In the same way, a **pure** function will always have the same result from a given input. Input 1 -> output 2. Every time. 32 | 33 | ```js 34 | // a pure function 35 | function addOne(x) { 36 | return x + 1; 37 | } 38 | addOne(1) 39 | //> 2 40 | addOne(1) 41 | //> 2 42 | ``` 43 | 44 | A function is "pure" if it doesn't change anything outside of its scope. Pure functions are easy to test, reuse and reason about. In other words, they make your job easier. 45 | 46 | On the other hand, **impure** functions are less predictable. The result may be different if you call it at a later time. 47 | 48 | ```js 49 | let y = 1; 50 | // impure function 51 | function increment(x) { 52 | y += x; 53 | return y; 54 | } 55 | increment(1) 56 | //> 2 57 | increment(1) 58 | //> 3 59 | ``` 60 | 61 | It's good practice to ensure your `map` functions remain pure. 62 | 63 | But `forEach` can be a little more dangerous. Why? Let's have a look. 64 | 65 | ```js 66 | [1, 2, 3].map(addOne); 67 | //> [2, 3, 4] 68 | 69 | [1, 2, 3].forEach(addOne); 70 | //> undefined 71 | ``` 72 | 73 | What? `undefined`? `forEach` runs a function on each item in the array, and doesn't care what the function returns. Functions called by `forEach` must make changes, called **side effects**, to even be noticed. 74 | 75 | ```js 76 | // impure function, changes log 77 | function addOneToLog(x) { 78 | console.log(x); 79 | } 80 | 81 | [1, 2, 3].forEach(addOneToLog); 82 | //> 2 83 | //> 3 84 | //> 4 85 | ``` 86 | 87 | Now that we see how `forEach` works, let's use it to make calls to the `console`. 88 | 89 | + checkout the data we'll use next: "myFixed". Save to continue. 90 | @test('04/01') 91 | @action(writeFromFile('data/myFixed.js', '04/myFixed.js')) 92 | @action(open('data/myFixed.js')) 93 | 94 | + Use `forEach` to log out your report card to the console 95 | @test('04/02') 96 | @action(open('04-forEach.js')) 97 | @action(set( 98 | ``` 99 | import myFixed from './data/myFixed'; 100 | // Array.forEach(fn) 101 | 102 | function logCourse(course) { 103 | console.log(`${course.grade} ${course.score} ${course.title}`); 104 | } 105 | 106 | // log your grades to the console 107 | myFixed.forEach(::>); 108 | ``` 109 | )) 110 | @hint('call `forEach` with `logCourse`') 111 | 112 | + Add a second parameter to `logCourseWithIndex` called `index`. Then call the function with `myFixed.forEach`. 113 | @test('04/03') 114 | @action(insert( 115 | ``` 116 | 117 | // add a second param called 'index' to the function 118 | function logCourseWithIndex(course::>) { 119 | console.log(`${index + 1} ${course.grade} ${course.score} ${course.title}`); 120 | } 121 | 122 | // log your grades to the console with an index 123 | myFixed.forEach(logCourseWithIndex); 124 | ``` 125 | )) 126 | @hint('Array methods can take more than one parameter') 127 | @hint('Add a second parameter to `logCourseWithIndex`') 128 | 129 | + Add a third parameter called `array` to `logCourseWithIndexAndArray`, then call the function with `myFixed.forEach`. 130 | @test('04/04') 131 | @action(insert( 132 | ``` 133 | 134 | // add a third param called 'array' to the function 135 | function logCourseWithIndexAndArray(course, index::>) { 136 | console.log(`${index + 1}/${array.length} ${course.grade} ${course.score} ${course.title}`); 137 | } 138 | 139 | // log your grades to the console with an index and array length 140 | myFixed.forEach(logCourseWithIndexAndArray); 141 | ``` 142 | )) 143 | @hint('Array methods can take more than one parameter') 144 | @hint('Add a third parameter to `logCourseWithIndexAndArray`') 145 | 146 | + What??? Suddenly Your data has all disappeared! 147 | 148 | It seems `myFixed` relies on a chain of methods. 149 | 150 | ```js 151 | myFixed = students 152 | .filter(isAda) 153 | .sort(compareScore) 154 | .map(increaseScore) 155 | .map(getGrade) 156 | .forEach(logCourseWithIndexAndArray) 157 | ``` 158 | 159 | This is why side-effects are dangerous. Students data must have changed, and now all of your transformations are effected. 160 | 161 | @test('04/05') 162 | @action(insert( 163 | ``` 164 | 165 | console.log(myFixed); 166 | ``` 167 | )) 168 | 169 | @onPageComplete('Something strange is going on. In the next step we'll try to `find` your data.') 170 | -------------------------------------------------------------------------------- /tutorial/03/map.md: -------------------------------------------------------------------------------- 1 | ## Map 2 | Array -> run a function over each item -> Array 3 | 4 | You've filtered and sorted our data, but neither of those actually change the data. 5 | 6 | Wouldn't it be simpler if you could just change your grades? 7 | 8 | You can use the array method `map` to run a function that returns changes to your data. 9 | 10 | As an example, let's look at how you would increment each number in an array. 11 | 12 | ```js 13 | function addOne(num) { 14 | return num + 1; 15 | } 16 | 17 | [1, 2, 3].map(addOne); 18 | //> [2, 3, 4] 19 | 20 | function addToVal(obj) { 21 | obj.val += 1; 22 | return obj; 23 | } 24 | [{ val: 1}].map(addToVal); 25 | //> [{ val: 2 }] 26 | ``` 27 | 28 | `map` can change data, and it can also alter structure of the data you're working with. 29 | 30 | ```js 31 | function makeObject(num) { 32 | return { val: num }; 33 | } 34 | 35 | [1, 2].map(makeObject); 36 | //> [{ val: 1 }, { val: 2 }] 37 | ``` 38 | 39 | Similarly, `map` can also restrict the data you want to work with. See the example below to see another way scores could be sorted. 40 | 41 | ```js 42 | myBest 43 | .map(function(student) { 44 | return student.score; 45 | }) 46 | .sort() 47 | .reverse() 48 | //> [93, 91, 88, 88, 82, 81, 73] 49 | ``` 50 | 51 | In this example, `map` transformed an object with keys of 'title', 'instructor', 'name', 'score' and 'grade', to an array of just scores. Values weren't changed, but rather limited to a smaller subset of scores. 52 | 53 | `map` is powerful. Let's see what you can do with it. 54 | 55 | Those D & F grades would look a lot better if they suddenly became A's. 56 | 57 | Let's go back to before we filtered out the bad grades, and instead change the grades to A's. 58 | 59 | + load "myCourses" 60 | @test('03/01') 61 | @action(writeFromFile('data/myCourses.js', '03/myCourses.js')) 62 | @action(open('data/myCourses.js')) 63 | 64 | + Make a function `changeGrade` that takes a course and changes the grade to an "A" 65 | @test('03/02') 66 | @action(open('03-map.js')) 67 | @action(set( 68 | ``` 69 | import myCourses from './data/myCourses'; 70 | // Array.map(fn) 71 | 72 | /* 73 | * change any the `course.grade` into an 'A' 74 | * 75 | * for example: 76 | * changeGrade({ grade: 'F' }) === { grade: 'A' }; 77 | */ 78 | 79 | function changeGrade(course) { 80 | ::> 81 | } 82 | 83 | ``` 84 | )) 85 | @hint('give `changeGrade` a parameter, call it "course"') 86 | @hint('set `course.grade` to "A"') 87 | @hint('return the changed course') 88 | 89 | 90 | + Map over the `myCourses` with the `changeGrade` function. Set `myChanged` to the result. 91 | @test('03/03') 92 | @action(insert( 93 | ``` 94 | // map over `myCourses` and call `changeGrade` for each item 95 | const myChanged = myCourses.map(::>); 96 | ``` 97 | )) 98 | @hint('simply call `.map(changeGrade)`') 99 | 100 | 101 | + Hold up. An A in "Data Science" class looks way to suspicious. Your parents might catch on to your cheating. 102 | 103 | Let's go back to `myCourses` and instead increment each score by 12 points. 104 | @test('03/04') 105 | @action(insert( 106 | ``` 107 | 108 | function increaseScore(course) { 109 | ::> 110 | } 111 | 112 | // map over `mySlightlyChanged` with a function `increaseScore` to increment each score by 12 113 | const mySlightlyChanged = myCourses; 114 | ``` 115 | )) 116 | @hint('give `increaseScore` a parameter, call it "course"') 117 | @hint('it should increase `course.score`') 118 | @hint('return `course`') 119 | 120 | + Wait. Now you're getting 105 in "Algorithm Design" class. Fix `increaseScore` so that the maximum score is 95. That should be less suspicious. 121 | @test('03/05') 122 | @hint('Use `Math.min(x, y)`') 123 | @hint('set `course.score` to `Math.min(95, course.score + 12)`') 124 | 125 | + One more problem. Now the scores don't match the grades. you have 95 score in "3D Computer Graphics", but only a "B" grade. Update your `increaseScore` function to also update the grade by using the `getGrade` function 126 | @test('03/06') 127 | @action(insert( 128 | ``` 129 | 130 | // use getGrade to set the course grade 131 | // update `increaseScore` to also update the grade 132 | function getGrade(score) { 133 | switch (true) { 134 | case (score >= 90): 135 | return "A"; 136 | case (score >= 80): 137 | return "B"; 138 | case (score >= 70): 139 | return "C"; 140 | case (score >= 60): 141 | return "D"; 142 | default: 143 | return "F"; 144 | } 145 | } 146 | 147 | ``` 148 | )) 149 | @hint('call `getGrade` inside of `increaseScore`') 150 | @hint('the `increaseScore` function should set course.grade equal to `getGrade(course.score)`') 151 | 152 | + Check to make sure everything is working. Set `scoresAndGrades` to an array of scores and grades only. 153 | @test('03/07') 154 | @action(insert( 155 | ``` 156 | 157 | // set `scoresAndGrades` to an array of scores and grades 158 | // it should return an array of objects like this: {score: 75, grade: 'C'} 159 | const scoresAndGrades = mySlightlyChanged.map(::>) 160 | ``` 161 | )) 162 | @hint('use `map` to return only the "score" & "grade" fields') 163 | @hint('map with a function with a parameter, call it "student"') 164 | @hint('you can destructure the param to be `function({score, grade})`') 165 | @hint('then simply return { score, grade }') 166 | 167 | @onPageComplete('In the next step we'll compare `map` with `forEach`') 168 | -------------------------------------------------------------------------------- /tutorial/07/reduce.md: -------------------------------------------------------------------------------- 1 | ## reduce 2 | Array -> anything 3 | 4 | We know our likely suspect is also in the school computer system. Perhaps our suspect also changed his grades. 5 | 6 | You can't be sure who is a cheater, but you can assume if the grades are well above the average, the person is likely to be the culprit. For this, we'll have to do some basic statistical calculations. We'll need a new tool for transforming arrays into different data representations. 7 | 8 | `map` has a major limitation: it will always output the same number of elements as the input array. 9 | 10 | When you want to transform data into something different, you'll likely want to use `reduce`. 11 | 12 | Reduce requires two parameters: 13 | 14 | * the running total (set by an initialValue) 15 | * the next value in the array 16 | 17 | ```js 18 | function add(total, next) { 19 | console.log(`add(${total}, ${next}) -> ${total + next}`) 20 | return total + next 21 | } 22 | 23 | const initialValue = 100; 24 | [1, 5, 10].reduce(add, initialValue); // initial value 25 | 26 | // add(100, 1) -> 101 27 | // add(101, 5) -> 106 28 | // add(106, 10) -> 116 29 | //> 116 30 | ``` 31 | 32 | Notice in the example we input an array of 3 items and output a single number. The data has been transformed. 33 | 34 | It takes a while to wrap your head around `reduce`, but once you do, you'll see it's usefulness everywhere. 35 | 36 | You may have noticed we've already used `reduce` to `flatten` our arrays. 37 | 38 | ```js 39 | Array.prototype.flatten = function() { 40 | return this.reduce((a, b) => a.concat(b), []); 41 | }; 42 | ``` 43 | 44 | With `flatten`, the initialValue was set to an empty array which each value was `concat` onto. 45 | 46 | Do some practice with `reduce`, before you use it to narrow down a cheating suspect. 47 | 48 | + load suspectData. We will come back to this after some practice; 49 | @test('07/01') 50 | @action(writeFromFile('data/suspectData.js', '07/suspectData.js')) 51 | @action(open('data/suspectData.js')) 52 | 53 | + Use `reduce` to sum the numbers in the `practice` array 54 | @test('07/02') 55 | @action(open('07-reduce.js')) 56 | @action(set( 57 | ``` 58 | import courses from './data/courses2'; 59 | // Array.reduce(fn(a, b), initialValue) 60 | 61 | const practice = [1, 1, 2, 3, 5, 8, 13, 21]; 62 | 63 | function add(a, b) { 64 | return a + b; 65 | } 66 | 67 | // total the numbers using a reduce function 68 | const total = practice.reduce(::>); 69 | ``` 70 | )) 71 | @hint('with only numbers, the initialValue defaults to 0') 72 | @hint('just call `reduce` with `add`') 73 | 74 | + Not all reduce functions are so easy. `reduce` is a little more difficult to master. 75 | 76 | `map` over each course and use `reduce` to calculate the class averages for each class. Set `averages` to the resulting array of all class averages. 77 | @test('07/03') 78 | @action(insert( 79 | ``` 80 | 81 | const averages = courses.map((course) => { 82 | const sum = course.students.reduce((total, student) => { 83 | ::> 84 | 85 | }); 86 | return Math.round(sum / course.students.length, 0); 87 | }); 88 | ``` 89 | )) 90 | @hint('set the initialValue to 0') 91 | @hint('like this: `reduce(function () {}, 0)`') 92 | @hint('return the sum of `student.score` and `total`') 93 | 94 | + `reduce` to an array of suspect scores from the `suspectData` we collected previously. 95 | @test('07/04') 96 | @action(open('07-reduce.js')) 97 | @action(insert( 98 | ``` 99 | 100 | // [{ name: 'suspectName', scores: [ 50, 65, 75, 85...] } ...] 101 | const suspectScores = suspectData.reduce((total, next) => { 102 | // see if suspect name has a list yet 103 | const index = total.findIndex((suspect) => suspect.name === next.name); 104 | if (index < 0) { 105 | total.push({ 106 | ::> 107 | 108 | }); 109 | } else { 110 | // push the next score onto the suspects scores 111 | total[index].scores.push(); 112 | } 113 | return total; 114 | }, []); 115 | 116 | ``` 117 | )) 118 | @hint('if the name is new, push an object with name & scores: `{ name: '', scores: [42]}`') 119 | @hint('match for `next.name` & `next.score`') 120 | @hint('you can concat the scores onto an array: `[].concat(next.score)`') 121 | @hint('if the name is already in the list, just add the `next.score`') 122 | 123 | + `map` over suspect data to find the `"difference"` from subtracting the students score from the average score. Add this to `suspectScores` using the key `difference`. The resulting array should look like this: 124 | ```js 125 | [{ 126 | name: 'suspectName', 127 | scores: [50, 65, 75 ...], 128 | difference: 15 129 | }] 130 | ``` 131 | @test('07/05') 132 | @action(insert( 133 | ``` 134 | 135 | const suspectStats = suspectScores.map((suspect) => { 136 | // calculate the total difference in scores from the averages 137 | const difference = suspect.scores.reduce(::>); 138 | 139 | return { 140 | name: suspect.name, 141 | scores: suspect.scores, 142 | difference: difference 143 | }; 144 | }); 145 | ``` 146 | )) 147 | @hint('You may want to use a second param: `index`') 148 | @hint('Compare the `suspect.scores[index]` with the `averages[index]`') 149 | @hint('To get a sum, start your `reduce` function at 0') 150 | 151 | 152 | + `reduce` down to likely suspect names by filtering with the `isCheater` function. 153 | 154 | This could be done with a `filter` & `map`, but it is simpler to just use one `reduce`. 155 | @test('07/06') 156 | @action(insert( 157 | ``` 158 | 159 | function isCheater(suspect) { 160 | return suspect.difference > 200; 161 | } 162 | 163 | // reduce down to a string of likely suspects 164 | const likelySuspects = suspectStats.reduce((::>) => {}, []); 165 | ``` 166 | )) 167 | @hint('use `.join(', ')`') 168 | 169 | + It looks like we have a likely suspect. 170 | @test('07/07') 171 | @action(insert( 172 | ``` 173 | console.log(likelySuspects); 174 | ``` 175 | )) 176 | -------------------------------------------------------------------------------- /tutorial/data/courses2.js: -------------------------------------------------------------------------------- 1 | var courses=[{title:"Relational Databases",instructor:"Sean Quentin Lewis",students:[{name:"!f",score:61,grade:"D"},{name:"Albert Gonzalez",score:35,grade:"F"},{name:"Brian Kernaghan",score:35,grade:"F"},{name:"Danielle Bunten Berry",score:78,grade:"C"},{name:"Donald Knuth",score:94,grade:"A"},{name:"Grace Hopper",score:36,grade:"F"},{name:"Hack Kerr",score:85,grade:"F"},{name:"James Gosling",score:30,grade:"F"},{name:"Ken Thompson",score:30,grade:"F"},{name:"Kevin Mitnick",score:72,grade:"C"},{name:"Linus Torvalds",score:34,grade:"F"},{name:"Niklaus Wirth",score:75,grade:"C"},{name:"Rebecca Heineman",score:71,grade:"C"},{name:"Tim Berners-Lee",score:54,grade:"F"},{name:"Xiao Tian",score:67,grade:"D"},{name:"Ying Cracker",score:57,grade:"F"}]},{title:"3D Computer Graphics",instructor:"G.L. Webb",students:[{name:"in",score:58,grade:"F"},{name:"Albert Gonzalez",score:37,grade:"F"},{name:"Brian Kernaghan",score:76,grade:"C"},{name:"Danielle Bunten Berry",score:53,grade:"F"},{name:"Donald Knuth",score:34,grade:"F"},{name:"Grace Hopper",score:74,grade:"C"},{name:"Hack Kerr",score:86,grade:"F"},{name:"James Gosling",score:94,grade:"A"},{name:"Ken Thompson",score:48,grade:"F"},{name:"Kevin Mitnick",score:52,grade:"F"},{name:"Linus Torvalds",score:90,grade:"A"},{name:"Niklaus Wirth",score:78,grade:"C"},{name:"Rebecca Heineman",score:73,grade:"C"},{name:"Tim Berners-Lee",score:94,grade:"A"},{name:"Xiao Tian",score:45,grade:"F"},{name:"Ying Cracker",score:77,grade:"C"}]},{title:"Front End Web Development",instructor:"Moe Zaick",students:[{name:"dt",score:31,grade:"F"},{name:"Albert Gonzalez",score:73,grade:"C"},{name:"Brian Kernaghan",score:47,grade:"F"},{name:"Danielle Bunten Berry",score:87,grade:"B"},{name:"Donald Knuth",score:80,grade:"B"},{name:"Grace Hopper",score:80,grade:"B"},{name:"Hack Kerr",score:92,grade:"C"},{name:"James Gosling",score:97,grade:"A"},{name:"Ken Thompson",score:64,grade:"D"},{name:"Kevin Mitnick",score:47,grade:"F"},{name:"Linus Torvalds",score:58,grade:"F"},{name:"Niklaus Wirth",score:93,grade:"A"},{name:"Rebecca Heineman",score:58,grade:"F"},{name:"Tim Berners-Lee",score:98,grade:"A"},{name:"Xiao Tian",score:36,grade:"F"},{name:"Ying Cracker",score:73,grade:"C"}]},{title:"Web Security",instructor:"Sue Denim",students:[{name:"he",score:51,grade:"F"},{name:"Albert Gonzalez",score:74,grade:"C"},{name:"Brian Kernaghan",score:92,grade:"A"},{name:"Danielle Bunten Berry",score:34,grade:"F"},{name:"Donald Knuth",score:44,grade:"F"},{name:"Grace Hopper",score:81,grade:"B"},{name:"Hack Kerr",score:75,grade:"F"},{name:"James Gosling",score:95,grade:"A"},{name:"Ken Thompson",score:84,grade:"B"},{name:"Kevin Mitnick",score:89,grade:"B"},{name:"Linus Torvalds",score:57,grade:"F"},{name:"Niklaus Wirth",score:88,grade:"B"},{name:"Rebecca Heineman",score:93,grade:"A"},{name:"Tim Berners-Lee",score:36,grade:"F"},{name:"Xiao Tian",score:87,grade:"B"},{name:"Ying Cracker",score:42,grade:"F"}]},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",students:[{name:"be",score:43,grade:"F"},{name:"Albert Gonzalez",score:94,grade:"A"},{name:"Brian Kernaghan",score:71,grade:"C"},{name:"Danielle Bunten Berry",score:66,grade:"D"},{name:"Donald Knuth",score:94,grade:"A"},{name:"Grace Hopper",score:99,grade:"A"},{name:"Hack Kerr",score:83,grade:"F"},{name:"James Gosling",score:99,grade:"A"},{name:"Ken Thompson",score:65,grade:"D"},{name:"Kevin Mitnick",score:47,grade:"F"},{name:"Linus Torvalds",score:93,grade:"A"},{name:"Niklaus Wirth",score:50,grade:"F"},{name:"Rebecca Heineman",score:33,grade:"F"},{name:"Tim Berners-Lee",score:51,grade:"F"},{name:"Xiao Tian",score:87,grade:"B"},{name:"Ying Cracker",score:60,grade:"D"}]},{title:"Data Science",instructor:"Ford Fulkerson",students:[{name:"st",score:28,grade:"F"},{name:"Albert Gonzalez",score:67,grade:"D"},{name:"Brian Kernaghan",score:66,grade:"D"},{name:"Danielle Bunten Berry",score:36,grade:"F"},{name:"Donald Knuth",score:36,grade:"F"},{name:"Grace Hopper",score:66,grade:"D"},{name:"Hack Kerr",score:96,grade:"A"},{name:"James Gosling",score:83,grade:"B"},{name:"Ken Thompson",score:35,grade:"F"},{name:"Kevin Mitnick",score:75,grade:"C"},{name:"Linus Torvalds",score:63,grade:"D"},{name:"Niklaus Wirth",score:75,grade:"C"},{name:"Rebecca Heineman",score:84,grade:"B"},{name:"Tim Berners-Lee",score:41,grade:"F"},{name:"Xiao Tian",score:49,grade:"F"},{name:"Ying Cracker",score:96,grade:"A"}]},{title:"Algorithm Design",instructor:"Gale Shapely",students:[{name:"re",score:63,grade:"D"},{name:"Albert Gonzalez",score:39,grade:"F"},{name:"Brian Kernaghan",score:69,grade:"D"},{name:"Danielle Bunten Berry",score:54,grade:"F"},{name:"Donald Knuth",score:83,grade:"B"},{name:"Grace Hopper",score:31,grade:"F"},{name:"Hack Kerr",score:94,grade:"A"},{name:"James Gosling",score:35,grade:"F"},{name:"Ken Thompson",score:67,grade:"D"},{name:"Kevin Mitnick",score:81,grade:"B"},{name:"Linus Torvalds",score:70,grade:"C"},{name:"Niklaus Wirth",score:74,grade:"C"},{name:"Rebecca Heineman",score:92,grade:"A"},{name:"Tim Berners-Lee",score:48,grade:"F"},{name:"Xiao Tian",score:80,grade:"B"},{name:"Ying Cracker",score:84,grade:"B"}]},{title:"Data Abstraction",instructor:"Aster Ricks",students:[{name:"ve",score:52,grade:"F"},{name:"Albert Gonzalez",score:70,grade:"C"},{name:"Brian Kernaghan",score:89,grade:"B"},{name:"Danielle Bunten Berry",score:38,grade:"F"},{name:"Donald Knuth",score:86,grade:"B"},{name:"Grace Hopper",score:42,grade:"F"},{name:"Hack Kerr",score:87,grade:"F"},{name:"James Gosling",score:89,grade:"B"},{name:"Ken Thompson",score:86,grade:"B"},{name:"Kevin Mitnick",score:41,grade:"F"},{name:"Linus Torvalds",score:76,grade:"C"},{name:"Niklaus Wirth",score:78,grade:"C"},{name:"Rebecca Heineman",score:70,grade:"C"},{name:"Tim Berners-Lee",score:74,grade:"C"},{name:"Xiao Tian",score:93,grade:"A"},{name:"Ying Cracker",score:95,grade:"A"}]},{title:"Data Structures",instructor:"Brodal Q.",students:[{name:"ng",score:58,grade:"F"},{name:"Albert Gonzalez",score:56,grade:"F"},{name:"Brian Kernaghan",score:58,grade:"F"},{name:"Danielle Bunten Berry",score:38,grade:"F"},{name:"Donald Knuth",score:85,grade:"B"},{name:"Grace Hopper",score:53,grade:"F"},{name:"Hack Kerr",score:89,grade:"B"},{name:"James Gosling",score:42,grade:"F"},{name:"Ken Thompson",score:87,grade:"B"},{name:"Kevin Mitnick",score:40,grade:"F"},{name:"Linus Torvalds",score:91,grade:"A"},{name:"Niklaus Wirth",score:51,grade:"F"},{name:"Rebecca Heineman",score:79,grade:"C"},{name:"Tim Berners-Lee",score:37,grade:"F"},{name:"Xiao Tian",score:84,grade:"B"},{name:"Ying Cracker",score:45,grade:"F"}]},{title:"Networks",instructor:"Van Emde Boas",students:[{name:"e!",score:35,grade:"F"},{name:"Albert Gonzalez",score:52,grade:"F"},{name:"Brian Kernaghan",score:61,grade:"D"},{name:"Danielle Bunten Berry",score:59,grade:"F"},{name:"Donald Knuth",score:89,grade:"B"},{name:"Grace Hopper",score:40,grade:"F"},{name:"Hack Kerr",score:102,grade:"F"},{name:"James Gosling",score:39,grade:"F"},{name:"Ken Thompson",score:83,grade:"B"},{name:"Kevin Mitnick",score:37,grade:"F"},{name:"Linus Torvalds",score:65,grade:"D"},{name:"Niklaus Wirth",score:36,grade:"F"},{name:"Rebecca Heineman",score:32,grade:"F"},{name:"Tim Berners-Lee",score:70,grade:"C"},{name:"Xiao Tian",score:52,grade:"F"},{name:"Ying Cracker",score:62,grade:"D"}]}]; 2 | -------------------------------------------------------------------------------- /tutorial/data/courses.js: -------------------------------------------------------------------------------- 1 | var courses=[{title:"Relational Databases",instructor:"Sean Quentin Lewis",students:[{name:"Ada Lovelace",score:91,grade:"A"},{name:"Albert Gonzalez",score:35,grade:"F"},{name:"Brian Kernaghan",score:35,grade:"F"},{name:"Danielle Bunten Berry",score:78,grade:"C"},{name:"Donald Knuth",score:94,grade:"A"},{name:"Grace Hopper",score:36,grade:"F"},{name:"Hack Kerr",score:85,grade:"F"},{name:"James Gosling",score:30,grade:"F"},{name:"Ken Thompson",score:30,grade:"F"},{name:"Kevin Mitnick",score:72,grade:"C"},{name:"Linus Torvalds",score:34,grade:"F"},{name:"Niklaus Wirth",score:75,grade:"C"},{name:"Rebecca Heineman",score:71,grade:"C"},{name:"Tim Berners-Lee",score:54,grade:"F"},{name:"Xiao Tian",score:67,grade:"D"},{name:"Ying Cracker",score:57,grade:"F"}]},{title:"3D Computer Graphics",instructor:"G.L. Webb",students:[{name:"Ada Lovelace",score:88,grade:"B"},{name:"Albert Gonzalez",score:37,grade:"F"},{name:"Brian Kernaghan",score:76,grade:"C"},{name:"Danielle Bunten Berry",score:53,grade:"F"},{name:"Donald Knuth",score:34,grade:"F"},{name:"Grace Hopper",score:74,grade:"C"},{name:"Hack Kerr",score:86,grade:"F"},{name:"James Gosling",score:94,grade:"A"},{name:"Ken Thompson",score:48,grade:"F"},{name:"Kevin Mitnick",score:52,grade:"F"},{name:"Linus Torvalds",score:90,grade:"A"},{name:"Niklaus Wirth",score:78,grade:"C"},{name:"Rebecca Heineman",score:73,grade:"C"},{name:"Tim Berners-Lee",score:94,grade:"A"},{name:"Xiao Tian",score:45,grade:"F"},{name:"Ying Cracker",score:77,grade:"C"}]},{title:"Front End Web Development",instructor:"Moe Zaick",students:[{name:"Ada Lovelace",score:61,grade:"D"},{name:"Albert Gonzalez",score:73,grade:"C"},{name:"Brian Kernaghan",score:47,grade:"F"},{name:"Danielle Bunten Berry",score:87,grade:"B"},{name:"Donald Knuth",score:80,grade:"B"},{name:"Grace Hopper",score:80,grade:"B"},{name:"Hack Kerr",score:92,grade:"C"},{name:"James Gosling",score:97,grade:"A"},{name:"Ken Thompson",score:64,grade:"D"},{name:"Kevin Mitnick",score:47,grade:"F"},{name:"Linus Torvalds",score:58,grade:"F"},{name:"Niklaus Wirth",score:93,grade:"A"},{name:"Rebecca Heineman",score:58,grade:"F"},{name:"Tim Berners-Lee",score:98,grade:"A"},{name:"Xiao Tian",score:36,grade:"F"},{name:"Ying Cracker",score:73,grade:"C"}]},{title:"Web Security",instructor:"Sue Denim",students:[{name:"Ada Lovelace",score:81,grade:"B"},{name:"Albert Gonzalez",score:74,grade:"C"},{name:"Brian Kernaghan",score:92,grade:"A"},{name:"Danielle Bunten Berry",score:34,grade:"F"},{name:"Donald Knuth",score:44,grade:"F"},{name:"Grace Hopper",score:81,grade:"B"},{name:"Hack Kerr",score:75,grade:"F"},{name:"James Gosling",score:95,grade:"A"},{name:"Ken Thompson",score:84,grade:"B"},{name:"Kevin Mitnick",score:89,grade:"B"},{name:"Linus Torvalds",score:57,grade:"F"},{name:"Niklaus Wirth",score:88,grade:"B"},{name:"Rebecca Heineman",score:93,grade:"A"},{name:"Tim Berners-Lee",score:36,grade:"F"},{name:"Xiao Tian",score:87,grade:"B"},{name:"Ying Cracker",score:42,grade:"F"}]},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",students:[{name:"Ada Lovelace",score:73,grade:"C"},{name:"Albert Gonzalez",score:94,grade:"A"},{name:"Brian Kernaghan",score:71,grade:"C"},{name:"Danielle Bunten Berry",score:66,grade:"D"},{name:"Donald Knuth",score:94,grade:"A"},{name:"Grace Hopper",score:99,grade:"A"},{name:"Hack Kerr",score:83,grade:"F"},{name:"James Gosling",score:99,grade:"A"},{name:"Ken Thompson",score:65,grade:"D"},{name:"Kevin Mitnick",score:47,grade:"F"},{name:"Linus Torvalds",score:93,grade:"A"},{name:"Niklaus Wirth",score:50,grade:"F"},{name:"Rebecca Heineman",score:33,grade:"F"},{name:"Tim Berners-Lee",score:51,grade:"F"},{name:"Xiao Tian",score:87,grade:"B"},{name:"Ying Cracker",score:60,grade:"D"}]},{title:"Data Science",instructor:"Ford Fulkerson",students:[{name:"Ada Lovelace",score:58,grade:"F"},{name:"Albert Gonzalez",score:67,grade:"D"},{name:"Brian Kernaghan",score:66,grade:"D"},{name:"Danielle Bunten Berry",score:36,grade:"F"},{name:"Donald Knuth",score:36,grade:"F"},{name:"Grace Hopper",score:66,grade:"D"},{name:"Hack Kerr",score:96,grade:"A"},{name:"James Gosling",score:83,grade:"B"},{name:"Ken Thompson",score:35,grade:"F"},{name:"Kevin Mitnick",score:75,grade:"C"},{name:"Linus Torvalds",score:63,grade:"D"},{name:"Niklaus Wirth",score:75,grade:"C"},{name:"Rebecca Heineman",score:84,grade:"B"},{name:"Tim Berners-Lee",score:41,grade:"F"},{name:"Xiao Tian",score:49,grade:"F"},{name:"Ying Cracker",score:96,grade:"A"}]},{title:"Algorithm Design",instructor:"Gale Shapely",students:[{name:"Ada Lovelace",score:93,grade:"A"},{name:"Albert Gonzalez",score:39,grade:"F"},{name:"Brian Kernaghan",score:69,grade:"D"},{name:"Danielle Bunten Berry",score:54,grade:"F"},{name:"Donald Knuth",score:83,grade:"B"},{name:"Grace Hopper",score:31,grade:"F"},{name:"Hack Kerr",score:94,grade:"A"},{name:"James Gosling",score:35,grade:"F"},{name:"Ken Thompson",score:67,grade:"D"},{name:"Kevin Mitnick",score:81,grade:"B"},{name:"Linus Torvalds",score:70,grade:"C"},{name:"Niklaus Wirth",score:74,grade:"C"},{name:"Rebecca Heineman",score:92,grade:"A"},{name:"Tim Berners-Lee",score:48,grade:"F"},{name:"Xiao Tian",score:80,grade:"B"},{name:"Ying Cracker",score:84,grade:"B"}]},{title:"Data Abstraction",instructor:"Aster Ricks",students:[{name:"Ada Lovelace",score:82,grade:"B"},{name:"Albert Gonzalez",score:70,grade:"C"},{name:"Brian Kernaghan",score:89,grade:"B"},{name:"Danielle Bunten Berry",score:38,grade:"F"},{name:"Donald Knuth",score:86,grade:"B"},{name:"Grace Hopper",score:42,grade:"F"},{name:"Hack Kerr",score:87,grade:"F"},{name:"James Gosling",score:89,grade:"B"},{name:"Ken Thompson",score:86,grade:"B"},{name:"Kevin Mitnick",score:41,grade:"F"},{name:"Linus Torvalds",score:76,grade:"C"},{name:"Niklaus Wirth",score:78,grade:"C"},{name:"Rebecca Heineman",score:70,grade:"C"},{name:"Tim Berners-Lee",score:74,grade:"C"},{name:"Xiao Tian",score:93,grade:"A"},{name:"Ying Cracker",score:95,grade:"A"}]},{title:"Data Structures",instructor:"Brodal Q.",students:[{name:"Ada Lovelace",score:88,grade:"B"},{name:"Albert Gonzalez",score:56,grade:"F"},{name:"Brian Kernaghan",score:58,grade:"F"},{name:"Danielle Bunten Berry",score:38,grade:"F"},{name:"Donald Knuth",score:85,grade:"B"},{name:"Grace Hopper",score:53,grade:"F"},{name:"Hack Kerr",score:89,grade:"B"},{name:"James Gosling",score:42,grade:"F"},{name:"Ken Thompson",score:87,grade:"B"},{name:"Kevin Mitnick",score:40,grade:"F"},{name:"Linus Torvalds",score:91,grade:"A"},{name:"Niklaus Wirth",score:51,grade:"F"},{name:"Rebecca Heineman",score:79,grade:"C"},{name:"Tim Berners-Lee",score:37,grade:"F"},{name:"Xiao Tian",score:84,grade:"B"},{name:"Ying Cracker",score:45,grade:"F"}]},{title:"Networks",instructor:"Van Emde Boas",students:[{name:"Ada Lovelace",score:65,grade:"D"},{name:"Albert Gonzalez",score:52,grade:"F"},{name:"Brian Kernaghan",score:61,grade:"D"},{name:"Danielle Bunten Berry",score:59,grade:"F"},{name:"Donald Knuth",score:89,grade:"B"},{name:"Grace Hopper",score:40,grade:"F"},{name:"Hack Kerr",score:102,grade:"F"},{name:"James Gosling",score:39,grade:"F"},{name:"Ken Thompson",score:83,grade:"B"},{name:"Kevin Mitnick",score:37,grade:"F"},{name:"Linus Torvalds",score:65,grade:"D"},{name:"Niklaus Wirth",score:36,grade:"F"},{name:"Rebecca Heineman",score:32,grade:"F"},{name:"Tim Berners-Lee",score:70,grade:"C"},{name:"Xiao Tian",score:52,grade:"F"},{name:"Ying Cracker",score:62,grade:"D"}]}]; 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Functional School 2 | 3 | A trip through functional programming in Javascript using common built-in Javascript array methods such as `map` & `reduce`. 4 | 5 | By the end, you should have an understanding of how to use array methods to manipulate semi-complex data. 6 | 7 | Level: Intermediate 8 | Keywords: javascript, functional 9 | Length: 1-2 hours 10 | 11 | 12 | ## CodeRoad 13 | 14 | CodeRoad is an open-sourced interactive tutorial platform for the Atom Editor. Learn more at [CodeRoad.io](http://coderoad.io). 15 | 16 | 17 | ## Setup 18 | 19 | * install the tutorial package 20 | 21 | `npm install --save coderoad-functional-school` 22 | 23 | * install and run the [atom-coderoad](https://github.com/coderoad/atom-coderoad) plugin 24 | 25 | 26 | ## Outline 27 | 28 | ##### Start 29 | 30 | Understanding the Data Set 31 | 32 | Over this tutorial series, we'll be changing and working with two different data sets. It'll be a big help to first understand what the data looks like. 33 | 34 | ```json 35 | var students = [ 36 | { 37 | "title": "Relational Databases", 38 | "instructor": "Sean Quentin Lewis", 39 | "name": "Ada Lovelace", 40 | "score": 91, 41 | "grade": "A" 42 | }, 43 | ... 44 | ] 45 | ``` 46 | 47 | Here we have an array of "student" objects. To get the first item in the array, you can use the array index. Array indexes start at 0. 48 | 49 | ```js 50 | console.log( 51 | 'first instructor', students[0].instructor 52 | ); 53 | // first instructor Sean Quentin Lewis 54 | ``` 55 | 56 | ##### Filter 57 | 58 | Array -> Array of items that match a condition 59 | 60 | You've hacked into the school's computer system, and just in time. The grades are in, but you're not too proud of your performance. That's okay, you have a plan: you're going to create a fake report card. 61 | 62 | It would be great if you could `filter` the scores that your parents will see. 63 | 64 | `filter` takes a matching condition function and only returns items that result in true. As an example, look at `isA` below: 65 | 66 | ```js 67 | function isA(x) { 68 | return x === 'a'; 69 | } 70 | ``` 71 | 72 | 73 | Like all of the methods in this chapter, `filter` is already part of the `Array.prototype`, so you can run it following any array. Each item in the array is passed into the params of the condition function, one by one. [Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). 74 | 75 | ```js 76 | const list = ['a', 'b']; 77 | list.filter(isA); 78 | 79 | // if isA(list[0]), add to output array 80 | // if isA(list[1]), add to output array 81 | // 82 | //> ['a'] 83 | ``` 84 | 85 | If your data was composed of objects, we could use dot notation to find matches. Checkout `isB` below. 86 | 87 | ```js 88 | function isB(x) { 89 | return x.item === 'b' 90 | } 91 | 92 | const list = [{item: 'a'}, {item: 'b'}]; 93 | list.filter(isB); 94 | //> [{item: 'b'}] 95 | ``` 96 | 97 | Where were we? Back to filtering our grades. 98 | 99 | There's too much student data in the computer system. We'll have to sort through it. Have a look at an example below: 100 | 101 | ```js 102 | console.log(students[0]); 103 | //> { course: 'Web Security', 104 | // instructor: 'Sue Denim', 105 | // name: 'Rebecca Heineman', 106 | // score: 93, 107 | // grade: 'A' } 108 | ``` 109 | 110 | ##### Sort 111 | 112 | Array -> sorted Array 113 | 114 | Your grades are filtered down to your name and good scores - but wouldn't it be better if your best grades were displayed first, at the top? Besides, your parents rarely read anything through. 115 | 116 | You can use the array method `sort` to arrange your data. Let's see how it works. 117 | 118 | ```js 119 | ['c', 'b', 'a'].sort(); 120 | //> ['a', 'b', 'c'] 121 | 122 | [3, 2, 1].sort(); 123 | //> [1, 2, 3] 124 | ``` 125 | 126 | But what about sorting scores inside of an object? 127 | 128 | ```js 129 | [{a: 3}, {a: 1}, {a: 2}].sort(); 130 | //> [{a: 3}, {a: 1}, {a: 2}] 131 | ``` 132 | 133 | That didn't work. Instead, you can write a custom `compareScore` function. 134 | 135 | A sort function takes two params, and compares the first to the second. It should return values saying where the second value should go in the array: 136 | 137 | * -1 : sort to a lower index (front) 138 | * 1 : sort to a higher index (back) 139 | * 0 : stay the same 140 | 141 | Alright, now time to sort your best grades to the top. 142 | 143 | First you'll need to write a sort condition function called `compareScore`. 144 | 145 | ##### Map 146 | 147 | Array -> run a function over each item -> Array 148 | 149 | You've filtered and sorted our data, but neither of those actually change the data. 150 | 151 | Wouldn't it be simpler if you could just change your grades? 152 | 153 | You can use the array method `map` to run a function that returns changes to your data. 154 | 155 | As an example, let's look at how you would increment each number in an array. 156 | 157 | ```js 158 | function addOne(num) { 159 | return num + 1; 160 | } 161 | 162 | [1, 2, 3].map(addOne); 163 | //> [2, 3, 4] 164 | 165 | function addToVal(obj) { 166 | obj.val += 1; 167 | return obj; 168 | } 169 | [{ val: 1}].map(addToVal); 170 | //> [{ val: 2 }] 171 | ``` 172 | 173 | `map` can change data, and it can also alter structure of the data you're working with. 174 | 175 | ```js 176 | function makeObject(num) { 177 | return { val: num }; 178 | } 179 | 180 | [1, 2].map(makeObject); 181 | //> [{ val: 1 }, { val: 2 }] 182 | ``` 183 | 184 | Similarly, `map` can also restrict the data you want to work with. See the example below to see another way scores could be sorted. 185 | 186 | ```js 187 | myBest 188 | .map(function(student) { 189 | return student.score; 190 | }) 191 | .sort() 192 | .reverse() 193 | //> [93, 91, 88, 88, 82, 81, 73] 194 | ``` 195 | 196 | In this example, `map` transformed an object with keys of 'title', 'instructor', 'name', 'score' and 'grade', to an array of just scores. Values weren't changed, but rather limited to a smaller subset of scores. 197 | 198 | `map` is powerful. Let's see what you can do with it. 199 | 200 | Those D & F grades would look a lot better if they suddenly became A's. 201 | 202 | Let's go back to before we filtered out the bad grades, and instead change the grades to A's. 203 | 204 | ##### forEach 205 | 206 | Array -> run a function for each item 207 | 208 | You've updated your grades, but they're still in an array. It's time to loop over them and log them to the console. 209 | 210 | To open the console, go to *View* > *Developer* > *Toggle Developer Tools*. Or press *cmd+opt+I* on Mac, *ctrl+alt+I* on Windows. 211 | 212 | `forEach` has a lot in common with `map`, but there is a big difference. Understanding that difference is important for grasping the difference between: 213 | 214 | * **functional** & **imperative** programming 215 | * **pure** & **impure** functions 216 | 217 | Know it or not, you're probably already used to "imperative" programming. 218 | 219 | > **Imperative** programming describes the order of actions 220 | 221 | Imperative code tells the computer what to do, step by step. 222 | 223 | ```js 224 | let x = 1; // make a variable 225 | x = x + 1; // add one 226 | x = x + 1; // add another 227 | console.log(x); 228 | //> 3 229 | ``` 230 | 231 | > **Functional** programming describes the data transformation 232 | 233 | Functional programming is a lot like writing math equations. As in math, 1 + 1 always equals 2. 234 | 235 | In the same way, a **pure** function will always have the same result from a given input. Input 1 -> output 2. Every time. 236 | 237 | ```js 238 | // a pure function 239 | function addOne(x) { 240 | return x + 1; 241 | } 242 | addOne(1) 243 | //> 2 244 | addOne(1) 245 | //> 2 246 | ``` 247 | 248 | A function is "pure" if it doesn't change anything outside of its scope. Pure functions are easy to test, reuse and reason about. In other words, they make your job easier. 249 | 250 | On the other hand, **impure** functions are less predictable. The result may be different if you call it at a later time. 251 | 252 | ```js 253 | let y = 1; 254 | // impure function 255 | function increment(x) { 256 | y += x; 257 | return y; 258 | } 259 | increment(1) 260 | //> 2 261 | increment(1) 262 | //> 3 263 | ``` 264 | 265 | It's good practice to ensure your `map` functions remain pure. 266 | 267 | But `forEach` can be a little more dangerous. Why? Let's have a look. 268 | 269 | ```js 270 | [1, 2, 3].map(addOne); 271 | //> [2, 3, 4] 272 | 273 | [1, 2, 3].forEach(addOne); 274 | //> undefined 275 | ``` 276 | 277 | What? `undefined`? `forEach` runs a function on each item in the array, and doesn't care what the function returns. Functions called by `forEach` must make changes, called **side effects**, to even be noticed. 278 | 279 | ```js 280 | // impure function, changes log 281 | function addOneToLog(x) { 282 | console.log(x); 283 | } 284 | 285 | [1, 2, 3].forEach(addOneToLog); 286 | //> 2 287 | //> 3 288 | //> 4 289 | ``` 290 | 291 | Now that we see how `forEach` works, let's use it to make calls to the `console`. 292 | 293 | ##### find 294 | 295 | Array -> first element that matches a condition 296 | 297 | Somehow your name has disappeared from the computer system. We'll have to `find` a way to get it back. 298 | 299 | You quickly put together a list of other students in class. If someone changed your name, it'll be the name that is not in that list. 300 | 301 | `find` works similar to `filter`, but returns only the first match. 302 | 303 | ```js 304 | const data = [1, 2, 3, 4, 5, 6]; 305 | 306 | function isEven(num) { 307 | return num % 2 === 0; 308 | } 309 | 310 | // returns all matching data to a condition 311 | data.filter(isEven); 312 | //> [2, 4, 6] 313 | 314 | // returns the first match 315 | data.find(isEven); 316 | //> [2] 317 | ``` 318 | 319 | Find is great for performantly matching unique values in data, such as an "id", or in our case: a name. 320 | 321 | ##### concat 322 | 323 | Array + Array -> Array 324 | 325 | Before we've been working on a structured set of student data. 326 | 327 | ```js 328 | // array of students 329 | [ 330 | { 331 | "title": "Relational Databases", 332 | "instructor": "Sean Quentin Lewis", 333 | "name": "Rebecca Heineman", 334 | "score": 71, 335 | "grade": "C" 336 | } 337 | // students in courses... 338 | ] 339 | ``` 340 | 341 | To be safe, let's now work on the original data set. Notice how it is structured differently. 342 | 343 | ```js 344 | // array of courses 345 | [ 346 | { 347 | "title": "Relational Databases", 348 | "instructor": "Sean Quentin Lewis", 349 | "students": [ 350 | { 351 | "name": "Rebecca Heineman", 352 | "score": 71, 353 | "grade": "C" 354 | } 355 | // students... 356 | ] 357 | } 358 | // courses... 359 | ] 360 | ``` 361 | 362 | In this data set, there is an array of students within an array of courses. So how can we recreate our original array of students from the courses? 363 | 364 | Weird things happen when you start combining arrays. We can use `concat` to bring sanity. 365 | 366 | ```js 367 | [1, 2] + [3, 4]; 368 | //> "1, 23, 4" 369 | 370 | [1, 2].push([3, 4]); 371 | //> 3 372 | 373 | [1, 2].join([3, 4]); 374 | //> "13, 42" 375 | 376 | [1, 2].concat([3, 4]); 377 | //> [1, 2, 3, 4] 378 | ``` 379 | 380 | Unfortunately, Javascript is missing a built in array method to concat multiple arrays together: let's call it `flatten` (sometimes called `concatAll`). 381 | 382 | `flatten` should loop over an array and `concat` each element. 383 | 384 | Let's look at an abstraction of what we need to do: 385 | 386 | ```js 387 | const start = [{ 388 | a: 1, 389 | c: [ 390 | { b: 1 } 391 | ] 392 | }, { 393 | a: 2, 394 | c: [ 395 | { b: 2 }, { b: 3 } 396 | ] 397 | }]; 398 | 399 | const middle = start.map(function(outer) { 400 | return outer.c.map(function(inner) { 401 | return { 402 | a: outer.a, 403 | b: inner.b 404 | }; 405 | }); 406 | }); 407 | //> [ [{ a: 1, b: 1 }], [{a: 2, b: 2}, {a: 2, b: 3}] ] 408 | 409 | const end = pre.flatten(); 410 | //> [{a: 1, b: 1}, {a: 2, b: 2}, {a: 2, b: 3}] 411 | ``` 412 | 413 | Back to business. 414 | 415 | We have a suspect in mind: a classmate named "Hack Kerr". He's a nice guy, and he's always been friendly to you - but there's something suspicious about him: his name. 416 | 417 | We'll test out flatten, then re-create our student array of data from the original course data. 418 | -------------------------------------------------------------------------------- /tutorial/06/courses2.js: -------------------------------------------------------------------------------- 1 | const courses = [{ 2 | title: "Relational Databases", 3 | instructor: "Sean Quentin Lewis", 4 | students: [{ 5 | name: "!f", 6 | score: 61, 7 | grade: "D" 8 | }, { 9 | name: "Albert Gonzalez", 10 | score: 35, 11 | grade: "F" 12 | }, { 13 | name: "Brian Kernaghan", 14 | score: 35, 15 | grade: "F" 16 | }, { 17 | name: "Danielle Bunten Berry", 18 | score: 78, 19 | grade: "C" 20 | }, { 21 | name: "Donald Knuth", 22 | score: 94, 23 | grade: "A" 24 | }, { 25 | name: "Grace Hopper", 26 | score: 36, 27 | grade: "F" 28 | }, { 29 | name: "Hack Kerr", 30 | score: 85, 31 | grade: "F" 32 | }, { 33 | name: "James Gosling", 34 | score: 30, 35 | grade: "F" 36 | }, { 37 | name: "Ken Thompson", 38 | score: 30, 39 | grade: "F" 40 | }, { 41 | name: "Kevin Mitnick", 42 | score: 72, 43 | grade: "C" 44 | }, { 45 | name: "Linus Torvalds", 46 | score: 34, 47 | grade: "F" 48 | }, { 49 | name: "Niklaus Wirth", 50 | score: 75, 51 | grade: "C" 52 | }, { 53 | name: "Rebecca Heineman", 54 | score: 71, 55 | grade: "C" 56 | }, { 57 | name: "Tim Berners-Lee", 58 | score: 54, 59 | grade: "F" 60 | }, { 61 | name: "Xiao Tian", 62 | score: 67, 63 | grade: "D" 64 | }, { 65 | name: "Ying Cracker", 66 | score: 57, 67 | grade: "F" 68 | }] 69 | }, { 70 | title: "3D Computer Graphics", 71 | instructor: "G.L. Webb", 72 | students: [{ 73 | name: "in", 74 | score: 58, 75 | grade: "F" 76 | }, { 77 | name: "Albert Gonzalez", 78 | score: 37, 79 | grade: "F" 80 | }, { 81 | name: "Brian Kernaghan", 82 | score: 76, 83 | grade: "C" 84 | }, { 85 | name: "Danielle Bunten Berry", 86 | score: 53, 87 | grade: "F" 88 | }, { 89 | name: "Donald Knuth", 90 | score: 34, 91 | grade: "F" 92 | }, { 93 | name: "Grace Hopper", 94 | score: 74, 95 | grade: "C" 96 | }, { 97 | name: "Hack Kerr", 98 | score: 86, 99 | grade: "F" 100 | }, { 101 | name: "James Gosling", 102 | score: 94, 103 | grade: "A" 104 | }, { 105 | name: "Ken Thompson", 106 | score: 48, 107 | grade: "F" 108 | }, { 109 | name: "Kevin Mitnick", 110 | score: 52, 111 | grade: "F" 112 | }, { 113 | name: "Linus Torvalds", 114 | score: 90, 115 | grade: "A" 116 | }, { 117 | name: "Niklaus Wirth", 118 | score: 78, 119 | grade: "C" 120 | }, { 121 | name: "Rebecca Heineman", 122 | score: 73, 123 | grade: "C" 124 | }, { 125 | name: "Tim Berners-Lee", 126 | score: 94, 127 | grade: "A" 128 | }, { 129 | name: "Xiao Tian", 130 | score: 45, 131 | grade: "F" 132 | }, { 133 | name: "Ying Cracker", 134 | score: 77, 135 | grade: "C" 136 | }] 137 | }, { 138 | title: "Front End Web Development", 139 | instructor: "Moe Zaick", 140 | students: [{ 141 | name: "dt", 142 | score: 31, 143 | grade: "F" 144 | }, { 145 | name: "Albert Gonzalez", 146 | score: 73, 147 | grade: "C" 148 | }, { 149 | name: "Brian Kernaghan", 150 | score: 47, 151 | grade: "F" 152 | }, { 153 | name: "Danielle Bunten Berry", 154 | score: 87, 155 | grade: "B" 156 | }, { 157 | name: "Donald Knuth", 158 | score: 80, 159 | grade: "B" 160 | }, { 161 | name: "Grace Hopper", 162 | score: 80, 163 | grade: "B" 164 | }, { 165 | name: "Hack Kerr", 166 | score: 92, 167 | grade: "C" 168 | }, { 169 | name: "James Gosling", 170 | score: 97, 171 | grade: "A" 172 | }, { 173 | name: "Ken Thompson", 174 | score: 64, 175 | grade: "D" 176 | }, { 177 | name: "Kevin Mitnick", 178 | score: 47, 179 | grade: "F" 180 | }, { 181 | name: "Linus Torvalds", 182 | score: 58, 183 | grade: "F" 184 | }, { 185 | name: "Niklaus Wirth", 186 | score: 93, 187 | grade: "A" 188 | }, { 189 | name: "Rebecca Heineman", 190 | score: 58, 191 | grade: "F" 192 | }, { 193 | name: "Tim Berners-Lee", 194 | score: 98, 195 | grade: "A" 196 | }, { 197 | name: "Xiao Tian", 198 | score: 36, 199 | grade: "F" 200 | }, { 201 | name: "Ying Cracker", 202 | score: 73, 203 | grade: "C" 204 | }] 205 | }, { 206 | title: "Web Security", 207 | instructor: "Sue Denim", 208 | students: [{ 209 | name: "he", 210 | score: 51, 211 | grade: "F" 212 | }, { 213 | name: "Albert Gonzalez", 214 | score: 74, 215 | grade: "C" 216 | }, { 217 | name: "Brian Kernaghan", 218 | score: 92, 219 | grade: "A" 220 | }, { 221 | name: "Danielle Bunten Berry", 222 | score: 34, 223 | grade: "F" 224 | }, { 225 | name: "Donald Knuth", 226 | score: 44, 227 | grade: "F" 228 | }, { 229 | name: "Grace Hopper", 230 | score: 81, 231 | grade: "B" 232 | }, { 233 | name: "Hack Kerr", 234 | score: 75, 235 | grade: "F" 236 | }, { 237 | name: "James Gosling", 238 | score: 95, 239 | grade: "A" 240 | }, { 241 | name: "Ken Thompson", 242 | score: 84, 243 | grade: "B" 244 | }, { 245 | name: "Kevin Mitnick", 246 | score: 89, 247 | grade: "B" 248 | }, { 249 | name: "Linus Torvalds", 250 | score: 57, 251 | grade: "F" 252 | }, { 253 | name: "Niklaus Wirth", 254 | score: 88, 255 | grade: "B" 256 | }, { 257 | name: "Rebecca Heineman", 258 | score: 93, 259 | grade: "A" 260 | }, { 261 | name: "Tim Berners-Lee", 262 | score: 36, 263 | grade: "F" 264 | }, { 265 | name: "Xiao Tian", 266 | score: 87, 267 | grade: "B" 268 | }, { 269 | name: "Ying Cracker", 270 | score: 42, 271 | grade: "F" 272 | }] 273 | }, { 274 | title: "Javascript Fundamentals", 275 | instructor: "Jay Kweerie", 276 | students: [{ 277 | name: "be", 278 | score: 43, 279 | grade: "F" 280 | }, { 281 | name: "Albert Gonzalez", 282 | score: 94, 283 | grade: "A" 284 | }, { 285 | name: "Brian Kernaghan", 286 | score: 71, 287 | grade: "C" 288 | }, { 289 | name: "Danielle Bunten Berry", 290 | score: 66, 291 | grade: "D" 292 | }, { 293 | name: "Donald Knuth", 294 | score: 94, 295 | grade: "A" 296 | }, { 297 | name: "Grace Hopper", 298 | score: 99, 299 | grade: "A" 300 | }, { 301 | name: "Hack Kerr", 302 | score: 83, 303 | grade: "F" 304 | }, { 305 | name: "James Gosling", 306 | score: 99, 307 | grade: "A" 308 | }, { 309 | name: "Ken Thompson", 310 | score: 65, 311 | grade: "D" 312 | }, { 313 | name: "Kevin Mitnick", 314 | score: 47, 315 | grade: "F" 316 | }, { 317 | name: "Linus Torvalds", 318 | score: 93, 319 | grade: "A" 320 | }, { 321 | name: "Niklaus Wirth", 322 | score: 50, 323 | grade: "F" 324 | }, { 325 | name: "Rebecca Heineman", 326 | score: 33, 327 | grade: "F" 328 | }, { 329 | name: "Tim Berners-Lee", 330 | score: 51, 331 | grade: "F" 332 | }, { 333 | name: "Xiao Tian", 334 | score: 87, 335 | grade: "B" 336 | }, { 337 | name: "Ying Cracker", 338 | score: 60, 339 | grade: "D" 340 | }] 341 | }, { 342 | title: "Data Science", 343 | instructor: "Ford Fulkerson", 344 | students: [{ 345 | name: "st", 346 | score: 28, 347 | grade: "F" 348 | }, { 349 | name: "Albert Gonzalez", 350 | score: 67, 351 | grade: "D" 352 | }, { 353 | name: "Brian Kernaghan", 354 | score: 66, 355 | grade: "D" 356 | }, { 357 | name: "Danielle Bunten Berry", 358 | score: 36, 359 | grade: "F" 360 | }, { 361 | name: "Donald Knuth", 362 | score: 36, 363 | grade: "F" 364 | }, { 365 | name: "Grace Hopper", 366 | score: 66, 367 | grade: "D" 368 | }, { 369 | name: "Hack Kerr", 370 | score: 96, 371 | grade: "A" 372 | }, { 373 | name: "James Gosling", 374 | score: 83, 375 | grade: "B" 376 | }, { 377 | name: "Ken Thompson", 378 | score: 35, 379 | grade: "F" 380 | }, { 381 | name: "Kevin Mitnick", 382 | score: 75, 383 | grade: "C" 384 | }, { 385 | name: "Linus Torvalds", 386 | score: 63, 387 | grade: "D" 388 | }, { 389 | name: "Niklaus Wirth", 390 | score: 75, 391 | grade: "C" 392 | }, { 393 | name: "Rebecca Heineman", 394 | score: 84, 395 | grade: "B" 396 | }, { 397 | name: "Tim Berners-Lee", 398 | score: 41, 399 | grade: "F" 400 | }, { 401 | name: "Xiao Tian", 402 | score: 49, 403 | grade: "F" 404 | }, { 405 | name: "Ying Cracker", 406 | score: 96, 407 | grade: "A" 408 | }] 409 | }, { 410 | title: "Algorithm Design", 411 | instructor: "Gale Shapely", 412 | students: [{ 413 | name: "re", 414 | score: 63, 415 | grade: "D" 416 | }, { 417 | name: "Albert Gonzalez", 418 | score: 39, 419 | grade: "F" 420 | }, { 421 | name: "Brian Kernaghan", 422 | score: 69, 423 | grade: "D" 424 | }, { 425 | name: "Danielle Bunten Berry", 426 | score: 54, 427 | grade: "F" 428 | }, { 429 | name: "Donald Knuth", 430 | score: 83, 431 | grade: "B" 432 | }, { 433 | name: "Grace Hopper", 434 | score: 31, 435 | grade: "F" 436 | }, { 437 | name: "Hack Kerr", 438 | score: 94, 439 | grade: "A" 440 | }, { 441 | name: "James Gosling", 442 | score: 35, 443 | grade: "F" 444 | }, { 445 | name: "Ken Thompson", 446 | score: 67, 447 | grade: "D" 448 | }, { 449 | name: "Kevin Mitnick", 450 | score: 81, 451 | grade: "B" 452 | }, { 453 | name: "Linus Torvalds", 454 | score: 70, 455 | grade: "C" 456 | }, { 457 | name: "Niklaus Wirth", 458 | score: 74, 459 | grade: "C" 460 | }, { 461 | name: "Rebecca Heineman", 462 | score: 92, 463 | grade: "A" 464 | }, { 465 | name: "Tim Berners-Lee", 466 | score: 48, 467 | grade: "F" 468 | }, { 469 | name: "Xiao Tian", 470 | score: 80, 471 | grade: "B" 472 | }, { 473 | name: "Ying Cracker", 474 | score: 84, 475 | grade: "B" 476 | }] 477 | }, { 478 | title: "Data Abstraction", 479 | instructor: "Aster Ricks", 480 | students: [{ 481 | name: "ve", 482 | score: 52, 483 | grade: "F" 484 | }, { 485 | name: "Albert Gonzalez", 486 | score: 70, 487 | grade: "C" 488 | }, { 489 | name: "Brian Kernaghan", 490 | score: 89, 491 | grade: "B" 492 | }, { 493 | name: "Danielle Bunten Berry", 494 | score: 38, 495 | grade: "F" 496 | }, { 497 | name: "Donald Knuth", 498 | score: 86, 499 | grade: "B" 500 | }, { 501 | name: "Grace Hopper", 502 | score: 42, 503 | grade: "F" 504 | }, { 505 | name: "Hack Kerr", 506 | score: 87, 507 | grade: "F" 508 | }, { 509 | name: "James Gosling", 510 | score: 89, 511 | grade: "B" 512 | }, { 513 | name: "Ken Thompson", 514 | score: 86, 515 | grade: "B" 516 | }, { 517 | name: "Kevin Mitnick", 518 | score: 41, 519 | grade: "F" 520 | }, { 521 | name: "Linus Torvalds", 522 | score: 76, 523 | grade: "C" 524 | }, { 525 | name: "Niklaus Wirth", 526 | score: 78, 527 | grade: "C" 528 | }, { 529 | name: "Rebecca Heineman", 530 | score: 70, 531 | grade: "C" 532 | }, { 533 | name: "Tim Berners-Lee", 534 | score: 74, 535 | grade: "C" 536 | }, { 537 | name: "Xiao Tian", 538 | score: 93, 539 | grade: "A" 540 | }, { 541 | name: "Ying Cracker", 542 | score: 95, 543 | grade: "A" 544 | }] 545 | }, { 546 | title: "Data Structures", 547 | instructor: "Brodal Q.", 548 | students: [{ 549 | name: "ng", 550 | score: 58, 551 | grade: "F" 552 | }, { 553 | name: "Albert Gonzalez", 554 | score: 56, 555 | grade: "F" 556 | }, { 557 | name: "Brian Kernaghan", 558 | score: 58, 559 | grade: "F" 560 | }, { 561 | name: "Danielle Bunten Berry", 562 | score: 38, 563 | grade: "F" 564 | }, { 565 | name: "Donald Knuth", 566 | score: 85, 567 | grade: "B" 568 | }, { 569 | name: "Grace Hopper", 570 | score: 53, 571 | grade: "F" 572 | }, { 573 | name: "Hack Kerr", 574 | score: 89, 575 | grade: "B" 576 | }, { 577 | name: "James Gosling", 578 | score: 42, 579 | grade: "F" 580 | }, { 581 | name: "Ken Thompson", 582 | score: 87, 583 | grade: "B" 584 | }, { 585 | name: "Kevin Mitnick", 586 | score: 40, 587 | grade: "F" 588 | }, { 589 | name: "Linus Torvalds", 590 | score: 91, 591 | grade: "A" 592 | }, { 593 | name: "Niklaus Wirth", 594 | score: 51, 595 | grade: "F" 596 | }, { 597 | name: "Rebecca Heineman", 598 | score: 79, 599 | grade: "C" 600 | }, { 601 | name: "Tim Berners-Lee", 602 | score: 37, 603 | grade: "F" 604 | }, { 605 | name: "Xiao Tian", 606 | score: 84, 607 | grade: "B" 608 | }, { 609 | name: "Ying Cracker", 610 | score: 45, 611 | grade: "F" 612 | }] 613 | }, { 614 | title: "Networks", 615 | instructor: "Van Emde Boas", 616 | students: [{ 617 | name: "e!", 618 | score: 35, 619 | grade: "F" 620 | }, { 621 | name: "Albert Gonzalez", 622 | score: 52, 623 | grade: "F" 624 | }, { 625 | name: "Brian Kernaghan", 626 | score: 61, 627 | grade: "D" 628 | }, { 629 | name: "Danielle Bunten Berry", 630 | score: 59, 631 | grade: "F" 632 | }, { 633 | name: "Donald Knuth", 634 | score: 89, 635 | grade: "B" 636 | }, { 637 | name: "Grace Hopper", 638 | score: 40, 639 | grade: "F" 640 | }, { 641 | name: "Hack Kerr", 642 | score: 102, 643 | grade: "F" 644 | }, { 645 | name: "James Gosling", 646 | score: 39, 647 | grade: "F" 648 | }, { 649 | name: "Ken Thompson", 650 | score: 83, 651 | grade: "B" 652 | }, { 653 | name: "Kevin Mitnick", 654 | score: 37, 655 | grade: "F" 656 | }, { 657 | name: "Linus Torvalds", 658 | score: 65, 659 | grade: "D" 660 | }, { 661 | name: "Niklaus Wirth", 662 | score: 36, 663 | grade: "F" 664 | }, { 665 | name: "Rebecca Heineman", 666 | score: 32, 667 | grade: "F" 668 | }, { 669 | name: "Tim Berners-Lee", 670 | score: 70, 671 | grade: "C" 672 | }, { 673 | name: "Xiao Tian", 674 | score: 52, 675 | grade: "F" 676 | }, { 677 | name: "Ying Cracker", 678 | score: 62, 679 | grade: "D" 680 | }] 681 | }]; 682 | export default courses; 683 | -------------------------------------------------------------------------------- /tutorial/data/students2.js: -------------------------------------------------------------------------------- 1 | var students=[{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"!f",score:91,grade:"A"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Albert Gonzalez",score:35,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Brian Kernaghan",score:35,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Danielle Bunten Berry",score:78,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Donald Knuth",score:94,grade:"A"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Grace Hopper",score:36,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Hack Kerr",score:85,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"James Gosling",score:30,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Ken Thompson",score:30,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Kevin Mitnick",score:72,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Linus Torvalds",score:34,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Niklaus Wirth",score:75,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Rebecca Heineman",score:71,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Tim Berners-Lee",score:54,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Xiao Tian",score:67,grade:"D"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Ying Cracker",score:57,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"in",score:88,grade:"B"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Albert Gonzalez",score:37,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Brian Kernaghan",score:76,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Danielle Bunten Berry",score:53,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Donald Knuth",score:34,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Grace Hopper",score:74,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Hack Kerr",score:86,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"James Gosling",score:94,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Ken Thompson",score:48,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Kevin Mitnick",score:52,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Linus Torvalds",score:90,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Niklaus Wirth",score:78,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Rebecca Heineman",score:73,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Tim Berners-Lee",score:94,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Xiao Tian",score:45,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Ying Cracker",score:77,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"dt",score:61,grade:"D"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Albert Gonzalez",score:73,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Brian Kernaghan",score:47,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Danielle Bunten Berry",score:87,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Donald Knuth",score:80,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Grace Hopper",score:80,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Hack Kerr",score:92,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"James Gosling",score:97,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Ken Thompson",score:64,grade:"D"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Kevin Mitnick",score:47,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Linus Torvalds",score:58,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Niklaus Wirth",score:93,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Rebecca Heineman",score:58,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Tim Berners-Lee",score:98,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Xiao Tian",score:36,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Ying Cracker",score:73,grade:"C"},{title:"Web Security",instructor:"Sue Denim",name:"Donald Knuth",score:44,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Albert Gonzalez",score:74,grade:"C"},{title:"Web Security",instructor:"Sue Denim",name:"Brian Kernaghan",score:92,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Danielle Bunten Berry",score:34,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"he",score:81,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Grace Hopper",score:81,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Hack Kerr",score:75,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"James Gosling",score:95,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Ken Thompson",score:84,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Kevin Mitnick",score:89,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Linus Torvalds",score:57,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Niklaus Wirth",score:88,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Rebecca Heineman",score:93,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Tim Berners-Lee",score:36,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Xiao Tian",score:87,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Ying Cracker",score:42,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"be",score:73,grade:"C"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Albert Gonzalez",score:94,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Brian Kernaghan",score:71,grade:"C"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Danielle Bunten Berry",score:66,grade:"D"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Donald Knuth",score:94,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Grace Hopper",score:99,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Hack Kerr",score:83,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"James Gosling",score:99,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Ken Thompson",score:65,grade:"D"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Kevin Mitnick",score:47,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Linus Torvalds",score:93,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Niklaus Wirth",score:50,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Rebecca Heineman",score:33,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Tim Berners-Lee",score:51,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Xiao Tian",score:87,grade:"B"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Ying Cracker",score:60,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"st",score:58,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Albert Gonzalez",score:67,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Brian Kernaghan",score:66,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Danielle Bunten Berry",score:36,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Donald Knuth",score:36,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Grace Hopper",score:66,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Hack Kerr",score:96,grade:"A"},{title:"Data Science",instructor:"Ford Fulkerson",name:"James Gosling",score:83,grade:"B"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Ken Thompson",score:35,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Kevin Mitnick",score:75,grade:"C"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Linus Torvalds",score:63,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Niklaus Wirth",score:75,grade:"C"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Rebecca Heineman",score:84,grade:"B"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Tim Berners-Lee",score:41,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Xiao Tian",score:49,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Ying Cracker",score:96,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"re",score:93,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Albert Gonzalez",score:39,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Brian Kernaghan",score:69,grade:"D"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Danielle Bunten Berry",score:54,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Donald Knuth",score:83,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Grace Hopper",score:31,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Hack Kerr",score:94,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"James Gosling",score:35,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Ken Thompson",score:67,grade:"D"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Kevin Mitnick",score:81,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Linus Torvalds",score:70,grade:"C"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Niklaus Wirth",score:74,grade:"C"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Rebecca Heineman",score:92,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Tim Berners-Lee",score:48,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Xiao Tian",score:80,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Ying Cracker",score:84,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"ve",score:82,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Albert Gonzalez",score:70,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Brian Kernaghan",score:89,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Danielle Bunten Berry",score:38,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Donald Knuth",score:86,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Grace Hopper",score:42,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Hack Kerr",score:87,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"James Gosling",score:89,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Ken Thompson",score:86,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Kevin Mitnick",score:41,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Linus Torvalds",score:76,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Niklaus Wirth",score:78,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Rebecca Heineman",score:70,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Tim Berners-Lee",score:74,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Xiao Tian",score:93,grade:"A"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Ying Cracker",score:95,grade:"A"},{title:"Data Structures",instructor:"Brodal Q.",name:"ng",score:88,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Albert Gonzalez",score:56,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Brian Kernaghan",score:58,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Danielle Bunten Berry",score:38,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Donald Knuth",score:85,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Grace Hopper",score:53,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Hack Kerr",score:89,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"James Gosling",score:42,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Ken Thompson",score:87,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Kevin Mitnick",score:40,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Linus Torvalds",score:91,grade:"A"},{title:"Data Structures",instructor:"Brodal Q.",name:"Niklaus Wirth",score:51,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Rebecca Heineman",score:79,grade:"C"},{title:"Data Structures",instructor:"Brodal Q.",name:"Tim Berners-Lee",score:37,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Xiao Tian",score:84,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Ying Cracker",score:45,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"e!",score:65,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Albert Gonzalez",score:52,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Brian Kernaghan",score:61,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Danielle Bunten Berry",score:59,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Donald Knuth",score:89,grade:"B"},{title:"Networks",instructor:"Van Emde Boas",name:"Grace Hopper",score:40,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Hack Kerr",score:102,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"James Gosling",score:39,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Ken Thompson",score:83,grade:"B"},{title:"Networks",instructor:"Van Emde Boas",name:"Kevin Mitnick",score:37,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Linus Torvalds",score:65,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Niklaus Wirth",score:36,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Rebecca Heineman",score:32,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Tim Berners-Lee",score:70,grade:"C"},{title:"Networks",instructor:"Van Emde Boas",name:"Xiao Tian",score:52,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Ying Cracker",score:62,grade:"D"}]; 2 | -------------------------------------------------------------------------------- /tutorial/data/students.js: -------------------------------------------------------------------------------- 1 | var students=[{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Ada Lovelace",score:91,grade:"A"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Albert Gonzalez",score:35,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Brian Kernaghan",score:35,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Danielle Bunten Berry",score:78,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Donald Knuth",score:94,grade:"A"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Grace Hopper",score:36,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Hack Kerr",score:85,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"James Gosling",score:30,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Ken Thompson",score:30,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Kevin Mitnick",score:72,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Linus Torvalds",score:34,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Niklaus Wirth",score:75,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Rebecca Heineman",score:71,grade:"C"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Tim Berners-Lee",score:54,grade:"F"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Xiao Tian",score:67,grade:"D"},{title:"Relational Databases",instructor:"Sean Quentin Lewis",name:"Ying Cracker",score:57,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Ada Lovelace",score:88,grade:"B"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Albert Gonzalez",score:37,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Brian Kernaghan",score:76,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Danielle Bunten Berry",score:53,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Donald Knuth",score:34,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Grace Hopper",score:74,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Hack Kerr",score:86,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"James Gosling",score:94,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Ken Thompson",score:48,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Kevin Mitnick",score:52,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Linus Torvalds",score:90,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Niklaus Wirth",score:78,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Rebecca Heineman",score:73,grade:"C"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Tim Berners-Lee",score:94,grade:"A"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Xiao Tian",score:45,grade:"F"},{title:"3D Computer Graphics",instructor:"G.L. Webb",name:"Ying Cracker",score:77,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Ada Lovelace",score:61,grade:"D"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Albert Gonzalez",score:73,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Brian Kernaghan",score:47,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Danielle Bunten Berry",score:87,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Donald Knuth",score:80,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Grace Hopper",score:80,grade:"B"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Hack Kerr",score:92,grade:"C"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"James Gosling",score:97,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Ken Thompson",score:64,grade:"D"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Kevin Mitnick",score:47,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Linus Torvalds",score:58,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Niklaus Wirth",score:93,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Rebecca Heineman",score:58,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Tim Berners-Lee",score:98,grade:"A"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Xiao Tian",score:36,grade:"F"},{title:"Front End Web Development",instructor:"Moe Zaick",name:"Ying Cracker",score:73,grade:"C"},{title:"Web Security",instructor:"Sue Denim",name:"Ada Lovelace",score:81,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Albert Gonzalez",score:74,grade:"C"},{title:"Web Security",instructor:"Sue Denim",name:"Brian Kernaghan",score:92,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Danielle Bunten Berry",score:34,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Donald Knuth",score:44,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Grace Hopper",score:81,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Hack Kerr",score:75,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"James Gosling",score:95,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Ken Thompson",score:84,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Kevin Mitnick",score:89,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Linus Torvalds",score:57,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Niklaus Wirth",score:88,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Rebecca Heineman",score:93,grade:"A"},{title:"Web Security",instructor:"Sue Denim",name:"Tim Berners-Lee",score:36,grade:"F"},{title:"Web Security",instructor:"Sue Denim",name:"Xiao Tian",score:87,grade:"B"},{title:"Web Security",instructor:"Sue Denim",name:"Ying Cracker",score:42,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Ada Lovelace",score:73,grade:"C"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Albert Gonzalez",score:94,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Brian Kernaghan",score:71,grade:"C"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Danielle Bunten Berry",score:66,grade:"D"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Donald Knuth",score:94,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Grace Hopper",score:99,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Hack Kerr",score:83,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"James Gosling",score:99,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Ken Thompson",score:65,grade:"D"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Kevin Mitnick",score:47,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Linus Torvalds",score:93,grade:"A"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Niklaus Wirth",score:50,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Rebecca Heineman",score:33,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Tim Berners-Lee",score:51,grade:"F"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Xiao Tian",score:87,grade:"B"},{title:"Javascript Fundamentals",instructor:"Jay Kweerie",name:"Ying Cracker",score:60,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Ada Lovelace",score:58,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Albert Gonzalez",score:67,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Brian Kernaghan",score:66,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Danielle Bunten Berry",score:36,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Donald Knuth",score:36,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Grace Hopper",score:66,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Hack Kerr",score:96,grade:"A"},{title:"Data Science",instructor:"Ford Fulkerson",name:"James Gosling",score:83,grade:"B"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Ken Thompson",score:35,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Kevin Mitnick",score:75,grade:"C"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Linus Torvalds",score:63,grade:"D"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Niklaus Wirth",score:75,grade:"C"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Rebecca Heineman",score:84,grade:"B"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Tim Berners-Lee",score:41,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Xiao Tian",score:49,grade:"F"},{title:"Data Science",instructor:"Ford Fulkerson",name:"Ying Cracker",score:96,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Ada Lovelace",score:93,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Albert Gonzalez",score:39,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Brian Kernaghan",score:69,grade:"D"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Danielle Bunten Berry",score:54,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Donald Knuth",score:83,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Grace Hopper",score:31,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Hack Kerr",score:94,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"James Gosling",score:35,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Ken Thompson",score:67,grade:"D"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Kevin Mitnick",score:81,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Linus Torvalds",score:70,grade:"C"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Niklaus Wirth",score:74,grade:"C"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Rebecca Heineman",score:92,grade:"A"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Tim Berners-Lee",score:48,grade:"F"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Xiao Tian",score:80,grade:"B"},{title:"Algorithm Design",instructor:"Gale Shapely",name:"Ying Cracker",score:84,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Ada Lovelace",score:82,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Albert Gonzalez",score:70,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Brian Kernaghan",score:89,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Danielle Bunten Berry",score:38,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Donald Knuth",score:86,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Grace Hopper",score:42,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Hack Kerr",score:87,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"James Gosling",score:89,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Ken Thompson",score:86,grade:"B"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Kevin Mitnick",score:41,grade:"F"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Linus Torvalds",score:76,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Niklaus Wirth",score:78,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Rebecca Heineman",score:70,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Tim Berners-Lee",score:74,grade:"C"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Xiao Tian",score:93,grade:"A"},{title:"Data Abstraction",instructor:"Aster Ricks",name:"Ying Cracker",score:95,grade:"A"},{title:"Data Structures",instructor:"Brodal Q.",name:"Ada Lovelace",score:88,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Albert Gonzalez",score:56,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Brian Kernaghan",score:58,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Danielle Bunten Berry",score:38,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Donald Knuth",score:85,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Grace Hopper",score:53,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Hack Kerr",score:89,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"James Gosling",score:42,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Ken Thompson",score:87,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Kevin Mitnick",score:40,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Linus Torvalds",score:91,grade:"A"},{title:"Data Structures",instructor:"Brodal Q.",name:"Niklaus Wirth",score:51,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Rebecca Heineman",score:79,grade:"C"},{title:"Data Structures",instructor:"Brodal Q.",name:"Tim Berners-Lee",score:37,grade:"F"},{title:"Data Structures",instructor:"Brodal Q.",name:"Xiao Tian",score:84,grade:"B"},{title:"Data Structures",instructor:"Brodal Q.",name:"Ying Cracker",score:45,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Ada Lovelace",score:65,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Albert Gonzalez",score:52,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Brian Kernaghan",score:61,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Danielle Bunten Berry",score:59,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Donald Knuth",score:89,grade:"B"},{title:"Networks",instructor:"Van Emde Boas",name:"Grace Hopper",score:40,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Hack Kerr",score:102,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"James Gosling",score:39,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Ken Thompson",score:83,grade:"B"},{title:"Networks",instructor:"Van Emde Boas",name:"Kevin Mitnick",score:37,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Linus Torvalds",score:65,grade:"D"},{title:"Networks",instructor:"Van Emde Boas",name:"Niklaus Wirth",score:36,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Rebecca Heineman",score:32,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Tim Berners-Lee",score:70,grade:"C"},{title:"Networks",instructor:"Van Emde Boas",name:"Xiao Tian",score:52,grade:"F"},{title:"Networks",instructor:"Van Emde Boas",name:"Ying Cracker",score:62,grade:"D"}]; 2 | -------------------------------------------------------------------------------- /tutorial/00/data.js: -------------------------------------------------------------------------------- 1 | const students = [{ 2 | title: "Relational Databases", 3 | instructor: "Sean Quentin Lewis", 4 | name: "Ada Lovelace", 5 | score: 91, 6 | grade: "A" 7 | }, { 8 | title: "Relational Databases", 9 | instructor: "Sean Quentin Lewis", 10 | name: "Albert Gonzalez", 11 | score: 35, 12 | grade: "F" 13 | }, { 14 | title: "Relational Databases", 15 | instructor: "Sean Quentin Lewis", 16 | name: "Brian Kernaghan", 17 | score: 35, 18 | grade: "F" 19 | }, { 20 | title: "Relational Databases", 21 | instructor: "Sean Quentin Lewis", 22 | name: "Danielle Bunten Berry", 23 | score: 78, 24 | grade: "C" 25 | }, { 26 | title: "Relational Databases", 27 | instructor: "Sean Quentin Lewis", 28 | name: "Donald Knuth", 29 | score: 94, 30 | grade: "A" 31 | }, { 32 | title: "Relational Databases", 33 | instructor: "Sean Quentin Lewis", 34 | name: "Grace Hopper", 35 | score: 36, 36 | grade: "F" 37 | }, { 38 | title: "Relational Databases", 39 | instructor: "Sean Quentin Lewis", 40 | name: "Hack Kerr", 41 | score: 85, 42 | grade: "F" 43 | }, { 44 | title: "Relational Databases", 45 | instructor: "Sean Quentin Lewis", 46 | name: "James Gosling", 47 | score: 30, 48 | grade: "F" 49 | }, { 50 | title: "Relational Databases", 51 | instructor: "Sean Quentin Lewis", 52 | name: "Ken Thompson", 53 | score: 30, 54 | grade: "F" 55 | }, { 56 | title: "Relational Databases", 57 | instructor: "Sean Quentin Lewis", 58 | name: "Kevin Mitnick", 59 | score: 72, 60 | grade: "C" 61 | }, { 62 | title: "Relational Databases", 63 | instructor: "Sean Quentin Lewis", 64 | name: "Linus Torvalds", 65 | score: 34, 66 | grade: "F" 67 | }, { 68 | title: "Relational Databases", 69 | instructor: "Sean Quentin Lewis", 70 | name: "Niklaus Wirth", 71 | score: 75, 72 | grade: "C" 73 | }, { 74 | title: "Relational Databases", 75 | instructor: "Sean Quentin Lewis", 76 | name: "Rebecca Heineman", 77 | score: 71, 78 | grade: "C" 79 | }, { 80 | title: "Relational Databases", 81 | instructor: "Sean Quentin Lewis", 82 | name: "Tim Berners-Lee", 83 | score: 54, 84 | grade: "F" 85 | }, { 86 | title: "Relational Databases", 87 | instructor: "Sean Quentin Lewis", 88 | name: "Xiao Tian", 89 | score: 67, 90 | grade: "D" 91 | }, { 92 | title: "Relational Databases", 93 | instructor: "Sean Quentin Lewis", 94 | name: "Ying Cracker", 95 | score: 57, 96 | grade: "F" 97 | }, { 98 | title: "3D Computer Graphics", 99 | instructor: "G.L. Webb", 100 | name: "Ada Lovelace", 101 | score: 88, 102 | grade: "B" 103 | }, { 104 | title: "3D Computer Graphics", 105 | instructor: "G.L. Webb", 106 | name: "Albert Gonzalez", 107 | score: 37, 108 | grade: "F" 109 | }, { 110 | title: "3D Computer Graphics", 111 | instructor: "G.L. Webb", 112 | name: "Brian Kernaghan", 113 | score: 76, 114 | grade: "C" 115 | }, { 116 | title: "3D Computer Graphics", 117 | instructor: "G.L. Webb", 118 | name: "Danielle Bunten Berry", 119 | score: 53, 120 | grade: "F" 121 | }, { 122 | title: "3D Computer Graphics", 123 | instructor: "G.L. Webb", 124 | name: "Donald Knuth", 125 | score: 34, 126 | grade: "F" 127 | }, { 128 | title: "3D Computer Graphics", 129 | instructor: "G.L. Webb", 130 | name: "Grace Hopper", 131 | score: 74, 132 | grade: "C" 133 | }, { 134 | title: "3D Computer Graphics", 135 | instructor: "G.L. Webb", 136 | name: "Hack Kerr", 137 | score: 86, 138 | grade: "F" 139 | }, { 140 | title: "3D Computer Graphics", 141 | instructor: "G.L. Webb", 142 | name: "James Gosling", 143 | score: 94, 144 | grade: "A" 145 | }, { 146 | title: "3D Computer Graphics", 147 | instructor: "G.L. Webb", 148 | name: "Ken Thompson", 149 | score: 48, 150 | grade: "F" 151 | }, { 152 | title: "3D Computer Graphics", 153 | instructor: "G.L. Webb", 154 | name: "Kevin Mitnick", 155 | score: 52, 156 | grade: "F" 157 | }, { 158 | title: "3D Computer Graphics", 159 | instructor: "G.L. Webb", 160 | name: "Linus Torvalds", 161 | score: 90, 162 | grade: "A" 163 | }, { 164 | title: "3D Computer Graphics", 165 | instructor: "G.L. Webb", 166 | name: "Niklaus Wirth", 167 | score: 78, 168 | grade: "C" 169 | }, { 170 | title: "3D Computer Graphics", 171 | instructor: "G.L. Webb", 172 | name: "Rebecca Heineman", 173 | score: 73, 174 | grade: "C" 175 | }, { 176 | title: "3D Computer Graphics", 177 | instructor: "G.L. Webb", 178 | name: "Tim Berners-Lee", 179 | score: 94, 180 | grade: "A" 181 | }, { 182 | title: "3D Computer Graphics", 183 | instructor: "G.L. Webb", 184 | name: "Xiao Tian", 185 | score: 45, 186 | grade: "F" 187 | }, { 188 | title: "3D Computer Graphics", 189 | instructor: "G.L. Webb", 190 | name: "Ying Cracker", 191 | score: 77, 192 | grade: "C" 193 | }, { 194 | title: "Front End Web Development", 195 | instructor: "Moe Zaick", 196 | name: "Ada Lovelace", 197 | score: 61, 198 | grade: "D" 199 | }, { 200 | title: "Front End Web Development", 201 | instructor: "Moe Zaick", 202 | name: "Albert Gonzalez", 203 | score: 73, 204 | grade: "C" 205 | }, { 206 | title: "Front End Web Development", 207 | instructor: "Moe Zaick", 208 | name: "Brian Kernaghan", 209 | score: 47, 210 | grade: "F" 211 | }, { 212 | title: "Front End Web Development", 213 | instructor: "Moe Zaick", 214 | name: "Danielle Bunten Berry", 215 | score: 87, 216 | grade: "B" 217 | }, { 218 | title: "Front End Web Development", 219 | instructor: "Moe Zaick", 220 | name: "Donald Knuth", 221 | score: 80, 222 | grade: "B" 223 | }, { 224 | title: "Front End Web Development", 225 | instructor: "Moe Zaick", 226 | name: "Grace Hopper", 227 | score: 80, 228 | grade: "B" 229 | }, { 230 | title: "Front End Web Development", 231 | instructor: "Moe Zaick", 232 | name: "Hack Kerr", 233 | score: 92, 234 | grade: "C" 235 | }, { 236 | title: "Front End Web Development", 237 | instructor: "Moe Zaick", 238 | name: "James Gosling", 239 | score: 97, 240 | grade: "A" 241 | }, { 242 | title: "Front End Web Development", 243 | instructor: "Moe Zaick", 244 | name: "Ken Thompson", 245 | score: 64, 246 | grade: "D" 247 | }, { 248 | title: "Front End Web Development", 249 | instructor: "Moe Zaick", 250 | name: "Kevin Mitnick", 251 | score: 47, 252 | grade: "F" 253 | }, { 254 | title: "Front End Web Development", 255 | instructor: "Moe Zaick", 256 | name: "Linus Torvalds", 257 | score: 58, 258 | grade: "F" 259 | }, { 260 | title: "Front End Web Development", 261 | instructor: "Moe Zaick", 262 | name: "Niklaus Wirth", 263 | score: 93, 264 | grade: "A" 265 | }, { 266 | title: "Front End Web Development", 267 | instructor: "Moe Zaick", 268 | name: "Rebecca Heineman", 269 | score: 58, 270 | grade: "F" 271 | }, { 272 | title: "Front End Web Development", 273 | instructor: "Moe Zaick", 274 | name: "Tim Berners-Lee", 275 | score: 98, 276 | grade: "A" 277 | }, { 278 | title: "Front End Web Development", 279 | instructor: "Moe Zaick", 280 | name: "Xiao Tian", 281 | score: 36, 282 | grade: "F" 283 | }, { 284 | title: "Front End Web Development", 285 | instructor: "Moe Zaick", 286 | name: "Ying Cracker", 287 | score: 73, 288 | grade: "C" 289 | }, { 290 | title: "Web Security", 291 | instructor: "Sue Denim", 292 | name: "Ada Lovelace", 293 | score: 81, 294 | grade: "B" 295 | }, { 296 | title: "Web Security", 297 | instructor: "Sue Denim", 298 | name: "Albert Gonzalez", 299 | score: 74, 300 | grade: "C" 301 | }, { 302 | title: "Web Security", 303 | instructor: "Sue Denim", 304 | name: "Brian Kernaghan", 305 | score: 92, 306 | grade: "A" 307 | }, { 308 | title: "Web Security", 309 | instructor: "Sue Denim", 310 | name: "Danielle Bunten Berry", 311 | score: 34, 312 | grade: "F" 313 | }, { 314 | title: "Web Security", 315 | instructor: "Sue Denim", 316 | name: "Donald Knuth", 317 | score: 44, 318 | grade: "F" 319 | }, { 320 | title: "Web Security", 321 | instructor: "Sue Denim", 322 | name: "Grace Hopper", 323 | score: 81, 324 | grade: "B" 325 | }, { 326 | title: "Web Security", 327 | instructor: "Sue Denim", 328 | name: "Hack Kerr", 329 | score: 75, 330 | grade: "F" 331 | }, { 332 | title: "Web Security", 333 | instructor: "Sue Denim", 334 | name: "James Gosling", 335 | score: 95, 336 | grade: "A" 337 | }, { 338 | title: "Web Security", 339 | instructor: "Sue Denim", 340 | name: "Ken Thompson", 341 | score: 84, 342 | grade: "B" 343 | }, { 344 | title: "Web Security", 345 | instructor: "Sue Denim", 346 | name: "Kevin Mitnick", 347 | score: 89, 348 | grade: "B" 349 | }, { 350 | title: "Web Security", 351 | instructor: "Sue Denim", 352 | name: "Linus Torvalds", 353 | score: 57, 354 | grade: "F" 355 | }, { 356 | title: "Web Security", 357 | instructor: "Sue Denim", 358 | name: "Niklaus Wirth", 359 | score: 88, 360 | grade: "B" 361 | }, { 362 | title: "Web Security", 363 | instructor: "Sue Denim", 364 | name: "Rebecca Heineman", 365 | score: 93, 366 | grade: "A" 367 | }, { 368 | title: "Web Security", 369 | instructor: "Sue Denim", 370 | name: "Tim Berners-Lee", 371 | score: 36, 372 | grade: "F" 373 | }, { 374 | title: "Web Security", 375 | instructor: "Sue Denim", 376 | name: "Xiao Tian", 377 | score: 87, 378 | grade: "B" 379 | }, { 380 | title: "Web Security", 381 | instructor: "Sue Denim", 382 | name: "Ying Cracker", 383 | score: 42, 384 | grade: "F" 385 | }, { 386 | title: "Javascript Fundamentals", 387 | instructor: "Jay Kweerie", 388 | name: "Ada Lovelace", 389 | score: 73, 390 | grade: "C" 391 | }, { 392 | title: "Javascript Fundamentals", 393 | instructor: "Jay Kweerie", 394 | name: "Albert Gonzalez", 395 | score: 94, 396 | grade: "A" 397 | }, { 398 | title: "Javascript Fundamentals", 399 | instructor: "Jay Kweerie", 400 | name: "Brian Kernaghan", 401 | score: 71, 402 | grade: "C" 403 | }, { 404 | title: "Javascript Fundamentals", 405 | instructor: "Jay Kweerie", 406 | name: "Danielle Bunten Berry", 407 | score: 66, 408 | grade: "D" 409 | }, { 410 | title: "Javascript Fundamentals", 411 | instructor: "Jay Kweerie", 412 | name: "Donald Knuth", 413 | score: 94, 414 | grade: "A" 415 | }, { 416 | title: "Javascript Fundamentals", 417 | instructor: "Jay Kweerie", 418 | name: "Grace Hopper", 419 | score: 99, 420 | grade: "A" 421 | }, { 422 | title: "Javascript Fundamentals", 423 | instructor: "Jay Kweerie", 424 | name: "Hack Kerr", 425 | score: 83, 426 | grade: "F" 427 | }, { 428 | title: "Javascript Fundamentals", 429 | instructor: "Jay Kweerie", 430 | name: "James Gosling", 431 | score: 99, 432 | grade: "A" 433 | }, { 434 | title: "Javascript Fundamentals", 435 | instructor: "Jay Kweerie", 436 | name: "Ken Thompson", 437 | score: 65, 438 | grade: "D" 439 | }, { 440 | title: "Javascript Fundamentals", 441 | instructor: "Jay Kweerie", 442 | name: "Kevin Mitnick", 443 | score: 47, 444 | grade: "F" 445 | }, { 446 | title: "Javascript Fundamentals", 447 | instructor: "Jay Kweerie", 448 | name: "Linus Torvalds", 449 | score: 93, 450 | grade: "A" 451 | }, { 452 | title: "Javascript Fundamentals", 453 | instructor: "Jay Kweerie", 454 | name: "Niklaus Wirth", 455 | score: 50, 456 | grade: "F" 457 | }, { 458 | title: "Javascript Fundamentals", 459 | instructor: "Jay Kweerie", 460 | name: "Rebecca Heineman", 461 | score: 33, 462 | grade: "F" 463 | }, { 464 | title: "Javascript Fundamentals", 465 | instructor: "Jay Kweerie", 466 | name: "Tim Berners-Lee", 467 | score: 51, 468 | grade: "F" 469 | }, { 470 | title: "Javascript Fundamentals", 471 | instructor: "Jay Kweerie", 472 | name: "Xiao Tian", 473 | score: 87, 474 | grade: "B" 475 | }, { 476 | title: "Javascript Fundamentals", 477 | instructor: "Jay Kweerie", 478 | name: "Ying Cracker", 479 | score: 60, 480 | grade: "D" 481 | }, { 482 | title: "Data Science", 483 | instructor: "Ford Fulkerson", 484 | name: "Ada Lovelace", 485 | score: 58, 486 | grade: "F" 487 | }, { 488 | title: "Data Science", 489 | instructor: "Ford Fulkerson", 490 | name: "Albert Gonzalez", 491 | score: 67, 492 | grade: "D" 493 | }, { 494 | title: "Data Science", 495 | instructor: "Ford Fulkerson", 496 | name: "Brian Kernaghan", 497 | score: 66, 498 | grade: "D" 499 | }, { 500 | title: "Data Science", 501 | instructor: "Ford Fulkerson", 502 | name: "Danielle Bunten Berry", 503 | score: 36, 504 | grade: "F" 505 | }, { 506 | title: "Data Science", 507 | instructor: "Ford Fulkerson", 508 | name: "Donald Knuth", 509 | score: 36, 510 | grade: "F" 511 | }, { 512 | title: "Data Science", 513 | instructor: "Ford Fulkerson", 514 | name: "Grace Hopper", 515 | score: 66, 516 | grade: "D" 517 | }, { 518 | title: "Data Science", 519 | instructor: "Ford Fulkerson", 520 | name: "Hack Kerr", 521 | score: 96, 522 | grade: "A" 523 | }, { 524 | title: "Data Science", 525 | instructor: "Ford Fulkerson", 526 | name: "James Gosling", 527 | score: 83, 528 | grade: "B" 529 | }, { 530 | title: "Data Science", 531 | instructor: "Ford Fulkerson", 532 | name: "Ken Thompson", 533 | score: 35, 534 | grade: "F" 535 | }, { 536 | title: "Data Science", 537 | instructor: "Ford Fulkerson", 538 | name: "Kevin Mitnick", 539 | score: 75, 540 | grade: "C" 541 | }, { 542 | title: "Data Science", 543 | instructor: "Ford Fulkerson", 544 | name: "Linus Torvalds", 545 | score: 63, 546 | grade: "D" 547 | }, { 548 | title: "Data Science", 549 | instructor: "Ford Fulkerson", 550 | name: "Niklaus Wirth", 551 | score: 75, 552 | grade: "C" 553 | }, { 554 | title: "Data Science", 555 | instructor: "Ford Fulkerson", 556 | name: "Rebecca Heineman", 557 | score: 84, 558 | grade: "B" 559 | }, { 560 | title: "Data Science", 561 | instructor: "Ford Fulkerson", 562 | name: "Tim Berners-Lee", 563 | score: 41, 564 | grade: "F" 565 | }, { 566 | title: "Data Science", 567 | instructor: "Ford Fulkerson", 568 | name: "Xiao Tian", 569 | score: 49, 570 | grade: "F" 571 | }, { 572 | title: "Data Science", 573 | instructor: "Ford Fulkerson", 574 | name: "Ying Cracker", 575 | score: 96, 576 | grade: "A" 577 | }, { 578 | title: "Algorithm Design", 579 | instructor: "Gale Shapely", 580 | name: "Ada Lovelace", 581 | score: 93, 582 | grade: "A" 583 | }, { 584 | title: "Algorithm Design", 585 | instructor: "Gale Shapely", 586 | name: "Albert Gonzalez", 587 | score: 39, 588 | grade: "F" 589 | }, { 590 | title: "Algorithm Design", 591 | instructor: "Gale Shapely", 592 | name: "Brian Kernaghan", 593 | score: 69, 594 | grade: "D" 595 | }, { 596 | title: "Algorithm Design", 597 | instructor: "Gale Shapely", 598 | name: "Danielle Bunten Berry", 599 | score: 54, 600 | grade: "F" 601 | }, { 602 | title: "Algorithm Design", 603 | instructor: "Gale Shapely", 604 | name: "Donald Knuth", 605 | score: 83, 606 | grade: "B" 607 | }, { 608 | title: "Algorithm Design", 609 | instructor: "Gale Shapely", 610 | name: "Grace Hopper", 611 | score: 31, 612 | grade: "F" 613 | }, { 614 | title: "Algorithm Design", 615 | instructor: "Gale Shapely", 616 | name: "Hack Kerr", 617 | score: 94, 618 | grade: "A" 619 | }, { 620 | title: "Algorithm Design", 621 | instructor: "Gale Shapely", 622 | name: "James Gosling", 623 | score: 35, 624 | grade: "F" 625 | }, { 626 | title: "Algorithm Design", 627 | instructor: "Gale Shapely", 628 | name: "Ken Thompson", 629 | score: 67, 630 | grade: "D" 631 | }, { 632 | title: "Algorithm Design", 633 | instructor: "Gale Shapely", 634 | name: "Kevin Mitnick", 635 | score: 81, 636 | grade: "B" 637 | }, { 638 | title: "Algorithm Design", 639 | instructor: "Gale Shapely", 640 | name: "Linus Torvalds", 641 | score: 70, 642 | grade: "C" 643 | }, { 644 | title: "Algorithm Design", 645 | instructor: "Gale Shapely", 646 | name: "Niklaus Wirth", 647 | score: 74, 648 | grade: "C" 649 | }, { 650 | title: "Algorithm Design", 651 | instructor: "Gale Shapely", 652 | name: "Rebecca Heineman", 653 | score: 92, 654 | grade: "A" 655 | }, { 656 | title: "Algorithm Design", 657 | instructor: "Gale Shapely", 658 | name: "Tim Berners-Lee", 659 | score: 48, 660 | grade: "F" 661 | }, { 662 | title: "Algorithm Design", 663 | instructor: "Gale Shapely", 664 | name: "Xiao Tian", 665 | score: 80, 666 | grade: "B" 667 | }, { 668 | title: "Algorithm Design", 669 | instructor: "Gale Shapely", 670 | name: "Ying Cracker", 671 | score: 84, 672 | grade: "B" 673 | }, { 674 | title: "Data Abstraction", 675 | instructor: "Aster Ricks", 676 | name: "Ada Lovelace", 677 | score: 82, 678 | grade: "B" 679 | }, { 680 | title: "Data Abstraction", 681 | instructor: "Aster Ricks", 682 | name: "Albert Gonzalez", 683 | score: 70, 684 | grade: "C" 685 | }, { 686 | title: "Data Abstraction", 687 | instructor: "Aster Ricks", 688 | name: "Brian Kernaghan", 689 | score: 89, 690 | grade: "B" 691 | }, { 692 | title: "Data Abstraction", 693 | instructor: "Aster Ricks", 694 | name: "Danielle Bunten Berry", 695 | score: 38, 696 | grade: "F" 697 | }, { 698 | title: "Data Abstraction", 699 | instructor: "Aster Ricks", 700 | name: "Donald Knuth", 701 | score: 86, 702 | grade: "B" 703 | }, { 704 | title: "Data Abstraction", 705 | instructor: "Aster Ricks", 706 | name: "Grace Hopper", 707 | score: 42, 708 | grade: "F" 709 | }, { 710 | title: "Data Abstraction", 711 | instructor: "Aster Ricks", 712 | name: "Hack Kerr", 713 | score: 87, 714 | grade: "F" 715 | }, { 716 | title: "Data Abstraction", 717 | instructor: "Aster Ricks", 718 | name: "James Gosling", 719 | score: 89, 720 | grade: "B" 721 | }, { 722 | title: "Data Abstraction", 723 | instructor: "Aster Ricks", 724 | name: "Ken Thompson", 725 | score: 86, 726 | grade: "B" 727 | }, { 728 | title: "Data Abstraction", 729 | instructor: "Aster Ricks", 730 | name: "Kevin Mitnick", 731 | score: 41, 732 | grade: "F" 733 | }, { 734 | title: "Data Abstraction", 735 | instructor: "Aster Ricks", 736 | name: "Linus Torvalds", 737 | score: 76, 738 | grade: "C" 739 | }, { 740 | title: "Data Abstraction", 741 | instructor: "Aster Ricks", 742 | name: "Niklaus Wirth", 743 | score: 78, 744 | grade: "C" 745 | }, { 746 | title: "Data Abstraction", 747 | instructor: "Aster Ricks", 748 | name: "Rebecca Heineman", 749 | score: 70, 750 | grade: "C" 751 | }, { 752 | title: "Data Abstraction", 753 | instructor: "Aster Ricks", 754 | name: "Tim Berners-Lee", 755 | score: 74, 756 | grade: "C" 757 | }, { 758 | title: "Data Abstraction", 759 | instructor: "Aster Ricks", 760 | name: "Xiao Tian", 761 | score: 93, 762 | grade: "A" 763 | }, { 764 | title: "Data Abstraction", 765 | instructor: "Aster Ricks", 766 | name: "Ying Cracker", 767 | score: 95, 768 | grade: "A" 769 | }, { 770 | title: "Data Structures", 771 | instructor: "Brodal Q.", 772 | name: "Ada Lovelace", 773 | score: 88, 774 | grade: "B" 775 | }, { 776 | title: "Data Structures", 777 | instructor: "Brodal Q.", 778 | name: "Albert Gonzalez", 779 | score: 56, 780 | grade: "F" 781 | }, { 782 | title: "Data Structures", 783 | instructor: "Brodal Q.", 784 | name: "Brian Kernaghan", 785 | score: 58, 786 | grade: "F" 787 | }, { 788 | title: "Data Structures", 789 | instructor: "Brodal Q.", 790 | name: "Danielle Bunten Berry", 791 | score: 38, 792 | grade: "F" 793 | }, { 794 | title: "Data Structures", 795 | instructor: "Brodal Q.", 796 | name: "Donald Knuth", 797 | score: 85, 798 | grade: "B" 799 | }, { 800 | title: "Data Structures", 801 | instructor: "Brodal Q.", 802 | name: "Grace Hopper", 803 | score: 53, 804 | grade: "F" 805 | }, { 806 | title: "Data Structures", 807 | instructor: "Brodal Q.", 808 | name: "Hack Kerr", 809 | score: 89, 810 | grade: "B" 811 | }, { 812 | title: "Data Structures", 813 | instructor: "Brodal Q.", 814 | name: "James Gosling", 815 | score: 42, 816 | grade: "F" 817 | }, { 818 | title: "Data Structures", 819 | instructor: "Brodal Q.", 820 | name: "Ken Thompson", 821 | score: 87, 822 | grade: "B" 823 | }, { 824 | title: "Data Structures", 825 | instructor: "Brodal Q.", 826 | name: "Kevin Mitnick", 827 | score: 40, 828 | grade: "F" 829 | }, { 830 | title: "Data Structures", 831 | instructor: "Brodal Q.", 832 | name: "Linus Torvalds", 833 | score: 91, 834 | grade: "A" 835 | }, { 836 | title: "Data Structures", 837 | instructor: "Brodal Q.", 838 | name: "Niklaus Wirth", 839 | score: 51, 840 | grade: "F" 841 | }, { 842 | title: "Data Structures", 843 | instructor: "Brodal Q.", 844 | name: "Rebecca Heineman", 845 | score: 79, 846 | grade: "C" 847 | }, { 848 | title: "Data Structures", 849 | instructor: "Brodal Q.", 850 | name: "Tim Berners-Lee", 851 | score: 37, 852 | grade: "F" 853 | }, { 854 | title: "Data Structures", 855 | instructor: "Brodal Q.", 856 | name: "Xiao Tian", 857 | score: 84, 858 | grade: "B" 859 | }, { 860 | title: "Data Structures", 861 | instructor: "Brodal Q.", 862 | name: "Ying Cracker", 863 | score: 45, 864 | grade: "F" 865 | }, { 866 | title: "Networks", 867 | instructor: "Van Emde Boas", 868 | name: "Ada Lovelace", 869 | score: 65, 870 | grade: "D" 871 | }, { 872 | title: "Networks", 873 | instructor: "Van Emde Boas", 874 | name: "Albert Gonzalez", 875 | score: 52, 876 | grade: "F" 877 | }, { 878 | title: "Networks", 879 | instructor: "Van Emde Boas", 880 | name: "Brian Kernaghan", 881 | score: 61, 882 | grade: "D" 883 | }, { 884 | title: "Networks", 885 | instructor: "Van Emde Boas", 886 | name: "Danielle Bunten Berry", 887 | score: 59, 888 | grade: "F" 889 | }, { 890 | title: "Networks", 891 | instructor: "Van Emde Boas", 892 | name: "Donald Knuth", 893 | score: 89, 894 | grade: "B" 895 | }, { 896 | title: "Networks", 897 | instructor: "Van Emde Boas", 898 | name: "Grace Hopper", 899 | score: 40, 900 | grade: "F" 901 | }, { 902 | title: "Networks", 903 | instructor: "Van Emde Boas", 904 | name: "Hack Kerr", 905 | score: 102, 906 | grade: "F" 907 | }, { 908 | title: "Networks", 909 | instructor: "Van Emde Boas", 910 | name: "James Gosling", 911 | score: 39, 912 | grade: "F" 913 | }, { 914 | title: "Networks", 915 | instructor: "Van Emde Boas", 916 | name: "Ken Thompson", 917 | score: 83, 918 | grade: "B" 919 | }, { 920 | title: "Networks", 921 | instructor: "Van Emde Boas", 922 | name: "Kevin Mitnick", 923 | score: 37, 924 | grade: "F" 925 | }, { 926 | title: "Networks", 927 | instructor: "Van Emde Boas", 928 | name: "Linus Torvalds", 929 | score: 65, 930 | grade: "D" 931 | }, { 932 | title: "Networks", 933 | instructor: "Van Emde Boas", 934 | name: "Niklaus Wirth", 935 | score: 36, 936 | grade: "F" 937 | }, { 938 | title: "Networks", 939 | instructor: "Van Emde Boas", 940 | name: "Rebecca Heineman", 941 | score: 32, 942 | grade: "F" 943 | }, { 944 | title: "Networks", 945 | instructor: "Van Emde Boas", 946 | name: "Tim Berners-Lee", 947 | score: 70, 948 | grade: "C" 949 | }, { 950 | title: "Networks", 951 | instructor: "Van Emde Boas", 952 | name: "Xiao Tian", 953 | score: 52, 954 | grade: "F" 955 | }, { 956 | title: "Networks", 957 | instructor: "Van Emde Boas", 958 | name: "Ying Cracker", 959 | score: 62, 960 | grade: "D" 961 | }]; 962 | export default students; 963 | -------------------------------------------------------------------------------- /tutorial/05/courses.js: -------------------------------------------------------------------------------- 1 | const courses = [{ 2 | title: "Relational Databases", 3 | instructor: "Sean Quentin Lewis", 4 | name: "!f", 5 | score: 91, 6 | grade: "A" 7 | }, { 8 | title: "Relational Databases", 9 | instructor: "Sean Quentin Lewis", 10 | name: "Albert Gonzalez", 11 | score: 35, 12 | grade: "F" 13 | }, { 14 | title: "Relational Databases", 15 | instructor: "Sean Quentin Lewis", 16 | name: "Brian Kernaghan", 17 | score: 35, 18 | grade: "F" 19 | }, { 20 | title: "Relational Databases", 21 | instructor: "Sean Quentin Lewis", 22 | name: "Danielle Bunten Berry", 23 | score: 78, 24 | grade: "C" 25 | }, { 26 | title: "Relational Databases", 27 | instructor: "Sean Quentin Lewis", 28 | name: "Donald Knuth", 29 | score: 94, 30 | grade: "A" 31 | }, { 32 | title: "Relational Databases", 33 | instructor: "Sean Quentin Lewis", 34 | name: "Grace Hopper", 35 | score: 36, 36 | grade: "F" 37 | }, { 38 | title: "Relational Databases", 39 | instructor: "Sean Quentin Lewis", 40 | name: "Hack Kerr", 41 | score: 85, 42 | grade: "F" 43 | }, { 44 | title: "Relational Databases", 45 | instructor: "Sean Quentin Lewis", 46 | name: "James Gosling", 47 | score: 30, 48 | grade: "F" 49 | }, { 50 | title: "Relational Databases", 51 | instructor: "Sean Quentin Lewis", 52 | name: "Ken Thompson", 53 | score: 30, 54 | grade: "F" 55 | }, { 56 | title: "Relational Databases", 57 | instructor: "Sean Quentin Lewis", 58 | name: "Kevin Mitnick", 59 | score: 72, 60 | grade: "C" 61 | }, { 62 | title: "Relational Databases", 63 | instructor: "Sean Quentin Lewis", 64 | name: "Linus Torvalds", 65 | score: 34, 66 | grade: "F" 67 | }, { 68 | title: "Relational Databases", 69 | instructor: "Sean Quentin Lewis", 70 | name: "Niklaus Wirth", 71 | score: 75, 72 | grade: "C" 73 | }, { 74 | title: "Relational Databases", 75 | instructor: "Sean Quentin Lewis", 76 | name: "Rebecca Heineman", 77 | score: 71, 78 | grade: "C" 79 | }, { 80 | title: "Relational Databases", 81 | instructor: "Sean Quentin Lewis", 82 | name: "Tim Berners-Lee", 83 | score: 54, 84 | grade: "F" 85 | }, { 86 | title: "Relational Databases", 87 | instructor: "Sean Quentin Lewis", 88 | name: "Xiao Tian", 89 | score: 67, 90 | grade: "D" 91 | }, { 92 | title: "Relational Databases", 93 | instructor: "Sean Quentin Lewis", 94 | name: "Ying Cracker", 95 | score: 57, 96 | grade: "F" 97 | }, { 98 | title: "3D Computer Graphics", 99 | instructor: "G.L. Webb", 100 | name: "in", 101 | score: 88, 102 | grade: "B" 103 | }, { 104 | title: "3D Computer Graphics", 105 | instructor: "G.L. Webb", 106 | name: "Albert Gonzalez", 107 | score: 37, 108 | grade: "F" 109 | }, { 110 | title: "3D Computer Graphics", 111 | instructor: "G.L. Webb", 112 | name: "Brian Kernaghan", 113 | score: 76, 114 | grade: "C" 115 | }, { 116 | title: "3D Computer Graphics", 117 | instructor: "G.L. Webb", 118 | name: "Danielle Bunten Berry", 119 | score: 53, 120 | grade: "F" 121 | }, { 122 | title: "3D Computer Graphics", 123 | instructor: "G.L. Webb", 124 | name: "Donald Knuth", 125 | score: 34, 126 | grade: "F" 127 | }, { 128 | title: "3D Computer Graphics", 129 | instructor: "G.L. Webb", 130 | name: "Grace Hopper", 131 | score: 74, 132 | grade: "C" 133 | }, { 134 | title: "3D Computer Graphics", 135 | instructor: "G.L. Webb", 136 | name: "Hack Kerr", 137 | score: 86, 138 | grade: "F" 139 | }, { 140 | title: "3D Computer Graphics", 141 | instructor: "G.L. Webb", 142 | name: "James Gosling", 143 | score: 94, 144 | grade: "A" 145 | }, { 146 | title: "3D Computer Graphics", 147 | instructor: "G.L. Webb", 148 | name: "Ken Thompson", 149 | score: 48, 150 | grade: "F" 151 | }, { 152 | title: "3D Computer Graphics", 153 | instructor: "G.L. Webb", 154 | name: "Kevin Mitnick", 155 | score: 52, 156 | grade: "F" 157 | }, { 158 | title: "3D Computer Graphics", 159 | instructor: "G.L. Webb", 160 | name: "Linus Torvalds", 161 | score: 90, 162 | grade: "A" 163 | }, { 164 | title: "3D Computer Graphics", 165 | instructor: "G.L. Webb", 166 | name: "Niklaus Wirth", 167 | score: 78, 168 | grade: "C" 169 | }, { 170 | title: "3D Computer Graphics", 171 | instructor: "G.L. Webb", 172 | name: "Rebecca Heineman", 173 | score: 73, 174 | grade: "C" 175 | }, { 176 | title: "3D Computer Graphics", 177 | instructor: "G.L. Webb", 178 | name: "Tim Berners-Lee", 179 | score: 94, 180 | grade: "A" 181 | }, { 182 | title: "3D Computer Graphics", 183 | instructor: "G.L. Webb", 184 | name: "Xiao Tian", 185 | score: 45, 186 | grade: "F" 187 | }, { 188 | title: "3D Computer Graphics", 189 | instructor: "G.L. Webb", 190 | name: "Ying Cracker", 191 | score: 77, 192 | grade: "C" 193 | }, { 194 | title: "Front End Web Development", 195 | instructor: "Moe Zaick", 196 | name: "dt", 197 | score: 61, 198 | grade: "D" 199 | }, { 200 | title: "Front End Web Development", 201 | instructor: "Moe Zaick", 202 | name: "Albert Gonzalez", 203 | score: 73, 204 | grade: "C" 205 | }, { 206 | title: "Front End Web Development", 207 | instructor: "Moe Zaick", 208 | name: "Brian Kernaghan", 209 | score: 47, 210 | grade: "F" 211 | }, { 212 | title: "Front End Web Development", 213 | instructor: "Moe Zaick", 214 | name: "Danielle Bunten Berry", 215 | score: 87, 216 | grade: "B" 217 | }, { 218 | title: "Front End Web Development", 219 | instructor: "Moe Zaick", 220 | name: "Donald Knuth", 221 | score: 80, 222 | grade: "B" 223 | }, { 224 | title: "Front End Web Development", 225 | instructor: "Moe Zaick", 226 | name: "Grace Hopper", 227 | score: 80, 228 | grade: "B" 229 | }, { 230 | title: "Front End Web Development", 231 | instructor: "Moe Zaick", 232 | name: "Hack Kerr", 233 | score: 92, 234 | grade: "C" 235 | }, { 236 | title: "Front End Web Development", 237 | instructor: "Moe Zaick", 238 | name: "James Gosling", 239 | score: 97, 240 | grade: "A" 241 | }, { 242 | title: "Front End Web Development", 243 | instructor: "Moe Zaick", 244 | name: "Ken Thompson", 245 | score: 64, 246 | grade: "D" 247 | }, { 248 | title: "Front End Web Development", 249 | instructor: "Moe Zaick", 250 | name: "Kevin Mitnick", 251 | score: 47, 252 | grade: "F" 253 | }, { 254 | title: "Front End Web Development", 255 | instructor: "Moe Zaick", 256 | name: "Linus Torvalds", 257 | score: 58, 258 | grade: "F" 259 | }, { 260 | title: "Front End Web Development", 261 | instructor: "Moe Zaick", 262 | name: "Niklaus Wirth", 263 | score: 93, 264 | grade: "A" 265 | }, { 266 | title: "Front End Web Development", 267 | instructor: "Moe Zaick", 268 | name: "Rebecca Heineman", 269 | score: 58, 270 | grade: "F" 271 | }, { 272 | title: "Front End Web Development", 273 | instructor: "Moe Zaick", 274 | name: "Tim Berners-Lee", 275 | score: 98, 276 | grade: "A" 277 | }, { 278 | title: "Front End Web Development", 279 | instructor: "Moe Zaick", 280 | name: "Xiao Tian", 281 | score: 36, 282 | grade: "F" 283 | }, { 284 | title: "Front End Web Development", 285 | instructor: "Moe Zaick", 286 | name: "Ying Cracker", 287 | score: 73, 288 | grade: "C" 289 | }, { 290 | title: "Web Security", 291 | instructor: "Sue Denim", 292 | name: "Donald Knuth", 293 | score: 44, 294 | grade: "F" 295 | }, { 296 | title: "Web Security", 297 | instructor: "Sue Denim", 298 | name: "Albert Gonzalez", 299 | score: 74, 300 | grade: "C" 301 | }, { 302 | title: "Web Security", 303 | instructor: "Sue Denim", 304 | name: "Brian Kernaghan", 305 | score: 92, 306 | grade: "A" 307 | }, { 308 | title: "Web Security", 309 | instructor: "Sue Denim", 310 | name: "Danielle Bunten Berry", 311 | score: 34, 312 | grade: "F" 313 | }, { 314 | title: "Web Security", 315 | instructor: "Sue Denim", 316 | name: "he", 317 | score: 81, 318 | grade: "B" 319 | }, { 320 | title: "Web Security", 321 | instructor: "Sue Denim", 322 | name: "Grace Hopper", 323 | score: 81, 324 | grade: "B" 325 | }, { 326 | title: "Web Security", 327 | instructor: "Sue Denim", 328 | name: "Hack Kerr", 329 | score: 75, 330 | grade: "F" 331 | }, { 332 | title: "Web Security", 333 | instructor: "Sue Denim", 334 | name: "James Gosling", 335 | score: 95, 336 | grade: "A" 337 | }, { 338 | title: "Web Security", 339 | instructor: "Sue Denim", 340 | name: "Ken Thompson", 341 | score: 84, 342 | grade: "B" 343 | }, { 344 | title: "Web Security", 345 | instructor: "Sue Denim", 346 | name: "Kevin Mitnick", 347 | score: 89, 348 | grade: "B" 349 | }, { 350 | title: "Web Security", 351 | instructor: "Sue Denim", 352 | name: "Linus Torvalds", 353 | score: 57, 354 | grade: "F" 355 | }, { 356 | title: "Web Security", 357 | instructor: "Sue Denim", 358 | name: "Niklaus Wirth", 359 | score: 88, 360 | grade: "B" 361 | }, { 362 | title: "Web Security", 363 | instructor: "Sue Denim", 364 | name: "Rebecca Heineman", 365 | score: 93, 366 | grade: "A" 367 | }, { 368 | title: "Web Security", 369 | instructor: "Sue Denim", 370 | name: "Tim Berners-Lee", 371 | score: 36, 372 | grade: "F" 373 | }, { 374 | title: "Web Security", 375 | instructor: "Sue Denim", 376 | name: "Xiao Tian", 377 | score: 87, 378 | grade: "B" 379 | }, { 380 | title: "Web Security", 381 | instructor: "Sue Denim", 382 | name: "Ying Cracker", 383 | score: 42, 384 | grade: "F" 385 | }, { 386 | title: "Javascript Fundamentals", 387 | instructor: "Jay Kweerie", 388 | name: "be", 389 | score: 73, 390 | grade: "C" 391 | }, { 392 | title: "Javascript Fundamentals", 393 | instructor: "Jay Kweerie", 394 | name: "Albert Gonzalez", 395 | score: 94, 396 | grade: "A" 397 | }, { 398 | title: "Javascript Fundamentals", 399 | instructor: "Jay Kweerie", 400 | name: "Brian Kernaghan", 401 | score: 71, 402 | grade: "C" 403 | }, { 404 | title: "Javascript Fundamentals", 405 | instructor: "Jay Kweerie", 406 | name: "Danielle Bunten Berry", 407 | score: 66, 408 | grade: "D" 409 | }, { 410 | title: "Javascript Fundamentals", 411 | instructor: "Jay Kweerie", 412 | name: "Donald Knuth", 413 | score: 94, 414 | grade: "A" 415 | }, { 416 | title: "Javascript Fundamentals", 417 | instructor: "Jay Kweerie", 418 | name: "Grace Hopper", 419 | score: 99, 420 | grade: "A" 421 | }, { 422 | title: "Javascript Fundamentals", 423 | instructor: "Jay Kweerie", 424 | name: "Hack Kerr", 425 | score: 83, 426 | grade: "F" 427 | }, { 428 | title: "Javascript Fundamentals", 429 | instructor: "Jay Kweerie", 430 | name: "James Gosling", 431 | score: 99, 432 | grade: "A" 433 | }, { 434 | title: "Javascript Fundamentals", 435 | instructor: "Jay Kweerie", 436 | name: "Ken Thompson", 437 | score: 65, 438 | grade: "D" 439 | }, { 440 | title: "Javascript Fundamentals", 441 | instructor: "Jay Kweerie", 442 | name: "Kevin Mitnick", 443 | score: 47, 444 | grade: "F" 445 | }, { 446 | title: "Javascript Fundamentals", 447 | instructor: "Jay Kweerie", 448 | name: "Linus Torvalds", 449 | score: 93, 450 | grade: "A" 451 | }, { 452 | title: "Javascript Fundamentals", 453 | instructor: "Jay Kweerie", 454 | name: "Niklaus Wirth", 455 | score: 50, 456 | grade: "F" 457 | }, { 458 | title: "Javascript Fundamentals", 459 | instructor: "Jay Kweerie", 460 | name: "Rebecca Heineman", 461 | score: 33, 462 | grade: "F" 463 | }, { 464 | title: "Javascript Fundamentals", 465 | instructor: "Jay Kweerie", 466 | name: "Tim Berners-Lee", 467 | score: 51, 468 | grade: "F" 469 | }, { 470 | title: "Javascript Fundamentals", 471 | instructor: "Jay Kweerie", 472 | name: "Xiao Tian", 473 | score: 87, 474 | grade: "B" 475 | }, { 476 | title: "Javascript Fundamentals", 477 | instructor: "Jay Kweerie", 478 | name: "Ying Cracker", 479 | score: 60, 480 | grade: "D" 481 | }, { 482 | title: "Data Science", 483 | instructor: "Ford Fulkerson", 484 | name: "st", 485 | score: 58, 486 | grade: "F" 487 | }, { 488 | title: "Data Science", 489 | instructor: "Ford Fulkerson", 490 | name: "Albert Gonzalez", 491 | score: 67, 492 | grade: "D" 493 | }, { 494 | title: "Data Science", 495 | instructor: "Ford Fulkerson", 496 | name: "Brian Kernaghan", 497 | score: 66, 498 | grade: "D" 499 | }, { 500 | title: "Data Science", 501 | instructor: "Ford Fulkerson", 502 | name: "Danielle Bunten Berry", 503 | score: 36, 504 | grade: "F" 505 | }, { 506 | title: "Data Science", 507 | instructor: "Ford Fulkerson", 508 | name: "Donald Knuth", 509 | score: 36, 510 | grade: "F" 511 | }, { 512 | title: "Data Science", 513 | instructor: "Ford Fulkerson", 514 | name: "Grace Hopper", 515 | score: 66, 516 | grade: "D" 517 | }, { 518 | title: "Data Science", 519 | instructor: "Ford Fulkerson", 520 | name: "Hack Kerr", 521 | score: 96, 522 | grade: "A" 523 | }, { 524 | title: "Data Science", 525 | instructor: "Ford Fulkerson", 526 | name: "James Gosling", 527 | score: 83, 528 | grade: "B" 529 | }, { 530 | title: "Data Science", 531 | instructor: "Ford Fulkerson", 532 | name: "Ken Thompson", 533 | score: 35, 534 | grade: "F" 535 | }, { 536 | title: "Data Science", 537 | instructor: "Ford Fulkerson", 538 | name: "Kevin Mitnick", 539 | score: 75, 540 | grade: "C" 541 | }, { 542 | title: "Data Science", 543 | instructor: "Ford Fulkerson", 544 | name: "Linus Torvalds", 545 | score: 63, 546 | grade: "D" 547 | }, { 548 | title: "Data Science", 549 | instructor: "Ford Fulkerson", 550 | name: "Niklaus Wirth", 551 | score: 75, 552 | grade: "C" 553 | }, { 554 | title: "Data Science", 555 | instructor: "Ford Fulkerson", 556 | name: "Rebecca Heineman", 557 | score: 84, 558 | grade: "B" 559 | }, { 560 | title: "Data Science", 561 | instructor: "Ford Fulkerson", 562 | name: "Tim Berners-Lee", 563 | score: 41, 564 | grade: "F" 565 | }, { 566 | title: "Data Science", 567 | instructor: "Ford Fulkerson", 568 | name: "Xiao Tian", 569 | score: 49, 570 | grade: "F" 571 | }, { 572 | title: "Data Science", 573 | instructor: "Ford Fulkerson", 574 | name: "Ying Cracker", 575 | score: 96, 576 | grade: "A" 577 | }, { 578 | title: "Algorithm Design", 579 | instructor: "Gale Shapely", 580 | name: "re", 581 | score: 93, 582 | grade: "A" 583 | }, { 584 | title: "Algorithm Design", 585 | instructor: "Gale Shapely", 586 | name: "Albert Gonzalez", 587 | score: 39, 588 | grade: "F" 589 | }, { 590 | title: "Algorithm Design", 591 | instructor: "Gale Shapely", 592 | name: "Brian Kernaghan", 593 | score: 69, 594 | grade: "D" 595 | }, { 596 | title: "Algorithm Design", 597 | instructor: "Gale Shapely", 598 | name: "Danielle Bunten Berry", 599 | score: 54, 600 | grade: "F" 601 | }, { 602 | title: "Algorithm Design", 603 | instructor: "Gale Shapely", 604 | name: "Donald Knuth", 605 | score: 83, 606 | grade: "B" 607 | }, { 608 | title: "Algorithm Design", 609 | instructor: "Gale Shapely", 610 | name: "Grace Hopper", 611 | score: 31, 612 | grade: "F" 613 | }, { 614 | title: "Algorithm Design", 615 | instructor: "Gale Shapely", 616 | name: "Hack Kerr", 617 | score: 94, 618 | grade: "A" 619 | }, { 620 | title: "Algorithm Design", 621 | instructor: "Gale Shapely", 622 | name: "James Gosling", 623 | score: 35, 624 | grade: "F" 625 | }, { 626 | title: "Algorithm Design", 627 | instructor: "Gale Shapely", 628 | name: "Ken Thompson", 629 | score: 67, 630 | grade: "D" 631 | }, { 632 | title: "Algorithm Design", 633 | instructor: "Gale Shapely", 634 | name: "Kevin Mitnick", 635 | score: 81, 636 | grade: "B" 637 | }, { 638 | title: "Algorithm Design", 639 | instructor: "Gale Shapely", 640 | name: "Linus Torvalds", 641 | score: 70, 642 | grade: "C" 643 | }, { 644 | title: "Algorithm Design", 645 | instructor: "Gale Shapely", 646 | name: "Niklaus Wirth", 647 | score: 74, 648 | grade: "C" 649 | }, { 650 | title: "Algorithm Design", 651 | instructor: "Gale Shapely", 652 | name: "Rebecca Heineman", 653 | score: 92, 654 | grade: "A" 655 | }, { 656 | title: "Algorithm Design", 657 | instructor: "Gale Shapely", 658 | name: "Tim Berners-Lee", 659 | score: 48, 660 | grade: "F" 661 | }, { 662 | title: "Algorithm Design", 663 | instructor: "Gale Shapely", 664 | name: "Xiao Tian", 665 | score: 80, 666 | grade: "B" 667 | }, { 668 | title: "Algorithm Design", 669 | instructor: "Gale Shapely", 670 | name: "Ying Cracker", 671 | score: 84, 672 | grade: "B" 673 | }, { 674 | title: "Data Abstraction", 675 | instructor: "Aster Ricks", 676 | name: "ve", 677 | score: 82, 678 | grade: "B" 679 | }, { 680 | title: "Data Abstraction", 681 | instructor: "Aster Ricks", 682 | name: "Albert Gonzalez", 683 | score: 70, 684 | grade: "C" 685 | }, { 686 | title: "Data Abstraction", 687 | instructor: "Aster Ricks", 688 | name: "Brian Kernaghan", 689 | score: 89, 690 | grade: "B" 691 | }, { 692 | title: "Data Abstraction", 693 | instructor: "Aster Ricks", 694 | name: "Danielle Bunten Berry", 695 | score: 38, 696 | grade: "F" 697 | }, { 698 | title: "Data Abstraction", 699 | instructor: "Aster Ricks", 700 | name: "Donald Knuth", 701 | score: 86, 702 | grade: "B" 703 | }, { 704 | title: "Data Abstraction", 705 | instructor: "Aster Ricks", 706 | name: "Grace Hopper", 707 | score: 42, 708 | grade: "F" 709 | }, { 710 | title: "Data Abstraction", 711 | instructor: "Aster Ricks", 712 | name: "Hack Kerr", 713 | score: 87, 714 | grade: "F" 715 | }, { 716 | title: "Data Abstraction", 717 | instructor: "Aster Ricks", 718 | name: "James Gosling", 719 | score: 89, 720 | grade: "B" 721 | }, { 722 | title: "Data Abstraction", 723 | instructor: "Aster Ricks", 724 | name: "Ken Thompson", 725 | score: 86, 726 | grade: "B" 727 | }, { 728 | title: "Data Abstraction", 729 | instructor: "Aster Ricks", 730 | name: "Kevin Mitnick", 731 | score: 41, 732 | grade: "F" 733 | }, { 734 | title: "Data Abstraction", 735 | instructor: "Aster Ricks", 736 | name: "Linus Torvalds", 737 | score: 76, 738 | grade: "C" 739 | }, { 740 | title: "Data Abstraction", 741 | instructor: "Aster Ricks", 742 | name: "Niklaus Wirth", 743 | score: 78, 744 | grade: "C" 745 | }, { 746 | title: "Data Abstraction", 747 | instructor: "Aster Ricks", 748 | name: "Rebecca Heineman", 749 | score: 70, 750 | grade: "C" 751 | }, { 752 | title: "Data Abstraction", 753 | instructor: "Aster Ricks", 754 | name: "Tim Berners-Lee", 755 | score: 74, 756 | grade: "C" 757 | }, { 758 | title: "Data Abstraction", 759 | instructor: "Aster Ricks", 760 | name: "Xiao Tian", 761 | score: 93, 762 | grade: "A" 763 | }, { 764 | title: "Data Abstraction", 765 | instructor: "Aster Ricks", 766 | name: "Ying Cracker", 767 | score: 95, 768 | grade: "A" 769 | }, { 770 | title: "Data Structures", 771 | instructor: "Brodal Q.", 772 | name: "ng", 773 | score: 88, 774 | grade: "B" 775 | }, { 776 | title: "Data Structures", 777 | instructor: "Brodal Q.", 778 | name: "Albert Gonzalez", 779 | score: 56, 780 | grade: "F" 781 | }, { 782 | title: "Data Structures", 783 | instructor: "Brodal Q.", 784 | name: "Brian Kernaghan", 785 | score: 58, 786 | grade: "F" 787 | }, { 788 | title: "Data Structures", 789 | instructor: "Brodal Q.", 790 | name: "Danielle Bunten Berry", 791 | score: 38, 792 | grade: "F" 793 | }, { 794 | title: "Data Structures", 795 | instructor: "Brodal Q.", 796 | name: "Donald Knuth", 797 | score: 85, 798 | grade: "B" 799 | }, { 800 | title: "Data Structures", 801 | instructor: "Brodal Q.", 802 | name: "Grace Hopper", 803 | score: 53, 804 | grade: "F" 805 | }, { 806 | title: "Data Structures", 807 | instructor: "Brodal Q.", 808 | name: "Hack Kerr", 809 | score: 89, 810 | grade: "B" 811 | }, { 812 | title: "Data Structures", 813 | instructor: "Brodal Q.", 814 | name: "James Gosling", 815 | score: 42, 816 | grade: "F" 817 | }, { 818 | title: "Data Structures", 819 | instructor: "Brodal Q.", 820 | name: "Ken Thompson", 821 | score: 87, 822 | grade: "B" 823 | }, { 824 | title: "Data Structures", 825 | instructor: "Brodal Q.", 826 | name: "Kevin Mitnick", 827 | score: 40, 828 | grade: "F" 829 | }, { 830 | title: "Data Structures", 831 | instructor: "Brodal Q.", 832 | name: "Linus Torvalds", 833 | score: 91, 834 | grade: "A" 835 | }, { 836 | title: "Data Structures", 837 | instructor: "Brodal Q.", 838 | name: "Niklaus Wirth", 839 | score: 51, 840 | grade: "F" 841 | }, { 842 | title: "Data Structures", 843 | instructor: "Brodal Q.", 844 | name: "Rebecca Heineman", 845 | score: 79, 846 | grade: "C" 847 | }, { 848 | title: "Data Structures", 849 | instructor: "Brodal Q.", 850 | name: "Tim Berners-Lee", 851 | score: 37, 852 | grade: "F" 853 | }, { 854 | title: "Data Structures", 855 | instructor: "Brodal Q.", 856 | name: "Xiao Tian", 857 | score: 84, 858 | grade: "B" 859 | }, { 860 | title: "Data Structures", 861 | instructor: "Brodal Q.", 862 | name: "Ying Cracker", 863 | score: 45, 864 | grade: "F" 865 | }, { 866 | title: "Networks", 867 | instructor: "Van Emde Boas", 868 | name: "e!", 869 | score: 65, 870 | grade: "D" 871 | }, { 872 | title: "Networks", 873 | instructor: "Van Emde Boas", 874 | name: "Albert Gonzalez", 875 | score: 52, 876 | grade: "F" 877 | }, { 878 | title: "Networks", 879 | instructor: "Van Emde Boas", 880 | name: "Brian Kernaghan", 881 | score: 61, 882 | grade: "D" 883 | }, { 884 | title: "Networks", 885 | instructor: "Van Emde Boas", 886 | name: "Danielle Bunten Berry", 887 | score: 59, 888 | grade: "F" 889 | }, { 890 | title: "Networks", 891 | instructor: "Van Emde Boas", 892 | name: "Donald Knuth", 893 | score: 89, 894 | grade: "B" 895 | }, { 896 | title: "Networks", 897 | instructor: "Van Emde Boas", 898 | name: "Grace Hopper", 899 | score: 40, 900 | grade: "F" 901 | }, { 902 | title: "Networks", 903 | instructor: "Van Emde Boas", 904 | name: "Hack Kerr", 905 | score: 102, 906 | grade: "F" 907 | }, { 908 | title: "Networks", 909 | instructor: "Van Emde Boas", 910 | name: "James Gosling", 911 | score: 39, 912 | grade: "F" 913 | }, { 914 | title: "Networks", 915 | instructor: "Van Emde Boas", 916 | name: "Ken Thompson", 917 | score: 83, 918 | grade: "B" 919 | }, { 920 | title: "Networks", 921 | instructor: "Van Emde Boas", 922 | name: "Kevin Mitnick", 923 | score: 37, 924 | grade: "F" 925 | }, { 926 | title: "Networks", 927 | instructor: "Van Emde Boas", 928 | name: "Linus Torvalds", 929 | score: 65, 930 | grade: "D" 931 | }, { 932 | title: "Networks", 933 | instructor: "Van Emde Boas", 934 | name: "Niklaus Wirth", 935 | score: 36, 936 | grade: "F" 937 | }, { 938 | title: "Networks", 939 | instructor: "Van Emde Boas", 940 | name: "Rebecca Heineman", 941 | score: 32, 942 | grade: "F" 943 | }, { 944 | title: "Networks", 945 | instructor: "Van Emde Boas", 946 | name: "Tim Berners-Lee", 947 | score: 70, 948 | grade: "C" 949 | }, { 950 | title: "Networks", 951 | instructor: "Van Emde Boas", 952 | name: "Xiao Tian", 953 | score: 52, 954 | grade: "F" 955 | }, { 956 | title: "Networks", 957 | instructor: "Van Emde Boas", 958 | name: "Ying Cracker", 959 | score: 62, 960 | grade: "D" 961 | }]; 962 | export default courses; 963 | -------------------------------------------------------------------------------- /coderoad.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "title": "Functional School", 4 | "description": "A trip through functional programming in Javascript using common built-in Javascript array methods such as `map` & `reduce`.\n\nBy the end, you should have an understanding of how to use array methods to manipulate semi-complex data.\n\nLevel: Intermediate\nKeywords: javascript, functional\nLength: 1-2 hours" 5 | }, 6 | "pages": [ 7 | { 8 | "title": "Start", 9 | "description": "Understanding the Data Set\n\nOver this tutorial series, we'll be changing and working with two different data sets. It'll be a big help to first understand what the data looks like.\n\n```json\nvar students = [\n {\n \"title\": \"Relational Databases\",\n \"instructor\": \"Sean Quentin Lewis\",\n \"name\": \"Ada Lovelace\",\n \"score\": 91,\n \"grade\": \"A\"\n },\n ...\n]\n```\n\nHere we have an array of \"student\" objects. To get the first item in the array, you can use the array index. Array indexes start at 0.\n\n```js\nconsole.log(\n 'first instructor', students[0].instructor\n);\n// first instructor Sean Quentin Lewis\n```", 10 | "tasks": [ 11 | { 12 | "description": "Look in \"data/students.js\". This is the data we will be working with. Run save to continue.", 13 | "tests": [ 14 | "00/01" 15 | ], 16 | "actions": [ 17 | "writeFromFile('data/students.js', '00/data.js')" 18 | ] 19 | }, 20 | { 21 | "description": "Set `first` to the first item in the `students` array.", 22 | "tests": [ 23 | "00/02" 24 | ], 25 | "actions": [ 26 | "open('setup.js')", 27 | "set('// Welcome to CodeRoad!\nconst students = require('./data/students').default;\n\nvar first = ::>\n')" 28 | ], 29 | "hints": [ 30 | "Get the first item in students using the array index", 31 | "Access the title of `students[0]`" 32 | ] 33 | }, 34 | { 35 | "description": "Set `myName` to the \"name\" of the first student in the list.", 36 | "tests": [ 37 | "00/03" 38 | ], 39 | "actions": [ 40 | "insert('var myName = ::>\n')" 41 | ], 42 | "hints": [ 43 | "Get the first \"name\" in the students using the array index", 44 | "Access the \"name\" of `first`", 45 | "Try `first.name`" 46 | ] 47 | }, 48 | { 49 | "description": "Log your name to the console.", 50 | "tests": [ 51 | "00/04" 52 | ], 53 | "actions": [ 54 | "insert('\nconsole.log(::>);\n')" 55 | ], 56 | "hints": [ 57 | "Use `console.log`", 58 | "Use `console.log(myName)`" 59 | ] 60 | } 61 | ], 62 | "onPageComplete": "Now we're ready to get started with `filter`ing our data." 63 | }, 64 | { 65 | "title": "Filter", 66 | "description": "Array -> Array of items that match a condition\n\nYou've hacked into the school's computer system, and just in time. The grades are in, but you're not too proud of your performance. That's okay, you have a plan: you're going to create a fake report card.\n\nIt would be great if you could `filter` the scores that your parents will see.\n\n`filter` takes a matching condition function and only returns items that result in true. As an example, look at `isA` below:\n\n```js\nfunction isA(x) {\n return x === 'a';\n}\n```\n\n\nLike all of the methods in this chapter, `filter` is already part of the `Array.prototype`, so you can run it following any array. Each item in the array is passed into the params of the condition function, one by one. [Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter).\n\n```js\nconst list = ['a', 'b'];\nlist.filter(isA);\n\n// if isA(list[0]), add to output array\n// if isA(list[1]), add to output array\n//\n//> ['a']\n```\n\nIf your data was composed of objects, we could use dot notation to find matches. Checkout `isB` below.\n\n```js\nfunction isB(x) {\n return x.item === 'b'\n}\n\nconst list = [{item: 'a'}, {item: 'b'}];\nlist.filter(isB);\n//> [{item: 'b'}]\n```\n\nWhere were we? Back to filtering our grades.\n\nThere's too much student data in the computer system. We'll have to sort through it. Have a look at an example below:\n\n```js\nconsole.log(students[0]);\n//> { course: 'Web Security',\n// instructor: 'Sue Denim',\n// name: 'Rebecca Heineman',\n// score: 93,\n// grade: 'A' }\n```", 67 | "tasks": [ 68 | { 69 | "description": "Write a filter condition function called `isAda` that returns true only if the name matches your name: \"Ada Lovelace\".", 70 | "tests": [ 71 | "01/01" 72 | ], 73 | "actions": [ 74 | "open('01-filter.js')", 75 | "set('import students from './data/students';\n// Array.filter(fn)\n\nfunction isAda(student) {\n // return true if student name\n // matches \"Ada Lovelace\"\n ::>\n}\n')" 76 | ], 77 | "hints": [ 78 | "Some tasks have hints", 79 | "Check if `student.name` matches \"Ada Lovelace\"", 80 | "Use `===` to check equality" 81 | ] 82 | }, 83 | { 84 | "description": "Set `const myData` to filter with the `isAda` function.", 85 | "tests": [ 86 | "01/02" 87 | ], 88 | "actions": [ 89 | "insert('// run the function name in filter\nconst myData = students.filter(::>);\n')" 90 | ], 91 | "hints": [ 92 | "Add a function to the `filter` call: `Array.filter(function() {})`", 93 | "Pass `isAda` into your `filter` call" 94 | ] 95 | }, 96 | { 97 | "description": "Write a filter condition called `isGoodGrade` that will filter out any \"D\" or \"F\" grades.", 98 | "tests": [ 99 | "01/03" 100 | ], 101 | "actions": [ 102 | "insert('\n\n// return true if student.grade is not a \"D\" or \"F\"\nfunction isGoodGrade(student) {\n ::>\n}\n')" 103 | ], 104 | "hints": [ 105 | "match for `student.grade` that isn't \"D\" or \"F\"", 106 | "use `!==` to check non-equality", 107 | "Match for both: `student.grade !== \"D\" && student.grade !== \"F\"`" 108 | ] 109 | }, 110 | { 111 | "description": "Set `const myBest` to your scores, excluding any grades that are \"D\" or \"F\".", 112 | "tests": [ 113 | "01/04" 114 | ], 115 | "actions": [ 116 | "insert('// filter out \"D\"'s and \"F\"'s here\nconst myBest = myData.filter(::>);\n\n')" 117 | ] 118 | } 119 | ], 120 | "onPageComplete": "In the next step we'll look at how to `sort` data" 121 | }, 122 | { 123 | "title": "Sort", 124 | "description": "Array -> sorted Array\n\nYour grades are filtered down to your name and good scores - but wouldn't it be better if your best grades were displayed first, at the top? Besides, your parents rarely read anything through.\n\nYou can use the array method `sort` to arrange your data. Let's see how it works.\n\n```js\n['c', 'b', 'a'].sort();\n//> ['a', 'b', 'c']\n\n[3, 2, 1].sort();\n//> [1, 2, 3]\n```\n\nBut what about sorting scores inside of an object?\n\n```js\n[{a: 3}, {a: 1}, {a: 2}].sort();\n//> [{a: 3}, {a: 1}, {a: 2}]\n```\n\nThat didn't work. Instead, you can write a custom `compareScore` function.\n\nA sort function takes two params, and compares the first to the second. It should return values saying where the second value should go in the array:\n\n * -1 : sort to a lower index (front)\n * 1 : sort to a higher index (back)\n * 0 : stay the same\n\nAlright, now time to sort your best grades to the top.\n\nFirst you'll need to write a sort condition function called `compareScore`.", 125 | "tasks": [ 126 | { 127 | "description": "look at the data we will work with next: `myBest`. Save to continue.\n@open('data/myBest.js')", 128 | "tests": [ 129 | "02/01" 130 | ], 131 | "actions": [ 132 | "writeFromFile('data/myBest.js', '02/myBest.js')" 133 | ] 134 | }, 135 | { 136 | "description": "`compareScore` should return 1 if the first score is less than the second", 137 | "tests": [ 138 | "02/02" 139 | ], 140 | "actions": [ 141 | "open('02-sort.js')", 142 | "set('import myBest from './data/myBest';\n// Array.sort(fn)\n\nfunction compareScore(a, b) {\n switch (true) {\n case b.score > a.score:\n // it should return 1 if b's score is more than a's\n return ::>\n case 'set condition here':\n // it should return -1 if b's score is less than a's\n\n default:\n // it should return 0 if b and a have the same score\n\n }\n}\n')" 143 | ] 144 | }, 145 | { 146 | "description": "`compareScore` should return -1 if the first score is more than the second", 147 | "tests": [ 148 | "02/03" 149 | ], 150 | "hints": [ 151 | "set the second case to `b.score < a.score`" 152 | ] 153 | }, 154 | { 155 | "description": "`compareScore` should return 0 if the first score is the same as the second", 156 | "tests": [ 157 | "02/04" 158 | ], 159 | "hints": [ 160 | "no case is necessary, use the `default` case" 161 | ] 162 | }, 163 | { 164 | "description": "Set `mySorted` to the result of `myBest` sorted by `compareScore`", 165 | "tests": [ 166 | "02/05" 167 | ], 168 | "actions": [ 169 | "insert('// use the compare function to sort myBest\nconst mySorted = myBest::>\n')" 170 | ], 171 | "hints": [ 172 | "try using `myBest.sort()`" 173 | ] 174 | } 175 | ], 176 | "onPageComplete": "In the next step we'll look at changing data with `map`" 177 | }, 178 | { 179 | "title": "Map", 180 | "description": "Array -> run a function over each item -> Array\n\nYou've filtered and sorted our data, but neither of those actually change the data.\n\nWouldn't it be simpler if you could just change your grades?\n\nYou can use the array method `map` to run a function that returns changes to your data.\n\nAs an example, let's look at how you would increment each number in an array.\n\n```js\nfunction addOne(num) {\n return num + 1;\n}\n\n[1, 2, 3].map(addOne);\n//> [2, 3, 4]\n\nfunction addToVal(obj) {\n obj.val += 1;\n return obj;\n}\n[{ val: 1}].map(addToVal);\n//> [{ val: 2 }]\n```\n\n`map` can change data, and it can also alter structure of the data you're working with.\n\n```js\nfunction makeObject(num) {\n return { val: num };\n}\n\n[1, 2].map(makeObject);\n//> [{ val: 1 }, { val: 2 }]\n```\n\nSimilarly, `map` can also restrict the data you want to work with. See the example below to see another way scores could be sorted.\n\n```js\nmyBest\n .map(function(student) {\n return student.score;\n })\n .sort()\n .reverse()\n//> [93, 91, 88, 88, 82, 81, 73]\n```\n\nIn this example, `map` transformed an object with keys of 'title', 'instructor', 'name', 'score' and 'grade', to an array of just scores. Values weren't changed, but rather limited to a smaller subset of scores.\n\n`map` is powerful. Let's see what you can do with it.\n\nThose D & F grades would look a lot better if they suddenly became A's.\n\nLet's go back to before we filtered out the bad grades, and instead change the grades to A's.", 181 | "tasks": [ 182 | { 183 | "description": "load \"myCourses\"", 184 | "tests": [ 185 | "03/01" 186 | ], 187 | "actions": [ 188 | "writeFromFile('data/myCourses.js', '03/myCourses.js')", 189 | "open('data/myCourses.js')" 190 | ] 191 | }, 192 | { 193 | "description": "Make a function `changeGrade` that takes a course and changes the grade to an \"A\"", 194 | "tests": [ 195 | "03/02" 196 | ], 197 | "actions": [ 198 | "open('03-map.js')", 199 | "set('import myCourses from './data/myCourses';\n// Array.map(fn)\n\n/*\n * change any the `course.grade` into an 'A'\n *\n * for example:\n * changeGrade({ grade: 'F' }) === { grade: 'A' };\n*/\n\nfunction changeGrade(course) {\n ::>\n}\n\n')" 200 | ], 201 | "hints": [ 202 | "give `changeGrade` a parameter, call it \"course\"", 203 | "set `course.grade` to \"A\"", 204 | "return the changed course" 205 | ] 206 | }, 207 | { 208 | "description": "Map over the `myCourses` with the `changeGrade` function. Set `myChanged` to the result.", 209 | "tests": [ 210 | "03/03" 211 | ], 212 | "actions": [ 213 | "insert('// map over `myCourses` and call `changeGrade` for each item\nconst myChanged = myCourses.map(::>);\n')" 214 | ], 215 | "hints": [ 216 | "simply call `.map(changeGrade)`" 217 | ] 218 | }, 219 | { 220 | "description": "Hold up. An A in \"Data Science\" class looks way to suspicious. Your parents might catch on to your cheating.\n\nLet's go back to `myCourses` and instead increment each score by 12 points.", 221 | "tests": [ 222 | "03/04" 223 | ], 224 | "actions": [ 225 | "insert('\nfunction increaseScore(course) {\n ::>\n}\n\n// map over `mySlightlyChanged` with a function `increaseScore` to increment each score by 12\nconst mySlightlyChanged = myCourses;\n')" 226 | ], 227 | "hints": [ 228 | "give `increaseScore` a parameter, call it \"course\"", 229 | "it should increase `course.score`", 230 | "return `course`" 231 | ] 232 | }, 233 | { 234 | "description": "Wait. Now you're getting 105 in \"Algorithm Design\" class. Fix `increaseScore` so that the maximum score is 95. That should be less suspicious.", 235 | "tests": [ 236 | "03/05" 237 | ], 238 | "hints": [ 239 | "Use `Math.min(x, y)`", 240 | "set `course.score` to `Math.min(95, course.score + 12)`" 241 | ] 242 | }, 243 | { 244 | "description": "One more problem. Now the scores don't match the grades. you have 95 score in \"3D Computer Graphics\", but only a \"B\" grade. Update your `increaseScore` function to also update the grade by using the `getGrade` function", 245 | "tests": [ 246 | "03/06" 247 | ], 248 | "actions": [ 249 | "insert('\n// use getGrade to set the course grade\n// update `increaseScore` to also update the grade\nfunction getGrade(score) {\n switch (true) {\n case (score >= 90):\n return \"A\";\n case (score >= 80):\n return \"B\";\n case (score >= 70):\n return \"C\";\n case (score >= 60):\n return \"D\";\n default:\n return \"F\";\n }\n}\n\n')" 250 | ], 251 | "hints": [ 252 | "call `getGrade` inside of `increaseScore`", 253 | "the `increaseScore` function should set course.grade equal to `getGrade(course.score)`" 254 | ] 255 | }, 256 | { 257 | "description": "Check to make sure everything is working. Set `scoresAndGrades` to an array of scores and grades only.", 258 | "tests": [ 259 | "03/07" 260 | ], 261 | "actions": [ 262 | "insert('\n// set `scoresAndGrades` to an array of scores and grades\n// it should return an array of objects like this: {score: 75, grade: 'C'}\nconst scoresAndGrades = mySlightlyChanged.map(::>)\n')" 263 | ], 264 | "hints": [ 265 | "use `map` to return only the \"score\" & \"grade\" fields", 266 | "map with a function with a parameter, call it \"student\"", 267 | "you can destructure the param to be `function({score, grade})`", 268 | "then simply return { score, grade }" 269 | ] 270 | } 271 | ], 272 | "onPageComplete": "In the next step we'll compare `map` with `forEach`" 273 | }, 274 | { 275 | "title": "forEach", 276 | "description": "Array -> run a function for each item\n\nYou've updated your grades, but they're still in an array. It's time to loop over them and log them to the console.\n\nTo open the console, go to *View* > *Developer* > *Toggle Developer Tools*. Or press *cmd+opt+I* on Mac, *ctrl+alt+I* on Windows.\n\n`forEach` has a lot in common with `map`, but there is a big difference. Understanding that difference is important for grasping the difference between:\n\n * **functional** & **imperative** programming\n * **pure** & **impure** functions\n\nKnow it or not, you're probably already used to \"imperative\" programming.\n\n> **Imperative** programming describes the order of actions\n\nImperative code tells the computer what to do, step by step.\n\n```js\nlet x = 1; // make a variable\nx = x + 1; // add one\nx = x + 1; // add another\nconsole.log(x);\n//> 3\n```\n\n> **Functional** programming describes the data transformation\n\nFunctional programming is a lot like writing math equations. As in math, 1 + 1 always equals 2.\n\nIn the same way, a **pure** function will always have the same result from a given input. Input 1 -> output 2. Every time.\n\n```js\n// a pure function\nfunction addOne(x) {\n return x + 1;\n}\naddOne(1)\n//> 2\naddOne(1)\n//> 2\n```\n\nA function is \"pure\" if it doesn't change anything outside of its scope. Pure functions are easy to test, reuse and reason about. In other words, they make your job easier.\n\nOn the other hand, **impure** functions are less predictable. The result may be different if you call it at a later time.\n\n```js\nlet y = 1;\n// impure function\nfunction increment(x) {\n y += x;\n return y;\n}\nincrement(1)\n//> 2\nincrement(1)\n//> 3\n```\n\nIt's good practice to ensure your `map` functions remain pure.\n\nBut `forEach` can be a little more dangerous. Why? Let's have a look.\n\n```js\n[1, 2, 3].map(addOne);\n//> [2, 3, 4]\n\n[1, 2, 3].forEach(addOne);\n//> undefined\n```\n\nWhat? `undefined`? `forEach` runs a function on each item in the array, and doesn't care what the function returns. Functions called by `forEach` must make changes, called **side effects**, to even be noticed.\n\n```js\n// impure function, changes log\nfunction addOneToLog(x) {\n console.log(x);\n}\n\n[1, 2, 3].forEach(addOneToLog);\n//> 2\n//> 3\n//> 4\n```\n\nNow that we see how `forEach` works, let's use it to make calls to the `console`.", 277 | "tasks": [ 278 | { 279 | "description": "checkout the data we'll use next: \"myFixed\". Save to continue.", 280 | "tests": [ 281 | "04/01" 282 | ], 283 | "actions": [ 284 | "writeFromFile('data/myFixed.js', '04/myFixed.js')", 285 | "open('data/myFixed.js')" 286 | ] 287 | }, 288 | { 289 | "description": "Use `forEach` to log out your report card to the console", 290 | "tests": [ 291 | "04/02" 292 | ], 293 | "actions": [ 294 | "open('04-forEach.js')", 295 | "set('import myFixed from './data/myFixed';\n// Array.forEach(fn)\n\nfunction logCourse(course) {\n console.log(`${course.grade} ${course.score} ${course.title}`);\n}\n\n// log your grades to the console\nmyFixed.forEach(::>);\n')" 296 | ], 297 | "hints": [ 298 | "call `forEach` with `logCourse`" 299 | ] 300 | }, 301 | { 302 | "description": "Add a second parameter to `logCourseWithIndex` called `index`. Then call the function with `myFixed.forEach`.", 303 | "tests": [ 304 | "04/03" 305 | ], 306 | "actions": [ 307 | "insert('\n// add a second param called 'index' to the function\nfunction logCourseWithIndex(course::>) {\n console.log(`${index + 1} ${course.grade} ${course.score} ${course.title}`);\n}\n\n// log your grades to the console with an index\nmyFixed.forEach(logCourseWithIndex);\n')" 308 | ], 309 | "hints": [ 310 | "Array methods can take more than one parameter", 311 | "Add a second parameter to `logCourseWithIndex`" 312 | ] 313 | }, 314 | { 315 | "description": "Add a third parameter called `array` to `logCourseWithIndexAndArray`, then call the function with `myFixed.forEach`.", 316 | "tests": [ 317 | "04/04" 318 | ], 319 | "actions": [ 320 | "insert('\n// add a third param called 'array' to the function\nfunction logCourseWithIndexAndArray(course, index::>) {\n console.log(`${index + 1}/${array.length} ${course.grade} ${course.score} ${course.title}`);\n}\n\n// log your grades to the console with an index and array length\nmyFixed.forEach(logCourseWithIndexAndArray);\n')" 321 | ], 322 | "hints": [ 323 | "Array methods can take more than one parameter", 324 | "Add a third parameter to `logCourseWithIndexAndArray`" 325 | ] 326 | }, 327 | { 328 | "description": "What??? Suddenly Your data has all disappeared!\n\nIt seems `myFixed` relies on a chain of methods.\n\n```js\nmyFixed = students\n .filter(isAda)\n .sort(compareScore)\n .map(increaseScore)\n .map(getGrade)\n .forEach(logCourseWithIndexAndArray)\n```\n\nThis is why side-effects are dangerous. Students data must have changed, and now all of your transformations are effected.", 329 | "tests": [ 330 | "04/05" 331 | ], 332 | "actions": [ 333 | "insert('\nconsole.log(myFixed);\n')" 334 | ] 335 | } 336 | ], 337 | "onPageComplete": "Something strange is going on. In the next step we'll try to `find` your data." 338 | }, 339 | { 340 | "title": "find", 341 | "description": "Array -> first element that matches a condition\n\nSomehow your name has disappeared from the computer system. We'll have to `find` a way to get it back.\n\nYou quickly put together a list of other students in class. If someone changed your name, it'll be the name that is not in that list.\n\n`find` works similar to `filter`, but returns only the first match.\n\n```js\nconst data = [1, 2, 3, 4, 5, 6];\n\nfunction isEven(num) {\n return num % 2 === 0;\n}\n\n// returns all matching data to a condition\ndata.filter(isEven);\n//> [2, 4, 6]\n\n// returns the first match\ndata.find(isEven);\n//> [2]\n```\n\nFind is great for performantly matching unique values in data, such as an \"id\", or in our case: a name.", 342 | "tasks": [ 343 | { 344 | "description": "load \"students\" data. Save to continue.", 345 | "tests": [ 346 | "05/01" 347 | ], 348 | "actions": [ 349 | "writeFromFile('data/myCourses2.js', '05/courses.js')", 350 | "open('data/myCourses2.js')" 351 | ] 352 | }, 353 | { 354 | "description": "`filter` to `courses` in the class titled \"Web Security\"", 355 | "tests": [ 356 | "05/02" 357 | ], 358 | "actions": [ 359 | "open('05-find.js')", 360 | "set('import courses from './data/myCourses2';\n// Array.find(fn)\n\n// filter for the course title matching \"Web Security\"\nconst myClass = courses.filter(::>);\n')" 361 | ], 362 | "hints": [ 363 | "create a `filter` function that takes a param `course`", 364 | "return `true` if a condition matches, otherwise `false`", 365 | "filter for `course.title === \"Web Security\"`" 366 | ] 367 | }, 368 | { 369 | "description": "`find` the name in `myClass` that isn't in the list of known students", 370 | "tests": [ 371 | "05/03" 372 | ], 373 | "actions": [ 374 | "insert('\nconst otherStudents = [\"Albert Gonzalez\", \"Brian Kernaghan\", \"Danielle Bunten Berry\", \"Donald Knuth\", \"Grace Hopper\", \"Hack Kerr\", \"James Gosling\", \"Ken Thompson\", \"Kevin Mitnick\", \"Linus Torvalds\", \"Niklaus Wirth\", \"Rebecca Heineman\", \"Tim Berners-Lee\", \"Xiao Tian\", \"Ying Cracker\"];\n\n')", 375 | "insert('// search for a student with a name\n// not matching students in `otherStudents`\nfunction notInList(::>) {\n\n}\n\n// find using `notInList`\nconst unknownStudent = myClass.find();\n')" 376 | ], 377 | "hints": [ 378 | "use `indexOf` to find what doesn't match", 379 | "use `otherStudents.indexOf(x) === -1` to find what doesn't match", 380 | "match for `student.name`" 381 | ] 382 | }, 383 | { 384 | "description": "`filter` down to students from courses without known names", 385 | "tests": [ 386 | "05/04" 387 | ], 388 | "actions": [ 389 | "insert('\n// filter using `notInList`\nconst unknownStudentList = courses.filter(::>);\n')" 390 | ], 391 | "hints": [ 392 | "consider reusing a function" 393 | ] 394 | }, 395 | { 396 | "description": "`map` over the result to get only the `name` property", 397 | "tests": [ 398 | "05/05" 399 | ], 400 | "actions": [ 401 | "insert('\n// list only student names\nconst unknownStudentNames = unknownStudentList.map(::>);\n')" 402 | ], 403 | "hints": [ 404 | "use `map` to return only the `student.name`", 405 | "try this inside of your map call: `student => student.name`" 406 | ] 407 | }, 408 | { 409 | "description": "`join('')` the array of names to output the result as a string", 410 | "tests": [ 411 | "05/06" 412 | ], 413 | "actions": [ 414 | "insert('\n// use `.join('')` to join the array of strings\nconst decodedName = unknownStudentNames::>;\nconsole.log(decodedName);\n')" 415 | ], 416 | "hints": [ 417 | "call `join` following `unknownStudentNames`" 418 | ] 419 | } 420 | ], 421 | "onPageComplete": "Very strange. In the next step, let's find out who wants revenge, and give it to him!" 422 | }, 423 | { 424 | "title": "concat", 425 | "description": "Array + Array -> Array\n\nBefore we've been working on a structured set of student data.\n\n```js\n// array of students\n[\n {\n \"title\": \"Relational Databases\",\n \"instructor\": \"Sean Quentin Lewis\",\n \"name\": \"Rebecca Heineman\",\n \"score\": 71,\n \"grade\": \"C\"\n }\n// students in courses...\n]\n```\n\nTo be safe, let's now work on the original data set. Notice how it is structured differently.\n\n```js\n// array of courses\n[\n {\n \"title\": \"Relational Databases\",\n \"instructor\": \"Sean Quentin Lewis\",\n \"students\": [\n {\n \"name\": \"Rebecca Heineman\",\n \"score\": 71,\n \"grade\": \"C\"\n }\n // students...\n ]\n }\n // courses...\n]\n```\n\nIn this data set, there is an array of students within an array of courses. So how can we recreate our original array of students from the courses?\n\nWeird things happen when you start combining arrays. We can use `concat` to bring sanity.\n\n```js\n[1, 2] + [3, 4];\n//> \"1, 23, 4\"\n\n[1, 2].push([3, 4]);\n//> 3\n\n[1, 2].join([3, 4]);\n//> \"13, 42\"\n\n[1, 2].concat([3, 4]);\n//> [1, 2, 3, 4]\n```\n\nUnfortunately, Javascript is missing a built in array method to concat multiple arrays together: let's call it `flatten` (sometimes called `concatAll`).\n\n`flatten` should loop over an array and `concat` each element.\n\nLet's look at an abstraction of what we need to do:\n\n```js\nconst start = [{\n a: 1,\n c: [\n { b: 1 }\n ]\n}, {\n a: 2,\n c: [\n { b: 2 }, { b: 3 }\n ]\n}];\n\nconst middle = start.map(function(outer) {\n return outer.c.map(function(inner) {\n return {\n a: outer.a,\n b: inner.b\n };\n });\n});\n//> [ [{ a: 1, b: 1 }], [{a: 2, b: 2}, {a: 2, b: 3}] ]\n\nconst end = pre.flatten();\n//> [{a: 1, b: 1}, {a: 2, b: 2}, {a: 2, b: 3}]\n```\n\nBack to business.\n\nWe have a suspect in mind: a classmate named \"Hack Kerr\". He's a nice guy, and he's always been friendly to you - but there's something suspicious about him: his name.\n\nWe'll test out flatten, then re-create our student array of data from the original course data.", 426 | "tasks": [ 427 | { 428 | "description": "load \"courses\"", 429 | "tests": [ 430 | "06/01" 431 | ], 432 | "actions": [ 433 | "writeFromFile('data/courses2.js', '06/courses2.js')", 434 | "open('data/courses2.js')" 435 | ] 436 | }, 437 | { 438 | "description": "First, test out `flatten` on the `flattenedArray`\nArray -> anything\n\nWe know our likely suspect is also in the school computer system. Perhaps our suspect also changed his grades.\n\nYou can't be sure who is a cheater, but you can assume if the grades are well above the average, the person is likely to be the culprit. For this, we'll have to do some basic statistical calculations. We'll need a new tool for transforming arrays into different data representations.\n\n`map` has a major limitation: it will always output the same number of elements as the input array.\n\nWhen you want to transform data into something different, you'll likely want to use `reduce`.\n\nReduce requires two parameters:\n\n * the running total (set by an initialValue)\n * the next value in the array\n\n```js\nfunction add(total, next) {\n console.log(`add(${total}, ${next}) -> ${total + next}`)\n return total + next\n}\n\nconst initialValue = 100;\n[1, 5, 10].reduce(add, initialValue); // initial value\n\n// add(100, 1) -> 101\n// add(101, 5) -> 106\n// add(106, 10) -> 116\n//> 116\n```\n\nNotice in the example we input an array of 3 items and output a single number. The data has been transformed.\n\nIt takes a while to wrap your head around `reduce`, but once you do, you'll see it's usefulness everywhere.\n\nYou may have noticed we've already used `reduce` to `flatten` our arrays.\n\n```js\nArray.prototype.flatten = function() {\n return this.reduce((a, b) => a.concat(b), []);\n};\n```\n\nWith `flatten`, the initialValue was set to an empty array which each value was `concat` onto.\n\nDo some practice with `reduce`, before you use it to narrow down a cheating suspect.", 439 | "tests": [ 440 | "06/02" 441 | ], 442 | "actions": [ 443 | "open('06-concat.js')", 444 | "set('```\nimport courses from './data/courses2');\n// Array.concat(any)\n\n// Array.prototype can be used to create new Array methods\nArray.prototype.flatten = function() {\n return this.reduce((a, b) => a.concat(b), []);\n};\n```\n))\n@action(insert(\n```\n\nconst numberedList = [[1, 2], [3, 4]];\n\n// use `flatten` on `numberedList`\nconst flattenedArray = numberedList::>;\n``` \n))\n@hint('call `.flatten()` on `numberedList`')\n\n\n+ Now `map` over the courses array, and `map` over the students array inside of it.\nReturn the fields:\n\n * title\n * instructor\n * name\n * grade\n * score\n@test('06/03')\n@action(insert(\n```\n\n// map over courses then\n// map over students inside of courses\nconst doubleArray = courses.map((course) => {\n return course.students.map((student) => {\n return {\n // fill in the fields\n title: ::>'',\n instructor: '',\n name: '',\n score: '',\n grade: ''\n };\n });\n});\n\n```\n))\n@hint('pair `course.title`')\n@hint('pair `student.name`')\n\n+ Use `flatten` to put all data into a single array. Set `students` to the result.\n@test('06/04')\n@action(insert(\n```\n// `flatten` doubleArray\nconst students = doubleArray::>;\n```\n))\n@hint('call `.flatten()` on `doubleArray`')\n\n+ Use the `suspects` array to `filter` to only data matching the names in the `suspects` array\n@test('06/05')\n@action(insert(\n```\n\nconst suspects = [\"Hack Kerr\"];\n// filter to data matching `suspects`\n\nconst suspectData = students::>;\n```\n))\n\n+ You just thought of two more suspects! Make a new variable called `newSuspects` and add it above `suspects`.\n\n```js\nconst newSuspects = ['Albert Gonzalez', 'Kevin Mitnick'];\n```\n\n`concat` the `newSuspects` onto the `suspects` list.\n@test('06/06')\n@hint('call `suspects.concat()` with `newSuspects`')\n\n\n## redu')" 445 | ] 446 | }, 447 | { 448 | "description": "load suspectData. We will come back to this after some practice;", 449 | "tests": [ 450 | "07/01" 451 | ], 452 | "actions": [ 453 | "writeFromFile('data/suspectData.js', '07/suspectData.js')", 454 | "open('data/suspectData.js')" 455 | ] 456 | }, 457 | { 458 | "description": "Use `reduce` to sum the numbers in the `practice` array", 459 | "tests": [ 460 | "07/02" 461 | ], 462 | "actions": [ 463 | "open('07-reduce.js')", 464 | "set('import courses from './data/courses2';\n// Array.reduce(fn(a, b), initialValue)\n\nconst practice = [1, 1, 2, 3, 5, 8, 13, 21];\n\nfunction add(a, b) {\n return a + b;\n}\n\n// total the numbers using a reduce function\nconst total = practice.reduce(::>);\n')" 465 | ], 466 | "hints": [ 467 | "with only numbers, the initialValue defaults to 0", 468 | "just call `reduce` with `add`" 469 | ] 470 | }, 471 | { 472 | "description": "Not all reduce functions are so easy. `reduce` is a little more difficult to master.\n\n`map` over each course and use `reduce` to calculate the class averages for each class. Set `averages` to the resulting array of all class averages.", 473 | "tests": [ 474 | "07/03" 475 | ], 476 | "actions": [ 477 | "insert('\nconst averages = courses.map((course) => {\n const sum = course.students.reduce((total, student) => {\n ::>\n\n });\n return Math.round(sum / course.students.length, 0);\n});\n')" 478 | ], 479 | "hints": [ 480 | "set the initialValue to 0", 481 | "like this: `reduce(function () {}, 0)`", 482 | "return the sum of `student.score` and `total`" 483 | ] 484 | }, 485 | { 486 | "description": "`reduce` to an array of suspect scores from the `suspectData` we collected previously.", 487 | "tests": [ 488 | "07/04" 489 | ], 490 | "actions": [ 491 | "open('07-reduce.js')", 492 | "insert('\n// [{ name: 'suspectName', scores: [ 50, 65, 75, 85...] } ...]\nconst suspectScores = suspectData.reduce((total, next) => {\n // see if suspect name has a list yet\n const index = total.findIndex((suspect) => suspect.name === next.name);\n if (index < 0) {\n total.push({\n ::>\n\n });\n } else {\n // push the next score onto the suspects scores\n total[index].scores.push();\n }\n return total;\n}, []);\n\n')" 493 | ], 494 | "hints": [ 495 | "if the name is new, push an object with name & scores: `{ name: '', scores: [42]}`", 496 | "match for `next.name` & `next.score`", 497 | "you can concat the scores onto an array: `[].concat(next.score)`", 498 | "if the name is already in the list, just add the `next.score`" 499 | ] 500 | }, 501 | { 502 | "description": "`map` over suspect data to find the `\"difference\"` from subtracting the students score from the average score. Add this to `suspectScores` using the key `difference`. The resulting array should look like this:\n```js\n[{\n name: 'suspectName',\n scores: [50, 65, 75 ...],\n difference: 15\n}]\n```", 503 | "tests": [ 504 | "07/05" 505 | ], 506 | "actions": [ 507 | "insert('\nconst suspectStats = suspectScores.map((suspect) => {\n // calculate the total difference in scores from the averages\n const difference = suspect.scores.reduce(::>);\n\n return {\n name: suspect.name,\n scores: suspect.scores,\n difference: difference\n };\n});\n')" 508 | ], 509 | "hints": [ 510 | "You may want to use a second param: `index`", 511 | "Compare the `suspect.scores[index]` with the `averages[index]`", 512 | "To get a sum, start your `reduce` function at 0" 513 | ] 514 | }, 515 | { 516 | "description": "`reduce` down to likely suspect names by filtering with the `isCheater` function.\n\nThis could be done with a `filter` & `map`, but it is simpler to just use one `reduce`.", 517 | "tests": [ 518 | "07/06" 519 | ], 520 | "actions": [ 521 | "insert('\nfunction isCheater(suspect) {\n return suspect.difference > 200;\n}\n\n// reduce down to a string of likely suspects\nconst likelySuspects = suspectStats.reduce((::>) => {}, []);\n')" 522 | ], 523 | "hints": [ 524 | "use `.join(', ')`" 525 | ] 526 | }, 527 | { 528 | "description": "It looks like we have a likely suspect.", 529 | "tests": [ 530 | "07/07" 531 | ], 532 | "actions": [ 533 | "insert('console.log(likelySuspects);\n')" 534 | ] 535 | } 536 | ], 537 | "onPageComplete": "In the next step, we'll look at using one of the most powerful methods: `reduce`" 538 | } 539 | ] 540 | } --------------------------------------------------------------------------------