Browse Source

1st pass on quest 4 subjects

content-update
Chris 3 years ago
parent
commit
9e4e30b087
  1. 76
      subjects/banner/README.md
  2. 95
      subjects/boxing_todo/README.md
  3. 27
      subjects/cipher/README.md
  4. 28
      subjects/error_types/README.md
  5. 29
      subjects/handling/README.md
  6. 62
      subjects/profanity_filter/README.md
  7. 32
      subjects/question_mark/README.md

76
subjects/banner/README.md

@ -2,17 +2,16 @@
### Instructions
`Result` is a better version of the `Option` type that describes possible error instead
of possible absence
"`Result` is a better version of the `Option` type that describes possible `error` instead of possible `absence`".
Create a structure called `Flag` that as the following elements:
Create a structure called `Flag` which has the following elements:
- short_hand: String
- long_hand: String
- desc: String
- short_hand: `String`
- long_hand: `String`
- desc: `String`
This structure must have associated to it a function called `opt_flag` that initializes the structure.
Receiving two references strings and returns the structure `Flag`. It should be used like this:
This structure must have a **function** called `opt_flag` which initializes the structure.
This **function** receives two strings references and returns a structure `Flag`. Here is an example of its usage:
```rust
let d = Flag::opt_flag("diff", "gives the difference between two numbers");
@ -21,26 +20,40 @@ Receiving two references strings and returns the structure `Flag`. It should be
// output: "short hand: -d, long hand: --diff, description: gives the difference between two numbers"
```
It will be given a second structure called `FlagsHandler` that has just one element: `flags: HashMap<(String, String), Callback>`
And the following functions associated to it, for you to complete :
A second structure called `FlagsHandler` will be given which just has one element: `flags: HashMap<(String, String), Callback>`
The following **functions** (methods) associated with `FlagsHandler` are for you to complete :
- `add_flag`, that adds to the HashMap the flag and the Callback function.
- `exec_func`, that executes the function using the flag provided and returns the result, that can
be either a string with the value from the callback or an error.
- `add_flag`, which adds to the HashMap the flag and the Callback function.
- `exec_func`, which executes the function using the flag provided and returns the result, which can be either a string with the value from the callback or an error.
It will also be provided a `type` called `Callback` being a function that is going to be used in the structure
A `type` called `Callback` will also be provided. It is a function which is going to be used in the structure
and functions above. This function will be the callback for the flag associated to it.
You will have to create the following callback functions :
- `div`, that converts the reference strings to `float`s and returns the `Result`, being the division of the `float`s or the standard (std) error: `ParseFloatError`.
- `rem`, that converts the reference strings to `float`s and returns the `Result`, being the remainder of the division of the `float`s or the standard (std) error `ParseFloatError`.
- `div` which converts the reference strings to `float`s and returns the `Result`, being the division of the `float`s or the standard (std) error: `ParseFloatError`.
- `rem` which converts the reference strings to `float`s and returns the `Result`, being the remainder of the division of the `float`s or the standard (std) error `ParseFloatError`.
### Notions
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
- [Method optflag](https://docs.rs/getopts/0.2.18/getopts/struct.Options.html#method.optflag)
### Expected Function
```rust
use std::collections::HashMap;
pub struct Flag {
// expected public fields
}
impl Flag {
pub fn opt_flag(l_h: &str, d: &str) -> Flag {
}
}
pub type Callback = fn(&str, &str) -> Result<String, ParseFloatError>;
pub struct FlagsHandler {
@ -48,29 +61,31 @@ pub struct FlagsHandler {
}
impl FlagsHandler {
pub fn add_flag(&mut self, flag: (String, String), func: Callback) {}
pub fn exec_func(&mut self, flag: (String, String), argv: &[&str]) -> String {}
pub fn add_flag(&mut self, flag: (String, String), func: Callback) {
}
}
pub fn exec_func(&mut self, flag: (String, String), argv: &[&str]) -> String {
pub struct Flag {
// expected public fields
}
}
impl Flag {
pub fn opt_flag(l_h: &str, d: &str) -> Flag {}
pub fn div(a: &str, b: &str) -> Result<String, ParseFloatError> {
}
pub fn rem(a: &str, b: &str) -> Result<String, ParseFloatError> {
pub fn div(a: &str, b: &str) -> Result<String, ParseFloatError> {}
pub fn rem(a: &str, b: &str) -> Result<String, ParseFloatError> {}
}
```
### Usage
Here is a program to test your function
Here is a program to test your function:
```rust
use banner::*;
use std::collections::HashMap;
fn main() {
let mut handler = FlagsHandler { flags: HashMap::new() };
@ -86,9 +101,9 @@ fn main() {
println!("{:?}", handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "2.0"]));
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "2.0"]));
println!("{:?}",handler.exec_func(("-d".to_string(), "--division".to_string()), &["a", "2.0"]));
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "fd"]));
}
```
@ -103,8 +118,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
"invalid float literal"
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/rust-by-example/error/result.html
- https://docs.rs/getopts/0.2.18/getopts/struct.Options.html#method.optflag

95
subjects/boxing_todo/README.md

@ -2,49 +2,62 @@
### Instructions
The objective is to do an api to parse a list of *todos* that is organized in a JSON file,
The objective is create an api to parse a list of _todos_ that is organized in a JSON file,
handling all possible errors in a multiple error system.
Organization of the JSON file:
```json
{
"title" : "TODO LIST FOR PISCINE RUST",
"tasks": [
{ "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 }
]
"title": "TODO LIST FOR PISCINE RUST",
"tasks": [
{ "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 }
]
}
```
Create a module in another file called **error.rs** that handles the boxing of errors.
This module must implement an `enum` called `ParseErr` that will take care of the
parsing errors, it must have the following elements:
#### Error.rs
Create a module in another file called **error.rs** which handles the boxing of errors.
This module must implement an `enum` called `ParseErr` which will take care of the
parsing errors. It must have the following elements:
- Empty
- Malformed, that has a dynamic boxed error as element
- Malformed, which has a dynamic boxed error as element
A structure called `ReadErr` that will take care of the reading errors, having just an element called `child_err` of type `Box<dyn Error>`.
A structure called `ReadErr` which will take care of the reading errors, having just an element called `child_err` of type `Box<dyn Error>`.
For each data structure you will have to implement a function called `fmt` for the trait `Display` that writes
out the message **"Fail to parse todo"** in case it's a parsing error, otherwise it writes the message
For each data structure you will have to implement a function called `fmt` for the trait `Display` which writes
out the message **"Failed to parse todo"** in case it is a parsing error. Otherwise, it should write the message
**"Failed to read todo file"**.
And for the `Error` trait the following functions:
For the `Error` trait the following functions (methods) have to be implemented:
- `description` which returns a string literal which says:
- `description` that returns a string literal that says:
- "Todo List parse failed: " for the `ParseErr`
- "Todo List read failed: " for the `ReadErr`.
- `cause` that returns an `Option` with the error:
- `cause` which returns an `Option` with the error:
- For the `ReadErr` it must just return the option with the error
- For the `ParseErr` it will return an option that can be `None` if the tasks are **empty** otherwise the error, if
the parsing is **malformed**.
- For the `ParseErr` it will return an option which can be `None` if the tasks are **empty** otherwise the error, if
the parsing is **malformed**.
#### lib.rs
In the **lib** file you will have to implement a function called `get_todo` that receives a string and returns a Result
that can be the structure `TodoList` or a boxing error. This function must be able to deserialize the json file,
basically it must parse and read the JSON file and return the `TodoList` if everything is fine otherwise the error.
In the **lib** file you will have to implement a **function** called `get_todo` which receives a string and returns a Result
which can be the structure `TodoList` or a boxing error. This **function** must be able to deserialize the json file.
Basically it must parse and read the JSON file and return the `TodoList` if everything is fine, otherwise it returns the error.
### Expected Function
### Notions
- [Module std::fmt](https://doc.rust-lang.org/std/fmt/)
- [Framework serde](https://serde.rs/)
- [Boxing errors](https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html)
- [Returning Traits wirh dyn](https://doc.rust-lang.org/stable/rust-by-example/trait/dyn.html)
### Expected Functions
For **error.rs**
@ -60,6 +73,7 @@ pub enum ParseErr {
// required by error trait
impl Display for ParseErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
@ -70,19 +84,27 @@ pub struct ReadErr {
// required by error trait
impl Display for ReadErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl Error for ReadErr {
fn description(&self) -> &str {}
fn cause(&self) -> Option<&dyn Error> {}
}
}
impl Error for ParseErr {
fn description(&self) -> &str {}
fn cause(&self) -> Option<&dyn Error> {}
fn description(&self) -> &str {
}
fn cause(&self) -> Option<&dyn Error> {
}
}
impl Error for ReadErr {
fn description(&self) -> &str {
}
fn cause(&self) -> Option<&dyn Error> {
}
}
```
for **lib.rs**
@ -90,8 +112,9 @@ for **lib.rs**
```rust
mod error;
use error::{ ParseErr, ReadErr };
use std::error::Error;
use serde::{ Deserialize, Serialize };
pub use std::error::Error;
pub use serde::{ Deserialize, Serialize };
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct Task {
@ -107,7 +130,9 @@ pub struct TodoList {
}
impl TodoList {
pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {}
pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {
}
}
```
@ -157,9 +182,3 @@ Todo List parse failed: None
Todo List parse failed: Malformed(Error("missing field `title`", line: 1, column: 2))
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://serde.rs/
- https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
- https://doc.rust-lang.org/stable/rust-by-example/trait/dyn.html

27
subjects/cipher/README.md

@ -2,15 +2,18 @@
### Instructions
The Atbash cipher is a encryption method in which each letter of a word is replaced with its mirror letter in the alphabet
The Atbash cipher is an encryption method in which each letter of a word is replaced by its mirror letter in the alphabet.
Your objective is to create a function called `cipher` this must return a Result wrapped in an Option, this result should return either a boolean
or an Error being the structure `CipherError`. This structure should be the error type for the function `cipher`
Your objective is to create a **function** called `cipher` which must return a `Result` wrapped in an `Option`, this result should return either a `boolean`
or an `Error` based on the structure `CipherError`. This structure should be the error type for the **function** `cipher`.
This function should compare the original string wih the ciphered string. returning true if the cipher is correct otherwise the error type
CipherErr with the a true or false if it is validated and the proper atbash cipher.
This function should compare the original `String` with the ciphered `String`. It should return `true` if the cipher is correct. If the cipher is incorrect it should return the error type `CipherErr` with a `boolean` and the expected atbash cipher `String`.
### Expected Function
### Notions
- [Module std::fmt](https://doc.rust-lang.org/std/fmt/index.html)
### Expected Function and structure
```rust
@ -19,16 +22,22 @@ pub struct CipherError {
// expected public fields
}
impl CipherError {
pub fn new(validation: bool, expected: String) -> CipherError {}
pub fn new(validation: bool, expected: String) -> CipherError {
}
}
pub fn cipher(original: &str, ciphered: &str) -> Option<Result<bool, CipherError>> {
}
pub fn cipher(original: &str, ciphered: &str) -> Option<Result<bool, CipherError>> {}
```
### Usage
Here is a program to test your function
Here is a program to test your function:
```rust
use cipher::*;
fn main() {
println!("{:?}", cipher("1Hello 2world!", "1Svool 2dliow!"));
println!("{:?}", cipher("1Hello 2world!", "svool"));

28
subjects/error_type/README.md → subjects/error_types/README.md

@ -2,16 +2,16 @@
### Instructions
For this exercise you will have to implement an **error type**.
For this exercise, you will have to implement an **error type**.
The main objective is to create a form validator, where you must implement a
The main objective is to create a form validator, where you must implement an
error type. This must validate the password and the first name. The
first name must not be empty and the password must have at least 8 char and a combination of alphanumeric and none alphanumeric ASCII characters
ex: "asDd123=%" => good
"asgfD" => error
"asdsdf2" => error
"sad_#$" => error
"asgfD" => error
"asdsdf2" => error
"sad\_#$" => error
Create a structure called `Form` that will have the following fields:
@ -30,8 +30,8 @@ It must have the fields:
- `form_values`, this will be a tuple of strings that will save the value that the user inserted into the form
ex: ("password", "asdaSD_")
("first_name", "someone")
ex: ("password", "asdaSD\_")
("first_name", "someone")
- `date`, that will have the date that the error occurred in the format "2020-12-14 09:33:41"
- `err`, that will have the error description:
@ -39,6 +39,11 @@ ex: ("password", "asdaSD_")
- "At least 8 characters"
- "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)"
### Notions
- [Error types](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html)
- [Struct NaiveDate](https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDate.html)
### Expected Function
```rust
@ -75,9 +80,11 @@ impl Form {
### Usage
Here is a program to test your function
Here is a program to test your function:
```rust
use error_types::*;
fn main() {
let mut form_output = Form::new(
String::from("Alice"),
@ -117,8 +124,3 @@ FErr { form_values: ("password", "asdasASd(_"), date: "2020-12-28 13:29:11", err
FErr { form_values: ("password", "asdasASd123SA"), date: "2020-12-28 13:29:11", err: "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)" }
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html
- https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDate.html

29
subjects/handling/README.md

@ -2,18 +2,26 @@
### Instructions
Write a function, called `open_or_create` that as two arguments:
Write a **function**, called `open_or_create` which has two arguments:
- `file : &str` which is the name of the files
- `content: &str` being the content to be written into the file
- `file : &str` which is the name of the file
- `content: &str` which will be the content to be written into the file
This functions should try to open a file, if it does not exist creates it.
You should panic, with the error, in case something goes wrong.
This function should try to open a file, if it does not exist, it should create it.
In case something goes wrong, it should panic, with the error.
### Notions
- [Error kind](https://doc.rust-lang.org/std/io/enum.ErrorKind.html)
- [struct file](https://doc.rust-lang.org/std/fs/struct.File.html)
- [OPenOptions](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html)
### Expected Function
```rust
pub fn open_or_create(s: &str, content: &str) {}
pub fn open_or_create(s: &str, content: &str) {
}
```
### Usage
@ -21,6 +29,10 @@ pub fn open_or_create(s: &str, content: &str) {}
Here is a program to test your function
```rust
use std::fs::File;
use std::io::Read;
use handling::*;
fn main() {
let path = "a.txt";
File::create(path).unwrap();
@ -41,8 +53,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
content to be written
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/std/io/enum.ErrorKind.html
- https://doc.rust-lang.org/std/fs/struct.File.html

62
subjects/profanity_filter/README.md

@ -2,10 +2,9 @@
### Instructions
Sometimes it is more desirable to catch the failure of some parts of a program instead
of just calling panic.
Sometimes it is more desirable to catch the failure of some parts of a program instead of just calling panic.
For this exercise you will have to create a message blocker, where you must block the word `stupid`
For this exercise you will have to create a message blocker, where you must block the word `stupid`.
You will have to create a structure called `Message`, this structure
must have the following elements:
@ -14,34 +13,50 @@ must have the following elements:
- user: String
- time_sent: String
The struct must also have a implementation of 2 functions associated to it:
The struct must also have a implementation of 2 **functions** associated with it:
- `new`, that initializes the structure
- `send_ms`, that only has its implementation type (**self**) as argument and returns an option.
This function must return `None` if the content of the message is either **empty** or contains the
word **stupid**. Otherwise it returns the content of the message.
- `new`, which initializes the structure
- `send_ms`, which only has its implementation type (**self**) as argument and returns an option:
- This function must return `None` if the content of the message is either **empty** or contains the word **stupid**. Otherwise it returns the content of the message.
You will have to create two more functions that aren't associated to any structure:
You will have to create two more **functions** that are not associated with any structure:
- `check_ms` that receives as parameters the reference to the structure `Message` and returns a tuple,
containing a `bool` and a `string`. This function will execute the function `send_ms` and if the result
of the option is `None` it should return (false, "ERROR: illegal"). Otherwise it returns `true` and the
content of the message sent.
- `date_format` that creates and formats the date and time that the message was sent, the format should
look like this: **Mon Oct 5 10:22:19 2020**
- `check_ms` which:
- receives as parameters the reference to the structure `Message`
- and returns a tuple, containing a `bool` and a `string`:
- This function will execute the function `send_ms` and if the result of the option is `None`, it should return (false, "ERROR: illegal").Otherwise it returns `true` and the content of the message sent.
- `date_format` which:
- creates and formats the date and time when the message was sent:
- The format should look like this: **Mon Oct 5 10:22:19 2020**
### Notions
- [Crate Chrono](https://docs.rs/chrono/0.4.19/chrono/)
- [Enum Definition](https://doc.rust-lang.org/stable/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values)
### Expected Function
```rust
pub struct Message {}
pub struct Message {
}
impl Message {
pub fn new(ms: String, u: String, t: String) -> Message {}
pub fn send_ms(&self) -> Option<&str> {}
pub fn new(ms: String, u: String, t: String) -> Message {
}
pub fn send_ms(&self) -> Option<&str> {
}
}
pub fn check_ms(ms: &Message) -> (bool, &str) {
}
pub fn check_ms(ms: &Message) -> (bool, &str) {}
pub fn format_date() -> String {}
pub fn format_date() -> String {
}
```
### Usage
@ -49,6 +64,8 @@ pub fn format_date() -> String {}
Here is a program to test your function
```rust
use profanity_filter::*;
fn main() {
let m0 = Message::new("hello there".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m0));
@ -74,8 +91,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
(false, "ERROR: illegal")
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://docs.rs/chrono/0.4.19/chrono/
- https://doc.rust-lang.org/stable/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values

32
subjects/question_mark/README.md

@ -2,17 +2,25 @@
### Instructions
You will have to create 3 structures:
3 structure have to be created:
- `One`, that contains one element called `first_layer` it should be an `Option` for the structure `Two`.
- `Two`, that contains one element called `second_layer` it should be an `Option` for the structure `Three`.
- `Three`, that contains one element called `third_layer` it should be an `Option` for the structure `Four`.
- `Four`, that contains one element called `fourth_layer` it should be an `u16` that is an `Option`.
- `One`:
- which contains one element called `first_layer` which should be an `Option` of the structure `Two`.
- `Two`:
- which contains one element called `second_layer` which should be an `Option` of the structure `Three`.
- `Three`:
- which contains one element called `third_layer` which should be an `Option` of the structure `Four`.
- `Four`:
- which contains one element called `fourth_layer` which is an `Option<u16>`.
Beside the structure you must create a function named `get_fourth_layer` that is associated to the `One` structure.
This function should return the `Option` value in the `Four` structure.
Beside the structure you must create a **function** named `get_fourth_layer` which is associated to the `One` structure (a method).
This **function** should return the `Option` value in the `Four` structure.
### Expected Function
### Notions
- [Unpacking options with ?](https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap/question_mark.html)
### Expected Function and structures
```rust
pub struct One {
@ -35,9 +43,11 @@ impl One {
### Usage
Here is a program to test your function
Here is a program to test your function:
```rust
use question_mark::*;
fn main() {
let a = One {
first_layer : Some(Two {
@ -64,7 +74,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
1000
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap/question_mark.html

Loading…
Cancel
Save