-
Notifications
You must be signed in to change notification settings - Fork 519
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ (concepts) Add new concept exercise
phone-number-analysis
This is inspired by the same in csharp track. Provides a gentle introduction to tuples.
- Loading branch information
Showing
11 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- [Tuples][tuples]: shows how to define and use tuples. | ||
|
||
## 1. Analyze a phone number | ||
|
||
- Make sure the tuple has values at the right place. | ||
- Tuples are passed as a [return value][tuples-return]. | ||
|
||
- Use `.split_at()` method on a string to split it and get a tuple of its parts. | ||
```rust | ||
let str = "Per Martin-Löf"; | ||
|
||
let (first, last) = str.split_at(3); | ||
|
||
first // => "Per" | ||
last // => " Martin-Löf" | ||
``` | ||
|
||
## 2. Detect if a phone number is fake prefix code (555) | ||
|
||
- You can extract the value of a field with the same sort of dot syntax as you employ with `struct`s or `class`s. | ||
|
||
[tuples]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type | ||
[tuples-return]: https://docs.microsoft.com/en-us/dotnet/csharp/tuples#tuples-as-method-return-values |
32 changes: 32 additions & 0 deletions
32
exercises/concept/phone-number-analysis/.docs/instructions.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Instructions | ||
|
||
This exercise has you analyze phone numbers. | ||
|
||
You are asked to implement 2 features. | ||
|
||
Phone numbers passed to the routines are guaranteed to be in the form | ||
NNN-NNN-NNNN e.g. 212-515-9876. | ||
|
||
## 1. Analyze a phone number | ||
|
||
Your analysis should return 3 pieces of data | ||
|
||
1. An indication of whether the number has a New York dialing code ie. 212 as the first 3 digits | ||
2. An indication of whether the number is fake having 555 as a prefix code in positions 5 to 7 (numbering from 1) | ||
3. The last 4 digits of the number. | ||
|
||
Implement the function `analyze()` to produce the phone number info. | ||
|
||
```rust | ||
analyze("631-555-1234"); | ||
// => (false, true, "1234") | ||
``` | ||
|
||
## 2. Detect if a phone number has a fake prefix code (555) | ||
|
||
Implement the function `is_fake()` to detect whether the phone number is fake using the phone number info produced in task 1. | ||
|
||
```rust | ||
is_fake(analyze("631-555-1234")); | ||
// => true | ||
``` |
114 changes: 114 additions & 0 deletions
114
exercises/concept/phone-number-analysis/.docs/introduction.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Introduction | ||
|
||
## Tuples | ||
|
||
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. | ||
|
||
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: | ||
|
||
```rust | ||
let my_tuple: (i32, f64, u8) = (500, 6.4, 1); | ||
``` | ||
|
||
The variable `my_tuple` binds to the entire tuple because a tuple is considered | ||
a single compound element. | ||
To get the individual values out of a tuple, we can use pattern matching to | ||
destructure a tuple value, like this: | ||
|
||
```rust | ||
let (x, y, z) = my_tuple; | ||
|
||
println!("{}", y); | ||
// => 6.4 | ||
|
||
``` | ||
|
||
This program first creates a tuple and binds it to the variable `my_tuple`. | ||
It then uses a pattern with let to take `my_tuple` and turn it into three separate variables, `x`, `y`, and `z`. | ||
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`. | ||
|
||
Sometimes, when _destructuring_ a tuple, some values might not be important or | ||
needed, these can be discarded by labeling them with "`_`" (underscore). | ||
|
||
```rust | ||
let (_, y, _) = my_tuple; | ||
|
||
println!("{}", y); | ||
// => 6.4 | ||
|
||
``` | ||
|
||
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: | ||
|
||
```rust | ||
let my_tuple: (i32, f64, u8) = (500, 6.4, 1); | ||
|
||
let five_hundred = my_tuple.0; | ||
|
||
let six_point_four = my_tuple.1; | ||
|
||
let one = my_tuple.2; | ||
``` | ||
|
||
This program creates the tuple `my_tuple` and then accesses each of its elements using their respective indices. | ||
As with most programming languages, the first index in a tuple is 0. | ||
|
||
A tuple can contain 0, or upto 12 elements. A tuple with zero elements has a | ||
special name, _unit_. | ||
|
||
```rust | ||
let my_zero_tuple = (); | ||
let my_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); | ||
``` | ||
|
||
### Calling methods | ||
One can call any methods on a value held by a tuple by either first destructuring that value out of the tuple or accessing it using it's index. | ||
|
||
```rust | ||
let my_tuple = (12, "hello"); | ||
|
||
let (my_num, my_str) = my_tuple; | ||
|
||
my_str.to_uppercase(); | ||
|
||
// OR | ||
|
||
my_tuple.1.to_uppercase(); | ||
``` | ||
|
||
### Functions can accept a tuple as a parameter. | ||
Accepting a tuple as a parameter requires to explicitly define its type. The | ||
following example illustrates that. | ||
|
||
```rust | ||
fn my_function(my_tuple: (i32, &str)) { | ||
// Do something with my_tuple | ||
} | ||
``` | ||
|
||
### Functions can return tuple as a result. | ||
Returning a tuple as a result requires to explicitly define its type. The | ||
following example illustrates that. | ||
|
||
```rust | ||
fn make_tuple(an_int: i32, a_string: &str) -> (i32, &str) { | ||
return (an_int, a_string); | ||
} | ||
``` | ||
|
||
### Methods can return tuple as a result. | ||
Methods on various types sometimes return a tuple as a result. Consider the | ||
following example of a `&str` variable's `.split_at()` method. | ||
|
||
```rust | ||
let str = "Per Martin-Löf"; | ||
|
||
let (first, last) = str.split_at(3); | ||
|
||
first // => "Per" | ||
last // => " Martin-Löf" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
/target/ | ||
**/*.rs.bk | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"authors": [ | ||
"devkabiir" | ||
], | ||
"files": { | ||
"solution": [ | ||
"src/lib.rs", | ||
"Cargo.toml" | ||
], | ||
"test": [ | ||
"tests/phone-number-analysis.rs" | ||
], | ||
"exemplar": [ | ||
".meta/exemplar.rs" | ||
] | ||
}, | ||
"blurb": "Learn about tuples by analysing phone numbers." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Design | ||
|
||
## Learning objectives | ||
|
||
- Know of the existence of tuples. | ||
- Know how to assigne a tuple. | ||
- Know how to access a value held by a tuple. | ||
- Know how to return a tuple as a result. | ||
- Know how to destructure tuple values into variables. | ||
- Know how to accept a tuple as a parameter. | ||
|
||
## Out of scope | ||
|
||
|
||
## Concepts | ||
|
||
- `tuples` | ||
|
||
## Prerequisites | ||
|
||
- `strings` | ||
- `if-statements` | ||
- `booleans` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
pub fn analyze(phone_number: &str) -> (bool, bool, &str) { | ||
let (dial_code, number) = phone_number.split_at(3); | ||
|
||
let (prefix_code, last_4_with_dash) = number.split_at(4); | ||
|
||
let (_, last_4) = last_4_with_dash.split_at(1); | ||
|
||
(dial_code == "212", prefix_code == "-555", last_4) | ||
} | ||
|
||
pub fn is_fake(info: (bool, bool, &str)) -> bool { | ||
info.1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[package] | ||
name = "phone_number_analysis" | ||
version = "0.1.0" | ||
edition = "2021" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
pub fn analyze(_phone_number: &str) -> (bool, bool, &str) { | ||
unimplemented!("Implement analyze") | ||
} | ||
|
||
pub fn is_fake(_info: (bool, bool, &str)) -> bool { | ||
unimplemented!("Implement is_fake") | ||
} |
59 changes: 59 additions & 0 deletions
59
exercises/concept/phone-number-analysis/tests/phone-number-analysis.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#[test] | ||
pub fn analyze_non_fake_non_newyork() { | ||
assert_eq!( | ||
(false, false, "1234"), | ||
phone_number_analysis::analyze("631-502-1234") | ||
); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn analyze_fake_non_newyork() { | ||
assert_eq!( | ||
(false, true, "1234"), | ||
phone_number_analysis::analyze("631-555-1234") | ||
); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn analyze_non_fake_newyork() { | ||
assert_eq!( | ||
(true, false, "1234"), | ||
phone_number_analysis::analyze("212-502-1234") | ||
); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn analyze_fake_newyork() { | ||
assert_eq!( | ||
(true, true, "1234"), | ||
phone_number_analysis::analyze("212-555-1234") | ||
); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn analyze_fake_fake() { | ||
assert_eq!( | ||
(false, false, "1234"), | ||
phone_number_analysis::analyze("515-212-1234") | ||
); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn is_fake_fake() { | ||
assert!(phone_number_analysis::is_fake( | ||
phone_number_analysis::analyze("212-555-1234") | ||
)); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
pub fn is_fake_non_fake() { | ||
assert!(!phone_number_analysis::is_fake( | ||
phone_number_analysis::analyze("555-212-1234") | ||
)); | ||
} |