From 486b917663b4a404cd0507b0199f9896db4ec3ff Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 9 Mar 2021 03:33:19 +0000 Subject: [PATCH] first pass --- subjects/borrow_box/README.md | 52 +++++++++++--------- subjects/box_it/README.md | 38 ++++++++------- subjects/box_recursion/README.md | 35 +++++++------- subjects/drop_the_thread/README.md | 28 ++++++----- subjects/how_many_references/README.md | 24 +++++----- subjects/ref_cell/README.md | 66 +++++++++++++------------- 6 files changed, 132 insertions(+), 111 deletions(-) diff --git a/subjects/borrow_box/README.md b/subjects/borrow_box/README.md index c7cdafc5..b29638f2 100644 --- a/subjects/borrow_box/README.md +++ b/subjects/borrow_box/README.md @@ -2,22 +2,26 @@ ### 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. -- `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. - - `update_score`, that 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`. - 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 - he is the winner and the function should not increase the score anymore for either players. + - `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`. + 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. -- `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 #[derive(Debug, Clone, Eq, PartialEq)] @@ -25,20 +29,30 @@ pub struct Game { // expected public fields } impl Game { - pub fn new(i: u32, pl1: String, pl2: String, n: u16) -> Box {} - pub fn read_winner(&self) -> (String, u16) {} - pub fn update_score(&mut self, user_name: String) {} - pub fn delete(self) -> String {} + pub fn new(i: u32, pl1: String, pl2: String, n: u16) -> Box { + + } + pub fn read_winner(&self) -> (String, u16) { + + } + pub fn update_score(&mut self, user_name: String) { + + } + pub fn delete(self) -> String { + + } } ``` ### Usage -Here is a program to test your function +Here is a program to test your functions, ```rust +use borrow_box::*; + 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()); // output : ("Same score! tied", 0) @@ -52,11 +66,10 @@ fn main() { game.update_score(String::from("Joao")); // this one will not count because it already 5 games played, the nbr_of_games game.update_score(String::from("Susana")); - + println!("{:?}", game.read_winner()); // output : ("Joao", 3) - game.delete(); println!("{:?}", game.delete()); // output : "game deleted: id -> 0" @@ -76,8 +89,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run "game deleted: id -> 0" student@ubuntu:~/[[ROOT]]/test$ ``` - - -### Notions - -- https://doc.rust-lang.org/book/ch15-01-box.html diff --git a/subjects/box_it/README.md b/subjects/box_it/README.md index 369f01de..535b4294 100644 --- a/subjects/box_it/README.md +++ b/subjects/box_it/README.md @@ -2,25 +2,36 @@ ### 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) - and transforms those numbers into `u32` and inserts it into a vector that must be saved in the heap using **Box**. +- `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 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 -pub fn transform_and_save_on_heap(s: String) -> Box> {} -pub fn take_value_ownership(a: Box>) -> Vec {} +pub fn transform_and_save_on_heap(s: String) -> Box> { + +} +pub fn take_value_ownership(a: Box>) -> Vec { + +} ``` ### Usage -Here is a program to test your function +Here is a program to test your functions ```rust +use box_it::*; + fn main() { 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); println!("Box value : {:?}", &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); println!("value : {:?}", &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 student@ubuntu:~/[[ROOT]]/test$ cargo run -Box value : [6800, 13500] +Box value : [5500, 8900, 32] size occupied in the stack : 8 bytes -value : [6800, 13500] +value : [5500, 8900, 32] size occupied in the stack : 24 bytes 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 diff --git a/subjects/box_recursion/README.md b/subjects/box_recursion/README.md index 1f867924..9d602743 100644 --- a/subjects/box_recursion/README.md +++ b/subjects/box_recursion/README.md @@ -2,25 +2,31 @@ ### 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` -- `add_worker`, that 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 - return a `Option` with the name of the worker. -- `search_worker`, that return a tuple with the name and type of worker. +- `new` which will initialize the `WorkEnvironment` as `None` +- `add_worker`, which receives two strings, one being the type of worker and the other the name of the worker. +- `remove_worker`, which removes the last worker that was placed in the `WorkEnvironment`, this function should + returns an `Option` with the name of the 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. -### 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 pub struct WorkEnvironment { pub grade: Link, } -pub type Link = +pub type Link = pub struct Worker { pub worker_type: String, @@ -40,9 +46,11 @@ impl WorkEnvironment { ### Usage -Here is a program to test your function +Here is a program to test your function, ```rust +use box_recursion::*; + fn main() { let mut list = WorkEnvironment::new(); list.add_worker(String::from("CEO"), String::from("Marie")); @@ -70,10 +78,3 @@ Some(("Alice", "Normal Worker")) WorkEnvironment { grade: None } 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 \ No newline at end of file diff --git a/subjects/drop_the_thread/README.md b/subjects/drop_the_thread/README.md index 5d034154..4e4a6583 100644 --- a/subjects/drop_the_thread/README.md +++ b/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" -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: + - `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. If the thread is not dropped, the state will be false otherwise true. - `Thread` that will have the following fields: - - `pid`, the id of the thread - - `cmd`, the name of the thread + - `pid`, the id 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) - Implementation of each structure: + - `Workers` : + - `new`, that creates a default worker - `new_worker`, that returns a tuple with the `pid` and a new `Thread`, 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 -### 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 use std::cell::{RefCell, Cell}; @@ -65,10 +74,11 @@ impl<'a> Thread<'a> { ### Usage -Here is a program to test your function +Here is a program to test your function, ```rust use std::rc::Rc; +use drop_the_thread::*; fn main() { let worker = Workers::new(); @@ -101,9 +111,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run (false, 2, Cell { value: 2 }, 1) 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 diff --git a/subjects/how_many_references/README.md b/subjects/how_many_references/README.md index 57815632..5c9ed6af 100644 --- a/subjects/how_many_references/README.md +++ b/subjects/how_many_references/README.md @@ -2,14 +2,19 @@ ### Instructions -Create the following functions : +Create the following **functions** : -- `add_ele` that adds an element to the value in the `Node` -- `how_many_references` that returns how many times the value is referenced in the code -- `rm_all_ref` that receives a `Rc` and removes all elements from the vector that +- `add_ele` which adds an element to the value in the `Node` +- `how_many_references` which returns how many times the value is referenced in the code +- `rm_all_ref` which receives a `Rc` 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 -### 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 pub use std::rc::Rc; @@ -31,9 +36,11 @@ pub fn how_many_references(value: &Rc) -> usize {} ### Usage -Here is a program to test your function +Here is a program to test your functions, ```rust +use how_many_references::*; + fn main() { let a = Rc::new(String::from("a")); let b = Rc::new(String::from("b")); @@ -71,8 +78,3 @@ b: 2 c: 2 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 diff --git a/subjects/ref_cell/README.md b/subjects/ref_cell/README.md index 7507201e..1f88560e 100644 --- a/subjects/ref_cell/README.md +++ b/subjects/ref_cell/README.md @@ -2,14 +2,14 @@ ### 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. -The main objective for this module is to limit how many times a value is referenced. +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 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 fn warning(&self, msg: &str); @@ -17,7 +17,7 @@ For the module you must create the following: 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. - 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", )** 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", )** to the `info` function -### 2ª part +### Second part (lib.rs) Afterwards you must use the module `messenger` and create the following: - A structure `Worker` that has the fields: - `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 - 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. - 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 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 -Here is a program to test your function +Here is a program to test your function, ```rust +use ref_cell::*; + fn main() { // initialize the worker - let Logger = Worker::new(1); + let logger = Worker::new(1); // initialize the tracker, with the max number of // called references as 10 - let track = Tracker::new(&Logger, 10); + let track = Tracker::new(&logger, 10); - let _a = Logger.track_value.clone(); // |\ - let _a1 = Logger.track_value.clone(); // | -> increase the Rc to 4 references - let _a2 = Logger.track_value.clone(); // |/ + let _a = logger.track_value.clone(); // |\ + let _a1 = logger.track_value.clone(); // | -> increase the Rc to 4 references + let _a2 = logger.track_value.clone(); // |/ // 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 _b1 = Logger.track_value.clone(); // | -> increase the Rc to 8 references - let _b2 = Logger.track_value.clone(); // | / - let _b3 = Logger.track_value.clone(); // |/ + let _b = logger.track_value.clone(); // |\ + let _b1 = logger.track_value.clone(); // | -> increase the Rc to 8 references + let _b2 = logger.track_value.clone(); // | / + let _b3 = logger.track_value.clone(); // |/ // this will set the value and making a verification of // 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 // 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!("{:?}", 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$ ``` - -### Notions - -- https://doc.rust-lang.org/std/cell/struct.RefCell.html -- https://doc.rust-lang.org/std/rc/struct.Rc.html