Skip to content

Commit c39eaa8

Browse files
committed
✨ (concepts) Add new concept exercise phone-number-analysis
This is inspired by the same in csharp track. Provides a gentle introduction to tuples.
1 parent 796f2ca commit c39eaa8

File tree

11 files changed

+297
-0
lines changed

11 files changed

+297
-0
lines changed

config.json

+13
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@
3535
},
3636
"exercises": {
3737
"concept": [
38+
{
39+
"slug": "phone-number-analysis",
40+
"uuid": "eabea697-cc15-472f-ab4e-5b2720a180d1",
41+
"name": "Phone Number Analysis",
42+
"concepts": [
43+
"tuples"
44+
],
45+
"prerequisites": [
46+
"strings",
47+
"booleans"
48+
],
49+
"status": "wip"
50+
},
3851
{
3952
"slug": "lucians-luscious-lasagna",
4053
"uuid": "29a2d3bd-eec8-454d-9dba-4b2d7d071925",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Hints
2+
3+
## General
4+
5+
- [Tuples][tuples]: shows how to define and use tuples.
6+
7+
## 1. Analyze a phone number
8+
9+
- Make sure the tuple has values at the right place.
10+
- Tuples are passed as a [return value][tuples-return].
11+
12+
- Use `.split_at()` method on a string to split it and get a tuple of its parts.
13+
```rust
14+
let str = "Per Martin-Löf";
15+
16+
let (first, last) = str.split_at(3);
17+
18+
first // => "Per"
19+
last // => " Martin-Löf"
20+
```
21+
22+
## 2. Detect if a phone number is fake prefix code (555)
23+
24+
- You can extract the value of a field with the same sort of dot syntax as you employ with `struct`s or `class`s.
25+
26+
[tuples]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type
27+
[tuples-return]: https://docs.microsoft.com/en-us/dotnet/csharp/tuples#tuples-as-method-return-values
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Instructions
2+
3+
This exercise has you analyze phone numbers.
4+
5+
You are asked to implement 2 features.
6+
7+
Phone numbers passed to the routines are guaranteed to be in the form
8+
NNN-NNN-NNNN e.g. 212-515-9876.
9+
10+
## 1. Analyze a phone number
11+
12+
Your analysis should return 3 pieces of data
13+
14+
1. An indication of whether the number has a New York dialing code ie. 212 as the first 3 digits
15+
2. An indication of whether the number is fake having 555 as a prefix code in positions 5 to 7 (numbering from 1)
16+
3. The last 4 digits of the number.
17+
18+
Implement the function `analyze()` to produce the phone number info.
19+
20+
```rust
21+
analyze("631-555-1234");
22+
// => (false, true, "1234")
23+
```
24+
25+
## 2. Detect if a phone number has a fake prefix code (555)
26+
27+
Implement the function `is_fake()` to detect whether the phone number is fake using the phone number info produced in task 1.
28+
29+
```rust
30+
is_fake(analyze("631-555-1234"));
31+
// => true
32+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Introduction
2+
3+
## Tuples
4+
5+
A _tuple_ is a general way of grouping together a number of values with a variety of types into one compound type. Tuples have a fixed length: once declared, they cannot grow or shrink in size.
6+
7+
We create a tuple by writing a comma-separated list of values inside parentheses. Each position in the tuple has a type, and the types of the different values in the tuple don’t have to be the same. We’ve added optional type annotations in this example:
8+
```rust
9+
let my_tuple: (i32, f64, u8) = (500, 6.4, 1);
10+
```
11+
12+
The variable `my_tuple` binds to the entire tuple because a tuple is considered
13+
a single compound element.
14+
To get the individual values out of a tuple, we can use pattern matching to
15+
destructure a tuple value, like this:
16+
```rust
17+
let (x, y, z) = my_tuple;
18+
```
19+
20+
This program first creates a tuple and binds it to the variable tup. It then
21+
uses a pattern with let to take tup and turn it into three separate variables,
22+
x, y, and z.
23+
This is called _destructuring_ because it breaks the single tuple into three parts. Finally, the program prints the value of y, which is 6.4.
24+
25+
We can also access a tuple element directly by using a period (.) followed by the index of the value we want to access. For example:
26+
```rust
27+
let my_tuple: (i32, f64, u8) = (500, 6.4, 1);
28+
29+
let five_hundred = my_tuple.0;
30+
31+
let six_point_four = my_tuple.1;
32+
33+
let one = my_tuple.2;
34+
```
35+
36+
This program creates the tuple x and then accesses each element of the tuple
37+
using their respective indices. As with most programming languages, the first
38+
index in a tuple is 0.
39+
40+
A tuple can contain 0, or upto 12 elements. A tuple with zero elements has a
41+
special name, _unit_.
42+
```rust
43+
let my_zero_tuple = ();
44+
let my_tuple = (1,2,3,4,5,6,7,8,9,10,11,12)
45+
```
46+
47+
48+
49+
### Calling methods
50+
One can call any methods on a value held by a tuple by either first
51+
destructuring that value out of the tuple or accessing it using it's index.
52+
```rust
53+
let my_tuple = (12, "hello");
54+
55+
let (my_num, my_str) = my_tuple;
56+
57+
my_str.to_uppercase();
58+
59+
// OR
60+
61+
my_tuple.1.to_uppercase();
62+
```
63+
64+
### Functions can accept a tuple as a parameter.
65+
Accepting a tuple as a parameter requires to explicitly define its type. The
66+
following example illustrates that.
67+
```rust
68+
fn my_function(my_tuple: (i32, &str)) {
69+
// Do something with my_tuple
70+
}
71+
```
72+
73+
### Functions can return tuple as a result.
74+
Returning a tuple as a result requires to explicitly define its type. The
75+
following example illustrates that.
76+
```rust
77+
fn make_tuple(an_int: i32, a_string: &str) -> (i32, &str) {
78+
return (an_int, a_string);
79+
}
80+
```
81+
82+
### Methods can return tuple as a result.
83+
Methods on various types sometimes return a tuple as a result. Consider the
84+
following example of a `&str` variable's `.split_at()` method.
85+
86+
```rust
87+
let str = "Per Martin-Löf";
88+
89+
let (first, last) = str.split_at(3);
90+
91+
first // => "Per"
92+
last // => " Martin-Löf"
93+
```
Original file line numberDiff line numberDiff line change
@@ -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
8+
Cargo.lock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"devkabiir"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/lib.rs",
8+
"Cargo.toml"
9+
],
10+
"test": [
11+
"tests/phone-number-analysis.rs"
12+
],
13+
"exemplar": [
14+
".meta/exemplar.rs"
15+
]
16+
},
17+
"blurb": "Learn about tuples by analysing phone numbers."
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Design
2+
3+
## Learning objectives
4+
5+
- Know of the existence of tuples.
6+
- Know how to assigne a tuple.
7+
- Know how to access a value held by a tuple.
8+
- Know how to return a tuple as a result.
9+
- Know how to destructure tuple values into variables.
10+
- Know how to accept a tuple as a parameter.
11+
12+
## Out of scope
13+
14+
15+
## Concepts
16+
17+
- `tuples`
18+
19+
## Prerequisites
20+
21+
- `strings`
22+
- `if-statements`
23+
- `booleans`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
pub fn analyze(phone_number: &str) -> (bool, bool, &str) {
2+
let (dial_code, number) = phone_number.split_at(3);
3+
4+
let (prefix_code, last_4_with_dash) = number.split_at(4);
5+
6+
let last_4 = last_4_with_dash.split_at(1).1;
7+
8+
return (dial_code == "212", prefix_code == "-555", last_4);
9+
}
10+
11+
pub fn is_fake(info: (bool, bool, &str)) -> bool {
12+
return info.1;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "phone_number_analysis"
3+
version = "0.1.0"
4+
edition = "2021"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub fn analyze(_phone_number: &str) -> (bool, bool, &str) {
2+
unimplemented!("Implement analyze")
3+
}
4+
5+
pub fn is_fake(_info: (bool, bool, &str)) -> bool {
6+
unimplemented!("Implement is_fake")
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#[test]
2+
pub fn analyze_non_fake_non_newyork() {
3+
assert_eq!(
4+
(false, false, "1234"),
5+
phone_number_analysis::analyze("631-502-1234")
6+
);
7+
}
8+
9+
#[test]
10+
#[ignore]
11+
pub fn analyze_fake_non_newyork() {
12+
assert_eq!(
13+
(false, true, "1234"),
14+
phone_number_analysis::analyze("631-555-1234")
15+
);
16+
}
17+
18+
#[test]
19+
#[ignore]
20+
pub fn analyze_non_fake_newyork() {
21+
assert_eq!(
22+
(true, false, "1234"),
23+
phone_number_analysis::analyze("212-502-1234")
24+
);
25+
}
26+
27+
#[test]
28+
#[ignore]
29+
pub fn analyze_fake_newyork() {
30+
assert_eq!(
31+
(true, true, "1234"),
32+
phone_number_analysis::analyze("212-555-1234")
33+
);
34+
}
35+
36+
#[test]
37+
#[ignore]
38+
pub fn analyze_fake_fake() {
39+
assert_eq!(
40+
(false, false, "1234"),
41+
phone_number_analysis::analyze("515-212-1234")
42+
);
43+
}
44+
45+
#[test]
46+
#[ignore]
47+
pub fn is_fake_fake() {
48+
assert!(phone_number_analysis::is_fake(
49+
phone_number_analysis::analyze("212-555-1234")
50+
));
51+
}
52+
53+
#[test]
54+
#[ignore]
55+
pub fn is_fake_non_fake() {
56+
assert!(!phone_number_analysis::is_fake(
57+
phone_number_analysis::analyze("555-212-1234")
58+
));
59+
}

0 commit comments

Comments
 (0)