diff --git a/exercises/01_http/.test/simple.test.js b/exercises/01_http/.test/simple.test.js deleted file mode 100644 index 9e8336d..0000000 --- a/exercises/01_http/.test/simple.test.js +++ /dev/null @@ -1,23 +0,0 @@ - -'use strict' - -const request = require('supertest') -const server = require('../index.js') -const status = require('http-status-codes') - -afterAll( () => server.close()) - -describe('GET /', () => { - test('the page should return a status code of "200 OK"', async done => { - expect.assertions(1) - const response = await request(server).get('/') - expect(response.status).toEqual(status.OK) - done() - }) - test('we should see the text "Hello World" displayed', async done => { - expect.assertions(1) - const response = await request(server).get('/') - expect(response.text).toEqual('Hello World') - done() - }) -}) diff --git a/exercises/01_http/01_url/.test/index.test.js b/exercises/01_http/01_url/.test/index.test.js deleted file mode 100644 index 3268875..0000000 --- a/exercises/01_http/01_url/.test/index.test.js +++ /dev/null @@ -1,129 +0,0 @@ - -'use strict' - -const request = require('supertest') -const server = require('../index.js') - -afterAll( () => server.close()) - -describe('GET /', () => { - test('we should see the text "Hello World" displayed', async done => { - expect.assertions(1) - const response = await request(server).get('/') - expect(response.text).toEqual('Hello World') - done() - }) -}) - -describe('GET /anon', () => { - test('we should see the text "Hello World" displayed', async done => { - expect.assertions(1) - const response = await request(server).get('/anon') - expect(response.text).toEqual('Hello World') - done() - }) -}) - -describe('GET /books/:index', () => { - test('passing index 0 returns "The Hobbit"', async done => { - expect.assertions(1) - const response = await request(server).get('/books/0') - expect(response.text).toEqual('The Hobbit') - done() - }) - test('passing index 2 returns "The Secret Garden"', async done => { - expect.assertions(1) - const response = await request(server).get('/books/2') - expect(response.text).toEqual('The Secret Garden') - done() - }) -}) - -describe('GET /name', () => { - test('browser should display all querystrings as a JSON string', async done => { - expect.assertions(1) - const response = await request(server).get('/name?firstname=Mark') - expect(response.text).toEqual('{"firstname":"Mark"}') - done() - }) -}) - -describe('GET /hello/:name', () => { - test('browser should display the name in the URL', async done => { - expect.assertions(1) - const response = await request(server).get('/hello/Mark') - expect(response.text).toEqual('hello Mark') - done() - }) - test('the "format" querystring should make name uppercase', async done => { - expect.assertions(1) - const response = await request(server).get('/hello/Mark?format=upper') - expect(response.text).toEqual('hello MARK') - done() - }) -}) - -describe('POST /form', () => { - test('adding a valid user', async done => { - expect.assertions(2) - const response = await request(server).post('/form').send('firstname=John&lastname=Doe') - expect(response.text).toEqual('your name is John Doe') - expect(response.status).toEqual(201) - done() - }) - test('trying adding a user with short name', async done => { - expect.assertions(1) - const response = await request(server).post('/form').send('firstname=Jo&lastname=Do') - expect(response.status).toEqual(422) - done() - }) -}) - -describe('GET /names', () => { - beforeAll( async() => { - await request(server).post('/form').send('firstname=John&lastname=Doe') - await request(server).post('/form').send('firstname=Jane&lastname=Doe') - await request(server).post('/form').send('firstname=Mickey&lastname=Mouse') - await request(server).post('/form').send('firstname=Fred&lastname=Flintstone') - }) - xit('get all names', async done => { - done() - }) - xit('get all names with filter', async done => { - done() - }) - xit('ignore filter if querystring less than 3 chars', async done => { - done() - }) - xit('get all names in CSV format', async done => { - done() - }) - xit('get all names in XML format', async done => { - done() - }) - xit('get all names in JSON format', async done => { - done() - }) - xit('get all names in HTML format', async done => { - done() - }) - xit('get all names in invalid format', async done => { - done() - }) -}) - -describe('DELETE /names', () => { - test('delete names from server', async done => { - expect.assertions(2) - await request(server).post('/form').send('firstname=John&lastname=Doe') - await request(server).post('/form').send('firstname=Jane&lastname=Doe') - const response = await request(server).get('/names').set('Accept', 'application/json') - expect(response.status).toBe(200) - const data = JSON.parse(response.text) - expect(data.names.length).toBeTruthy - await request(server).del('/names') - const response2 = await request(server).get('/names').set('Accept', 'application/json') - expect(response2.status).toBe(404) - done() - }) -}) diff --git a/exercises/01_http/01_url/index.js b/exercises/01_http/01_url/index.js deleted file mode 100644 index ef915ea..0000000 --- a/exercises/01_http/01_url/index.js +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env node - -/* IMPORTING MODULES */ -const Koa = require('koa') -const Router = require('koa-router') -const bodyParser = require('koa-bodyparser') -const staticFiles = require('koa-static') -const js2xmlparser = require('js2xmlparser') - -/* CONFIGURING THE MIDDLEWARE */ -const app = new Koa() -app.use(bodyParser()) -const router = new Router() -app.use(router.routes()) -app.use(staticFiles('./public')) - -/* GLOBAL VARIABLES */ -const port = 8080 -let names = [] - -function hello(ctx) { - ctx.body = 'Hello World' -} - -router.get('/', hello) - -router.get('/anon', ctx => { - ctx.body = 'Hello World' -}) - -router.get('/books/:index', ctx => { - const books = ['The Hobbit', 'Alice in Wonderland', 'The Secret Garden'] - const parameters = ctx.params - const title = books[parameters.index] - ctx.body = title -}) - -router.get('/name', ctx => ctx.body = JSON.stringify(ctx.query)) - -router.get('/hello/:name', ctx => { - let myname = ctx.params.name - if(ctx.query.format === 'upper') myname = myname.toUpperCase() - ctx.body = `hello ${myname}` -}) - -router.post('/form', ctx => { - const minLength = 3 - console.log(ctx.request.body) - const body = ctx.request.body - if(body.lastname.length >= minLength) { - names.push( { firstname: body.firstname, lastname: body.lastname } ) - ctx.status = 201 - ctx.body = `your name is ${body.firstname} ${body.lastname}` - } else { - ctx.status = 422 - ctx.body = 'invalid lastname' - } - //ctx.body = 'form processed' -}) - -router.get('/names', ctx => { - let list = names - let search = 'x' - const minLength = 3 - - if(ctx.query.search && ctx.query.search.length >= minLength) { - search = ctx.query.search.toLowerCase() - } else if(ctx.headers.search && ctx.headers.search.length >= minLength) { - search = ctx.headers.search.toLowerCase() - } - - console.log(`Accept: ${ctx.get('Accept')}`) - - if(search.length >= minLength) list = names.filter( val => `${val.firstname} ${val.lastname}`.toLowerCase().includes(search)) - if(list.length === 0) { - ctx.status = 404 - ctx.body = 'No Names found' - return - } - switch (ctx.accepts('application/json', 'application/xml', 'text/html', 'text/html', 'text/csv')) { - case 'text/csv': - ctx.set('content-type', 'text/csv') - ctx.body = formatCSV(list) - break - case 'text/html': - ctx.set('content-type', 'text/html') - ctx.body = formatHTML(list) - break - case 'application/json': - ctx.set('content-type', 'application/json') - ctx.body = {names: list} - break - case 'application/xml': - ctx.set('content-type', 'application/xml') - ctx.body = js2xmlparser.parse('people', list) - break - default: - ctx.status = 406 - ctx.body = 'unsupported MIME type' - break - } -}) - -router.del('/names', ctx => { - names = [] - ctx.status = 204 - ctx.body = 'all names deleted' -}) - -function formatCSV(list) { - let data = '' - for(const name of list) data += `${name.firstname}, ${name.lastname}\n` - return data -} - -function formatHTML(list) { - let data = '' - for(const name of list) { - data += `\n` - } - data += '
${name.firstname}${name.lastname}
' - return data -} - -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/01_http/01_url/jest.config.js b/exercises/01_http/01_url/jest.config.js deleted file mode 100644 index f98b651..0000000 --- a/exercises/01_http/01_url/jest.config.js +++ /dev/null @@ -1,6 +0,0 @@ - -'use strict' - -module.exports = { - verbose: true, -} diff --git a/exercises/01_http/01_url/public/form.html b/exercises/01_http/01_url/public/form.html deleted file mode 100644 index c4d01d6..0000000 --- a/exercises/01_http/01_url/public/form.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -
- First name:
- -
- Last name:
- -

- -
- - diff --git a/exercises/01_http/01_url/public/main.css b/exercises/01_http/01_url/public/main.css deleted file mode 100644 index 728a6ee..0000000 --- a/exercises/01_http/01_url/public/main.css +++ /dev/null @@ -1,5 +0,0 @@ - -table, th, td { - border: 1px solid black; - } - \ No newline at end of file diff --git a/exercises/01_http/02_headers/index.js b/exercises/01_http/02_headers/index.js deleted file mode 100644 index 3572559..0000000 --- a/exercises/01_http/02_headers/index.js +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs-extra') -const js2xmlparser = require('js2xmlparser') -const Koa = require('koa') -const Router = require('koa-router') -const status = require('http-status-codes') -const views = require('koa-views') -const send = require('koa-send') - -const app = new Koa() -const router = new Router() -//const sendfile = require('koa-sendfile') - -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -const port = 8080 - -const bodyParser = require('koa-bodyparser') -app.use(bodyParser()) - -const staticFiles = require('koa-static') -app.use(staticFiles('./public')) - -const names = [] - -router.get('/', ctx => { - ctx.body = 'Hello World' -}) - -router.get('/hello', async ctx => { - await ctx.render('hello') -}) - -router.get('/hello/:name', ctx => { - console.log(ctx.params) - const myname = ctx.params.name - ctx.body = `hello ${myname}` -}) - -router.get('/hello/:first/:last', ctx => { - console.log(ctx.params) - const name = { - firstname: ctx.params.first, - lastname: ctx.params.last - } - console.log(name) - ctx.body = `hello ${name.firstname} ${name.lastname}` -}) - -router.get('/animal/:name', async ctx => { - try { - console.log(ctx.params.name) - const exists = await fs.pathExists(`public/${ctx.params.name}.png`) - if(exists === false) throw new Error(`There is no ${ctx.params.name} image`) - console.log(`found ${ctx.params.name}.png`) - ctx.set('content-type', 'image/png') - console.log('sending file') - const filename = `./public/${ctx.params.name}.png` - console.log(filename) - await send(ctx, filename) - } catch(err) { - console.log(err.message) - ctx.status = status.NOT_FOUND - ctx.body = err.message - } -}) - -router.get('/form', async ctx => { - await ctx.render('form') -}) - -router.post('/form', async ctx => { - try { - console.log('processing the file') - const min = 3 - const body = ctx.request.body - console.log(body) - if(body.firstname === undefined || body.lastname === undefined) { - throw new Error('missing data in request body') - } - if(body.firstname.length < min || body.lastname.length < min) { - throw new Error('invalid data in request body') - } - names.push( { firstname: body.firstname, lastname: body.lastname } ) - ctx.status = status.CREATED - ctx.body = `your name is ${body.firstname} ${body.lastname}` - } catch(err) { - ctx.status = status.UNPROCESSABLE_ENTITY - ctx.body = err.message - } -}) - -router.get('/names', async ctx => { - try { - const min = 3 - let list = names - let search = 'x' - if(ctx.get('search') && ctx.get('search').length >= min) search = ctx.get('search').toLowerCase() - if(ctx.query.search && ctx.query.search.length >= min) search = ctx.query.search.toLowerCase() - console.log(`search: ${search}`) - if(search.length >= min) { - console.log(`you are searching for '${search}'`) - list = names.filter( val => `${val.firstname} ${val.lastname}`.toLowerCase().includes(search)) - } - if(list.length === 0) { - ctx.status = status.NOT_FOUND - ctx.body = 'No Names found' - return - } - // we have some data to display! - console.log(`accept header: ${ctx.get('accept')}`) - console.log(`type: ${ctx.request.type}`) - let body = '' - let statusCode = status.OK - switch(ctx.get('accept')) { - case 'text/csv': - console.log('plain text') - body = getCsv(list) - break - case 'text/html': - console.log('web page') - body = getHtml(list) - break - case 'application/json': - console.log('JSON data') - body = getJson(list) - break - case 'application/xml': - console.log('xml data') - body = getXml(list) - break - default: - console.log('invalid content type') - statusCode = status.NOT_ACCEPTABLE - } - ctx.set('content-type', ctx.get('accept')) - ctx.status = statusCode - ctx.body = body - - } catch(err) { - // - } -}) - -function getCsv(names) { - let data = '' - for(const name of names) { - data += `${name.firstname}, ${name.lastname}\n` - } - return data -} - -function getHtml(names) { - let data = '' - for(const name of names) { - data += `` - } - data += '
${name.firstname}${name.lastname}
' - return data -} - -function getJson(names) { - return names -} - -function getXml(names) { - return js2xmlparser.parse('people', names) -} - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/01_http/02_headers/package.json b/exercises/01_http/02_headers/package.json deleted file mode 100644 index 3bbf022..0000000 --- a/exercises/01_http/02_headers/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "02_headers", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "fs-extra": "^7.0.1", - "http-status-codes": "^1.3.0", - "js2xmlparser": "^3.0.0", - "koa": "^2.6.2", - "koa-bodyparser": "^4.2.1", - "koa-router": "^7.4.0", - "koa-send": "^5.0.0", - "koa-sendfile": "^2.0.1", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/01_http/02_headers/public/bear.png b/exercises/01_http/02_headers/public/bear.png deleted file mode 100644 index 6d0b954..0000000 Binary files a/exercises/01_http/02_headers/public/bear.png and /dev/null differ diff --git a/exercises/01_http/02_headers/public/cat.png b/exercises/01_http/02_headers/public/cat.png deleted file mode 100644 index 21e7acc..0000000 Binary files a/exercises/01_http/02_headers/public/cat.png and /dev/null differ diff --git a/exercises/01_http/02_headers/public/chicken.jpg b/exercises/01_http/02_headers/public/chicken.jpg deleted file mode 100644 index 5fee798..0000000 Binary files a/exercises/01_http/02_headers/public/chicken.jpg and /dev/null differ diff --git a/exercises/01_http/02_headers/public/cow.png b/exercises/01_http/02_headers/public/cow.png deleted file mode 100644 index 25b2dbc..0000000 Binary files a/exercises/01_http/02_headers/public/cow.png and /dev/null differ diff --git a/exercises/01_http/02_headers/public/horse.png b/exercises/01_http/02_headers/public/horse.png deleted file mode 100644 index fa38887..0000000 Binary files a/exercises/01_http/02_headers/public/horse.png and /dev/null differ diff --git a/exercises/01_http/02_headers/public/main.css b/exercises/01_http/02_headers/public/main.css deleted file mode 100644 index ed3a58a..0000000 --- a/exercises/01_http/02_headers/public/main.css +++ /dev/null @@ -1,4 +0,0 @@ - -table, th, td { - border: 1px solid black; -} diff --git a/exercises/01_http/02_headers/public/penguin.png b/exercises/01_http/02_headers/public/penguin.png deleted file mode 100644 index 317b36f..0000000 Binary files a/exercises/01_http/02_headers/public/penguin.png and /dev/null differ diff --git a/exercises/01_http/02_headers/public/pig.png b/exercises/01_http/02_headers/public/pig.png deleted file mode 100644 index 3eaa4de..0000000 Binary files a/exercises/01_http/02_headers/public/pig.png and /dev/null differ diff --git a/exercises/01_http/02_headers/test.sh b/exercises/01_http/02_headers/test.sh deleted file mode 100755 index dc47979..0000000 --- a/exercises/01_http/02_headers/test.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' - -if [ ! -d "/usr/local/lib/node_modules/eslint" ]; then - echo "looks like you don't have eslint installed... fixing this." - npm install -g eslint -fi - -eval "eslint . >/dev/null; exit $?" - -if [exit]; then - echo "looks like you have some issue with your code..." - echo "run the ${GREEN}eslint .${NC} command to see what needs fixing" - echo " when your code is fixed run this script again." - exit 1 -fi - -# npm uninstall -g eslint - -exit 0 - -# Black 0;30 Dark Gray 1;30 -# Red 0;31 Light Red 1;31 -# Green 0;32 Light Green 1;32 -# Brown/Orange 0;33 Yellow 1;33 -# Blue 0;34 Light Blue 1;34 -# Purple 0;35 Light Purple 1;35 -# Cyan 0;36 Light Cyan 1;36 -# Light Gray 0;37 White 1;37 \ No newline at end of file diff --git a/exercises/01_http/02_headers/views/form.html b/exercises/01_http/02_headers/views/form.html deleted file mode 100644 index c4d01d6..0000000 --- a/exercises/01_http/02_headers/views/form.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -
- First name:
- -
- Last name:
- -

- -
- - diff --git a/exercises/01_http/02_headers/views/hello.html b/exercises/01_http/02_headers/views/hello.html deleted file mode 100644 index e36a0cd..0000000 --- a/exercises/01_http/02_headers/views/hello.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Hello World - - -

Hello World

- - diff --git a/exercises/01_http/index.js b/exercises/01_http/index.js deleted file mode 100644 index f67e740..0000000 --- a/exercises/01_http/index.js +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const app = new Koa() - -const port = 8080 - -app.use( ctx => ctx.body = 'Hello World') - -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/01_http/jest.config.js b/exercises/01_http/jest.config.js deleted file mode 100644 index 9220761..0000000 --- a/exercises/01_http/jest.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - verbose: true, - testRegex: 'simple.test.js' -} diff --git a/exercises/02_html/01_syntax/coventry.html b/exercises/02_html/01_syntax/coventry.html deleted file mode 100644 index ff42ccb..0000000 --- a/exercises/02_html/01_syntax/coventry.html +++ /dev/null @@ -1,89 +0,0 @@ - -History of a City: Coventry - -By Dr Charles Insley - -Copyright BBC 2005 - -Join Charles Insley in Coventry for a walk through time. Although each town or city is different, they share many common themes. Discover how to read the history of your town from the buildings around you. - -Every town or city carries at least some of its past into the present. Local architecture, street names and churches all stand testimony to the passage of time. Just walking around any town - it could be your town - can become a walk into the past made visible by the buildings around you! - -Of course, the history of every town or city is different but most share common aspects and themes. Many began as medieval market centres, grew during the Industrial Revolution of the late 18th & 19th centuries and have expanded and developed and expanded again since the World War Two. - -All of these changes can be seen in the towns and cities around us. If we take Coventry as an example, we can see the remains of its medieval past in St Mary's Hall, the beginnings of its industrial greatness in the working class terraces of Chapelfields, or the triumph of the motor car in the semi-detached suburbs such as Earlsdon. - -Taking an even closer look at Coventry can illustrate just how much of the past can be seen when you are looking with the eyes of an historian. - -Opening themes - -The most obvious place to start is in the gutted shell of the Cathedral Church of St Michael. These Gothic ruins hint at Coventry's medieval past. -Although, like many places, very little of medieval Coventry is still standing, there is enough to give us a flavour of the bustling cloth centre that was the medieval city. - -The historical records tell us that as a settlement, Coventry may date back to the 10th century, while the building, which was to become the priory, was founded in the mid-11th century by Leofric, Earl of Mercia and his notorious wife, Godgifu, or Godiva. Many of the place-names of the villages around Coventry, places that have ultimately become its suburbs, are also Anglo-Saxon in origin. - -Despite the loss of most of Coventry's surviving medieval buildings during the Blitz, the street plan of central Coventry was essentially that of the medieval city. Even now, after the complete rebuilding of the city centre, the ghost of medieval Coventry remains in some of the street names, such as Pool Meadow, Broadgate, Cross Cheaping, Earl Street, Jordan Well, Fleet Street, Spon Street and Greyfriars Green. - -Documentary evidence tells us that Coventry was a booming wool & cloth centre in the Middle Ages and one of the wealthiest cities in medieval England. Evidence of this wealth is hard to find, but it is there. -If we walk across the city centre from the old cathedral, we can see one of the most remarkable survivors of the destruction of 1940: the magnificent St Mary's Hall. This is one of the most impressive guildhalls surviving in England and was the seat of the city's medieval corporation, its government. Even now, this is an impressive building and tells us something about the wealth of the city in the medieval period. - -Across the 1960s pedestrian shopping precinct, and just inside the ring road, is Spon Street where with its surviving medieval shops & houses. These impressive half-timbered buildings, with their jettied upper storeys (where the first floor sticks out beyond the ground floor) give some indication of the economic standing of the city towards the end of the Middle Ages when these houses were built. Behind the 1960s shops on New Union Street we can see the remains of the once-majestic Cheylesmore manor, the Coventry palace of the Earls of Warwick. - -Coventry differs from many other towns & cities in that there was no period of rebuilding and redevelopment in the 16th, 17th and early 18th centuries. Although the city had been a booming wool town in the Middle Ages, its economic fortunes had plummeted towards the end of the 15th century, to the extent that it was not sufficiently prosperous in the next 200 to 300 years to be substantially rebuilt or expanded. - -The city walls, for instance, were not finally removed until the 18th century, although traces of this, such as Cork Street Gate, still remain. The result was that much of medieval Coventry was still standing in the first half of the 20th century, cheek by jowl with the town houses of the 18th century and the terraces of the 19th century, only to be destroyed in the disastrous air raid of November 1940. - -The Industrial Revolution - -The Industrial Revolution changed the face of Britain and the period from the middle of the 18th century to the end of the 19th is one of the most interesting in urban history. -As in many other towns and cities, the Industrial Revolution has left its thumbprint on Coventry. Almost overnight, many towns and cities dramatically increased in size as people moved to the towns to take up jobs in the new industries. - -This period saw a sustained campaign of building and rebuilding in many towns and cities: working class housing for the tens of thousands of industrial labourers and improved housing for the middle classes who began to move away from the often crowded town and city centres and into the newly expanding suburbs. - -Leaving the city centre, you come to parts of Coventry that were fields until well into the 18th century. Again, many towns and cities, where we can see 18th & 19th century development of areas once very rural, mirror Coventry's experience. - -Chapelfields was one of these new suburbs: its name highlights its rural origins. The houses in Chapelfields were built to house workers in the watch industry and some of these watchmakers' terraces are still standing. These are highly distinctive buildings: their large attic windows provided light for the watchmakers who used these attics as workshops. - -A few streets over from Chapelfields are the narrow terraces built in Earlsdon during the 19th century for workers in Coventry's other industry, ribbon weaving and making. But Coventry's expansion in the 18th and 19th centuries was not just about the working class. - -Go back into the city centre and you will find the houses built for Coventry's more prosperous 18th-century inhabitants in the fine Georgian town houses of The Quadrant and Warwick Road and the handful of surviving 18th-century houses on Little Park Street. - -Urban growth and industry - -Like many cities and towns, much of Coventry's building environment dates from the 20th century and can be seen anywhere you choose to stand in Coventry. -In the 19th century, Earlsdon was very much a working class suburb full of terraces built for ribbon weavers and watchmakers. But by the 20th century, Earlsdon was rapidly becoming an affluent middle class suburb, with streets of detached and semi-detached houses being built during the 1920s and 1930s on what had once been open fields. - -As in many towns, the 20th century saw not only a massive increase in population but also the urban middle classes moving out from the town or city centre into these newly developed suburbs and commuting to work by bus, tram or even car. - -Coventry's car industry grew out of light engineering, especially sewing machine and bicycle manufacture. Paradoxically, it is much harder to find the physical evidence of these early, small factories than it is for earlier industry. Many of these factories were built only just outside the city centre, cheek by jowl, with terraced housing built at the same time. - -Even during the expansion of the motor industry in the 1920s and 1930s, the factories of firms such as Standard-Triumph, Lea Francis and Alvis were still only just outside the city centre. Part of the reason why so much of Coventry was destroyed or badly damaged during 1940 was that the Luftwaffe's industrial targets were right in the middle of the city. - -It is only since the 1960s that Coventry's car industry and its surviving car factories (Jaguar, Peugeot-Citröen, along with Alvis, makers of military vehicles, and Rolls-Royce Aero-engines) have moved to the outskirts of the city. - -Redevelopment in the 20th century - -If you were to stand in Broadgate, in the city centre, almost everything in sight dates from the 1950s or later. You can still see the highly innovative pedestrian shopping precinct built during the 1950s and 1960s. -On the horizon are the tower blocks from the 1960s and 1970s and the final phase of the expansion of suburban Coventry. Places such as Allesley Park, with its modern semi-detached houses, also date from the post-war period. - -Yet the view from Broadgate has also been one of continuous change since the war. Large parts of the 1960s precincts have been demolished to make way for more recent shopping centres, while those factories which were still centrally located in the 1980s, such as the Alvis works, have now moved out beyond the edges of the city and been replaced with retail parks. - -Although the damage done by the Luftwaffe in 1940 was considerable, Coventry's post-war experience is shared by many other towns and cities. As with most towns and cities, the arrival of the motor vehicle has meant that narrow streets built in the medieval or early modern periods were simply inadequate to cope with ever increasing levels of traffic. This has led to the replanning of city centre road systems to cope with this traffic, and in many cases, the building of ring-roads and bypasses. - -Where to go next - -Although there is no such thing as a typical British town or city, many aspects of Coventry's history are mirrored in other urban centres: its medieval origins; its expansion as an industrial centre in the 19th and 20th centuries; and its redevelopment since the war, with traditional industries giving way to new technology-based industries and retail complexes. -For anyone interested in looking at their town or city, it is these themes that may provide a way into urban history - perhaps the history of the suburb in which you live, an industry associated with your family or the town's social infrastructure, such as its schools or hospitals. - -In addition to the physical record, there are a vast array of documentary sources to look at: school log-books, medieval court records, monastic records, probate records (wills), company accounts, Ordnance Survey maps, deposited plans, diaries and antiquarian papers, as well as the records produced by central and local government. - -As with any research, rather than just plunging in, read what other historians have said about your topic and get some sense of the things to look at and the sources to use. Most modern histories of towns and cities, such as those produced by the Victoria County History, will have a detailed list of the sources used and where they can be found. - -You will have to visit a number of different places to search for sources, although your first port of call is likely to be the local city or county record office. - -The disappearing past - -In any town or city, the old and the new stand next to each other. As towns and cities continually evolve and are developed, the old, sadly, often makes way for the new. -Much of the Victorian terraced housing in the city centre survived the bombing of 1940, only to be demolished afterwards to make way for the replanning of the city centre. Now only one street of Victorian terraces, Starley Road, remains within the ring road and only a long campaign by its residents prevented its demolition in the 1980s. - -Much of the urban history we can see today will eventually be lost, so get out now and take advantage of it and explore the buildings of your town or city. Next time you walk to the shops, or to the bus stop, or to work, look up and around. diff --git a/exercises/02_html/01_syntax/index.js b/exercises/02_html/01_syntax/index.js deleted file mode 100644 index bf94004..0000000 --- a/exercises/02_html/01_syntax/index.js +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -const port = 8080 - -app.use(views(`${__dirname}`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('coventry')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/01_syntax/package.json b/exercises/02_html/01_syntax/package.json deleted file mode 100644 index 701e135..0000000 --- a/exercises/02_html/01_syntax/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "01_syntax", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/02_html/02_lists/commodore64.html b/exercises/02_html/02_lists/commodore64.html deleted file mode 100644 index 06fdfb2..0000000 --- a/exercises/02_html/02_lists/commodore64.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/exercises/02_html/02_lists/computers80.html b/exercises/02_html/02_lists/computers80.html deleted file mode 100644 index db0b7b4..0000000 --- a/exercises/02_html/02_lists/computers80.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - 1980's home computers - - - - -
- A computer with a monitor -
Photo: Piotr Siedlecki, public domain via http://www.publicdomainpictures.net.
-
-
-

1980's Home Computers

- -

In early 1980's, home computers became mainstream. For the first time, computers could be purchased by an average family household.

- -

Clever uses

-

The main usage for a home computer was, of course, games. As cool games may not be a valid reason for purchasing an expensive gadget, a wide variety of potential uses were invented to satisfy those family members who might otherwise be sceptical.

- -

Legendary computers

-

The best known computer of the eighties was Commodore 64, but there are other computers that gained popularity.

- -

Read the Wikipedia article for Retrocomputing.

- -

Key concepts

-

The hardware charateristics of a home computer could be defined by its graphics and sound capabilities, CPU, and amount of memory.

- - - -
- - - \ No newline at end of file diff --git a/exercises/02_html/02_lists/express.js b/exercises/02_html/02_lists/express.js deleted file mode 100644 index 2e2cb2d..0000000 --- a/exercises/02_html/02_lists/express.js +++ /dev/null @@ -1,17 +0,0 @@ - -const express = require('express') -const app = express() - -const port = 8080 - -app.get('/', (req, res) => { - res.sendFile(`${__dirname}/html/computers80.html`) -}) - -app.get('/commodore', (req, res) => { - res.sendFile(`${__dirname}/commodore64.html`) -}) - -app.listen(port, () => { - console.log(`app listening on port ${port}`) -}) diff --git a/exercises/02_html/02_lists/index.js b/exercises/02_html/02_lists/index.js deleted file mode 100644 index f3848e4..0000000 --- a/exercises/02_html/02_lists/index.js +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('computers80')) -router.get('/commodore', async ctx => ctx.render('commodore64')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/02_lists/package.json b/exercises/02_html/02_lists/package.json deleted file mode 100644 index c0e25a7..0000000 --- a/exercises/02_html/02_lists/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "02_lists", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/02_html/02_lists/public/computer.png b/exercises/02_html/02_lists/public/computer.png deleted file mode 100644 index b71ac38..0000000 Binary files a/exercises/02_html/02_lists/public/computer.png and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/index.js b/exercises/02_html/03_hypermedia/index.js deleted file mode 100644 index a56923c..0000000 --- a/exercises/02_html/03_hypermedia/index.js +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('index')) -router.get('/commodore', async ctx => ctx.render('commodore64')) -router.get('/paradoxes', async ctx => ctx.render('paradoxes')) - -router.get('/date', async ctx => { - const today = new Date() - const dd = today.getDate() - const mm = today.getMonth()+1 - const yyyy = today.getFullYear() - ctx.body = `

The date is: ${dd}/${mm}/${yyyy}` -}) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/03_hypermedia/package.json b/exercises/02_html/03_hypermedia/package.json deleted file mode 100644 index b86d93c..0000000 --- a/exercises/02_html/03_hypermedia/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "03_hypermedia", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/02_html/03_hypermedia/public/computer.png b/exercises/02_html/03_hypermedia/public/computer.png deleted file mode 100644 index b71ac38..0000000 Binary files a/exercises/02_html/03_hypermedia/public/computer.png and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/coventry.mp5 b/exercises/02_html/03_hypermedia/public/coventry.mp5 deleted file mode 100644 index f5ce2d2..0000000 Binary files a/exercises/02_html/03_hypermedia/public/coventry.mp5 and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/coventry.ogv b/exercises/02_html/03_hypermedia/public/coventry.ogv deleted file mode 100644 index e3753fe..0000000 Binary files a/exercises/02_html/03_hypermedia/public/coventry.ogv and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/coventry_cathedral.jpg b/exercises/02_html/03_hypermedia/public/coventry_cathedral.jpg deleted file mode 100644 index f529bdb..0000000 Binary files a/exercises/02_html/03_hypermedia/public/coventry_cathedral.jpg and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/guitar.mp3 b/exercises/02_html/03_hypermedia/public/guitar.mp3 deleted file mode 100644 index c982a31..0000000 Binary files a/exercises/02_html/03_hypermedia/public/guitar.mp3 and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/guitar.ogg b/exercises/02_html/03_hypermedia/public/guitar.ogg deleted file mode 100644 index 28c6961..0000000 Binary files a/exercises/02_html/03_hypermedia/public/guitar.ogg and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/paradox.jpeg b/exercises/02_html/03_hypermedia/public/paradox.jpeg deleted file mode 100644 index 93f9c97..0000000 Binary files a/exercises/02_html/03_hypermedia/public/paradox.jpeg and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/public/tune.mp3 b/exercises/02_html/03_hypermedia/public/tune.mp3 deleted file mode 100644 index 738ab35..0000000 Binary files a/exercises/02_html/03_hypermedia/public/tune.mp3 and /dev/null differ diff --git a/exercises/02_html/03_hypermedia/views/cathedral.html b/exercises/02_html/03_hypermedia/views/cathedral.html deleted file mode 100644 index 529ed8a..0000000 --- a/exercises/02_html/03_hypermedia/views/cathedral.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - The HTML5 Template - - - - -

Coventry Cathedral

- -

http://www.coventrycathedral.org.uk/wpsite/our-history/

- -

The place we call ‘Coventry Cathedral’ is in fact two buildings that lie at the very heart of the city of Coventry. The Ruins of the ‘old Cathedral’ are the remains of a medieval parish church, consecrated to be the Cathedral of the new Diocese of Coventry in 1918. In a little over 20 years, this building would be destroyed by enemy air attack in the Second World War. Rather than sweeping away the ruins or rebuilding a replica of the former church, inspired by the message of Christ for reconciliation, the then leaders of the Cathedral Community took the courageous step to build a new Cathedral and preserve the remains of the old Cathedral as a moving reminder of the folly and waste of war. From that point, Coventry Cathedral became the inspiration for a ministry of peace and reconciliation that has reached out across the entire world.

- -

The ‘new’ Cathedral was itself an inspiration to many fine artists of the post-war era. The architect, Sir Basil Spence, commissioned work from Graham Sutherland, John Piper, Ralph Beyer, John Hutton, Jacob Epstein, Elisabeth Frink and others – most still to reach the peak of their artistic careers. In the ‘old Cathedral’ it is still possible to see (uniquely) at eye-level, sections of outstanding, hand painted glass by John Thornton (circa 1450). Thornton, born in Coventry, was recognised as a master glass painter of his time and went on to paint the windows of York Minster. Coventry Cathedral is fortunate to have a very fine collection of his glass which is being conserved with a view to future public display and can be viewed by special arrangement in the meantime.

- -

Today the ruins of the old Cathedral are preserved as a memorial and sacred space for the City. They also provide a dramatic backdrop to open air events and film recording on occasions. The Coventry Litany of Reconciliation is prayed here every Friday at noon. As part of our 2012 Golden Jubilee we are planning to open up the old chapels and crypts under the ruins to create a Visitor Centre that will offer a new and moving reconciliation experience to visitors before they enter the Cathedral.

- -

The interior of the iconic new Cathedral provides many surprises. During the Second World War, the then senior clergyman of the Cathedral, Provost Richard Howard, witnessed the way Christians of all denominations came together to pray – for themselves, for peace and for their enemies – and conceived of an ecumenical space within a future, new Coventry Cathedral. The revolutionary and boundary-breaking nature of this idea should never be under-estimated. The Chapel of Unity is that unique space.

- -

Although physically attached to the new Cathedral, this Chapel is not consecrated as Anglican/Church of England space, but is on a 999 year lease to an ecumenical Joint Council. In the Chapel of Unity Christians of any and all denominations may gather to worship and receive the sacraments. For more information click here.

- -

In the 1990s, a national poll saw Coventry Cathedral elected as the nation’s favourite 20th Century building. It never fails to move, excite and delight all who visit and worship here.

- - \ No newline at end of file diff --git a/exercises/02_html/03_hypermedia/views/commodore64.html b/exercises/02_html/03_hypermedia/views/commodore64.html deleted file mode 100644 index 7efb89b..0000000 --- a/exercises/02_html/03_hypermedia/views/commodore64.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/exercises/02_html/03_hypermedia/views/index.html b/exercises/02_html/03_hypermedia/views/index.html deleted file mode 100644 index 3659c4c..0000000 --- a/exercises/02_html/03_hypermedia/views/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Retro Computers - - - - -

Retro Computers

-
    -
  1. Commodore 64
  2. -
- - \ No newline at end of file diff --git a/exercises/02_html/03_hypermedia/views/paradoxes.html b/exercises/02_html/03_hypermedia/views/paradoxes.html deleted file mode 100644 index a529613..0000000 --- a/exercises/02_html/03_hypermedia/views/paradoxes.html +++ /dev/null @@ -1,43 +0,0 @@ - -Paradoxes - -- The Heap -- The Liar Paradox -- Limited And Unlimited - -The Heap - -Let’s travel back to the fourth century BC and start with Eubulides of Miletus, the man who is credited as the inventor of paradoxes. Eubulides came up with four fun brainteasers that require careful thinking to solve. -The Heap (aka The Sorites Paradox) is the first of these classical paradoxes, and it’s a question of degrees: - -If a man has zero hairs on his head, we say he’s bald. However, a man who has 10,000 hairs on his head is not considered to be bald. But what if we add a single hair to the head of the man with zero hairs? He would still clearly be bald. - -Now let’s say that a man has 1,000 hairs only. But the strands are evenly spaced and really thin. Would this man be bald or not bald? - -Would you consider a single grain of wheat a “heap of wheat?” Definitely not. How about two grains? Still, probably not. So when do a few grains or a few hairs end and a whole heap or baldness actually begin? - -The problem is one of vagueness. Where does one description end and another begin? - -The Liar Paradox - -The first sentence of this paragraph is a lie. Stop and think about that sentence for a second. Is it true? Or a lie? A true lie? This is called The Liar Paradox, and it’s also from the time of Eubulides. It’s straightforward and fun and takes the form of one short statement: “This sentence is a lie.” Another incarnation of the paradox is: “Everything I say is false.” - -The problem with both statements: They’re true, but they contradict themselves if that is so. How can a true statement contradict itself? Wouldn’t that make it both true and untrue at the same time? - -If either quotation above is really a lie, then that statement is true and contradicts itself. Even worse, if every other statement previously uttered by the speaker is false, then this one sentence, “Everything I say is false,” is a true sentence and contradicts itself. - -So, what do you think? Is the sentence a lie? - -Limited And Unlimited - -The next paradox comes from a man named Zeno of Elea who lived circa 495–430 BC. He came up with quite a few brainteasers which are still puzzling to this day. Have you ever wondered about the similarities we see in nature from small to large? Have you ever thought that maybe, just maybe, our whole universe is really just a tiny atom in the universe of some much larger entity? - -Zeno wanted to show that the idea of a plurality of things (which all exist side by side in time and space) brought with it some serious logical inconsistencies. The Limited And Unlimited Paradox displayed this. Does one thing exist or many? What separates one thing from the next? Where is the line? - -This is also called The Paradox of Density, and let’s put it a little differently. This works with multiple objects, but we’ll start with just two. If there are two things, what separates them? You need a third thing to separate the two.The Paradox of Density takes place on many different scales, but you get the basic idea. So, is there just one massive entity called the universe that contains indistinguishable matter of varying densities (air, the floor, a tree, etc.)? - -Is all matter perpetually divisible? Or if we divide matter into objects small enough, will we eventually reach the object so small that it cannot be divided? - -The smartest scientific minds of the human race still grapple with these questions today. - -http://listverse.com/2018/01/12/10-insanely-fun-and-simple-philosophical-paradoxes/ \ No newline at end of file diff --git a/exercises/02_html/04_tables/comparison.html b/exercises/02_html/04_tables/comparison.html deleted file mode 100644 index 42b0dda..0000000 --- a/exercises/02_html/04_tables/comparison.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Comparison of three computers - - - - -

A comparison of technical data of three popular 80's home computers:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Technical comparison
PropertyCommodore 64ZX SpectrumCommodore VIC-20
CPUMOS Technology 6510Zilog Z80MOS Technology 6502
RAM64 kilobytes16 or 64 kilobytes5 kilobytes
ROM20 kilobytes16 kilobytes16 kilobytes
- -
- - - - \ No newline at end of file diff --git a/exercises/02_html/04_tables/index.js b/exercises/02_html/04_tables/index.js deleted file mode 100644 index f78d6a4..0000000 --- a/exercises/02_html/04_tables/index.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('comparison')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/04_tables/package.json b/exercises/02_html/04_tables/package.json deleted file mode 100644 index f086c16..0000000 --- a/exercises/02_html/04_tables/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "04_tables", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/02_html/05_semantic/index.js b/exercises/02_html/05_semantic/index.js deleted file mode 100644 index e2b33d1..0000000 --- a/exercises/02_html/05_semantic/index.js +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('review')) -router.get('/cafe', async ctx => ctx.render('cafe')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/05_semantic/package.json b/exercises/02_html/05_semantic/package.json deleted file mode 100644 index 7c76ce3..0000000 --- a/exercises/02_html/05_semantic/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "05_semantic", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - } -} diff --git a/exercises/02_html/05_semantic/public/poster.jpg b/exercises/02_html/05_semantic/public/poster.jpg deleted file mode 100644 index 900e64a..0000000 Binary files a/exercises/02_html/05_semantic/public/poster.jpg and /dev/null differ diff --git a/exercises/02_html/05_semantic/public/waiting_room.jpg b/exercises/02_html/05_semantic/public/waiting_room.jpg deleted file mode 100644 index 875f268..0000000 Binary files a/exercises/02_html/05_semantic/public/waiting_room.jpg and /dev/null differ diff --git a/exercises/02_html/05_semantic/views/cafe.html b/exercises/02_html/05_semantic/views/cafe.html deleted file mode 100644 index 958800a..0000000 --- a/exercises/02_html/05_semantic/views/cafe.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - The Java Coding Cafe - - - - -

Welcome to the Java Cafe

-

The Java Cafe is passionate in providing quality home-baked goods, deliciously innovative classic dishes and excellent beverages that evoke the atmosphere of the 1990s.

-

Our cafés in Coventry and Cupertino aim to provide a wonderful place to relax, socialise, work, hold meetings and above all enjoy exceptional-quality food and drinks at an unbeatable price.

-

Payment in GBP only.

-

Hours: Mo-Fri 10am-7pm Sa 10am-22pm Su 10am-21pm

-

Payment accepted: Cash, Credit Card

-

Priory Street, Coventry, CV1 5FB

-

Tourist Board 4 star rating

-

Serves Lavazza coffee

-

javacafe@example.com

-

Tel: 024 7655 5555

- - diff --git a/exercises/02_html/05_semantic/views/review.html b/exercises/02_html/05_semantic/views/review.html deleted file mode 100644 index 4ef9c3e..0000000 --- a/exercises/02_html/05_semantic/views/review.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Review: The Social Network - - - - -

Film Reviews

-

Poster for 'The Social Network'

-
-

The Social Network

-

12A

-

Courtesy of The Guardian

-

by

- - -

From the first sentence, the first word, the first nervily in-drawn breath, this compulsively watchable picture announces itself as the unmistakable work of Aaron Sorkin. His whip-smart, mile-a-minute dialogue made The West Wing deeply addictive on TV, and after uncertain works such as Charlie Wilson's War and the strange, small-screen drama Studio 60 on the Sunset Strip – in which Sorkin's distinctive, faintly martyred seriousness was bafflingly applied to the backstage shenanigans of a fictional television comedy – this writer is triumphantly back on form. He's found an almost perfect subject: the creation of the networking website Facebook, and the backstabbing legal row among the various nerds, geeks, brainiacs and maniacs about who gets the credit and the cash.

-
-
-

Overall rating: 4/5

-
- -
- - - diff --git a/exercises/02_html/06_markdown/computers.md b/exercises/02_html/06_markdown/computers.md deleted file mode 100644 index 426c755..0000000 --- a/exercises/02_html/06_markdown/computers.md +++ /dev/null @@ -1,11 +0,0 @@ - -# 80s Computers - -Here is a list of the best computers from the 1980s. - -1. Commodore 64 -2. ZX Spectrum - -| Computer | Year | -| ----------- | ----: | -| Commodore64 | 1982 | \ No newline at end of file diff --git a/exercises/02_html/06_markdown/express.js b/exercises/02_html/06_markdown/express.js deleted file mode 100644 index 23d8cab..0000000 --- a/exercises/02_html/06_markdown/express.js +++ /dev/null @@ -1,23 +0,0 @@ - -'use strict' - -const express = require('express') -const app = express() - -const marked = require('marked') -const fs = require('fs') - -const port = 8080 - -app.get('/', (req, res) => { - fs.readFile(`${__dirname}/computers.md`, 'utf8', (err, data) => { - if(err) { - console.log(err) - } - res.send(marked(data.toString())) - }) -}) - -app.listen(port, () => { - console.log(`app listening on port ${port}`) -}) diff --git a/exercises/02_html/06_markdown/index.js b/exercises/02_html/06_markdown/index.js deleted file mode 100644 index 60ca1b2..0000000 --- a/exercises/02_html/06_markdown/index.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -const marked = require('marked') -const readFile = require('fs-readfile-promise') - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -app.use(require('koa-static')('public')) -const port = 8080 - -router.get('/', async ctx => ctx.body = marked(await readFile('./computers.md', 'utf8'))) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/02_html/06_markdown/package.json b/exercises/02_html/06_markdown/package.json deleted file mode 100644 index 68cbafb..0000000 --- a/exercises/02_html/06_markdown/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "06_markdown", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "fs-extra": "^7.0.1", - "fs-readfile-promise": "^3.0.1", - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5", - "kow": "^3.2.3", - "marked": "^0.6.0" - }, - "devDependencies": {}, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} diff --git a/exercises/02_html/template.html b/exercises/02_html/template.html deleted file mode 100644 index 7c6c42d..0000000 --- a/exercises/02_html/template.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - The HTML5 Template - - - - - - - diff --git a/exercises/03_css/01_formatting/index.js b/exercises/03_css/01_formatting/index.js deleted file mode 100644 index 3784d93..0000000 --- a/exercises/03_css/01_formatting/index.js +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('hello')) -router.get('/test', async ctx => await ctx.render('csstest')) -router.get('/comparison', async ctx => await ctx.render('comparison')) -router.get('/hello', async ctx => await ctx.render('hello-world')) -router.get('/selectors', async ctx => await ctx.render('selectors')) -router.get('/targets', async ctx => await ctx.render('targets')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/03_css/01_formatting/package.json b/exercises/03_css/01_formatting/package.json deleted file mode 100644 index ac7ecb5..0000000 --- a/exercises/03_css/01_formatting/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "01_formatting", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "express": "^4.16.2", - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - }, - "description": "" -} diff --git a/exercises/03_css/01_formatting/public/css/hello.css b/exercises/03_css/01_formatting/public/css/hello.css deleted file mode 100644 index fb0e5d2..0000000 --- a/exercises/03_css/01_formatting/public/css/hello.css +++ /dev/null @@ -1,4 +0,0 @@ - -h1 { - color: red; -} \ No newline at end of file diff --git a/exercises/03_css/01_formatting/public/css/selectors.css b/exercises/03_css/01_formatting/public/css/selectors.css deleted file mode 100644 index 41f8b1c..0000000 --- a/exercises/03_css/01_formatting/public/css/selectors.css +++ /dev/null @@ -1,19 +0,0 @@ -body { - font-family: Arial, Verdana, sans-serif; -} - -p { - color: blue; -} - -h1.alert { - font-size: 3em; -} - -.alert { - color: red; -} - -p#unique { - font-size: 0.8em; -} diff --git a/exercises/03_css/01_formatting/public/css/simple.css b/exercises/03_css/01_formatting/public/css/simple.css deleted file mode 100644 index 061fbf3..0000000 --- a/exercises/03_css/01_formatting/public/css/simple.css +++ /dev/null @@ -1,9 +0,0 @@ -body { - font-family: Arial, Verdana, sans-serif; -} - -h1, -h2 { - color: blue; - font-weight: bold; -} \ No newline at end of file diff --git a/exercises/03_css/01_formatting/public/css/targetstyles.css b/exercises/03_css/01_formatting/public/css/targetstyles.css deleted file mode 100644 index 7cebbae..0000000 --- a/exercises/03_css/01_formatting/public/css/targetstyles.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - font-family: Arial, Verdana, sans-serif; -} diff --git a/exercises/03_css/01_formatting/public/images/comparison.png b/exercises/03_css/01_formatting/public/images/comparison.png deleted file mode 100644 index 86b62f1..0000000 Binary files a/exercises/03_css/01_formatting/public/images/comparison.png and /dev/null differ diff --git a/exercises/03_css/01_formatting/public/images/computer.png b/exercises/03_css/01_formatting/public/images/computer.png deleted file mode 100644 index b71ac38..0000000 Binary files a/exercises/03_css/01_formatting/public/images/computer.png and /dev/null differ diff --git a/exercises/03_css/01_formatting/public/images/tickmark.png b/exercises/03_css/01_formatting/public/images/tickmark.png deleted file mode 100644 index b796c51..0000000 Binary files a/exercises/03_css/01_formatting/public/images/tickmark.png and /dev/null differ diff --git a/exercises/03_css/01_formatting/views/comparison.html b/exercises/03_css/01_formatting/views/comparison.html deleted file mode 100644 index 42b0dda..0000000 --- a/exercises/03_css/01_formatting/views/comparison.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Comparison of three computers - - - - -

A comparison of technical data of three popular 80's home computers:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Technical comparison
PropertyCommodore 64ZX SpectrumCommodore VIC-20
CPUMOS Technology 6510Zilog Z80MOS Technology 6502
RAM64 kilobytes16 or 64 kilobytes5 kilobytes
ROM20 kilobytes16 kilobytes16 kilobytes
- -
- - - - \ No newline at end of file diff --git a/exercises/03_css/01_formatting/views/csstest.html b/exercises/03_css/01_formatting/views/csstest.html deleted file mode 100644 index 0791d1a..0000000 --- a/exercises/03_css/01_formatting/views/csstest.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Vintage Home Computers - - - -
-

1980's Home Computers

-

In early 1980's, home computers became mainstream. For the first time, computers could be - purchased by an average family household.

-
- A computer with a monitor -
Photo: Piotr Siedlecki, public domain via http://www.publicdomainpictures.net.
-
-

Novel uses

-

The main usage for a home computer was, of course, games. As cool games may not be a valid reason for purchasing an expensive gadget, - a wide variety of potential uses were invented to satisfy those family members who might otherwise be sceptical. -

-

Some reasons often mentioned were:

- -

While some of these use cases are perfectly valid, it is still unclear how many families actually used - their brand new home computer (duly equipped with a cassette drive) to actually record every food item they removed from the freezer.

- -

Legendary computers

-

The three most memorizable 1980's home computers, in subjective order of importance, might be:

-
    -
  1. Commodore 64
  2. -
  3. Sinclair ZX Spectrum
  4. -
  5. Commodore Vic-20
  6. -
-

Read the Wikipedia article for Retrocomputing.

- -

Key concepts

- The hardware charateristics of a home computer could be defined by its graphics and sound capabilities, CPU, and amount of memory. The types of memory were: -
-
RAM
-
Random access memory. The memory usable by programs. The amount was typically in the ballpark of 20 to 64 kilobytes. However, the Basic interpreter by default consumed a part of this.
- -
ROM
-
Read-only memory. This was normally smaller in size than RAM and roughly corresponded to the hardware implementation of the operating system.
-
-
- - -
-

Disclaimer: All opinions in this page reflect the views of their author(s), not the organization.

- - - - diff --git a/exercises/03_css/01_formatting/views/hello-world.html b/exercises/03_css/01_formatting/views/hello-world.html deleted file mode 100644 index 32dc15b..0000000 --- a/exercises/03_css/01_formatting/views/hello-world.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Document - - - - - - - - - - -
- - \ No newline at end of file diff --git a/exercises/03_css/01_formatting/views/hello.html b/exercises/03_css/01_formatting/views/hello.html deleted file mode 100644 index de2ff46..0000000 --- a/exercises/03_css/01_formatting/views/hello.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Let's see CSS at Work - - - - - -

Hello CSS!

-

Use this file to see how CSS can be used to change the appearance of a web page.

- - \ No newline at end of file diff --git a/exercises/03_css/01_formatting/views/selectors.html b/exercises/03_css/01_formatting/views/selectors.html deleted file mode 100644 index 771ea37..0000000 --- a/exercises/03_css/01_formatting/views/selectors.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - Selectors - - - - -

Classes and identifiers.

- -

This is a regular paragraph.

- -

This is a regular paragraph, too.

- -

This paragraph belongs to a special group of paragraphs. It is a member of 'alert' class.

- -

This paragraph should be uniquely formatted. It is assigned an identifier.

- -

This paragraph is in 'alert' class, too.

- - - \ No newline at end of file diff --git a/exercises/03_css/01_formatting/views/targets.html b/exercises/03_css/01_formatting/views/targets.html deleted file mode 100644 index 5738cf4..0000000 --- a/exercises/03_css/01_formatting/views/targets.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - Selecting elements - - - - - -

Element selection demo

- -

The sources of energy are:

-
    -
  1. protein
  2. -
  3. carbohydrates
  4. -
  5. fat
  6. -
- -

Sources of carbohydrates:

- - - - - \ No newline at end of file diff --git a/exercises/03_css/02_layout/index.js b/exercises/03_css/02_layout/index.js deleted file mode 100644 index edaffdb..0000000 --- a/exercises/03_css/02_layout/index.js +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const app = new Koa() -const router = new Router() -const views = require('koa-views') -app.use(require('koa-static')('public')) -const port = 8080 - -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) - -router.get('/', async ctx => await ctx.render('boxmodel')) -router.get('/boxmodel', async ctx => await ctx.render('boxmodel')) -router.get('/columns', async ctx => await ctx.render('columns')) -router.get('/floating', async ctx => await ctx.render('floating')) -router.get('/menu', async ctx => await ctx.render('menu')) - -app.use(router.routes()) -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/03_css/02_layout/package.json b/exercises/03_css/02_layout/package.json deleted file mode 100644 index 23ad549..0000000 --- a/exercises/03_css/02_layout/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "02_layout", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "express": "^4.16.2", - "koa": "^2.6.2", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - }, - "description": "" -} diff --git a/exercises/03_css/02_layout/public/css/floatstyles.css b/exercises/03_css/02_layout/public/css/floatstyles.css deleted file mode 100644 index 92edd7b..0000000 --- a/exercises/03_css/02_layout/public/css/floatstyles.css +++ /dev/null @@ -1,10 +0,0 @@ - -body { - font-family: Arial, Verdana, sans-serif; - margin-left: 200px; -} - - - - - diff --git a/exercises/03_css/02_layout/public/css/menustyles.css b/exercises/03_css/02_layout/public/css/menustyles.css deleted file mode 100644 index 78aadc5..0000000 --- a/exercises/03_css/02_layout/public/css/menustyles.css +++ /dev/null @@ -1,31 +0,0 @@ - - -body { - font-family: Arial, Verdana, sans-serif; -} - -nav ul { - list-style: none; -} - -nav ul li { - float: left; - width: 10%; - text-align: center; -} - -nav ul li ul { - visibility: hidden; - position: absolute; -} - -nav ul li ul li { - float: none; - margin-left: 0px; - width: 100%; - text-align: center; -} - -nav ul li:hover > ul { - visibility:visible; -} \ No newline at end of file diff --git a/exercises/03_css/02_layout/public/images/berries.png b/exercises/03_css/02_layout/public/images/berries.png deleted file mode 100644 index dc780d1..0000000 Binary files a/exercises/03_css/02_layout/public/images/berries.png and /dev/null differ diff --git a/exercises/03_css/02_layout/public/images/box_assignment.png b/exercises/03_css/02_layout/public/images/box_assignment.png deleted file mode 100644 index 4b0a022..0000000 Binary files a/exercises/03_css/02_layout/public/images/box_assignment.png and /dev/null differ diff --git a/exercises/03_css/02_layout/public/images/menu.png b/exercises/03_css/02_layout/public/images/menu.png deleted file mode 100644 index bc57010..0000000 Binary files a/exercises/03_css/02_layout/public/images/menu.png and /dev/null differ diff --git a/exercises/03_css/02_layout/public/images/onions.png b/exercises/03_css/02_layout/public/images/onions.png deleted file mode 100644 index 835330c..0000000 Binary files a/exercises/03_css/02_layout/public/images/onions.png and /dev/null differ diff --git a/exercises/03_css/02_layout/views/boxmodel.html b/exercises/03_css/02_layout/views/boxmodel.html deleted file mode 100644 index 5f488c4..0000000 --- a/exercises/03_css/02_layout/views/boxmodel.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Illustration of CSS box model - - - - - -

-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce in malesuada libero. Etiam consectetur enim enim, id porta neque facilisis non. Proin consequat a sapien eu consectetur. Quisque bibendum lorem tortor, nec facilisis risus venenatis vel. Nullam et nunc varius, elementum mi vitae, mattis lacus. Mauris et lacinia magna. Nam faucibus purus ac felis vulputate suscipit. Sed vitae est egestas, euismod neque eu, molestie leo. -

- -

-Fusce viverra enim ante, vel dapibus metus maximus et. Proin ac metus justo. Donec nec scelerisque ante. Vestibulum a lectus nisl. Curabitur dictum a purus non sagittis. Cras semper ipsum ut eros lobortis vestibulum. Aenean eu urna nulla. Quisque mattis ex nec odio sollicitudin, a pulvinar nibh faucibus. Nullam quis rutrum purus, nec condimentum est. Aenean sagittis feugiat ante, sit amet dignissim elit vulputate ac. Aenean nec erat blandit, posuere orci malesuada, aliquam sem. Ut rutrum neque nec sapien consectetur dignissim. -

- -

-Nam odio lectus, accumsan vitae dignissim vitae, condimentum eu ipsum. Ut tristique vel leo at condimentum. Quisque tincidunt et tellus ut feugiat. Proin consectetur nulla eu fringilla cursus. Vivamus mi tellus, consectetur vitae commodo vitae, placerat sit amet nisl. Vestibulum et porttitor est. Cras varius quam a enim commodo consequat. Ut egestas dapibus est, a varius enim tincidunt ac. Quisque scelerisque ante quis porta mollis. Mauris nec maximus orci. Nunc ac justo ut nisl euismod vehicula in lacinia ante. Nulla sollicitudin nisi posuere, volutpat lorem nec, sagittis purus. Duis suscipit vulputate purus ac vulputate. Pellentesque suscipit ornare mi, et finibus tortor rutrum eget. -

- -

-In at ipsum id ligula vehicula porttitor. Suspendisse in risus vitae nunc lacinia lacinia. Cras finibus diam odio, vel posuere justo vestibulum tempor. Integer sed pharetra lacus. Integer elit mauris, vehicula ut tortor ut, vehicula iaculis odio. Integer tincidunt tincidunt quam, a laoreet sem mollis porta. Sed consequat sagittis urna quis aliquet. Proin vitae orci ultrices nisi rutrum blandit. -

- - - \ No newline at end of file diff --git a/exercises/03_css/02_layout/views/columns.html b/exercises/03_css/02_layout/views/columns.html deleted file mode 100644 index 7f84098..0000000 --- a/exercises/03_css/02_layout/views/columns.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - Test file for CSS formatting - - - -

Text to be formatted in columns

- - -

-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris efficitur nisi nulla, condimentum suscipit tellus ullamcorper in. In vulputate leo vitae orci lacinia, at feugiat leo ullamcorper. Morbi malesuada consectetur dolor, et luctus massa lacinia id. Ut interdum egestas luctus. Vivamus ac orci tristique, mattis dui ut, auctor leo. Nulla commodo, ante id blandit tempor, diam ante pellentesque lectus, ac iaculis enim tortor a mi. Morbi orci quam, dictum id nibh eget, mollis ultricies erat. Pellentesque porttitor leo ut laoreet convallis. Praesent porttitor sapien nec lacus ullamcorper, sed euismod risus sagittis. Curabitur non ultricies diam. Suspendisse ac eros in ante fringilla interdum et nec justo. Proin ac massa eleifend, tincidunt purus sit amet, hendrerit leo. Fusce ac nisl tempus, pellentesque lacus eu, mattis quam. Quisque et erat tortor. Sed at egestas erat. -

- -

-Cras pharetra feugiat orci, sed aliquam felis condimentum vel. Quisque id nunc nulla. Aliquam efficitur sagittis pulvinar. In aliquam ac lacus et consequat. In dapibus condimentum vulputate. Aliquam dictum ut sapien nec condimentum. Vestibulum non facilisis nisi. Donec dictum risus et est rutrum consectetur. Integer nec aliquet ex, egestas convallis velit. Sed egestas dolor id suscipit imperdiet. Vestibulum malesuada tincidunt urna, eu rutrum orci luctus ac. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent iaculis aliquam elit eu porttitor. Phasellus tincidunt massa id sem placerat, nec cursus ipsum porta. Integer diam magna, consequat eget sodales id, placerat in ante. Nam et enim at ipsum sodales commodo. -

- -

-Curabitur faucibus elit in sapien dapibus, vel tristique ligula lacinia. Morbi non ex dapibus, viverra mi eget, efficitur dui. Fusce hendrerit turpis eget justo consequat, in tempus mauris vestibulum. Sed sed rutrum odio. Curabitur eget ipsum imperdiet, accumsan lectus vitae, fermentum justo. Integer quam ex, rhoncus sit amet sem ut, tincidunt fermentum eros. In hac habitasse platea dictumst. Duis posuere lectus nec ex suscipit accumsan. Vivamus lectus ante, porttitor a semper id, ullamcorper et erat. Phasellus sed velit ac risus ultrices porttitor non vel neque. Proin porttitor turpis vitae pretium vehicula. Proin pellentesque urna at iaculis tristique. -

- -

-Fusce suscipit, ex ac pretium pretium, magna mauris condimentum nisi, id porta sapien est ac turpis. Nulla sit amet blandit metus. Morbi a arcu facilisis, consequat dui vitae, dapibus lacus. Etiam vestibulum nisl consequat enim condimentum lobortis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum elementum ac metus ac aliquam. Nulla quis massa venenatis diam convallis sodales. Duis quis lobortis nibh. Sed dolor justo, condimentum non orci sit amet, efficitur maximus est. Sed gravida vulputate condimentum. Maecenas libero ex, condimentum quis blandit quis, tincidunt vitae risus. Morbi ultricies eu arcu nec faucibus. -

- -

-Donec a vehicula neque, ac efficitur augue. In malesuada laoreet fringilla. Proin est massa, mattis at iaculis eu, auctor eu nibh. Sed tempus, felis eget dapibus commodo, enim neque ultricies ex, nec convallis dui nisl quis neque. Suspendisse potenti. Curabitur ac finibus ipsum, sit amet egestas felis. Sed cursus, est faucibus tempor lobortis, nisl ante blandit lectus, sit amet tincidunt justo tortor eget elit. Aliquam erat volutpat. Aenean enim nisl, tincidunt eleifend nisl ut, egestas laoreet massa. -

- -

-Sed vitae venenatis diam. Nulla consectetur nisl justo, vel rutrum diam volutpat eu. Proin dictum mi eu elementum gravida. Nunc tristique, lorem sit amet placerat ornare, libero tortor iaculis nibh, non accumsan turpis nulla nec elit. Nunc sed dui lorem. Quisque velit sem, sagittis eget mauris a, bibendum viverra ligula. Nam posuere tincidunt leo. Aenean a volutpat lacus. Maecenas condimentum, purus sit amet accumsan varius, arcu sem fringilla enim, nec sodales urna odio eu ante. Morbi ut suscipit mi. Ut rutrum urna purus, sit amet tristique diam mattis vel. Nunc pharetra, risus ac rutrum consequat, arcu quam dignissim nibh, eget pretium enim metus cursus felis. Pellentesque purus dui, imperdiet at nulla sed, accumsan posuere diam. Vestibulum varius condimentum ex, vulputate tempus mauris congue id. Sed ullamcorper mauris sed diam convallis dapibus. Vestibulum dictum sit amet mauris eu hendrerit. -

- -

-Vestibulum condimentum dui ac mi accumsan, eu interdum augue sollicitudin. Donec rutrum iaculis turpis et ultrices. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum consequat feugiat elit, sed malesuada tortor tristique eget. Quisque et elementum lacus. Sed nec tincidunt nisl. Curabitur tincidunt lorem a dolor tincidunt mattis. Nullam vehicula vulputate enim, eu lacinia ex imperdiet semper. Cras sollicitudin magna quis orci lacinia facilisis. Vivamus mauris odio, pharetra a est et, tempus congue purus. Mauris urna felis, ornare quis sem blandit, scelerisque molestie nunc. Sed pulvinar sagittis nulla sit amet dapibus. Nunc hendrerit, metus vel rutrum pharetra, tellus magna accumsan felis, quis venenatis dolor dui vel leo. Aliquam erat volutpat. Sed egestas in lorem id malesuada. -

- -

-Cras risus sem, euismod nec porta sagittis, ornare vitae orci. Sed tristique, neque sit amet interdum eleifend, massa augue varius magna, sed tempor neque risus et lacus. Curabitur a ullamcorper lorem, vel gravida eros. Phasellus vitae convallis diam. Proin tempor, diam nec congue aliquet, libero dolor rhoncus magna, at dapibus quam purus nec orci. Proin sed vehicula tortor, id consequat ligula. Maecenas nunc magna, rutrum non malesuada id, facilisis eget tortor. Curabitur quis lacus non lectus interdum dapibus. Donec interdum varius tempus. Nunc convallis suscipit placerat. Integer facilisis sapien ut risus placerat, id vehicula neque pretium. Ut non bibendum risus. -

- -

-Vivamus sagittis augue turpis, quis convallis risus sagittis eu. Donec suscipit pharetra elit, non faucibus purus accumsan a. Suspendisse at tincidunt elit, vel aliquam felis. Curabitur pretium, quam nec volutpat bibendum, purus nisl rhoncus nibh, ut posuere ex odio non orci. Mauris eget lobortis nisl. Mauris sapien justo, tristique vulputate velit mollis, convallis mollis magna. In ante leo, pretium eget nibh at, malesuada scelerisque erat. Vestibulum finibus ultrices sollicitudin. Vivamus odio ex, vestibulum nec commodo sed, sagittis in orci. Donec aliquam arcu varius faucibus mattis. Mauris eleifend eros at volutpat auctor. Aenean vel ligula at velit sodales consectetur in a massa. In vitae rhoncus felis, non fringilla lorem. Maecenas vel pharetra dui, vel sodales est. In sodales nulla orci, id consectetur felis malesuada at. -

- -

-Donec elementum, arcu quis maximus congue, neque ante convallis leo, quis cursus enim augue vitae justo. Nam mattis sed arcu eget ornare. Integer dignissim dui nec egestas tristique. Aliquam erat volutpat. Cras eget tortor diam. In hac habitasse platea dictumst. Integer tempus egestas felis eget mollis. Nam a neque accumsan erat auctor condimentum. Etiam quis venenatis lectus. Praesent sed lacus in massa lacinia tempor. Pellentesque laoreet metus vel augue gravida, in iaculis velit ultricies. Donec porta faucibus volutpat. Vestibulum in risus velit. -

- -

-Aenean lacinia justo efficitur tellus mattis, ac pellentesque elit finibus. Curabitur et diam turpis. Curabitur lobortis nec ipsum nec eleifend. Proin pulvinar, neque eget consectetur ornare, sem eros posuere neque, vel mattis dui risus vitae nisl. Nulla non sollicitudin lacus, sed faucibus ligula. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In fermentum eget elit sed fringilla. Curabitur viverra justo diam, quis vehicula turpis tristique quis. Proin ultrices elit risus. Praesent scelerisque metus ut augue suscipit, id pretium enim consectetur. Ut pulvinar malesuada rutrum. -

- -

-Nunc vel quam consequat, eleifend lectus porttitor, fringilla sapien. Integer id semper arcu, ut luctus nulla. Duis id risus ac erat mollis auctor sed in leo. Mauris dignissim ligula at nulla gravida tempor. Integer fringilla venenatis accumsan. In semper facilisis nisi sit amet commodo. Nulla dapibus nunc eu hendrerit suscipit. -

- - - - \ No newline at end of file diff --git a/exercises/03_css/02_layout/views/floating.html b/exercises/03_css/02_layout/views/floating.html deleted file mode 100644 index d45bda9..0000000 --- a/exercises/03_css/02_layout/views/floating.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - Illustration of a floating element - - - - - -

Onions

- -
- -

Onions in cooking

- -
-Onions -
Image: Petr Kratochvil, public domain via www.publicdomainpictures.net.
-
- -

-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce in malesuada libero. Etiam consectetur enim enim, id porta neque facilisis non. Proin consequat a sapien eu consectetur. Quisque bibendum lorem tortor, nec facilisis risus venenatis vel. Nullam et nunc varius, elementum mi vitae, mattis lacus. Mauris et lacinia magna. Nam faucibus purus ac felis vulputate suscipit. Sed vitae est egestas, euismod neque eu, molestie leo. -

- -

-Fusce viverra enim ante, vel dapibus metus maximus et. Proin ac metus justo. Donec nec scelerisque ante. Vestibulum a lectus nisl. Curabitur dictum a purus non sagittis. Cras semper ipsum ut eros lobortis vestibulum. Aenean eu urna nulla. Quisque mattis ex nec odio sollicitudin, a pulvinar nibh faucibus. Nullam quis rutrum purus, nec condimentum est. Aenean sagittis feugiat ante, sit amet dignissim elit vulputate ac. Aenean nec erat blandit, posuere orci malesuada, aliquam sem. Ut rutrum neque nec sapien consectetur dignissim. -

- -

-Nam odio lectus, accumsan vitae dignissim vitae, condimentum eu ipsum. Ut tristique vel leo at condimentum. Quisque tincidunt et tellus ut feugiat. Proin consectetur nulla eu fringilla cursus. Vivamus mi tellus, consectetur vitae commodo vitae, placerat sit amet nisl. Vestibulum et porttitor est. Cras varius quam a enim commodo consequat. Ut egestas dapibus est, a varius enim tincidunt ac. Quisque scelerisque ante quis porta mollis. Mauris nec maximus orci. Nunc ac justo ut nisl euismod vehicula in lacinia ante. Nulla sollicitudin nisi posuere, volutpat lorem nec, sagittis purus. Duis suscipit vulputate purus ac vulputate. Pellentesque suscipit ornare mi, et finibus tortor rutrum eget. -

- -

-In at ipsum id ligula vehicula porttitor. Suspendisse in risus vitae nunc lacinia lacinia. Cras finibus diam odio, vel posuere justo vestibulum tempor. Integer sed pharetra lacus. Integer elit mauris, vehicula ut tortor ut, vehicula iaculis odio. Integer tincidunt tincidunt quam, a laoreet sem mollis porta. Sed consequat sagittis urna quis aliquet. Proin vitae orci ultrices nisi rutrum blandit. -

- -

-Mauris dapibus auctor diam sit amet euismod. Sed in nibh augue. Mauris porttitor consequat egestas. Mauris consectetur commodo blandit. Suspendisse faucibus tristique nulla, in maximus elit feugiat nec. Mauris sagittis orci eu elit mattis lacinia. Donec molestie risus sed urna maximus eleifend. Nunc accumsan facilisis eros et vestibulum. -

- -

-Sed dui turpis, pellentesque egestas eleifend eget, accumsan id dolor. Vestibulum suscipit in urna at semper. Curabitur luctus eros et luctus rhoncus. Sed ac ipsum dolor. Integer ex sapien, egestas quis sapien vel, fringilla aliquam libero. In sapien eros, feugiat quis auctor at, facilisis sit amet magna. Fusce leo ex, viverra quis gravida sit amet, faucibus a quam. Cras tempus lorem vitae metus cursus malesuada. -

- -

-Nullam egestas id augue nec eleifend. Curabitur facilisis malesuada orci at venenatis. Duis at porttitor felis, ac varius elit. Sed pellentesque ligula eros, eu sollicitudin dolor placerat quis. Vestibulum suscipit, leo sit amet tristique hendrerit, ante velit congue lorem, sit amet volutpat ante ligula eget ex. Sed at ultrices turpis. Nulla sit amet egestas sapien. Donec sed lacinia mauris. Morbi suscipit erat nec orci vehicula iaculis. Fusce rhoncus at nunc vitae pretium. Nam consectetur luctus est, sit amet rhoncus ex consectetur ac. Nam in pretium nisl. Vivamus ultricies interdum elit a mattis. Phasellus lectus tellus, molestie in ultricies a, volutpat in ipsum. Aenean maximus viverra congue. -

- -
- - - - \ No newline at end of file diff --git a/exercises/03_css/02_layout/views/menu.html b/exercises/03_css/02_layout/views/menu.html deleted file mode 100644 index 5e1cddd..0000000 --- a/exercises/03_css/02_layout/views/menu.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - HTML Menus - - - - -

HTML/CSS Menu demonstration

- - - - - \ No newline at end of file diff --git a/exercises/03_css/emmet.md b/exercises/03_css/emmet.md deleted file mode 100644 index 7a2198f..0000000 --- a/exercises/03_css/emmet.md +++ /dev/null @@ -1,30 +0,0 @@ - -# Emmet - -Now you've (hopefully) learned how to write proper/valid HTML codes, it's the time to do some tricks. - -> [Laziness is the mother of invention](http://innovators.vassar.edu/innovator.html?id=8). - -[Emmet](http://emmet.io) is a plugin for text editors etc that saves your time from typing full HTML/CSS tags. Emmet is enabled by default in C9 through the Plugin Manager. - -![](https://a.disquscdn.com/uploads/mediaembed/images/3016/7557/original.jpg) - -In C9 start a new workspace and name it lab5. Open the auto-generated hello-world.html file and remove all contents. Type in the exclamation mark and immediately hit the tab key. What happened? - -![](exercises/.images/03_ex.png). - -What you see is that the editor expands the single character into a full HTML template. Behind the scene, it's Emmet that does the job. - -![](exercises/.images/03_expand.png). - -There are quite a few other tricks you can do as well, for example: - -* Type `table1` and hit tab immediately, it will expand into full table element. - - ![](exercises/.images/03_tb.png). - -* Type `ul>li*8` and hit tab immediately, it will expand into full list element. - - ![](exercises/.images/03_ul.png). - -Some more example usages can be found [here](https://www.smashingmagazine.com/2013/03/goodbye-zen-coding-hello-emmet/). diff --git a/exercises/04_functions_objects/callbacks.js b/exercises/04_functions_objects/callbacks.js deleted file mode 100644 index b53d164..0000000 --- a/exercises/04_functions_objects/callbacks.js +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -const quotes = require('./quotes') - -quotes.getQuotes('philip larkin', (err, data) => { - if(err) console.log(err.message) - console.log(data) -}) diff --git a/exercises/04_functions_objects/contact.js b/exercises/04_functions_objects/contact.js deleted file mode 100644 index 2160dd8..0000000 --- a/exercises/04_functions_objects/contact.js +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -/* This script demonstrates how JavaScript can be used to handle exceptions. */ - -const readline = require('readline-sync') - -/* any code that could throw an exception needs to be wrapped in a try block. If any line of code in the try block throws an exception the program immediately jumps to the catch block, passing the Error object thrown. Regardless of whether an error was thrown or not, the code in the finally block is run. */ -try { - const email = String(readline.question('enter email address: ')) - console.log('email is a '+typeof email+' and contains '+email) - validateEmail(email) - const score = Number(readline.question('assign score 1-10: ')) - console.log('score is a '+typeof score+' and contains '+score) - validateScore(score) - const comment = String(readline.question('enter your comment : ')) - validateComment(comment) - console.log(`Thank you ${email}. You gave us a rating of ${score}/10 with the comment "${comment}"`) -} catch(err) { - console.log(`${err.name} thrown`) - console.log(`The error message is: ${err.message}`) - console.log(err.stack) -} finally { - console.log('the script has finished') -} - -/** - * Checks to see if the supplied parameter is formatted as a valid email - * address. - * @param {string} email - The email address to be checked. - * @returns {bool} the validity of the email address string - * @throws {TypeError} if the parameter is not a valid email address. - */ -function validateEmail(email) { - console.log(email) - return true -} - -/** - * Checks to see if the supplied parameter is a valid integer in the range 1-10. - * @param {string} score - The user-specified score. - * @returns {bool} whether the parameter is a valid integer in range - * @throws {TypeError} if the parameter is not a valid integer. - * @throws {RangeError} if the parameter is not in the range 1-10. - */ -function validateScore(score) { - const minScore = 0 - const maxScore = 10 - if (Number.isNaN(score) || score % 1 !== minScore) { - throw new TypeError('parameter is not a valid integer') - } - if (score < 1 || score > maxScore) { - throw new RangeError('parameter should be in the range 1-10') - } - return true -} - -/** - * Checks to see if the supplied comment is 'valid'. - * @param {string} comment - The user-specified score. - * @returns {bool} whether the comment is 'valid' - * @throws {RangeError} if the comment is not long enough. - */ -function validateComment(comment) { - const minLen = 5 - if (comment.length < minLen) { - throw new RangeError('comment should be at least 5 characters long') - } - return true -} diff --git a/exercises/04_functions_objects/countries.json b/exercises/04_functions_objects/countries.json deleted file mode 100644 index 3588034..0000000 --- a/exercises/04_functions_objects/countries.json +++ /dev/null @@ -1,1002 +0,0 @@ -[ - { - "country": "Name", - "code": "Code" - }, - { - "country": "Afghanistan", - "code": "AF" - }, - { - "country": "Åland Islands", - "code": "AX" - }, - { - "country": "Albania", - "code": "AL" - }, - { - "country": "Algeria", - "code": "DZ" - }, - { - "country": "American Samoa", - "code": "AS" - }, - { - "country": "Andorra", - "code": "AD" - }, - { - "country": "Angola", - "code": "AO" - }, - { - "country": "Anguilla", - "code": "AI" - }, - { - "country": "Antarctica", - "code": "AQ" - }, - { - "country": "Antigua and Barbuda", - "code": "AG" - }, - { - "country": "Argentina", - "code": "AR" - }, - { - "country": "Armenia", - "code": "AM" - }, - { - "country": "Aruba", - "code": "AW" - }, - { - "country": "Australia", - "code": "AU" - }, - { - "country": "Austria", - "code": "AT" - }, - { - "country": "Azerbaijan", - "code": "AZ" - }, - { - "country": "Bahamas", - "code": "BS" - }, - { - "country": "Bahrain", - "code": "BH" - }, - { - "country": "Bangladesh", - "code": "BD" - }, - { - "country": "Barbados", - "code": "BB" - }, - { - "country": "Belarus", - "code": "BY" - }, - { - "country": "Belgium", - "code": "BE" - }, - { - "country": "Belize", - "code": "BZ" - }, - { - "country": "Benin", - "code": "BJ" - }, - { - "country": "Bermuda", - "code": "BM" - }, - { - "country": "Bhutan", - "code": "BT" - }, - { - "country": "Bolivia, Plurinational State of", - "code": "BO" - }, - { - "country": "Bonaire, Sint Eustatius and Saba", - "code": "BQ" - }, - { - "country": "Bosnia and Herzegovina", - "code": "BA" - }, - { - "country": "Botswana", - "code": "BW" - }, - { - "country": "Bouvet Island", - "code": "BV" - }, - { - "country": "Brazil", - "code": "BR" - }, - { - "country": "British Indian Ocean Territory", - "code": "IO" - }, - { - "country": "Brunei Darussalam", - "code": "BN" - }, - { - "country": "Bulgaria", - "code": "BG" - }, - { - "country": "Burkina Faso", - "code": "BF" - }, - { - "country": "Burundi", - "code": "BI" - }, - { - "country": "Cambodia", - "code": "KH" - }, - { - "country": "Cameroon", - "code": "CM" - }, - { - "country": "Canada", - "code": "CA" - }, - { - "country": "Cape Verde", - "code": "CV" - }, - { - "country": "Cayman Islands", - "code": "KY" - }, - { - "country": "Central African Republic", - "code": "CF" - }, - { - "country": "Chad", - "code": "TD" - }, - { - "country": "Chile", - "code": "CL" - }, - { - "country": "China", - "code": "CN" - }, - { - "country": "Christmas Island", - "code": "CX" - }, - { - "country": "Cocos (Keeling) Islands", - "code": "CC" - }, - { - "country": "Colombia", - "code": "CO" - }, - { - "country": "Comoros", - "code": "KM" - }, - { - "country": "Congo", - "code": "CG" - }, - { - "country": "Congo, the Democratic Republic of the", - "code": "CD" - }, - { - "country": "Cook Islands", - "code": "CK" - }, - { - "country": "Costa Rica", - "code": "CR" - }, - { - "country": "Côte d'Ivoire", - "code": "CI" - }, - { - "country": "Croatia", - "code": "HR" - }, - { - "country": "Cuba", - "code": "CU" - }, - { - "country": "Curaçao", - "code": "CW" - }, - { - "country": "Cyprus", - "code": "CY" - }, - { - "country": "Czech Republic", - "code": "CZ" - }, - { - "country": "Denmark", - "code": "DK" - }, - { - "country": "Djibouti", - "code": "DJ" - }, - { - "country": "Dominica", - "code": "DM" - }, - { - "country": "Dominican Republic", - "code": "DO" - }, - { - "country": "Ecuador", - "code": "EC" - }, - { - "country": "Egypt", - "code": "EG" - }, - { - "country": "El Salvador", - "code": "SV" - }, - { - "country": "Equatorial Guinea", - "code": "GQ" - }, - { - "country": "Eritrea", - "code": "ER" - }, - { - "country": "Estonia", - "code": "EE" - }, - { - "country": "Ethiopia", - "code": "ET" - }, - { - "country": "Falkland Islands (Malvinas)", - "code": "FK" - }, - { - "country": "Faroe Islands", - "code": "FO" - }, - { - "country": "Fiji", - "code": "FJ" - }, - { - "country": "Finland", - "code": "FI" - }, - { - "country": "France", - "code": "FR" - }, - { - "country": "French Guiana", - "code": "GF" - }, - { - "country": "French Polynesia", - "code": "PF" - }, - { - "country": "French Southern Territories", - "code": "TF" - }, - { - "country": "Gabon", - "code": "GA" - }, - { - "country": "Gambia", - "code": "GM" - }, - { - "country": "Georgia", - "code": "GE" - }, - { - "country": "Germany", - "code": "DE" - }, - { - "country": "Ghana", - "code": "GH" - }, - { - "country": "Gibraltar", - "code": "GI" - }, - { - "country": "Greece", - "code": "GR" - }, - { - "country": "Greenland", - "code": "GL" - }, - { - "country": "Grenada", - "code": "GD" - }, - { - "country": "Guadeloupe", - "code": "GP" - }, - { - "country": "Guam", - "code": "GU" - }, - { - "country": "Guatemala", - "code": "GT" - }, - { - "country": "Guernsey", - "code": "GG" - }, - { - "country": "Guinea", - "code": "GN" - }, - { - "country": "Guinea-Bissau", - "code": "GW" - }, - { - "country": "Guyana", - "code": "GY" - }, - { - "country": "Haiti", - "code": "HT" - }, - { - "country": "Heard Island and McDonald Islands", - "code": "HM" - }, - { - "country": "Holy See (Vatican City State)", - "code": "VA" - }, - { - "country": "Honduras", - "code": "HN" - }, - { - "country": "Hong Kong", - "code": "HK" - }, - { - "country": "Hungary", - "code": "HU" - }, - { - "country": "Iceland", - "code": "IS" - }, - { - "country": "India", - "code": "IN" - }, - { - "country": "Indonesia", - "code": "ID" - }, - { - "country": "Iran, Islamic Republic of", - "code": "IR" - }, - { - "country": "Iraq", - "code": "IQ" - }, - { - "country": "Ireland", - "code": "IE" - }, - { - "country": "Isle of Man", - "code": "IM" - }, - { - "country": "Israel", - "code": "IL" - }, - { - "country": "Italy", - "code": "IT" - }, - { - "country": "Jamaica", - "code": "JM" - }, - { - "country": "Japan", - "code": "JP" - }, - { - "country": "Jersey", - "code": "JE" - }, - { - "country": "Jordan", - "code": "JO" - }, - { - "country": "Kazakhstan", - "code": "KZ" - }, - { - "country": "Kenya", - "code": "KE" - }, - { - "country": "Kiribati", - "code": "KI" - }, - { - "country": "Korea, Democratic People's Republic of", - "code": "KP" - }, - { - "country": "Korea, Republic of", - "code": "KR" - }, - { - "country": "Kuwait", - "code": "KW" - }, - { - "country": "Kyrgyzstan", - "code": "KG" - }, - { - "country": "Lao People's Democratic Republic", - "code": "LA" - }, - { - "country": "Latvia", - "code": "LV" - }, - { - "country": "Lebanon", - "code": "LB" - }, - { - "country": "Lesotho", - "code": "LS" - }, - { - "country": "Liberia", - "code": "LR" - }, - { - "country": "Libya", - "code": "LY" - }, - { - "country": "Liechtenstein", - "code": "LI" - }, - { - "country": "Lithuania", - "code": "LT" - }, - { - "country": "Luxembourg", - "code": "LU" - }, - { - "country": "Macao", - "code": "MO" - }, - { - "country": "Macedonia, the Former Yugoslav Republic of", - "code": "MK" - }, - { - "country": "Madagascar", - "code": "MG" - }, - { - "country": "Malawi", - "code": "MW" - }, - { - "country": "Malaysia", - "code": "MY" - }, - { - "country": "Maldives", - "code": "MV" - }, - { - "country": "Mali", - "code": "ML" - }, - { - "country": "Malta", - "code": "MT" - }, - { - "country": "Marshall Islands", - "code": "MH" - }, - { - "country": "Martinique", - "code": "MQ" - }, - { - "country": "Mauritania", - "code": "MR" - }, - { - "country": "Mauritius", - "code": "MU" - }, - { - "country": "Mayotte", - "code": "YT" - }, - { - "country": "Mexico", - "code": "MX" - }, - { - "country": "Micronesia, Federated States of", - "code": "FM" - }, - { - "country": "Moldova, Republic of", - "code": "MD" - }, - { - "country": "Monaco", - "code": "MC" - }, - { - "country": "Mongolia", - "code": "MN" - }, - { - "country": "Montenegro", - "code": "ME" - }, - { - "country": "Montserrat", - "code": "MS" - }, - { - "country": "Morocco", - "code": "MA" - }, - { - "country": "Mozambique", - "code": "MZ" - }, - { - "country": "Myanmar", - "code": "MM" - }, - { - "country": "Namibia", - "code": "NA" - }, - { - "country": "Nauru", - "code": "NR" - }, - { - "country": "Nepal", - "code": "NP" - }, - { - "country": "Netherlands", - "code": "NL" - }, - { - "country": "New Caledonia", - "code": "NC" - }, - { - "country": "New Zealand", - "code": "NZ" - }, - { - "country": "Nicaragua", - "code": "NI" - }, - { - "country": "Niger", - "code": "NE" - }, - { - "country": "Nigeria", - "code": "NG" - }, - { - "country": "Niue", - "code": "NU" - }, - { - "country": "Norfolk Island", - "code": "NF" - }, - { - "country": "Northern Mariana Islands", - "code": "MP" - }, - { - "country": "Norway", - "code": "NO" - }, - { - "country": "Oman", - "code": "OM" - }, - { - "country": "Pakistan", - "code": "PK" - }, - { - "country": "Palau", - "code": "PW" - }, - { - "country": "Palestine, State of", - "code": "PS" - }, - { - "country": "Panama", - "code": "PA" - }, - { - "country": "Papua New Guinea", - "code": "PG" - }, - { - "country": "Paraguay", - "code": "PY" - }, - { - "country": "Peru", - "code": "PE" - }, - { - "country": "Philippines", - "code": "PH" - }, - { - "country": "Pitcairn", - "code": "PN" - }, - { - "country": "Poland", - "code": "PL" - }, - { - "country": "Portugal", - "code": "PT" - }, - { - "country": "Puerto Rico", - "code": "PR" - }, - { - "country": "Qatar", - "code": "QA" - }, - { - "country": "Réunion", - "code": "RE" - }, - { - "country": "Romania", - "code": "RO" - }, - { - "country": "Russian Federation", - "code": "RU" - }, - { - "country": "Rwanda", - "code": "RW" - }, - { - "country": "Saint Barthélemy", - "code": "BL" - }, - { - "country": "Saint Helena, Ascension and Tristan da Cunha", - "code": "SH" - }, - { - "country": "Saint Kitts and Nevis", - "code": "KN" - }, - { - "country": "Saint Lucia", - "code": "LC" - }, - { - "country": "Saint Martin (French part)", - "code": "MF" - }, - { - "country": "Saint Pierre and Miquelon", - "code": "PM" - }, - { - "country": "Saint Vincent and the Grenadines", - "code": "VC" - }, - { - "country": "Samoa", - "code": "WS" - }, - { - "country": "San Marino", - "code": "SM" - }, - { - "country": "Sao Tome and Principe", - "code": "ST" - }, - { - "country": "Saudi Arabia", - "code": "SA" - }, - { - "country": "Senegal", - "code": "SN" - }, - { - "country": "Serbia", - "code": "RS" - }, - { - "country": "Seychelles", - "code": "SC" - }, - { - "country": "Sierra Leone", - "code": "SL" - }, - { - "country": "Singapore", - "code": "SG" - }, - { - "country": "Sint Maarten (Dutch part)", - "code": "SX" - }, - { - "country": "Slovakia", - "code": "SK" - }, - { - "country": "Slovenia", - "code": "SI" - }, - { - "country": "Solomon Islands", - "code": "SB" - }, - { - "country": "Somalia", - "code": "SO" - }, - { - "country": "South Africa", - "code": "ZA" - }, - { - "country": "South Georgia and the South Sandwich Islands", - "code": "GS" - }, - { - "country": "South Sudan", - "code": "SS" - }, - { - "country": "Spain", - "code": "ES" - }, - { - "country": "Sri Lanka", - "code": "LK" - }, - { - "country": "Sudan", - "code": "SD" - }, - { - "country": "Suriname", - "code": "SR" - }, - { - "country": "Svalbard and Jan Mayen", - "code": "SJ" - }, - { - "country": "Swaziland", - "code": "SZ" - }, - { - "country": "Sweden", - "code": "SE" - }, - { - "country": "Switzerland", - "code": "CH" - }, - { - "country": "Syrian Arab Republic", - "code": "SY" - }, - { - "country": "Taiwan, Province of China", - "code": "TW" - }, - { - "country": "Tajikistan", - "code": "TJ" - }, - { - "country": "Tanzania, United Republic of", - "code": "TZ" - }, - { - "country": "Thailand", - "code": "TH" - }, - { - "country": "Timor-Leste", - "code": "TL" - }, - { - "country": "Togo", - "code": "TG" - }, - { - "country": "Tokelau", - "code": "TK" - }, - { - "country": "Tonga", - "code": "TO" - }, - { - "country": "Trinidad and Tobago", - "code": "TT" - }, - { - "country": "Tunisia", - "code": "TN" - }, - { - "country": "Turkey", - "code": "TR" - }, - { - "country": "Turkmenistan", - "code": "TM" - }, - { - "country": "Turks and Caicos Islands", - "code": "TC" - }, - { - "country": "Tuvalu", - "code": "TV" - }, - { - "country": "Uganda", - "code": "UG" - }, - { - "country": "Ukraine", - "code": "UA" - }, - { - "country": "United Arab Emirates", - "code": "AE" - }, - { - "country": "United Kingdom", - "code": "GB" - }, - { - "country": "United States", - "code": "US" - }, - { - "country": "United States Minor Outlying Islands", - "code": "UM" - }, - { - "country": "Uruguay", - "code": "UY" - }, - { - "country": "Uzbekistan", - "code": "UZ" - }, - { - "country": "Vanuatu", - "code": "VU" - }, - { - "country": "Venezuela, Bolivarian Republic of", - "code": "VE" - }, - { - "country": "Viet Nam", - "code": "VN" - }, - { - "country": "Virgin Islands, British", - "code": "VG" - }, - { - "country": "Virgin Islands, U.S.", - "code": "VI" - }, - { - "country": "Wallis and Futuna", - "code": "WF" - }, - { - "country": "Western Sahara", - "code": "EH" - }, - { - "country": "Yemen", - "code": "YE" - }, - { - "country": "Zambia", - "code": "ZM" - }, - { - "country": "Zimbabwe", - "code": "ZW" - } -] \ No newline at end of file diff --git a/exercises/04_functions_objects/currency.js b/exercises/04_functions_objects/currency.js deleted file mode 100644 index 0725b1f..0000000 --- a/exercises/04_functions_objects/currency.js +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -const request = require('request') - -const symbol = 'GBP' - -const printRates = (err, res, body) => { - if (err) throw 'could not complete request' - const data = JSON.parse(body) // this converts the formatted string into a javascript object - console.log(`for each EUR you will get ${data.rates[symbol]} ${symbol} today`) -} - -const url = 'currency.json' - -request.get( url, printRates) diff --git a/exercises/04_functions_objects/currency.json b/exercises/04_functions_objects/currency.json deleted file mode 100644 index 62026e0..0000000 --- a/exercises/04_functions_objects/currency.json +++ /dev/null @@ -1,644 +0,0 @@ -[ - { - "country": "European Union", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "USA", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Australia", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Canada", - "currency": "Canadian Dollar", - "code": "CAD", - "rate": 1.6462 - }, - { - "country": "Aland Islands", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "American Samoa", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Andorra", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Australia", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Austria", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Barbados", - "currency": "Barbadian Dollar", - "code": "BBD", - "rate": 2.3474 - }, - { - "country": "Belgium", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Brazil", - "currency": "Brazilian Real", - "code": "BRL", - "rate": 4.5301 - }, - { - "country": "Bulgaria", - "currency": "Bulgarian Lev", - "code": "BGN", - "rate": 2.0119 - }, - { - "country": "Canada", - "currency": "Canadian Dollar", - "code": "CAD", - "rate": 1.6462 - }, - { - "country": "China", - "currency": "Chinese Renminbi", - "code": "CNY", - "rate": 8.1426 - }, - { - "country": "Christmas Island", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Cocos (Keeling) Islands", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Cook Islands", - "currency": "New Zealand Dollar", - "code": "NZD", - "rate": 1.7508 - }, - { - "country": "Croatia", - "currency": "Croatian Kuna", - "code": "HRK", - "rate": 7.6781 - }, - { - "country": "Cyprus", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Czech Republic", - "currency": "Czech Koruna", - "code": "CZK", - "rate": 26.6556 - }, - { - "country": "Denmark", - "currency": "Danish Krone", - "code": "DKK", - "rate": 7.6552 - }, - { - "country": "Dominican Republic", - "currency": "Dominican Peso", - "code": "DOP", - "rate": 57.2267 - }, - { - "country": "Ecuador", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "El Salvador", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Estonia", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "European Union", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Faroe Islands", - "currency": "Danish Krone", - "code": "DKK", - "rate": 7.6552 - }, - { - "country": "Fiji", - "currency": "Fijian Dollar", - "code": "FJD", - "rate": 2.4674 - }, - { - "country": "Finland", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "France", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "French Guiana", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "French Southern Territories", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Germany", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Greece", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Greenland", - "currency": "Danish Krone", - "code": "DKK", - "rate": 7.6552 - }, - { - "country": "Guadeloupe", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Guam", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Haiti", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Holy See (Vatican City State)", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Hong Kong", - "currency": "Hong Kong Dollar", - "code": "HKD", - "rate": 9.537 - }, - { - "country": "Hungary", - "currency": "Hungarian Forint", - "code": "HUF", - "rate": 325.5257 - }, - { - "country": "Iceland", - "currency": "Icelandic Króna", - "code": "ISK", - "rate": 140.099 - }, - { - "country": "Indonesia", - "currency": "Indonesian Rupiah", - "code": "IDR", - "rate": 16 - }, - { - "country": "Ireland", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Israel", - "currency": "Israeli New Sheqel", - "code": "ILS", - "rate": 4.476 - }, - { - "country": "Italy", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Japan", - "currency": "Japanese Yen", - "code": "JPY", - "rate": 134.1945 - }, - { - "country": "Jordan", - "currency": "Jordanian Dinar", - "code": "JOD", - "rate": 0.8344 - }, - { - "country": "Kenya", - "currency": "Kenyan Shilling", - "code": "KES", - "rate": 119.2441 - }, - { - "country": "Kiribati", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Korea, Republic of", - "currency": "South Korean Won", - "code": "KRW", - "rate": 1 - }, - { - "country": "Latvia", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Lesotho", - "currency": "South African Rand", - "code": "ZAR", - "rate": 17.4405 - }, - { - "country": "Liechtenstein", - "currency": "Swiss Franc", - "code": "CHF", - "rate": 1.2121 - }, - { - "country": "Lithuania", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Luxembourg", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Malaysia", - "currency": "Malaysian Ringgit", - "code": "MYR", - "rate": 4.912 - }, - { - "country": "Malta", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Marshall Islands", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Martinique", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Mauritius", - "currency": "Mauritian Rupee", - "code": "MUR", - "rate": 40.1008 - }, - { - "country": "Mayotte", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Mexico", - "currency": "Mexican Peso", - "code": "MXN", - "rate": 23.539 - }, - { - "country": "Micronesia, Federated States of", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Monaco", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Montenegro", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Namibia", - "currency": "South African Rand", - "code": "ZAR", - "rate": 17.4405 - }, - { - "country": "Nauru", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Netherlands", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "New Zealand", - "currency": "New Zealand Dollar", - "code": "NZD", - "rate": 1.7508 - }, - { - "country": "Niue", - "currency": "New Zealand Dollar", - "code": "NZD", - "rate": 1.7508 - }, - { - "country": "Norfolk Island", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "Northern Mariana Islands", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Norway", - "currency": "Norwegian Krone", - "code": "NOK", - "rate": 10.5497 - }, - { - "country": "Palau", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Panama", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Philippines", - "currency": "Philippine Peso", - "code": "PHP", - "rate": 61.7703 - }, - { - "country": "Pitcairn", - "currency": "New Zealand Dollar", - "code": "NZD", - "rate": 1.7508 - }, - { - "country": "Poland", - "currency": "Polish Zloty", - "code": "PLN", - "rate": 4.3987 - }, - { - "country": "Portugal", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Puerto Rico", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Qatar", - "currency": "Qatari Riyal", - "code": "QAR", - "rate": 4.4062 - }, - { - "country": "Russian Federation", - "currency": "Russian Ruble", - "code": "RUB", - "rate": 80.3644 - }, - { - "country": "Saint Barthélemy", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Saint Martin (French part)", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "San Marino", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Saudi Arabia", - "currency": "Saudi Riyal", - "code": "SAR", - "rate": 4.5964 - }, - { - "country": "Singapore", - "currency": "Singapore Dollar", - "code": "SGD", - "rate": 1.6608 - }, - { - "country": "Slovakia", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Slovenia", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "South Africa", - "currency": "South African Rand", - "code": "ZAR", - "rate": 17.4405 - }, - { - "country": "Spain", - "currency": "Euro", - "code": "EUR", - "rate": 1.08 - }, - { - "country": "Sweden", - "currency": "Swedish Krona", - "code": "SEK", - "rate": 10.9409 - }, - { - "country": "Switzerland", - "currency": "Swiss Franc", - "code": "CHF", - "rate": 1.2121 - }, - { - "country": "Taiwan", - "currency": "New Taiwan Dollar", - "code": "TWD", - "rate": 36.3001 - }, - { - "country": "Thailand", - "currency": "Thai Baht", - "code": "THB", - "rate": 38.9959 - }, - { - "country": "Timor-Leste", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Tokelau", - "currency": "New Zealand Dollar", - "code": "NZD", - "rate": 1.7508 - }, - { - "country": "Turkey", - "currency": "Turkish New Lira", - "code": "TRY", - "rate": 6.2351 - }, - { - "country": "Turks and Caicos Islands", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Tuvalu", - "currency": "Australian Dollar", - "code": "AUD", - "rate": 1.7282 - }, - { - "country": "United Arab Emirates", - "currency": "UAE Dirham", - "code": "AED", - "rate": 4.4499 - }, - { - "country": "USA", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Vietnam", - "currency": "Vietnamese Dong", - "code": "VND", - "rate": 26 - }, - { - "country": "Virgin Islands, British", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - }, - { - "country": "Virgin Islands, U.S.", - "currency": "U.S. Dollar", - "code": "USD", - "rate": 1.2362 - } -] \ No newline at end of file diff --git a/exercises/04_functions_objects/currencyLogic.js b/exercises/04_functions_objects/currencyLogic.js deleted file mode 100644 index 4c5ef5d..0000000 --- a/exercises/04_functions_objects/currencyLogic.js +++ /dev/null @@ -1,68 +0,0 @@ - -const puppeteer = require('puppeteer') -const fs = require('fs') -const request = require('request') -const csv = require('fast-csv') - -const getRates = async query => { - const width = 1920 - const height = 926 - const browser = await puppeteer.launch({ headless: false}) - const page = await browser.newPage() - await page.setViewport({ width: width, height: height }) - await page.goto('https://www.travelex.co.uk/currency/exchange-rates', { waitUntil: 'domcontentloaded' }) - await page.waitFor(5000) - try { - await page.click('a#loadAll') - } catch (error) { - console.log('the loadAll button has already been clicked.') - } - console.log('ready to grab page content') - //const html = await page.content() - const dom = await page.evaluate(() => { - const elements = document.querySelectorAll('div.row') - console.log(`found ${elements.length} rows.`) - const hotels = [] - elements.forEach((element) => { - const quoteJson = {} - try { - //quoteJson.quote = element.innerText.replace(/ +/g, ',') - quoteJson.country = element.querySelector('span.col:first-child').innerText - //quoteJson.currencyStr = element.querySelector('span.col:nth-child(2)').innerText - quoteJson.currency = element.querySelector('span.col:nth-child(2)').innerText.split(' (')[0] - quoteJson.code = element.querySelector('span.col:nth-child(2)').innerText.split(' (')[1].replace(')', '') - quoteJson.rate = parseFloat(element.querySelector('span.col:nth-child(3)').innerText) - } catch (err) { - return new Error('oops') - } - hotels.push(quoteJson) - }) - return hotels - }) - await browser.close() - return dom -} - -const getCurrency = callback => getRates().then(data => callback(null, data)).catch(err => callback(err)) - -getCurrency( (err, data) => { - if(err) console.log('oops!') - console.log(`found ${data.length} CURRENCY codes`) - console.log(data.length) - fs.writeFileSync('currency.json', JSON.stringify(data, null, 2)) -}) - - -const getCountries = callback => { - const countryData = [] - csv.fromStream(request('https://datahub.io/core/country-list/r/0.csv')) - .on('data', (data) => countryData.push({country: data[0], code: data[1]})) - .on('end', () => callback(null, countryData)) -} - -getCountries( (err, data) => { - if(err) console.log('oops!') - //console.log(data) - console.log(`found ${data.length} COUNTRY codes`) - fs.writeFileSync('countries.json', JSON.stringify(data, null, 2)) -}) diff --git a/exercises/04_functions_objects/employee.js b/exercises/04_functions_objects/employee.js deleted file mode 100644 index 507492a..0000000 --- a/exercises/04_functions_objects/employee.js +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node -/* eslint no-magic-numbers: 0 */ - -'use strict' - -const employee = { - firstName: 'Colin', - 'last name': 'Stephen', - startYear: 2010, - getName: () => `${this.firstName} ${this['last name']}`, - setName: function(fullname) { - console.log(fullname) - const words = fullname.toString().split(' ') - console.log(words) - console.log(this) - this.firstName = words[0] || '' - this['last name'] = words[1] || '' - } -} - -const jsonString = JSON.stringify(employee, null, 2) -console.log(jsonString) - -employee.setName('Micky Mouse') -console.log(JSON.stringify(employee, null, 2)) diff --git a/exercises/04_functions_objects/functional.js b/exercises/04_functions_objects/functional.js deleted file mode 100644 index e07d327..0000000 --- a/exercises/04_functions_objects/functional.js +++ /dev/null @@ -1,28 +0,0 @@ - -function addOld(...values) { - let total = 0 - console.log(values) - console.log(values[1]) - for (let i=0; i acc + val) -} - -const add = (...values) => values.reduce((acc, val) => acc + val) - -console.log(add(1, 2, 3, 4)) - -function f5() { - let sum = 0 - for (let i = 0, j = arguments.length; i < j; i++) { - sum += arguments[i] - } - return sum / arguments.length -} - -console.log(f5(1, 2, 3)) diff --git a/exercises/04_functions_objects/maths.js b/exercises/04_functions_objects/maths.js deleted file mode 100644 index c998a47..0000000 --- a/exercises/04_functions_objects/maths.js +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env node -/* eslint no-magic-numbers: 0 */ - -'use strict' - -function largestNumber(a, b) { - if (a > b) return a - if (b > a) return b - return null -} - -const biggest = largestNumber(5, 8) -console.log(biggest) -// the code below achieves the same using the 'spread operator' -const nums = [5, 8] -const biggest2 = largestNumber(...nums) -console.log(biggest2) - -// example using the arguments object -function add() { - let total = 0 - console.log(arguments) - console.log(arguments['1']) - for(const arg of arguments) { - total += arg - } - return total -} - -const addNums = add(1, 2, 3, 4) -console.log(addNums) - - -// example using a rest parameter -function add2(...values) { - let total = 0 - console.log(values) - for (let i=0; i { - const quotient = Math.floor(dividend / divisor) - return dividend - quotient -} - -console.log(remainder2(13, 4)) - -// function expression using arrow syntax and one parameter -const sqr = num => num * num -console.log(sqr(4)) diff --git a/exercises/04_functions_objects/nestedcallbacks.js b/exercises/04_functions_objects/nestedcallbacks.js deleted file mode 100644 index cd3fcc1..0000000 --- a/exercises/04_functions_objects/nestedcallbacks.js +++ /dev/null @@ -1,61 +0,0 @@ - -'use strict' - -const request = require('request') - -getInput('enter base currency', (err, base) => { - if (err) { - console.log(err.message) - process.exit() - } - base = base.trim() - checkValidCurrencyCode(base, err => { - if (err) { - console.log(err.message) - process.exit() - } - getData(`http://api.fixer.io/latest?base=${base}`, (err, data) => { - if (err) { - console.log(err.message) - process.exit() - } - const obj = JSON.parse(data) - printObject(obj) - process.exit() - }) - }) -}) - -function getInput(prompt, callback) { - try { - process.stdin.resume() - process.stdin.setEncoding('utf8') - process.stdout.write(`${prompt}: `) - process.stdin.on('data', text => callback(null, text)) - } catch(err) { - callback(err) - } -} - -function checkValidCurrencyCode(code, callback) { - code = code.trim() - request('http://api.fixer.io/latest', (err, res, body) => { - if (err) callback(new Error('invalid API call')) - const rates = JSON.parse(body).rates - if (!rates.hasOwnProperty(code)) callback(new Error(`invalid currency code ${code}`)) - callback(null, true) - }) -} - -function getData(url, callback) { - request(url, (err, res, body) => { - if (err) callback(new Error('invalid API call')) - callback(null, body) - }) -} - -function printObject(data) { - const indent = 2 - const str = JSON.stringify(data, null, indent) - console.log(str) -} diff --git a/exercises/04_functions_objects/objects.js b/exercises/04_functions_objects/objects.js deleted file mode 100644 index 65dd7f3..0000000 --- a/exercises/04_functions_objects/objects.js +++ /dev/null @@ -1,13 +0,0 @@ - -'use strict' - -const employee = { - firstName: 'Colin', - 'last name': 'Stephen', - 'department': 'Computing' -} - -const {firstName: first, 'last name': last, department: dept} = employee -console.log(first) // prints 'Colin' -console.log(last) // prints 'Stephen' -console.log(dept) // prints 'Computing' diff --git a/exercises/04_functions_objects/page.html b/exercises/04_functions_objects/page.html deleted file mode 100644 index 5b4f5f5..0000000 --- a/exercises/04_functions_objects/page.html +++ /dev/null @@ -1,3304 +0,0 @@ - - - - Currency Exchange - View Live Foreign Exchange Rates - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TRAVELEX UK - - - - - - - - - - - - - - -
-
-
-
-
- - - - - - - - - - - - - -
-
-
- - - - -
-
- - - - - - - -Buy Currency -
-
- - - - - -
-
-
- -
- - - - - -
-
-
-

Currency exchange rates

-

View today’s foreign currency exchange rates below and sign up to our newsletter to stay up-to-date on the latest currency news, happy hours and offers.

- - sign-up-now.png
- -
-
- - - - -
-
-
-
- - - -
- - - - -
-
-
- - - - -
-
- - -
-
-
-

Today’s exchange rates

We monitor market rates every day, to bring you great value on your travel money.

-

Whether you’re looking to convert your pounds to dollars, euros or any other currency, simply choose the currency you need below to see our rates of the day.

-
Today’s exchange rates
-
-
- - - -
-
-
-
-

Find a currency

- -
-
-
- Currencies - Country - Currency - Sell Rate - More Info -
-
- -
- - Load all currencies - - -
- - - -
-
-
-
- - - - - - -
-

Read our great reviews on Trustpilot!

-
-
- -
- -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Great Service

-

- As ever Travelex has provided a great service. It has been both accurate and prompt. -

- Susan Colebrook -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

So far so good

-

- So far so good. As yet have not used on holiday but trust that all will be ok. -

- Catherine Thomson -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

The whole experience was smooth and…

-

- The whole experience was smooth and professional. And great exchange rates. :) -

- Ruxandra Cordea -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Simple process

-

- Simple process. Friendly staff -

- AB -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Travelex - Ease of Use

-

- Travelex is very good but one complaint: - -Why can't I leave all of my details for the next time? -

- Colin McArthur -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

First time user

-

- It was rad to use and seemingly safe. I have used them twice now. -

- Me -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Great service with the best exchange…

-

- Great service with the best exchange rates as always. Never let me down yet. -

- Michael Mc -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

A good service but not fully secure

-

- As usual the process was easy, and the delivery made the day indicated. -There are, however, two areas where improvement ... is desirable - -Delivery timing: an improvement would be a delivery slot of say 2 hours (or even before noon/after noon would be an improvement), as finding a day to be tied to home can be a challenge! - -Security: I had expected to prove ID on delivery - none was requested. Also my squiggle on a touch screen with my finger would never pass muster as an identifiable signature, and as no ID was requested there was no attempt to verify the 'signature'. A system that isn't really secure and open to failure by mistake or deliberate act! -

- Eric Lowe -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

No unwelcome surprises on next month's statement!

-

- Easy to top up card and track spend online. Reasonable exchange rate. Saves money in the long run as no transaction fees ... for purchases or withdrawing from cash machines when using currency selected - no unwelcome surprises on next month's statement! Helped me to control my non essential spending. No need to carry cash or multiple cards as welcome everywhere I went. Added security backed by MasterCard. Reusable - this is the second time I have used it and will definitely use again. -

- Alondoner -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Holiday cash

-

- Excellent speedy service. Will definitely use again. -

- Susan Cotton -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

The best way to manage travel money no…

-

- The best way to manage travel money no matter where you go. By far. -Even if you can't buy the currency direct you can get... decent exchange rates by using the card. -

- N Portsmouth -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Great service

-

- Great service. Helpful professional staff. -

- K Harper -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Instant money transfer and could see…

-

- Instant money transfer and could see transactions almost immediately. -

- Alok Shah -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Everything was smooth on the website…

-

- Everything was smooth on the website and next day delivery a big bonus. I've used the site several times and am very hap... py with it. -I have recommended it to several people. One little problem, the exchange rate! Oh well, can't have everything. -

- Johnnyhupnorth -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Easy to find and helpful staff.

-

- Was easy to find the correct desk. The gentleman that serverd us was very polite and chatty. Even though it was 5.30am -N... ot the best exchange rate but if you live left it a little late then this is the best option. Would probably use again . -

- Shane -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Great Service

-

- As ever Travelex has provided a great service. It has been both accurate and prompt. -

- Susan Colebrook -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

So far so good

-

- So far so good. As yet have not used on holiday but trust that all will be ok. -

- Catherine Thomson -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

The whole experience was smooth and…

-

- The whole experience was smooth and professional. And great exchange rates. :) -

- Ruxandra Cordea -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Simple process

-

- Simple process. Friendly staff -

- AB -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

Travelex - Ease of Use

-

- Travelex is very good but one complaint: - -Why can't I leave all of my details for the next time? -

- Colin McArthur -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-

First time user

-

- It was rad to use and seemingly safe. I have used them twice now. -

- Me -
- - - - - - - - - - - - - - - -
-
- -
-
-
-

Travelex is rated 4 stars by Trustpilot based on over 34635 reviews

-
-
- -
-
- - - - - -
-
-
-
-
-

Travelex Wire: Low cost money transfer from the experts

-

Travelex Wire is our brand new money transfer service from Travelex directly, offering a low-cost way of sending money internationally.

-

With Travelex Wire, simply set up your money transfer online, with fees from as little as £3^.

Find out more
-
-
-
-

- - How to calculate exchange rates - -

-
-

Exchange rates are influenced by banks and trading institutions and the volume of currency they are buying and selling at any given time. Currencies are traded (bought and sold) daily around the world.

-

One currency can be purchased by another currency through banking institutions or on the open market. The volumes of currencies traded are increased and decreased depending on the attractiveness of any particular currency, which depends on a multitude of factors such as political stability, economic strength, government debt and fiscal policy among others.

-

Government central banks also have the ability to set a currency at a constant price through a method called pegging, which essentially tethers the value of one currency to another. The value (or price) of a currency is determined by its traded volume. If a currency is competitively priced, traders will buy the currency, essentially driving up its value. If a currency is not competitively priced, traders may avoid buying, or even sell it, essentially driving down its value.

- - - - - - - - -
-
-
-
-
-

- - How to read exchange rates - currency jargon explained - -

-
-

Foreign exchange can be confusing, so to help break through the confusion, here are some common terms associated with currency:

-
    -
  • Buy rate This is the rate at which we buy foreign currency back from you into your local currency. For example, if you were returning from America, we would exchange your US dollars back into British pounds at the buy rate of the day.
  • -
-
    -
  • Commission – This is a common fee that foreign exchange providers charge for exchanging one currency with another.
  • -
-
    -
  • Cross rate – This is the rate we give to customers who want to exchange currencies that do not involve the local currency. For example, if you want to exchange Australian dollars into US dollars.
  • -
-
    -
  • Currency Pair - This the the relationship between two country's currencies. It is often denoted like this: GBP/USD, EUR/JAP, AUD/INR
  • -
-
    -
  • Holiday money rate or tourist rate – This is another term for a sell rate. 
  • -
-
    -
  • Sell rate This is the rate at which we sell foreign currency in exchange for local currency. For example, if you were heading to Europe, you would exchange British pounds for euros at the sell rate.
  • -
-
    -
  • Spot rate This is known more formally as the ‘interbank’ rate. It is the rate banks or large financial institutions charge each other when trading significant amounts of foreign currency. In the business, this is sometimes referred to as a ‘spot rate
  • -
-
    -
  • Spread – This is the difference between the buy and sell rates offered by a foreign exchange provider such as us. 
  • -
- - - - - - - - -
-
-
-
-
-

- - Exchange Rates FAQ's - -

-
-

Why do currency exchange rates fluctuate?

-

Currencies constantly move up and down against each other as financial markets change. These movements can be caused by supply and demand, as well as by political and economic events.

-

Why are tourist money exchange rates not the same as the market spot rate?

-

The market (or spot) exchange rate, is the rate at which banks exchange currencies. There are a lot of processes and people involved in providing currency into your hands. There is a cost to doing this, which means that the value of the currency is affected to cover all of said cost. 

-

At Travelex, we work to provide you with the best value on your foreign currency as possible. We are constantly striving to improve our systems and processes to make them more efficient, meaning that you get the best value for your travel money exchange rates from us.

-

Find out more on spot rates and tourist rates here.

-

-

Does it pay to shop around and compare rates?

-

There are a lot of foreign currency providers in the UK, offering you a range of products and services. With so much choice, it means that you can spend time to find the best exchange rate in the market. However, there is usually very little difference; it can be just a matter of pence. 

- - - - - - - - -
-
-
-

Need some extra help with your currency?


Currency converter

See how much your mojito, poncho, or dinner in Paris will cost you in British pounds by using our simple currency converter.

Convert currency

Travel rate tracker

Not sure if it’s the right time to buy your currency? Let us do the hard work by monitoring the rates for you! We'll email you when your chosen currency hits the rate you need.

Track rates
-
-
-

*We compared the average cost of sending money abroad from the UK with Travelex Wire – in euros or US dollars across a range of values – against the average costs of sending equivalent sums abroad using the online services of leading money transfer providers in the UK. The price data used for the purpose of this analysis was obtained via online research between 1st June 2017 and 30th June 2017. Find out more here.

- - - - - - - - -
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/exercises/04_functions_objects/palindrome/index.js b/exercises/04_functions_objects/palindrome/index.js deleted file mode 100644 index 0d4dda6..0000000 --- a/exercises/04_functions_objects/palindrome/index.js +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -String.prototype.palindrome = require('./palindrome') - -const phrases = ['eve', 'kayak', 'mom', 'wow', 'noon', 'Not a palindrome'] - -for (const phrase of phrases) { - if (phrase.palindrome()) { - console.log(`"${phrase}" is a palindrome`) - } else { - console.log(`"${phrase}" is NOT a palindrome`) - } -} - -/* -for (const phrase of phrases) { - const answer = phrase.palindrome() ? '' : 'NOT ' - console.log(`"${phrase}" is ${answer}a palindrome`) -} -*/ diff --git a/exercises/04_functions_objects/palindrome/palindrome.js b/exercises/04_functions_objects/palindrome/palindrome.js deleted file mode 100644 index 84d03a8..0000000 --- a/exercises/04_functions_objects/palindrome/palindrome.js +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node -/* eslint no-magic-numbers: 0 */ - -'use strict' - -module.exports = function() { - const len = this.length-1 - for (let i = 0; i <= len; i++) { - if (this.charAt(i) !== this.charAt(len-i)) { - return false - } - if (i === len-i) { - return true - } - } - return true -} - -/* -// a more elegant solution: can you see how it works? -module.exports = function() { - const reversed = this.split('').reverse().join('') - return (reversed === this.valueOf()) -} -*/ diff --git a/exercises/04_functions_objects/prototypes.js b/exercises/04_functions_objects/prototypes.js deleted file mode 100644 index 6d5c9c7..0000000 --- a/exercises/04_functions_objects/prototypes.js +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node -/* eslint no-magic-numbers: 0 */ - -'use strict' - -String.prototype.toArray = function() { - const strArr = this.split('') - return strArr -} - -const nameArray = 'John Doe'.toArray() -console.log(nameArray) diff --git a/exercises/04_functions_objects/quotesOld.js b/exercises/04_functions_objects/quotesOld.js deleted file mode 100644 index c917650..0000000 --- a/exercises/04_functions_objects/quotesOld.js +++ /dev/null @@ -1,55 +0,0 @@ - -'use strict' - -const puppeteer = require('puppeteer') - -const search = async query => { - const width = 1920 - const height = 926 - const browser = await puppeteer.launch({ headless: true}) - const page = await browser.newPage() - await page.setViewport({ width: width, height: height }) - await page.goto(`https://www.brainyquote.com/search_results?q=${query}`, { waitUntil: 'networkidle0' }) - await autoScroll(page) - const dom = await page.evaluate(() => { - const elements = document.querySelectorAll('div.m-brick') - const hotels = [] - elements.forEach((element) => { - const quoteJson = {} - try { - quoteJson.quote = element.querySelector('a.b-qt').innerText - quoteJson.author = element.querySelector('a.bq-aut').innerText - quoteJson.tags = element.querySelector('div.kw-box').innerText.split(',').map( tag => tag.trim().toUpperCase()) - //quoteJson.id = document.querySelector('a.b-qt').className.match(/\d+/)[0] - } catch (err) { - return new Error('oops') - } - hotels.push(quoteJson) - }) - return hotels - }) - await browser.close() - return dom -} - -async function autoScroll(page){ - await page.evaluate( async() => { - await new Promise( resolve => { - let totalHeight = 0 - const distance = 100 - const delay = 60 - const timer = setInterval(() => { - const scrollHeight = document.body.scrollHeight - window.scrollBy(0, distance) - totalHeight += distance - - if(totalHeight >= scrollHeight){ - clearInterval(timer) - resolve() - } - }, delay) - }) - }) -} - -module.exports.getQuotes = (query, callback) => search(query).then(data => callback(null, data)).catch(err => callback(err)) diff --git a/exercises/04_functions_objects/strings.js b/exercises/04_functions_objects/strings.js deleted file mode 100644 index 9db49c6..0000000 --- a/exercises/04_functions_objects/strings.js +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env node -/* eslint no-magic-numbers: 0 */ - -'use strict' - -const names = ['Mark', 'John', 'Stephen', 'James', 'William'] - -function uppercase(nameArray) { - const result = [] - for (const name of nameArray) { - result.push(name.toUpperCase()) - } - return result -} - -// create a function to reverse the order of the indexes (index 0 should be William) - -console.log(uppercase(names)) - -// here is the same functionality written using the array's map() method. -const upper = names.map( value => value.toUpperCase() ) - -console.log(upper) - -// rest operator, passing in unknown number of parameters. - -function longest(...params) { - let longest = '' - for (const name of params) { - if (name.length > longest.length) { - longest = name - } - } - return longest -} - -const long = longest('John', 'William', 'Peter') -console.log(long) - -// rewriting this using reduce. - -const long2 = names.reduce( (acc, val) => { - if (val.length > acc.length) { - return val - } else { - return acc - } -}) - -console.log(long2) - -// rewritten using the Conditional Operator - -const long3 = names.reduce( (acc, val) => val.length > acc.length ? val : acc) - -console.log(long3) - -const data = ['Coventry', 3.14159, 'Computer', 42, true, 365.25, 101] - -const integers = data.filter( val => Number.isInteger(val) ) - -console.log(integers) - -const floats = data.filter( val => typeof val === 'number' && val % 1 !== 0) - -console.log(floats) - -const strings = data.filter( val => typeof val === 'string') - -console.log(strings) diff --git a/exercises/10_apis/02_scraping/index.js b/exercises/10_apis/02_scraping/index.js deleted file mode 100644 index 24a3a19..0000000 --- a/exercises/10_apis/02_scraping/index.js +++ /dev/null @@ -1,72 +0,0 @@ - - -const puppeteer = require('puppeteer') -const fs = require('fs') -const request = require('request') -//const csv = require('fast-csv') - -const getRates = async query => { - const width = 1920 - const height = 926 - const browser = await puppeteer.launch({ headless: false}) - const page = await browser.newPage() - await page.setViewport({ width: width, height: height }) - await page.goto('https://www.amazon.co.uk/s/ref=sr_pg_1?keywords=javascript', { waitUntil: 'domcontentloaded' }) - await page.waitFor(5000) - console.log('ready to grab page content') - //const html = await page.content() - let records - const dom = await page.evaluate(() => { - const elements = document.querySelectorAll('li#result_1 > div') - records = elements.length - // const hotels = [] - // elements.forEach((element) => { - // const quoteJson = {} - // try { - // //quoteJson.quote = element.innerText.replace(/ +/g, ',') - // quoteJson.country = element.querySelector('span.col:first-child').innerText - // //quoteJson.currencyStr = element.querySelector('span.col:nth-child(2)').innerText - // quoteJson.currency = element.querySelector('span.col:nth-child(2)').innerText.split(' (')[0] - // quoteJson.code = element.querySelector('span.col:nth-child(2)').innerText.split(' (')[1].replace(')', '') - // quoteJson.rate = parseFloat(element.querySelector('span.col:nth-child(3)').innerText) - // } catch (err) { - // return new Error('oops') - // } - // hotels.push(quoteJson) - // }) - // return hotels - }) - console.log(`found ${records} records`) - await browser.close() - return dom -} - -const getCurrency = callback => getRates().catch(err => callback(err)) - -getCurrency( (err, data) => { - if(err) console.log('oops!') - console.log(`found ${data.length} CURRENCY codes`) - console.log(data.length) - fs.writeFileSync('currency.json', JSON.stringify(data, null, 2)) -}) - -/* -https://www.amazon.co.uk/s/ref=sr_pg_2?rh=n%3A266239%2Ck%3Ajavascript&page=2&d=1&keywords=javascript&ie=UTF8&qid=1546457800 - -https://www.amazon.co.uk/s/ref=sr_pg_2?page=2&keywords=javascript - -https://www.amazon.co.uk/s/ref=sr_pg_3?keywords=javascript - -https://www.amazon.co.uk/JavaScript-Definitive-Guide-Guides/dp/0596805527/ref=sr_1_3?ie=UTF8&qid=1546457942&sr=8-3&keywords=javascript - -simple search (note the number refers to the pagenation of the results): -https://www.amazon.co.uk/s/ref=sr_pg_1?keywords=javascript - -uses the ISBN10 number: -https://www.amazon.co.uk/dp/0596805527 - -DOM EXTRACTION -use the Chrome plugin Element Locator. - -li#result_1 > div > div:nth-of-type(2) > div > div:nth-of-type(2) -*/ diff --git a/exercises/10_apis/02_scraping/package.json b/exercises/10_apis/02_scraping/package.json deleted file mode 100644 index f86168a..0000000 --- a/exercises/10_apis/02_scraping/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "02_scraping", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "puppeteer": "^1.11.0", - "request": "^2.88.0" - } -} diff --git a/exercises/10_apis/books/__tests__/books.test.js b/exercises/10_apis/books/__tests__/books.test.js deleted file mode 100644 index b7ac565..0000000 --- a/exercises/10_apis/books/__tests__/books.test.js +++ /dev/null @@ -1,65 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const fs = require('fs') -const books = require('../modules/books') - -jest.mock('../modules/google') - -const path = './modules/__mocks__/__mockData__/' - -describe('search', () => { - - let req - - beforeEach( () => { - req = JSON.parse(fs.readFileSync(`${path}req.json`, 'utf8')) - }) - - test('make a search with valid request', async() => { - const result = await books.search(req) - const expected = fs.readFileSync(`${path}validTable.txt`, 'utf8') - // compare text using regex to remove whitespace - expect(result.replace(/\s/g, '')).toBe(expected.replace(/\s/g, '')) - }) - - test('make a search with no query parameters', async() => { - delete req.query - const result = await books.search(req) - expect(result.replace(/\s/g, '')).toBe('') - }) - - test('make a search with missing q query parameter', async() => { - try { - delete req.query.q - await books.search(req) - } catch(err) { - expect(err.message).toMatch('invalid isbn') - } - }) - -}) - -describe('details', () => { - - let req - - beforeEach( () => { - req = JSON.parse(fs.readFileSync(`${path}req.json`, 'utf8')) - }) - - test('return details of a book using a valid isbn number', async() => { - console.log(req) - const result = await books.details(req) - const expected = fs.readFileSync(`${path}9781785885587.json`, 'utf8') - expect(result.replace(/\s/g, '')).toBe(expected.replace(/\s/g, '')) - }) - - // test('request a book with no params', async() => { - // delete req.params - // await books.details(req).rejects.toEqual(Error('invalid isbn')) - // }) - -}) diff --git a/exercises/10_apis/books/__tests__/google.test.js b/exercises/10_apis/books/__tests__/google.test.js deleted file mode 100644 index b7e156f..0000000 --- a/exercises/10_apis/books/__tests__/google.test.js +++ /dev/null @@ -1,48 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const google = require('../modules/google') - - -describe('search', () => { - - test('check response is valid', async() => { - const base = 'https://www.googleapis.com/books/v1/volumes' - const fields = 'items(id,volumeInfo(title,industryIdentifiers))' - const url = `${base}?maxResults=20&fields=${fields}&q=java` - const data = await google.search(url) - expect(typeof data).toBe('string') - const json = JSON.parse(data) - expect(Array.isArray(json.items)).toBeTruthy() - expect(json.items.length).toBe(20) - }) - -}) - -describe('getBook', async() => { - - test('get book with valid isbn', async() => { - const fields = 'items(volumeInfo(title,authors,description,publisher))' - const url = `https://www.googleapis.com/books/v1/volumes?fields=${fields}&q=isbn:9781785885587` - const data = await google.getBook(url) - expect(typeof data).toBe('string') - const json = JSON.parse(data) - expect(json.title).toBeTruthy() - expect(json.authors).toBeTruthy() - expect(Array.isArray(json.authors)) - }) - - // toThrowError does not support promises! - test('try to use invalid isbn number', async() => { - try { - const fields = 'items(volumeInfo(title,authors,description,publisher))' - const url = `https://www.googleapis.com/books/v1/volumes?fields=${fields}&q=isbn:9781785885581` - await google.getBook(url) - } catch(err) { - expect(err.message).toMatch('invalid isbn') - } - }) - -}) diff --git a/exercises/10_apis/books/__tests__/utility.test.js b/exercises/10_apis/books/__tests__/utility.test.js deleted file mode 100644 index 6852233..0000000 --- a/exercises/10_apis/books/__tests__/utility.test.js +++ /dev/null @@ -1,142 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const fs = require('fs') - -const utility = require('../modules/utility') - -const path = './modules/__mocks__/__mockData__/' - -describe('buildString', () => { - - test('build url with default count', () => { - const str = utility.buildString('java') - expect(str) - .toBe('https://www.googleapis.com/books/v1/volumes?maxResults=20&fields=items(id,volumeInfo(title,industryIdentifiers))&q=java') - }) - - test('build url specifying count', () => { - const str = utility.buildString('java', 2) - expect(str) - .toBe('https://www.googleapis.com/books/v1/volumes?maxResults=2&fields=items(id,volumeInfo(title,industryIdentifiers))&q=java') - }) - - test('throw error if count too large', () => { - expect(() => utility.buildString('java', 21)) - .toThrowError('invalid count parameter') - }) - - test('throw error if count 0', () => { - expect(() => utility.buildString('java', 0)) - .toThrowError('invalid count parameter') - }) - - test('throw error if count negative', () => { - expect(() => utility.buildString('test', -1)) - .toThrowError('invalid count parameter') - }) - -}) - -describe('buildBookURL', () => { - - test('build url with valid isbn13 number', () => { - const str = utility.buildBookURL(9780226285108) - expect(str) - .toBe('https://www.googleapis.com/books/v1/volumes?fields=items(volumeInfo(title,authors,description,publisher))&q=isbn:9780226285108') - }) - - test('passing isbn as a string', () => { - expect(() => utility.buildBookURL('9780226285108')) - .toThrowError('parameter has invalid data type') - }) - - test('passing isbn number that is too long', () => { - expect(() => utility.buildBookURL(97802262851081)) - .toThrowError('invalid isbn') - }) - - test('passing isbn number that is too short', () => { - expect(() => utility.buildBookURL(978022628510)) - .toThrowError('invalid isbn') - }) - -}) - -describe('extractFields', () => { - - let goodData - - beforeAll( () => { - goodData = fs.readFileSync(`${path}java.json`, 'utf8') - expect(typeof goodData).toBe('string') - }) - - test('extracted data is in an array', () => { - const bookData = utility.extractFields(goodData) - expect(Array.isArray(bookData)).toBeTruthy() - expect(bookData.length).toBe(20) - }) - - test('passing string without books array', () => { - expect(() => utility.extractFields('{"name": "Mark"}')) - .toThrowError('no book data found') - }) - - test('passing object instead of string', () => { - expect(() => utility.extractFields({name: 'Mark'})) - .toThrowError('parameter has invalid data type') - }) - - test('extract title fields', () => { - const bookData = utility.extractFields(goodData) - expect(bookData[0].title).toBe('Thinking in Java') - expect(bookData[1].title).toBe('Practical Java') - }) - - test('extract ISBN13 data', () => { - const bookData = utility.extractFields(goodData) - expect(bookData[0].isbn).toBe(9780131002876) - expect(bookData[1].isbn).toBe(9780201616460) - }) - -}) - -describe('build table string', () => { - - let goodData - let goodHTML - - beforeAll( () => { - goodData = JSON.parse(fs.readFileSync(`${path}extractedData.json`, 'utf8')) - goodHTML = fs.readFileSync(`${path}validTable.txt`, 'utf8') - }) - - test('check parameter is an object', () => { - expect(typeof goodData).toBe('object') - }) - - test('thow error if parameter is not an object', () => { - expect(() => utility.buildTable('bad parameter')) - .toThrowError('invalid parameter data type') - }) - - test('check that parameter is an array (not object)', () => { - expect(() => utility.buildTable({name: 'Mark'})) - .toThrowError('invalid parameter data type') - }) - - test('check the function returns a string', () => { - const table = utility.buildTable(goodData) - expect(typeof table).toBe('string') - }) - - test('build 2 column table', async() => { - const table = utility.buildTable(goodData) - // compare text using regex to remove whitespace - expect(table.replace(/\s/g, '')).toBe(goodHTML.replace(/\s/g, '')) - }) - -}) diff --git a/exercises/10_apis/books/html/index.html b/exercises/10_apis/books/html/index.html deleted file mode 100644 index 9209f66..0000000 --- a/exercises/10_apis/books/html/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Google Book Search - - - - -
- - -
- ${books} - - diff --git a/exercises/10_apis/books/index.js b/exercises/10_apis/books/index.js deleted file mode 100644 index ae53933..0000000 --- a/exercises/10_apis/books/index.js +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -const express = require('express') -const es6Renderer = require('express-es6-template-engine') -const bodyParser = require('body-parser') -const app = express() -app.use(express.static('public')) -app.use(bodyParser.urlencoded({ extended: true })) - -app.engine('html', es6Renderer) -app.set('views', 'html') -app.set('view engine', 'html') - -const books = require('./modules/books') - -const port = 8080 - -// const status = { -// ok: 200, -// created: 201, -// notFound: 404, -// notAcceptable: 406, -// conflict: 409 -// } - -app.get('/', async(req, res) => { - try { - console.log(`query ${req.query.q}`) - const bookList = await books.search(req) - console.log(bookList) - res.render('index', {locals: {books: bookList}}) - } catch(err) { - console.log(err.message) - } -}) - -app.listen(port, () => console.log(`app listening on port ${port}`)) diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885581.json b/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885581.json deleted file mode 100644 index 9e26dfe..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885581.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885587.json b/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885587.json deleted file mode 100644 index e4b3294..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/9781785885587.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "title": "Node.Js Design Patterns - Second Edition", - "authors": [ - "Mario Casciaro", - "Luciano Mammino" - ], - "publisher": "Packt Publishing", - "description": "Get the best out of Node.js by mastering its most powerful components and patterns to create modular and scalable applications with easeAbout This Book- Create reusable patterns and modules by leveraging the new features of Node.js .- Understand the asynchronous single thread design of node and grasp all its features and patterns to take advantage of various functions.- This unique guide will help you get the most out of Node.js and its ecosystem.Who This Book Is ForThe book is meant for developers and software architects with a basic working knowledge of JavaScript who are interested in acquiring a deeper understanding of how to design and develop enterprise-level Node.js applications.Basic knowledge of Node.js is also helpful to get the most out of this book.What You Will Learn- Design and implement a series of server-side JavaScript patterns so you understand why and when to apply them in different use case scenarios- Become comfortable with writing asynchronous code by leveraging constructs such as callbacks, promises, generators and the async-await syntax- Identify the most important concerns and apply unique tricks to achieve higher scalability and modularity in your Node.js application- Untangle your modules by organizing and connecting them coherently- Reuse well-known techniques to solve common design and coding issues- Explore the latest trends in Universal JavaScript, learn how to write code that runs on both Node.js and the browser and leverage React and its ecosystem to implement universal applicationsIn DetailNode.js is a massively popular software platform that lets you use JavaScript to easily create scalable server-side applications. It allows you to create efficient code, enabling a more sustainable way of writing software made of only one language across the full stack, along with extreme levels of reusability, pragmatism, simplicity, and collaboration. Node.js is revolutionizing the web and the way people and companies create their software.In this book, we will take you on a journey across various ideas and components, and the challenges you would commonly encounter while designing and developing software using the Node.js platform. You will also discover the \"Node.js way\" of dealing with design and coding decisions.The book kicks off by exploring the basics of Node.js describing it's asynchronous single-threaded architecture and the main design patterns. It then shows you how to master the asynchronous control flow patterns,and the stream component and it culminates into a detailed list of Node.js implementations of the most common design patterns as well as some specific design patterns that are exclusive to the Node.js world.Lastly, it dives into more advanced concepts such as Universal Javascript, and scalability' and it's meant to conclude the journey by giving the reader all the necessary concepts to be able to build an enterprise grade application using Node.js.Style and approachThis book takes its intended readers through a comprehensive explanation to create a scalable and efficient real-time server-side apps." -} diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/extractedData.json b/exercises/10_apis/books/modules/__mocks__/__mockData__/extractedData.json deleted file mode 100644 index 238c353..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/extractedData.json +++ /dev/null @@ -1,80 +0,0 @@ -[ - { - "title": "Thinking in Java", - "isbn": 9780131002876 - }, - { - "title": "Practical Java", - "isbn": 9780201616460 - }, - { - "title": "Java in a Time of Revolution", - "isbn": 9789793780146 - }, - { - "title": "Java", - "isbn": 9780764535437 - }, - { - "title": "The History of Java" - }, - { - "title": "The Religion of Java", - "isbn": 9780226285108 - }, - { - "title": "Natural Language Processing with Java", - "isbn": 9781784398941 - }, - { - "title": "Java and Modern Europe", - "isbn": 9780700704330 - }, - { - "title": "Java Web Development Illuminated", - "isbn": 9780763734237 - }, - { - "title": "Introduction to Neural Networks with Java", - "isbn": 9781604390087 - }, - { - "title": "TCP/IP Sockets in Java", - "isbn": 9780080568782 - }, - { - "title": "Java in a Nutshell", - "isbn": 9780596007737 - }, - { - "title": "Java and XSLT", - "isbn": 9780596001438 - }, - { - "title": "Wicked Cool Java", - "isbn": 9781593270612 - }, - { - "title": "Java NIO Ron Hitchens", - "isbn": 9780596002886 - }, - { - "title": "Effective Java", - "isbn": 9780132778046 - }, - { - "title": "Java I/O", - "isbn": 9781449390884 - }, - { - "title": "The History of Java" - }, - { - "title": "Programming with Java", - "isbn": 9780070141698 - }, - { - "title": "Concurrent Programming in Java", - "isbn": 9780201310092 - } -] diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/java.json b/exercises/10_apis/books/modules/__mocks__/__mockData__/java.json deleted file mode 100644 index 0e371c1..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/java.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "items": [ - { - "id": "Ql6QgWf6i7cC", - "volumeInfo": { - "title": "Thinking in Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0131002872" - }, - { - "type": "ISBN_13", - "identifier": "9780131002876" - } - ] - } - }, - { - "id": "iWPeqljHNcoC", - "volumeInfo": { - "title": "Practical Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0201616467" - }, - { - "type": "ISBN_13", - "identifier": "9780201616460" - } - ] - } - }, - { - "id": "87totx4p3ZcC", - "volumeInfo": { - "title": "Java in a Time of Revolution", - "industryIdentifiers": [ - { - "type": "ISBN_13", - "identifier": "9789793780146" - }, - { - "type": "ISBN_10", - "identifier": "9793780142" - } - ] - } - }, - { - "id": "Ql0UWMUu3ooC", - "volumeInfo": { - "title": "Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0764535439" - }, - { - "type": "ISBN_13", - "identifier": "9780764535437" - } - ] - } - }, - { - "id": "gJEC2q7DzpQC", - "volumeInfo": { - "title": "The History of Java", - "industryIdentifiers": [ - { - "type": "OTHER", - "identifier": "HARVARD:32044021066998" - } - ] - } - }, - { - "id": "-SYM4PW-YAgC", - "volumeInfo": { - "title": "The Religion of Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0226285103" - }, - { - "type": "ISBN_13", - "identifier": "9780226285108" - } - ] - } - }, - { - "id": "q7y4BwAAQBAJ", - "volumeInfo": { - "title": "Natural Language Processing with Java", - "industryIdentifiers": [ - { - "type": "ISBN_13", - "identifier": "9781784398941" - }, - { - "type": "ISBN_10", - "identifier": "1784398942" - } - ] - } - }, - { - "id": "qXayo7k3oakC", - "volumeInfo": { - "title": "Java and Modern Europe", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0700704337" - }, - { - "type": "ISBN_13", - "identifier": "9780700704330" - } - ] - } - }, - { - "id": "oY9fShrQyUgC", - "volumeInfo": { - "title": "Java Web Development Illuminated", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0763734233" - }, - { - "type": "ISBN_13", - "identifier": "9780763734237" - } - ] - } - }, - { - "id": "Swlcw7M4uD8C", - "volumeInfo": { - "title": "Introduction to Neural Networks with Java", - "industryIdentifiers": [ - { - "type": "ISBN_13", - "identifier": "9781604390087" - }, - { - "type": "ISBN_10", - "identifier": "1604390085" - } - ] - } - }, - { - "id": "lfHo7uMk7r4C", - "volumeInfo": { - "title": "TCP/IP Sockets in Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0080568785" - }, - { - "type": "ISBN_13", - "identifier": "9780080568782" - } - ] - } - }, - { - "id": "mvzgNSmHEUAC", - "volumeInfo": { - "title": "Java in a Nutshell", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0596007736" - }, - { - "type": "ISBN_13", - "identifier": "9780596007737" - } - ] - } - }, - { - "id": "eSRnOKwU4hUC", - "volumeInfo": { - "title": "Java and XSLT", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0596001436" - }, - { - "type": "ISBN_13", - "identifier": "9780596001438" - } - ] - } - }, - { - "id": "diqHjRjMhW0C", - "volumeInfo": { - "title": "Wicked Cool Java", - "industryIdentifiers": [ - { - "type": "ISBN_13", - "identifier": "9781593270612" - }, - { - "type": "ISBN_10", - "identifier": "1593270615" - } - ] - } - }, - { - "id": "z7TQ8NSooS4C", - "volumeInfo": { - "title": "Java NIO Ron Hitchens", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0596002882" - }, - { - "type": "ISBN_13", - "identifier": "9780596002886" - } - ] - } - }, - { - "id": "ka2VUBqHiWkC", - "volumeInfo": { - "title": "Effective Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0132778041" - }, - { - "type": "ISBN_13", - "identifier": "9780132778046" - } - ] - } - }, - { - "id": "42etT_9-_9MC", - "volumeInfo": { - "title": "Java I/O", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "1449390889" - }, - { - "type": "ISBN_13", - "identifier": "9781449390884" - } - ] - } - }, - { - "id": "_-dCAAAAcAAJ", - "volumeInfo": { - "title": "The History of Java", - "industryIdentifiers": [ - { - "type": "OTHER", - "identifier": "BSB:BSB10359645" - } - ] - } - }, - { - "id": "ZdBYoyWIsMQC", - "volumeInfo": { - "title": "Programming with Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "007014169X" - }, - { - "type": "ISBN_13", - "identifier": "9780070141698" - } - ] - } - }, - { - "id": "-x1S4neCSOYC", - "volumeInfo": { - "title": "Concurrent Programming in Java", - "industryIdentifiers": [ - { - "type": "ISBN_10", - "identifier": "0201310090" - }, - { - "type": "ISBN_13", - "identifier": "9780201310092" - } - ] - } - } - ] - } \ No newline at end of file diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/req.json b/exercises/10_apis/books/modules/__mocks__/__mockData__/req.json deleted file mode 100644 index 9e8c606..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/req.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "query": { - "q": "java" - }, - "params": { - "isbn": 9781785885587 - }, - "method": "GET", - "url": "/?q=java", - "headers": { - "host": "xxx", - "user-agent": "xxx" - } -} \ No newline at end of file diff --git a/exercises/10_apis/books/modules/__mocks__/__mockData__/validTable.txt b/exercises/10_apis/books/modules/__mocks__/__mockData__/validTable.txt deleted file mode 100644 index b8fedbf..0000000 --- a/exercises/10_apis/books/modules/__mocks__/__mockData__/validTable.txt +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Thinking in Java9780131002876
Practical Java9780201616460
Java in a Time of Revolution9789793780146
Java9780764535437
The History of Javano ISBN
The Religion of Java9780226285108
Natural Language Processing with Java9781784398941
Java and Modern Europe9780700704330
Java Web Development Illuminated9780763734237
Introduction to Neural Networks with Java9781604390087
TCP/IP Sockets in Java9780080568782
Java in a Nutshell9780596007737
Java and XSLT9780596001438
Wicked Cool Java9781593270612
Java NIO Ron Hitchens9780596002886
Effective Java9780132778046
Java I/O9781449390884
The History of Javano ISBN
Programming with Java9780070141698
Concurrent Programming in Java9780201310092
\ No newline at end of file diff --git a/exercises/10_apis/books/modules/__mocks__/google.js b/exercises/10_apis/books/modules/__mocks__/google.js deleted file mode 100644 index a2b093a..0000000 --- a/exercises/10_apis/books/modules/__mocks__/google.js +++ /dev/null @@ -1,32 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const fs = require('fs') - -/** - * Makes a Google Books API query - * @param {String} searchString the URL to use for the query - * @returns {String} a JSON-formatter string - */ -module.exports.search = async url => { - const [,query] = url.split('q=') // destructuring assignment - const file = `./modules/__mocks__/__mockData__/${query}.json` - const data = fs.readFileSync(file) - const json = JSON.parse(data) - return JSON.stringify(json, null, 2) -} - -/** - * Retrieved data on a book using a RESTful API URL - * @param {String} searchString the URL to use for the query - * @returns {String} a JSON-formatter string - */ -module.exports.getBook = async url => { - const [,isbn] = url.split('q=isbn:') // destructuring assignment - const file = `./modules/__mocks__/__mockData__/${isbn}.json` - const data = fs.readFileSync(file) - const json = JSON.parse(data) - return JSON.stringify(json, null, 2) -} diff --git a/exercises/10_apis/books/modules/books.js b/exercises/10_apis/books/modules/books.js deleted file mode 100644 index 8d3b579..0000000 --- a/exercises/10_apis/books/modules/books.js +++ /dev/null @@ -1,37 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const utility = require('./utility') -const google = require('./google') -//jest.mock('./google') - -/** - * Makes a Google Books API query - * @param {String} request the http request object - * @returns {Promise} an html table of data as a string - */ -module.exports.search = async request => { - if(request.query === undefined) { - return '' - } - if(request.query.q === undefined) { - return '' - } - const url = utility.buildString(request.query.q) - const data = await google.search(url) - const books = utility.extractFields(data) - const table = utility.buildTable(books) - return table -} - -module.exports.details = async request => { - //delete request.params - if(request.params === undefined) { - return Promise.reject('invalid isbn') - } - const url = utility.buildBookURL(request.params.isbn) - const data = await google.getBook(url) - return data -} diff --git a/exercises/10_apis/books/modules/google.js b/exercises/10_apis/books/modules/google.js deleted file mode 100644 index 67e84dd..0000000 --- a/exercises/10_apis/books/modules/google.js +++ /dev/null @@ -1,32 +0,0 @@ - -'use strict' - -/* eslint-disable no-magic-numbers */ - -const rest = require('rest') - -/** - * Makes a Google Books API query - * @param {String} url the URL to use for the query - * @returns {Promise} An array of books as a JSON string - */ -module.exports.search = async url => { - const data = await rest(url) - //console.log(data.entity) - return data.entity -} - -/** - * Makes a Google Books API query to return details of one book - * based on its ISBN. - * @param {String} url the URL to use for the query - * @returns {Promise} Book details as a JSON string - * @throws {Error} invalid isbn - */ -module.exports.getBook = async url => { - const data = await rest(url) - const len = parseInt(data.headers['Content-Length']) - if(len <= 4) throw new Error('invalid isbn') - const json = JSON.parse(data.entity) - return JSON.stringify(json.items[0].volumeInfo, null, 2) -} diff --git a/exercises/10_apis/books/modules/utility.js b/exercises/10_apis/books/modules/utility.js deleted file mode 100644 index 3ef2fab..0000000 --- a/exercises/10_apis/books/modules/utility.js +++ /dev/null @@ -1,91 +0,0 @@ - -'use strict' - -const maxRecords = 20 - -/** Builds the url needed by the Google Books API. - * @function buildString - * @param {String} query the string to search for - * @param {Number} [count=40] the number of records to return (max 40) - * @returns {String} the URL - */ -module.exports.buildString = (query, count = maxRecords) => { - if(count > maxRecords || count < 1) { - throw new Error('invalid count parameter') - } - const base = 'https://www.googleapis.com/books/v1/volumes' - const fields = 'items(id,volumeInfo(title,industryIdentifiers))' - const url = `${base}?maxResults=${count}&fields=${fields}&q=${query}` - //console.log(url) - return url -} - -module.exports.buildBookURL = isbn => { - const isbnLen = 13 - if(typeof isbn !== 'number') { - throw new Error('parameter has invalid data type') - } - if(isbn.toString().length !== isbnLen) { - throw new Error('invalid isbn') - } - const fields = 'items(volumeInfo(title,authors,description,publisher))' - const url = `https://www.googleapis.com/books/v1/volumes?fields=${fields}&q=isbn:${isbn}` - return url -} - -/* -------------------------------------------------------------------------- */ - -/** - * Extracts data from the json - * @param {String} jsonStr the json string to parse - * @returns {Array} an array of book details - */ -module.exports.extractFields = jsonStr => { - const bookArray = [] - if(typeof jsonStr !== 'string') { - throw new Error('parameter has invalid data type') - } - const json = JSON.parse(jsonStr) - if(!Array.isArray(json.items)) throw new Error('no book data found') - for(const n of json.items) { - const item = {} - item.title = n.volumeInfo.title - for(const m of n.volumeInfo.industryIdentifiers) { - if(m.type === 'ISBN_13') { - item.isbn = parseInt(m.identifier) - } - } - bookArray.push(item) - } - return bookArray -} - -/** - * Extracts data from the json - * @param {Array} bookArray an array containing the books found - * @returns {String} a string containing the html table - */ -module.exports.buildTable = bookArray => { - if(typeof bookArray !== 'object') { - throw new Error('invalid parameter data type') - } - if(!Array.isArray(bookArray)) { - throw new Error('invalid parameter data type') - } - let result = '\n' - for(const n of bookArray) { - if(n.isbn !== undefined) { - result += ` - - - ` - } else { - result += ` - - - ` - } - } - result += '
${n.title}${n.isbn}
${n.title}no ISBN
' - return result -} diff --git a/exercises/10_apis/books/package.json b/exercises/10_apis/books/package.json deleted file mode 100644 index f3cb37c..0000000 --- a/exercises/10_apis/books/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "books", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "tests": "jest", - "watch": "node_modules/.bin/jest --coverage --watchAll", - "coverage": "node_modules/.bin/jest --coverage", - "jsdoc": "node_modules/.bin/jsdoc -d docs/jsdoc/ modules/" - }, - "author": "", - "license": "ISC", - "jest": { - "verbose": true - }, - "dependencies": { - "express": "^4.16.3", - "express-es6-template-engine": "^2.0.3", - "rest": "^2.0.0" - }, - "devDependencies": { - "jest": "^23.1.0", - "jsdoc": "^3.5.5" - } -} diff --git a/exercises/10_apis/books/public/style.css b/exercises/10_apis/books/public/style.css deleted file mode 100644 index e69de29..0000000 diff --git a/exercises/10_auth/simple/index.js b/exercises/10_auth/simple/index.js deleted file mode 100644 index 47b3381..0000000 --- a/exercises/10_auth/simple/index.js +++ /dev/null @@ -1,36 +0,0 @@ - -'use strict' - -const Router = require('koa-router') -const auth = require('koa-simple-auth') -const koaBody = require('koa-body')() -const router = module.exports = new Router() - -const catch_api_error = async ctx => { - try{ - yield next - } catch(err){ - this.body = JSON.stringify({ 'error': err.message }) - } -} - -router.post('/login', - catch_api_error, - koaBody, - auth.login, - function *() { - this.body = JSON.stringify({ authenticated: true }) - } -) - -router.post('/register', catch_api_error, koaBody, auth.register, function *() { - this.body = JSON.stringify({ authenticated: true }) -}) - -router.get('/unregister', catch_api_error, koaBody, auth.unregister, function *() { - this.body = JSON.stringify({ authenticated: false }) -}) - -router.get('/logout', auth.logout, function *() { - this.body = JSON.stringify({ authenticated: false }) -}) diff --git a/exercises/11_koa/books.json b/exercises/11_koa/books.json deleted file mode 100644 index fd62de9..0000000 --- a/exercises/11_koa/books.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "author": "Roald Dahl", - "books": [ - { - "title": "The Gremlins", - "year": 1943 - }, - { - "title": "Over to You", - "year": 1946 - }, - { - "title": "Some Time Never", - "year": 1948 - }, - { - "title": "Someone Like You", - "year": 1953 - }, - { - "title": "James and the Giant Peach", - "year": 1961 - }, - { - "title": "Charlie and the Chocolate Factory", - "year": 1964 - }, - { - "title": "The Magic Finger", - "year": 1966 - }, - { - "title": "Fantastic Mr Fox", - "year": 1968 - }, - { - "title": "Charlie and the Great Glass Elevator", - "year": 1972 - } - ] -} \ No newline at end of file diff --git a/exercises/11_koa/index.js b/exercises/11_koa/index.js deleted file mode 100755 index 0453c2a..0000000 --- a/exercises/11_koa/index.js +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env node - -const Koa = require('koa') -const Router = require('koa-router') -const views = require('koa-views') -const stat = require('koa-static') -const fs = require('fs') - -const app = new Koa() -const router = new Router() -app.use(stat('public')) -app.use(views(`${__dirname}/views`, { extension: 'html' }, {map: { handlebars: 'handlebars' }})) -app.use(router.routes()) - -const port = 8080 - -router.get('/', async ctx => await ctx.render('hello')) - -router.get('/books', ctx => { - getBooks( (err, data) => { - if(err) ctx.body = err - let html = '
    ' - data.books.forEach( item => { - html += `
  1. ${item}
  2. ` - }) - html += '
' - ctx.body = html - }) -}) - -function getBooks(callback) { - fs.readFile('books.json', 'utf8', (err, data) => { - if(err) callback('Could Not Find File') - const books = JSON.parse(data) - console.log(books) - callback(null, books) - }) -} - -module.exports = app.listen(port, () => console.log(`listening on port ${port}`)) diff --git a/exercises/11_koa/package.json b/exercises/11_koa/package.json deleted file mode 100644 index 2f272fd..0000000 --- a/exercises/11_koa/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "koa-intro", - "version": "1.0.0", - "description": "Simple Koa Web App", - "main": "index.js", - "scripts": { - "server": "node index.js", - "test": "./node_modules/.bin/jest" - }, - "jest": { - "testEnvironment": "node", - "verbose": true - }, - "author": "Mark Tyers", - "license": "ISC", - "dependencies": { - "http-status-codes": "^1.3.0", - "koa": "^2.7.0", - "koa-router": "^7.4.0", - "koa-static": "^5.0.0", - "koa-views": "^6.1.5" - }, - "devDependencies": { - "jest": "^24.1.0", - "supertest": "^3.4.2" - } -} diff --git a/exercises/11_koa/public/css/hello.css b/exercises/11_koa/public/css/hello.css deleted file mode 100644 index fb0e5d2..0000000 --- a/exercises/11_koa/public/css/hello.css +++ /dev/null @@ -1,4 +0,0 @@ - -h1 { - color: red; -} \ No newline at end of file diff --git a/exercises/11_koa/public/images/computer.png b/exercises/11_koa/public/images/computer.png deleted file mode 100644 index b71ac38..0000000 Binary files a/exercises/11_koa/public/images/computer.png and /dev/null differ diff --git a/exercises/11_koa/views/hello.html b/exercises/11_koa/views/hello.html deleted file mode 100644 index 06cab1b..0000000 --- a/exercises/11_koa/views/hello.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Let's see CSS at Work - - - - - -

Hello CSS!

-

Use this file to see how CSS can be used to change the appearance of a web page.

- - \ No newline at end of file diff --git a/exercises/12_reactjs/auth/.babelrc b/exercises/12_reactjs/auth/.babelrc deleted file mode 100755 index 3c62e37..0000000 --- a/exercises/12_reactjs/auth/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "react", - "env", - "stage-0" - ] -} \ No newline at end of file diff --git a/exercises/12_reactjs/auth/.gitignore b/exercises/12_reactjs/auth/.gitignore deleted file mode 100755 index 66dce68..0000000 --- a/exercises/12_reactjs/auth/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules -jspm_packages -typings - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history \ No newline at end of file diff --git a/exercises/12_reactjs/auth/LICENSE b/exercises/12_reactjs/auth/LICENSE deleted file mode 100755 index 5fb47a9..0000000 --- a/exercises/12_reactjs/auth/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Jason Watmore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/exercises/12_reactjs/auth/README.md b/exercises/12_reactjs/auth/README.md deleted file mode 100755 index 985ae51..0000000 --- a/exercises/12_reactjs/auth/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# react-basic-authentication-example - -React - Basic HTTP Authentication Tutorial & Example - -To see a demo and further details go to http://jasonwatmore.com/post/2018/09/11/react-basic-http-authentication-tutorial-example \ No newline at end of file diff --git a/exercises/12_reactjs/auth/package.json b/exercises/12_reactjs/auth/package.json deleted file mode 100755 index 723f105..0000000 --- a/exercises/12_reactjs/auth/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "react-basic-authentication-example", - "version": "1.0.0", - "repository": { - "type": "git", - "url": "https://github.com/cornflourblue/react-basic-authentication-example.git" - }, - "license": "MIT", - "scripts": { - "start": "webpack-dev-server --open" - }, - "dependencies": { - "react": "^16.0.0", - "react-dom": "^16.0.0", - "react-router-dom": "^4.1.2" - }, - "devDependencies": { - "babel-core": "^6.26.0", - "babel-loader": "^7.1.5", - "babel-preset-env": "^1.6.1", - "babel-preset-react": "^6.16.0", - "babel-preset-stage-0": "^6.24.1", - "html-webpack-plugin": "^3.2.0", - "path": "^0.12.7", - "webpack": "^4.15.0", - "webpack-cli": "^3.0.8", - "webpack-dev-server": "^3.1.3" - } -} diff --git a/exercises/12_reactjs/auth/src/App/App.jsx b/exercises/12_reactjs/auth/src/App/App.jsx deleted file mode 100755 index 43e288d..0000000 --- a/exercises/12_reactjs/auth/src/App/App.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { BrowserRouter as Router, Route } from 'react-router-dom'; - -import { PrivateRoute } from '../_components'; -import { HomePage } from '../HomePage'; -import { LoginPage } from '../LoginPage'; - -class App extends React.Component { - render() { - return ( -
-
-
- -
- - -
-
-
-
-
- ); - } -} - -export { App }; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/App/index.js b/exercises/12_reactjs/auth/src/App/index.js deleted file mode 100755 index 9342f37..0000000 --- a/exercises/12_reactjs/auth/src/App/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './App'; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/HomePage/HomePage.jsx b/exercises/12_reactjs/auth/src/HomePage/HomePage.jsx deleted file mode 100755 index d3f65ef..0000000 --- a/exercises/12_reactjs/auth/src/HomePage/HomePage.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; - -import { userService } from '../_services'; - -class HomePage extends React.Component { - constructor(props) { - super(props); - - this.state = { - user: {}, - users: [] - }; - } - - componentDidMount() { - this.setState({ - user: JSON.parse(localStorage.getItem('user')), - users: { loading: true } - }); - userService.getAll().then(users => this.setState({ users })); - } - - render() { - const { user, users } = this.state; - return ( -
-

Hi {user.firstName}!

-

You're logged in with React & Basic HTTP Authentication!!

-

Users from secure api end point:

- {users.loading && Loading users...} - {users.length && -
    - {users.map((user, index) => -
  • - {user.firstName + ' ' + user.lastName} -
  • - )} -
- } -

- Logout -

-
- ); - } -} - -export { HomePage }; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/HomePage/index.js b/exercises/12_reactjs/auth/src/HomePage/index.js deleted file mode 100755 index 17bea76..0000000 --- a/exercises/12_reactjs/auth/src/HomePage/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './HomePage'; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/LoginPage/LoginPage.jsx b/exercises/12_reactjs/auth/src/LoginPage/LoginPage.jsx deleted file mode 100755 index 0a0b8f5..0000000 --- a/exercises/12_reactjs/auth/src/LoginPage/LoginPage.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react'; - -import { userService } from '../_services'; - -class LoginPage extends React.Component { - constructor(props) { - super(props); - - userService.logout(); - - this.state = { - username: '', - password: '', - submitted: false, - loading: false, - error: '' - }; - - this.handleChange = this.handleChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - } - - handleChange(e) { - const { name, value } = e.target; - this.setState({ [name]: value }); - } - - handleSubmit(e) { - e.preventDefault(); - - this.setState({ submitted: true }); - const { username, password, returnUrl } = this.state; - - // stop here if form is invalid - if (!(username && password)) { - return; - } - - this.setState({ loading: true }); - userService.login(username, password) - .then( - user => { - const { from } = this.props.location.state || { from: { pathname: "/" } }; - this.props.history.push(from); - }, - error => this.setState({ error, loading: false }) - ); - } - - render() { - const { username, password, submitted, loading, error } = this.state; - return ( -
-
- Username: test
- Password: test -
-

Login

-
-
- - - {submitted && !username && -
Username is required
- } -
-
- - - {submitted && !password && -
Password is required
- } -
-
- - {loading && - - } -
- {error && -
{error}
- } -
-
- ); - } -} - -export { LoginPage }; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/LoginPage/index.js b/exercises/12_reactjs/auth/src/LoginPage/index.js deleted file mode 100755 index 52a0ddd..0000000 --- a/exercises/12_reactjs/auth/src/LoginPage/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './LoginPage'; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/_components/PrivateRoute.jsx b/exercises/12_reactjs/auth/src/_components/PrivateRoute.jsx deleted file mode 100755 index e105dd4..0000000 --- a/exercises/12_reactjs/auth/src/_components/PrivateRoute.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; - -export const PrivateRoute = ({ component: Component, ...rest }) => ( - ( - localStorage.getItem('user') - ? - : - )} /> -) \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/_components/index.js b/exercises/12_reactjs/auth/src/_components/index.js deleted file mode 100755 index e0d535e..0000000 --- a/exercises/12_reactjs/auth/src/_components/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './PrivateRoute'; diff --git a/exercises/12_reactjs/auth/src/_helpers/auth-header.js b/exercises/12_reactjs/auth/src/_helpers/auth-header.js deleted file mode 100755 index 72271ef..0000000 --- a/exercises/12_reactjs/auth/src/_helpers/auth-header.js +++ /dev/null @@ -1,10 +0,0 @@ -export function authHeader() { - // return authorization header with basic auth credentials - let user = JSON.parse(localStorage.getItem('user')); - - if (user && user.authdata) { - return { 'Authorization': 'Basic ' + user.authdata }; - } else { - return {}; - } -} \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/_helpers/fake-backend.js b/exercises/12_reactjs/auth/src/_helpers/fake-backend.js deleted file mode 100755 index 6fe82ba..0000000 --- a/exercises/12_reactjs/auth/src/_helpers/fake-backend.js +++ /dev/null @@ -1,57 +0,0 @@ -export function configureFakeBackend() { - let users = [{ id: 1, username: 'test', password: 'test', firstName: 'Test', lastName: 'User' }]; - let realFetch = window.fetch; - window.fetch = function (url, opts) { - return new Promise((resolve, reject) => { - // wrap in timeout to simulate server api call - setTimeout(() => { - - // authenticate - if (url.endsWith('/users/authenticate') && opts.method === 'POST') { - // get parameters from post request - let params = JSON.parse(opts.body); - - // find if any user matches login credentials - let filteredUsers = users.filter(user => { - return user.username === params.username && user.password === params.password; - }); - - if (filteredUsers.length) { - // if login details are valid return user details - let user = filteredUsers[0]; - let responseJson = { - id: user.id, - username: user.username, - firstName: user.firstName, - lastName: user.lastName - }; - resolve({ ok: true, text: () => Promise.resolve(JSON.stringify(responseJson)) }); - } else { - // else return error - reject('Username or password is incorrect'); - } - - return; - } - - // get users - if (url.endsWith('/users') && opts.method === 'GET') { - // check for fake auth token in header and return users if valid, this security - // is implemented server side in a real application - if (opts.headers && opts.headers.Authorization === `Basic ${window.btoa('test:test')}`) { - resolve({ ok: true, text: () => Promise.resolve(JSON.stringify(users)) }); - } else { - // return 401 not authorised if token is null or invalid - resolve({ status: 401, text: () => Promise.resolve() }); - } - - return; - } - - // pass through any requests not handled above - realFetch(url, opts).then(response => resolve(response)); - - }, 500); - }); - } -} \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/_helpers/index.js b/exercises/12_reactjs/auth/src/_helpers/index.js deleted file mode 100755 index 81252a8..0000000 --- a/exercises/12_reactjs/auth/src/_helpers/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from './fake-backend'; -export * from './auth-header'; \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/_services/index.js b/exercises/12_reactjs/auth/src/_services/index.js deleted file mode 100755 index e17ee5c..0000000 --- a/exercises/12_reactjs/auth/src/_services/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './user.service'; diff --git a/exercises/12_reactjs/auth/src/_services/user.service.js b/exercises/12_reactjs/auth/src/_services/user.service.js deleted file mode 100755 index 03b2c80..0000000 --- a/exercises/12_reactjs/auth/src/_services/user.service.js +++ /dev/null @@ -1,62 +0,0 @@ -import config from 'config'; -import { authHeader } from '../_helpers'; - -export const userService = { - login, - logout, - getAll -}; - -function login(username, password) { - const requestOptions = { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ username, password }) - }; - - return fetch(`${config.apiUrl}/users/authenticate`, requestOptions) - .then(handleResponse) - .then(user => { - // login successful if there's a user in the response - if (user) { - // store user details and basic auth credentials in local storage - // to keep user logged in between page refreshes - user.authdata = window.btoa(username + ':' + password); - localStorage.setItem('user', JSON.stringify(user)); - } - - return user; - }); -} - -function logout() { - // remove user from local storage to log user out - localStorage.removeItem('user'); -} - -function getAll() { - const requestOptions = { - method: 'GET', - headers: authHeader() - }; - - return fetch(`${config.apiUrl}/users`, requestOptions).then(handleResponse); -} - -function handleResponse(response) { - return response.text().then(text => { - const data = text && JSON.parse(text); - if (!response.ok) { - if (response.status === 401) { - // auto logout if 401 response returned from api - logout(); - location.reload(true); - } - - const error = (data && data.message) || response.statusText; - return Promise.reject(error); - } - - return data; - }); -} \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/index.html b/exercises/12_reactjs/auth/src/index.html deleted file mode 100755 index 4ef6ff6..0000000 --- a/exercises/12_reactjs/auth/src/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - React - Basic HTTP Authentication Example & Tutorial - - - - -
- - - - - \ No newline at end of file diff --git a/exercises/12_reactjs/auth/src/index.jsx b/exercises/12_reactjs/auth/src/index.jsx deleted file mode 100755 index ea31d00..0000000 --- a/exercises/12_reactjs/auth/src/index.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { render } from 'react-dom'; - -import { App } from './App'; - -// setup fake backend -import { configureFakeBackend } from './_helpers'; -configureFakeBackend(); - -render( - , - document.getElementById('app') -); \ No newline at end of file diff --git a/exercises/12_reactjs/auth/webpack.config.js b/exercises/12_reactjs/auth/webpack.config.js deleted file mode 100755 index 3d93e51..0000000 --- a/exercises/12_reactjs/auth/webpack.config.js +++ /dev/null @@ -1,29 +0,0 @@ -var path = require('path'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); - -module.exports = { - mode: 'development', - resolve: { - extensions: ['.js', '.jsx'] - }, - module: { - rules: [ - { - test: /\.jsx?$/, - loader: 'babel-loader' - } - ] - }, - plugins: [new HtmlWebpackPlugin({ - template: './src/index.html' - })], - devServer: { - historyApiFallback: true - }, - externals: { - // global app config object - config: JSON.stringify({ - apiUrl: 'http://localhost:4000' - }) - } -} \ No newline at end of file diff --git a/exercises/12_reactjs/spa/.gitignore b/exercises/12_reactjs/spa/.gitignore deleted file mode 100644 index 4d29575..0000000 --- a/exercises/12_reactjs/spa/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/exercises/12_reactjs/spa/README.md b/exercises/12_reactjs/spa/README.md deleted file mode 100644 index 9d9614c..0000000 --- a/exercises/12_reactjs/spa/README.md +++ /dev/null @@ -1,68 +0,0 @@ -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `npm start` - -Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser. - -The page will reload if you make edits.
-You will also see any lint errors in the console. - -### `npm test` - -Launches the test runner in the interactive watch mode.
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `npm run build` - -Builds the app for production to the `build` folder.
-It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.
-Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `npm run eject` - -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** - -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. - -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting - -### Analyzing the Bundle Size - -This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size - -### Making a Progressive Web App - -This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app - -### Advanced Configuration - -This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration - -### Deployment - -This section has moved here: https://facebook.github.io/create-react-app/docs/deployment - -### `npm run build` fails to minify - -This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify diff --git a/exercises/12_reactjs/spa/package.json b/exercises/12_reactjs/spa/package.json deleted file mode 100644 index f8fbcaa..0000000 --- a/exercises/12_reactjs/spa/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "my-app", - "version": "0.1.0", - "private": true, - "dependencies": { - "react": "^16.7.0", - "react-dom": "^16.7.0", - "react-router-dom": "^4.3.1", - "react-scripts": "2.1.2" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": "react-app" - }, - "browserslist": [ - ">0.2%", - "not dead", - "not ie <= 11", - "not op_mini all" - ] -} diff --git a/exercises/12_reactjs/spa/public/index.html b/exercises/12_reactjs/spa/public/index.html deleted file mode 100644 index 425ca7a..0000000 --- a/exercises/12_reactjs/spa/public/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - React Router Example - - -
- - diff --git a/exercises/12_reactjs/spa/src/Contact.js b/exercises/12_reactjs/spa/src/Contact.js deleted file mode 100644 index 44116db..0000000 --- a/exercises/12_reactjs/spa/src/Contact.js +++ /dev/null @@ -1,17 +0,0 @@ - -import React, { Component } from "react" - -class Contact extends Component { - render() { - return ( -
-

GOT QUESTIONS?

-

The easiest thing to do is post on - our forums. -

-
- ) - } -} - -export default Contact diff --git a/exercises/12_reactjs/spa/src/Home.js b/exercises/12_reactjs/spa/src/Home.js deleted file mode 100644 index 7852654..0000000 --- a/exercises/12_reactjs/spa/src/Home.js +++ /dev/null @@ -1,22 +0,0 @@ - -import React, { Component } from "react"; - -class Home extends Component { - render() { - return ( -
-

HELLO

-

Cras facilisis urna ornare ex volutpat, et - convallis erat elementum. Ut aliquam, ipsum vitae - gravida suscipit, metus dui bibendum est, eget rhoncus nibh - metus nec massa. Maecenas hendrerit laoreet augue - nec molestie. Cum sociis natoque penatibus et magnis - dis parturient montes, nascetur ridiculus mus.

- -

Duis a turpis sed lacus dapibus elementum sed eu lectus.

-
- ) - } -} - -export default Home diff --git a/exercises/12_reactjs/spa/src/Main.js b/exercises/12_reactjs/spa/src/Main.js deleted file mode 100644 index 16fc8dd..0000000 --- a/exercises/12_reactjs/spa/src/Main.js +++ /dev/null @@ -1,34 +0,0 @@ - -import React, { Component } from "react"; -import { - Route, - NavLink, - HashRouter -} from "react-router-dom"; -import Home from "./Home"; -import Stuff from "./Stuff"; -import Contact from "./Contact"; - -class Main extends Component { - render() { - return ( - -
-

Simple SPA

-
    -
  • Home
  • -
  • Stuff
  • -
  • Contact
  • -
-
- - - -
-
-
- ) - } -} - -export default Main diff --git a/exercises/12_reactjs/spa/src/Stuff.js b/exercises/12_reactjs/spa/src/Stuff.js deleted file mode 100644 index f993342..0000000 --- a/exercises/12_reactjs/spa/src/Stuff.js +++ /dev/null @@ -1,23 +0,0 @@ - -import React, { Component } from "react" - -class Stuff extends Component { - render() { - return ( -
-

STUFF

-

Mauris sem velit, vehicula eget sodales vitae, - rhoncus eget sapien:

-
    -
  1. Nulla pulvinar diam
  2. -
  3. Facilisis bibendum
  4. -
  5. Vestibulum vulputate
  6. -
  7. Eget erat
  8. -
  9. Id porttitor
  10. -
-
- ) - } -} - -export default Stuff diff --git a/exercises/12_reactjs/spa/src/index.css b/exercises/12_reactjs/spa/src/index.css deleted file mode 100644 index 155e6ac..0000000 --- a/exercises/12_reactjs/spa/src/index.css +++ /dev/null @@ -1,40 +0,0 @@ - -body { - background-color: #FFCC00; - padding: 20px; - margin: 0; - } - h1, h2, p, ul, li { - font-family: sans-serif; - } - ul.header li { - display: inline; - list-style-type: none; - margin: 0; - } - ul.header { - background-color: #111; - padding: 0; - } - ul.header li a { - color: #FFF; - font-weight: bold; - text-decoration: none; - padding: 20px; - display: inline-block; - } - .content { - background-color: #FFF; - padding: 20px; - } - .content h2 { - padding: 0; - margin: 0; - } - .content li { - margin-bottom: 10px; - } - .active { - background-color: #0099FF; - } - \ No newline at end of file diff --git a/exercises/12_reactjs/spa/src/index.js b/exercises/12_reactjs/spa/src/index.js deleted file mode 100644 index be77b27..0000000 --- a/exercises/12_reactjs/spa/src/index.js +++ /dev/null @@ -1,7 +0,0 @@ - -import React from "react" -import ReactDOM from "react-dom" -import Main from "./Main" -import "./index.css" - -ReactDOM.render(
, document.getElementById("root"))