Browse Source

first pass

content-update
Chris 3 years ago
parent
commit
486b917663
  1. 52
      subjects/borrow_box/README.md
  2. 38
      subjects/box_it/README.md
  3. 35
      subjects/box_recursion/README.md
  4. 28
      subjects/drop_the_thread/README.md
  5. 24
      subjects/how_many_references/README.md
  6. 66
      subjects/ref_cell/README.md

52
subjects/borrow_box/README.md

@ -2,22 +2,26 @@
### Instructions ### Instructions
You will have to create a **CRUD** functionality. Therefore creating the following functions : In this exercise, a **CRUD** functionality will have to be created. Therefore the following functions will have to be defined :
- `new`, that receives two players and initializes them with a name and a score. This functions should - `new`, which receives two players and initializes them with a name and a score. This functions should
return the structure wrapped in a Box. return the structure wrapped in a Box.
- `read_winner`, returns a tuple with the name and the score of the player who is winning. - `read_winner`, which returns a tuple with the name and the score of the player who is winning.
In case none of the players are winning, it should return the same tuple with the string "Same score! tied" and the tied score. In case none of the players are winning, it should return the same tuple with the string "Same score! tied" and the tied score.
- `update_score`, that receives the name of a player. - `update_score`, which receives the name of a player.
This function should increment the score of the player. The score should only be increased if it does not pass the `nbr_of_games`. This function should increment the score of the player. The score should only be increased if it does not pass the `nbr_of_games`.
Example: if the nbr_of_games is 3 then the game should be best out of three. So if one play as 2 wins then Example: if the nbr_of_games is 3 then the winner of the game should be the one who is the best out of three games. So if one play as 2 wins then
he is the winner and the function should not increase the score anymore for either players. he is the winner and the function should not increase the score anymore for either players.
- `delete`, that takes the ownership of the boxed game and returning a string : "Game deleted: id -> 0". - `delete`, which takes the ownership of the boxed game and returning a string : "Game deleted: id -> 0".
### Expected Function ### Notions
- [Box Pointers](https://doc.rust-lang.org/book/ch15-01-box.html)
### Expected Functions
```rust ```rust
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
@ -25,20 +29,30 @@ pub struct Game {
// expected public fields // expected public fields
} }
impl Game { impl Game {
pub fn new(i: u32, pl1: String, pl2: String, n: u16) -> Box<Game> {} pub fn new(i: u32, pl1: String, pl2: String, n: u16) -> Box<Game> {
pub fn read_winner(&self) -> (String, u16) {}
pub fn update_score(&mut self, user_name: String) {} }
pub fn delete(self) -> String {} pub fn read_winner(&self) -> (String, u16) {
}
pub fn update_score(&mut self, user_name: String) {
}
pub fn delete(self) -> String {
}
} }
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your functions,
```rust ```rust
use borrow_box::*;
fn main() { fn main() {
let mut game = Game::create_game(0, String::from("Joao"), String::from("Susana"), 5); let mut game = Game::new(0, String::from("Joao"), String::from("Susana"), 5);
println!("{:?}", game.read_winner()); println!("{:?}", game.read_winner());
// output : ("Same score! tied", 0) // output : ("Same score! tied", 0)
@ -52,11 +66,10 @@ fn main() {
game.update_score(String::from("Joao")); game.update_score(String::from("Joao"));
// this one will not count because it already 5 games played, the nbr_of_games // this one will not count because it already 5 games played, the nbr_of_games
game.update_score(String::from("Susana")); game.update_score(String::from("Susana"));
println!("{:?}", game.read_winner()); println!("{:?}", game.read_winner());
// output : ("Joao", 3) // output : ("Joao", 3)
game.delete();
println!("{:?}", game.delete()); println!("{:?}", game.delete());
// output : "game deleted: id -> 0" // output : "game deleted: id -> 0"
@ -76,8 +89,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
"game deleted: id -> 0" "game deleted: id -> 0"
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/book/ch15-01-box.html

38
subjects/box_it/README.md

@ -2,25 +2,36 @@
### Instructions ### Instructions
Create the following functions: Create the following **functions**:
- `transform_and_save_on_heap`, that receives a string with a number (that can or not have a k (kilo) suffix) - `transform_and_save_on_heap`, which receives a string with a number (that can or not have a k (kilo) suffix)
and transforms those numbers into `u32` and inserts it into a vector that must be saved in the heap using **Box**. and transforms those numbers into `u32` and inserts them into a vector which must be saved in the heap using **Box**.
- `take_value_ownership`, that takes the value (unboxed value) form the box and returns it - `take_value_ownership`, which takes the value (unboxed value) from the box and returns it
### Expected Function ### Notions
- [smart pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
- [using box](https://doc.rust-lang.org/book/ch15-01-box.html)
### Expected Functions
```rust ```rust
pub fn transform_and_save_on_heap(s: String) -> Box<Vec<u32>> {} pub fn transform_and_save_on_heap(s: String) -> Box<Vec<u32>> {
pub fn take_value_ownership(a: Box<Vec<u32>>) -> Vec<u32> {}
}
pub fn take_value_ownership(a: Box<Vec<u32>>) -> Vec<u32> {
}
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your functions
```rust ```rust
use box_it::*;
fn main() { fn main() {
let new_str = String::from("5.5k 8.9k 32"); let new_str = String::from("5.5k 8.9k 32");
@ -28,7 +39,7 @@ fn main() {
let a_h = transform_and_save_on_heap(new_str); let a_h = transform_and_save_on_heap(new_str);
println!("Box value : {:?}", &a_h); println!("Box value : {:?}", &a_h);
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_h))); println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_h)));
let a_b_v = take_value_ownership(a_h); let a_b_v = take_value_ownership(a_h);
println!("value : {:?}", &a_b_v); println!("value : {:?}", &a_b_v);
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_b_v))); println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_b_v)));
@ -40,14 +51,9 @@ And its output:
```console ```console
student@ubuntu:~/[[ROOT]]/test$ cargo run student@ubuntu:~/[[ROOT]]/test$ cargo run
Box value : [6800, 13500] Box value : [5500, 8900, 32]
size occupied in the stack : 8 bytes size occupied in the stack : 8 bytes
value : [6800, 13500] value : [5500, 8900, 32]
size occupied in the stack : 24 bytes size occupied in the stack : 24 bytes
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/book/ch15-00-smart-pointers.html
- https://doc.rust-lang.org/book/ch15-01-box.html

35
subjects/box_recursion/README.md

@ -2,25 +2,31 @@
### Instructions ### Instructions
Using the given code create the following functions: Using the given code create the following **functions**:
- `new` that will initialize the `WorkEnvironment` as `None` - `new` which will initialize the `WorkEnvironment` as `None`
- `add_worker`, that receives two strings, one being the type of worker and the other the name of the worker. - `add_worker`, which receives two strings, one being the type of worker and the other the name of the worker.
- `remove_worker`, that removes the last worker that was placed in the `WorkEnvironment`, this functions should - `remove_worker`, which removes the last worker that was placed in the `WorkEnvironment`, this function should
return a `Option` with the name of the worker. returns an `Option` with the name of the worker.
- `search_worker`, that return a tuple with the name and type of worker. - `search_worker`, which returns a tuple with the name and type of worker.
You must also create a type called `Link` this will be the connection of the structures `WorkEnvironment` and `Worker`. You must also create a type called `Link`. This will be the connection of the structures `WorkEnvironment` and `Worker`.
Do not forget that this will be a recursion type and it must point to `None` if there is no workers. Do not forget that this will be a recursion type and it must point to `None` if there is no workers.
### Expected Function ### Notions
- [enum](https://doc.rust-lang.org/rust-by-example/custom_types/enum.html)
- [boc](https://doc.rust-lang.org/book/ch15-01-box.html)
- [Module std::option](https://doc.rust-lang.org/std/option/)
### Expected Functions and structures
```rust ```rust
pub struct WorkEnvironment { pub struct WorkEnvironment {
pub grade: Link, pub grade: Link,
} }
pub type Link = pub type Link =
pub struct Worker { pub struct Worker {
pub worker_type: String, pub worker_type: String,
@ -40,9 +46,11 @@ impl WorkEnvironment {
### Usage ### Usage
Here is a program to test your function Here is a program to test your function,
```rust ```rust
use box_recursion::*;
fn main() { fn main() {
let mut list = WorkEnvironment::new(); let mut list = WorkEnvironment::new();
list.add_worker(String::from("CEO"), String::from("Marie")); list.add_worker(String::from("CEO"), String::from("Marie"));
@ -70,10 +78,3 @@ Some(("Alice", "Normal Worker"))
WorkEnvironment { grade: None } WorkEnvironment { grade: None }
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/rust-by-example/custom_types/enum.html
- https://doc.rust-lang.org/book/ch15-01-box.html
- https://doc.rust-lang.org/std/option/
- https://doc.rust-lang.org/book/ch15-01-box.html

28
subjects/drop_the_thread/README.md

@ -4,20 +4,23 @@
"Interior mutability is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data" "Interior mutability is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data"
You must create a Drop checker API. For this you must create: in this exercise a Drop checker API has to be created. For this you must define:
- Two structures: - Two structures:
- `Workers` that will have two fields: - `Workers` that will have two fields:
- `drops` that will save the number of dropped threads - `drops` that will save the number of dropped threads.
- `states` that will save a state of multiple threads. - `states` that will save a state of multiple threads.
If the thread is not dropped, the state will be false otherwise true. If the thread is not dropped, the state will be false otherwise true.
- `Thread` that will have the following fields: - `Thread` that will have the following fields:
- `pid`, the id of the thread - `pid`, the id of the thread.
- `cmd`, the name of the thread - `cmd`, the name of the thread.
- `parent`, that will be the link to the structure `Workers` (Tip: this must be a reference to the structure Workers) - `parent`, that will be the link to the structure `Workers` (Tip: this must be a reference to the structure Workers)
- Implementation of each structure: - Implementation of each structure:
- `Workers` : - `Workers` :
- `new`, that creates a default worker - `new`, that creates a default worker
- `new_worker`, that returns a tuple with the `pid` and a new `Thread`, - `new_worker`, that returns a tuple with the `pid` and a new `Thread`,
this function must receive a `String` being the `cmd` this function must receive a `String` being the `cmd`
@ -33,7 +36,13 @@ You must create a Drop checker API. For this you must create:
- You must implement for the structure `Thread` the `Drop` trait. In this trait you must call the function `add_drop` so that the state of the thread changes - You must implement for the structure `Thread` the `Drop` trait. In this trait you must call the function `add_drop` so that the state of the thread changes
### Expected Function ### Notions
- [Trait std::ops::Drop](https://doc.bccnsoft.com/docs/rust-1.36.0-docs-html/std/ops/trait.Drop.html)
- [Struct std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html)
- [Interior Mutability](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html)
### Expected Functions
```rust ```rust
use std::cell::{RefCell, Cell}; use std::cell::{RefCell, Cell};
@ -65,10 +74,11 @@ impl<'a> Thread<'a> {
### Usage ### Usage
Here is a program to test your function Here is a program to test your function,
```rust ```rust
use std::rc::Rc; use std::rc::Rc;
use drop_the_thread::*;
fn main() { fn main() {
let worker = Workers::new(); let worker = Workers::new();
@ -101,9 +111,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
(false, 2, Cell { value: 2 }, 1) (false, 2, Cell { value: 2 }, 1)
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.bccnsoft.com/docs/rust-1.36.0-docs-html/std/ops/trait.Drop.html
- https://doc.rust-lang.org/std/cell/struct.RefCell.html
- https://doc.rust-lang.org/book/ch15-05-interior-mutability.html

24
subjects/how_many_references/README.md

@ -2,14 +2,19 @@
### Instructions ### Instructions
Create the following functions : Create the following **functions** :
- `add_ele` that adds an element to the value in the `Node` - `add_ele` which adds an element to the value in the `Node`
- `how_many_references` that returns how many times the value is referenced in the code - `how_many_references` which returns how many times the value is referenced in the code
- `rm_all_ref` that receives a `Rc<String>` and removes all elements from the vector that - `rm_all_ref` which receives a `Rc<String>` and removes all elements from the vector that
are equal to that value, this should only happen if the two Rcs point to the same allocation are equal to that value, this should only happen if the two Rcs point to the same allocation
### Expected Function ### Notions
- [Reference Counted Smart Pointer](https://doc.rust-lang.org/book/ch15-04-rc.html)
- [Struct std::rc::Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html)
### Expected Functions and structures
```rust ```rust
pub use std::rc::Rc; pub use std::rc::Rc;
@ -31,9 +36,11 @@ pub fn how_many_references(value: &Rc<String>) -> usize {}
### Usage ### Usage
Here is a program to test your function Here is a program to test your functions,
```rust ```rust
use how_many_references::*;
fn main() { fn main() {
let a = Rc::new(String::from("a")); let a = Rc::new(String::from("a"));
let b = Rc::new(String::from("b")); let b = Rc::new(String::from("b"));
@ -71,8 +78,3 @@ b: 2
c: 2 c: 2
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/book/ch15-04-rc.html
- https://doc.rust-lang.org/std/rc/struct.Rc.html

66
subjects/ref_cell/README.md

@ -2,14 +2,14 @@
### Instructions ### Instructions
### 1Âş part #### First part (messenger.rs)
Create a module called `messenger`. This module will be able to inform a user of how much references of a given value he is using. Create a module called `messenger`. This module will be able to inform a user of how many references of a given value he is using.
The main objective for this module is to limit how many times a value is referenced. The main objective of this module is to limit how many times a value is referenced.
For the module you must create the following: For this module the following must be created:
- A trait `Logger` that implements three functions: `warning`, `info`, `error`. All function should receive a reference to themselves and a string literal. - A trait `Logger` which implements three functions: `warning`, `info`, `error`. All **functions** should receive a reference to themselves and a string literal.
```rust ```rust
fn warning(&self, msg: &str); fn warning(&self, msg: &str);
@ -17,7 +17,7 @@ For the module you must create the following:
fn error(&self, msg: &str); fn error(&self, msg: &str);
``` ```
- A structure called `Tracker`, that must have the fields: `logger` being a reference to the `Logger`, `value` being the count of how many times the value was referenced, - A structure called `Tracker`, which must have the fields: `logger` being a reference to the `Logger`, `value` being the count of how many times the value was referenced,
`max` being the max count of references the actual value can achieve. `max` being the max count of references the actual value can achieve.
- An implementation of three functions that are associated to the `Tracker` structure: - An implementation of three functions that are associated to the `Tracker` structure:
@ -27,66 +27,71 @@ For the module you must create the following:
If the percentage is equal or greater to 70% of the limit usage, it should write **("Warning: you have used up over {}% of your quota! Proceeds with precaution", <calculated_percentage>)** to the `warning` function If the percentage is equal or greater to 70% of the limit usage, it should write **("Warning: you have used up over {}% of your quota! Proceeds with precaution", <calculated_percentage>)** to the `warning` function
- `peek` that will take a peek of how much usage the variable already has. It should write **("Info: you are using up too {}% of your quote", <calculated_percentage>)** to the `info` function - `peek` that will take a peek of how much usage the variable already has. It should write **("Info: you are using up too {}% of your quote", <calculated_percentage>)** to the `info` function
### 2ÂŞ part ### Second part (lib.rs)
Afterwards you must use the module `messenger` and create the following: Afterwards you must use the module `messenger` and create the following:
- A structure `Worker` that has the fields: - A structure `Worker` that has the fields:
- `track_value` this will be the value that will be tracked by the tracker. - `track_value` this will be the value that will be tracked by the tracker.
- `mapped_messages` that will have the latest messages. This must be a HashMap with the key being the type of message - `mapped_messages` that will have the latest messages. This must be a HashMap with the key being the type of message
sent by the logger (info, error or warning) and the value being the message sent by the logger (info, error or warning) and the value being the message
- `all_messages` that will be a vector of all messages sent. - `all_messages` that will be a vector of all messages sent.
- A `new` function that initializes the structure `Worker` - A `new` function that initializes the structure `Worker`
- To use the trait `Logger` you must implement it for the Worker structure. Each function (warning, error and info) must insert the message to the - To use the trait `Logger` you must implement it for the Worker structure. Each function (warning, error and info) must insert the message to the
respective fields of the structure Worker. respective fields of the structure Worker.
You must use **interior mutability**, this means it must be able to mutate data even when there are immutable references to that data. You must use **interior mutability**, this means it must be able to mutate data even when there are immutable references to that data. Consequently, the user will not need to use the keyword `mut` (tip: RefCell)
So the user doesn't need to use the keyword `mut` (tip: RefCell) ### Notions
- [std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html)
- [Struct std::rc::Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html)
### Usage ### Usage
Here is a program to test your function Here is a program to test your function,
```rust ```rust
use ref_cell::*;
fn main() { fn main() {
// initialize the worker // initialize the worker
let Logger = Worker::new(1); let logger = Worker::new(1);
// initialize the tracker, with the max number of // initialize the tracker, with the max number of
// called references as 10 // called references as 10
let track = Tracker::new(&Logger, 10); let track = Tracker::new(&logger, 10);
let _a = Logger.track_value.clone(); // |\ let _a = logger.track_value.clone(); // |\
let _a1 = Logger.track_value.clone(); // | -> increase the Rc to 4 references let _a1 = logger.track_value.clone(); // | -> increase the Rc to 4 references
let _a2 = Logger.track_value.clone(); // |/ let _a2 = logger.track_value.clone(); // |/
// take a peek of how much we already used from our quota // take a peek of how much we already used from our quota
track.peek(&Logger.track_value); track.peek(&logger.track_value);
let _b = Logger.track_value.clone(); // |\ let _b = logger.track_value.clone(); // |\
let _b1 = Logger.track_value.clone(); // | -> increase the Rc to 8 references let _b1 = logger.track_value.clone(); // | -> increase the Rc to 8 references
let _b2 = Logger.track_value.clone(); // | / let _b2 = logger.track_value.clone(); // | /
let _b3 = Logger.track_value.clone(); // |/ let _b3 = logger.track_value.clone(); // |/
// this will set the value and making a verification of // this will set the value and making a verification of
// how much we already used of our quota // how much we already used of our quota
track.set_value(&Logger.track_value); track.set_value(&logger.track_value);
let _c = Logger.track_value.clone(); // | -> increase the Rc to 9 references let _c = logger.track_value.clone(); // | -> increase the Rc to 9 references
// this will set the value and making a verification of // this will set the value and making a verification of
// how much we already used of our quota // how much we already used of our quota
track.set_value(&Logger.track_value); track.set_value(&logger.track_value);
let _c1 = Logger.track_value.clone(); // | -> increase the Rc to 10 references, this will be the limit let _c1 = logger.track_value.clone(); // | -> increase the Rc to 10 references, this will be the limit
track.set_value(&Logger.track_value); track.set_value(&logger.track_value);
for (k ,v) in Logger.mapped_messages.into_inner() { for (k ,v) in logger.mapped_messages.into_inner() {
println!("{:?}", (k ,v)); println!("{:?}", (k ,v));
} }
println!("{:?}", Logger.all_messages.into_inner()); println!("{:?}", logger.all_messages.into_inner());
} }
``` ```
@ -105,8 +110,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
] ]
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/std/cell/struct.RefCell.html
- https://doc.rust-lang.org/std/rc/struct.Rc.html

Loading…
Cancel
Save