Skip to content

Commit eca0d75

Browse files
author
programmiri
committed
Add exercise ETL with solution for it
1 parent f5f2f3b commit eca0d75

File tree

7 files changed

+4463
-0
lines changed

7 files changed

+4463
-0
lines changed

etl/.eslintrc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"root": true,
3+
"parser": "babel-eslint",
4+
"parserOptions": {
5+
"ecmaVersion": 7,
6+
"sourceType": "module"
7+
},
8+
"env": {
9+
"es6": true,
10+
"node": true,
11+
"jest": true
12+
},
13+
"extends": [
14+
"eslint:recommended",
15+
"plugin:import/errors",
16+
"plugin:import/warnings"
17+
],
18+
"rules": {
19+
"linebreak-style": "off",
20+
21+
"import/extensions": "off",
22+
"import/no-default-export": "off",
23+
"import/no-unresolved": "off",
24+
"import/prefer-default-export": "off"
25+
}
26+
}

etl/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# ETL
2+
3+
We are going to do the `Transform` step of an Extract-Transform-Load.
4+
5+
### ETL
6+
7+
Extract-Transform-Load (ETL) is a fancy way of saying, "We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so
8+
we're going to migrate this."
9+
10+
(Typically, this is followed by, "We're only going to need to run this
11+
once." That's then typically followed by much forehead slapping and
12+
moaning about how stupid we could possibly be.)
13+
14+
### The goal
15+
16+
We're going to extract some scrabble scores from a legacy system.
17+
18+
The old system stored a list of letters per score:
19+
20+
- 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T",
21+
- 2 points: "D", "G",
22+
- 3 points: "B", "C", "M", "P",
23+
- 4 points: "F", "H", "V", "W", "Y",
24+
- 5 points: "K",
25+
- 8 points: "J", "X",
26+
- 10 points: "Q", "Z",
27+
28+
The shiny new scrabble system instead stores the score per letter, which
29+
makes it much faster and easier to calculate the score for a word. It
30+
also stores the letters in lower-case regardless of the case of the
31+
input letters:
32+
33+
- "a" is worth 1 point.
34+
- "b" is worth 3 points.
35+
- "c" is worth 3 points.
36+
- "d" is worth 2 points.
37+
- Etc.
38+
39+
Your mission, should you choose to accept it, is to transform the legacy data
40+
format to the shiny new format.
41+
42+
### Notes
43+
44+
A final note about scoring, Scrabble is played around the world in a
45+
variety of languages, each with its own unique scoring table. For
46+
example, an "E" is scored at 2 in the Māori-language version of the
47+
game while being scored at 4 in the Hawaiian-language version.
48+
49+
## Setup
50+
51+
Go through the setup instructions for Javascript to install the necessary
52+
dependencies:
53+
54+
[https://exercism.io/tracks/javascript/installation](https://exercism.io/tracks/javascript/installation)
55+
56+
## Requirements
57+
58+
Install assignment dependencies:
59+
60+
```bash
61+
$ npm install
62+
```
63+
64+
## Making the test suite pass
65+
66+
Execute the tests with:
67+
68+
```bash
69+
$ npm test
70+
```
71+
72+
In the test suites all tests but the first have been skipped.
73+
74+
Once you get a test passing, you can enable the next one by changing `xtest` to
75+
`test`.
76+
77+
## Source
78+
79+
The Jumpstart Lab team [http://jumpstartlab.com](http://jumpstartlab.com)
80+
81+
## Submitting Incomplete Solutions
82+
83+
It's possible to submit an incomplete solution so you can see how others have
84+
completed the exercise.

etl/babel.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
presets: [
3+
[
4+
'@babel/env',
5+
{
6+
targets: {
7+
node: 'current',
8+
},
9+
useBuiltIns: false,
10+
},
11+
12+
],
13+
],
14+
};

etl/etl.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const transform = (oldMap) => {
2+
return Object.keys(oldMap).reduce((acc, curr) => {
3+
oldMap[curr].forEach((letter) => {
4+
acc[letter.toLowerCase()] = Number(curr);
5+
});
6+
return acc;
7+
}, {});
8+
};

etl/etl.spec.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { transform } from './etl';
2+
3+
describe('Transform', () => {
4+
test('transforms one value', () => {
5+
const old = { 1: ['A'] };
6+
const expected = { a: 1 };
7+
8+
expect(transform(old)).toEqual(expected);
9+
});
10+
11+
test('transforms more values', () => {
12+
const old = { 1: ['A', 'E', 'I', 'O', 'U'] };
13+
const expected = {
14+
a: 1,
15+
e: 1,
16+
i: 1,
17+
o: 1,
18+
u: 1,
19+
};
20+
21+
expect(transform(old)).toEqual(expected);
22+
});
23+
24+
test('transforms more keys', () => {
25+
const old = { 1: ['A', 'E'], 2: ['D', 'G'] };
26+
const expected = {
27+
a: 1,
28+
e: 1,
29+
d: 2,
30+
g: 2,
31+
};
32+
33+
expect(transform(old)).toEqual(expected);
34+
});
35+
36+
test('transforms a full dataset', () => {
37+
const old = {
38+
1: ['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'],
39+
2: ['D', 'G'],
40+
3: ['B', 'C', 'M', 'P'],
41+
4: ['F', 'H', 'V', 'W', 'Y'],
42+
5: ['K'],
43+
8: ['J', 'X'],
44+
10: ['Q', 'Z'],
45+
};
46+
const expected = {
47+
a: 1,
48+
b: 3,
49+
c: 3,
50+
d: 2,
51+
e: 1,
52+
f: 4,
53+
g: 2,
54+
h: 4,
55+
i: 1,
56+
j: 8,
57+
k: 5,
58+
l: 1,
59+
m: 3,
60+
n: 1,
61+
o: 1,
62+
p: 3,
63+
q: 10,
64+
r: 1,
65+
s: 1,
66+
t: 1,
67+
u: 1,
68+
v: 4,
69+
w: 4,
70+
x: 8,
71+
y: 4,
72+
z: 10,
73+
};
74+
75+
expect(transform(old)).toEqual(expected);
76+
});
77+
});

etl/package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "exercism-javascript",
3+
"description": "Exercism exercises in Javascript.",
4+
"author": "Katrina Owen",
5+
"private": true,
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/exercism/javascript"
9+
},
10+
"devDependencies": {
11+
"@babel/cli": "^7.5.5",
12+
"@babel/core": "^7.5.5",
13+
"@babel/preset-env": "^7.5.5",
14+
"@types/jest": "^24.0.16",
15+
"@types/node": "^12.6.8",
16+
"babel-eslint": "^10.0.2",
17+
"babel-jest": "^24.8.0",
18+
"eslint": "^6.1.0",
19+
"eslint-plugin-import": "^2.18.2",
20+
"jest": "^24.8.0"
21+
},
22+
"jest": {
23+
"modulePathIgnorePatterns": [
24+
"package.json"
25+
]
26+
},
27+
"scripts": {
28+
"test": "jest --no-cache ./*",
29+
"watch": "jest --no-cache --watch ./*",
30+
"lint": "eslint .",
31+
"lint-test": "eslint . && jest --no-cache ./* "
32+
},
33+
"license": "MIT",
34+
"dependencies": {}
35+
}

0 commit comments

Comments
 (0)