aboutsummaryrefslogtreecommitdiff
path: root/rust/etl
diff options
context:
space:
mode:
authorFederico Igne <git@federicoigne.com>2020-12-28 09:42:59 +0000
committerFederico Igne <git@federicoigne.com>2021-11-03 18:55:08 +0000
commit11fd2671d7021f0672a89f9ea20ec42643e693bf (patch)
tree8b7efa3bfa55c3a99bff2435e849b587e1f65605 /rust/etl
parent8351828eadc332fe34ffd609a4aae96fe0511e78 (diff)
downloadexercism-11fd2671d7021f0672a89f9ea20ec42643e693bf.tar.gz
exercism-11fd2671d7021f0672a89f9ea20ec42643e693bf.zip
[rust] ETL
Diffstat (limited to 'rust/etl')
-rw-r--r--rust/etl/.exercism/metadata.json1
-rw-r--r--rust/etl/.gitignore8
-rw-r--r--rust/etl/Cargo.toml4
-rw-r--r--rust/etl/README.md127
-rw-r--r--rust/etl/src/lib.rs7
-rw-r--r--rust/etl/tests/etl.rs80
6 files changed, 227 insertions, 0 deletions
diff --git a/rust/etl/.exercism/metadata.json b/rust/etl/.exercism/metadata.json
new file mode 100644
index 0000000..88b070e
--- /dev/null
+++ b/rust/etl/.exercism/metadata.json
@@ -0,0 +1 @@
{"track":"rust","exercise":"etl","id":"c78c2dc057e14376b48708b6e603c67d","url":"https://exercism.io/my/solutions/c78c2dc057e14376b48708b6e603c67d","handle":"dyamon","is_requester":true,"auto_approve":false} \ No newline at end of file
diff --git a/rust/etl/.gitignore b/rust/etl/.gitignore
new file mode 100644
index 0000000..db7f315
--- /dev/null
+++ b/rust/etl/.gitignore
@@ -0,0 +1,8 @@
1# Generated by Cargo
2# will have compiled files and executables
3/target/
4**/*.rs.bk
5
6# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
8Cargo.lock
diff --git a/rust/etl/Cargo.toml b/rust/etl/Cargo.toml
new file mode 100644
index 0000000..e94ff4d
--- /dev/null
+++ b/rust/etl/Cargo.toml
@@ -0,0 +1,4 @@
1[package]
2edition = "2018"
3name = "etl"
4version = "1.0.0"
diff --git a/rust/etl/README.md b/rust/etl/README.md
new file mode 100644
index 0000000..6480d7c
--- /dev/null
+++ b/rust/etl/README.md
@@ -0,0 +1,127 @@
1# ETL
2
3We are going to do the `Transform` step of an Extract-Transform-Load.
4
5### ETL
6
7Extract-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
8we're going to migrate this."
9
10(Typically, this is followed by, "We're only going to need to run this
11once." That's then typically followed by much forehead slapping and
12moaning about how stupid we could possibly be.)
13
14### The goal
15
16We're going to extract some Scrabble scores from a legacy system.
17
18The 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
28The shiny new Scrabble system instead stores the score per letter, which
29makes it much faster and easier to calculate the score for a word. It
30also stores the letters in lower-case regardless of the case of the
31input 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
39Your mission, should you choose to accept it, is to transform the legacy data
40format to the shiny new format.
41
42### Notes
43
44A final note about scoring, Scrabble is played around the world in a
45variety of languages, each with its own unique scoring table. For
46example, an "E" is scored at 2 in the Māori-language version of the
47game while being scored at 4 in the Hawaiian-language version.
48
49## Rust Installation
50
51Refer to the [exercism help page][help-page] for Rust installation and learning
52resources.
53
54## Writing the Code
55
56Execute the tests with:
57
58```bash
59$ cargo test
60```
61
62All but the first test have been ignored. After you get the first test to
63pass, open the tests source file which is located in the `tests` directory
64and remove the `#[ignore]` flag from the next test and get the tests to pass
65again. Each separate test is a function with `#[test]` flag above it.
66Continue, until you pass every test.
67
68If you wish to run all ignored tests without editing the tests source file, use:
69
70```bash
71$ cargo test -- --ignored
72```
73
74To run a specific test, for example `some_test`, you can use:
75
76```bash
77$ cargo test some_test
78```
79
80If the specific test is ignored use:
81
82```bash
83$ cargo test some_test -- --ignored
84```
85
86To learn more about Rust tests refer to the [online test documentation][rust-tests]
87
88Make sure to read the [Modules][modules] chapter if you
89haven't already, it will help you with organizing your files.
90
91## Further improvements
92
93After you have solved the exercise, please consider using the additional utilities, described in the [installation guide](https://exercism.io/tracks/rust/installation), to further refine your final solution.
94
95To format your solution, inside the solution directory use
96
97```bash
98cargo fmt
99```
100
101To see, if your solution contains some common ineffective use cases, inside the solution directory use
102
103```bash
104cargo clippy --all-targets
105```
106
107## Submitting the solution
108
109Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer.
110
111## Feedback, Issues, Pull Requests
112
113The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
114
115If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
116
117[help-page]: https://exercism.io/tracks/rust/learning
118[modules]: https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
119[cargo]: https://doc.rust-lang.org/book/ch14-00-more-about-cargo.html
120[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
121
122## Source
123
124The Jumpstart Lab team [http://jumpstartlab.com](http://jumpstartlab.com)
125
126## Submitting Incomplete Solutions
127It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/rust/etl/src/lib.rs b/rust/etl/src/lib.rs
new file mode 100644
index 0000000..dd0752c
--- /dev/null
+++ b/rust/etl/src/lib.rs
@@ -0,0 +1,7 @@
1use std::collections::BTreeMap;
2
3pub fn transform(h: &BTreeMap<i32, Vec<char>>) -> BTreeMap<char, i32> {
4 h.iter()
5 .flat_map(|(k, v)| v.iter().map(move |x| (x.to_ascii_lowercase(), *k)))
6 .collect()
7}
diff --git a/rust/etl/tests/etl.rs b/rust/etl/tests/etl.rs
new file mode 100644
index 0000000..e8e1e01
--- /dev/null
+++ b/rust/etl/tests/etl.rs
@@ -0,0 +1,80 @@
1use std::collections::BTreeMap;
2
3#[test]
4fn test_transform_one_value() {
5 let input = input_from(&[(1, vec!['A'])]);
6
7 let expected = expected_from(&[('a', 1)]);
8
9 assert_eq!(expected, etl::transform(&input));
10}
11
12#[test]
13fn test_transform_more_values() {
14 let input = input_from(&[(1, vec!['A', 'E', 'I', 'O', 'U'])]);
15
16 let expected = expected_from(&[('a', 1), ('e', 1), ('i', 1), ('o', 1), ('u', 1)]);
17
18 assert_eq!(expected, etl::transform(&input));
19}
20
21#[test]
22fn test_more_keys() {
23 let input = input_from(&[(1, vec!['A', 'E']), (2, vec!['D', 'G'])]);
24
25 let expected = expected_from(&[('a', 1), ('e', 1), ('d', 2), ('g', 2)]);
26
27 assert_eq!(expected, etl::transform(&input));
28}
29
30#[test]
31fn test_full_dataset() {
32 let input = input_from(&[
33 (1, vec!['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T']),
34 (2, vec!['D', 'G']),
35 (3, vec!['B', 'C', 'M', 'P']),
36 (4, vec!['F', 'H', 'V', 'W', 'Y']),
37 (5, vec!['K']),
38 (8, vec!['J', 'X']),
39 (10, vec!['Q', 'Z']),
40 ]);
41
42 let expected = expected_from(&[
43 ('a', 1),
44 ('b', 3),
45 ('c', 3),
46 ('d', 2),
47 ('e', 1),
48 ('f', 4),
49 ('g', 2),
50 ('h', 4),
51 ('i', 1),
52 ('j', 8),
53 ('k', 5),
54 ('l', 1),
55 ('m', 3),
56 ('n', 1),
57 ('o', 1),
58 ('p', 3),
59 ('q', 10),
60 ('r', 1),
61 ('s', 1),
62 ('t', 1),
63 ('u', 1),
64 ('v', 4),
65 ('w', 4),
66 ('x', 8),
67 ('y', 4),
68 ('z', 10),
69 ]);
70
71 assert_eq!(expected, etl::transform(&input));
72}
73
74fn input_from(v: &[(i32, Vec<char>)]) -> BTreeMap<i32, Vec<char>> {
75 v.iter().cloned().collect()
76}
77
78fn expected_from(v: &[(char, i32)]) -> BTreeMap<char, i32> {
79 v.iter().cloned().collect()
80}