Browse Source

Merge pull request #754 from 01-edu/rust-subject-review-quest-06

first pass remarks
pull/762/head
augusto-mantilla 3 years ago committed by GitHub
parent
commit
357235ed83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      subjects/blood_types/README.md
  2. 79
      subjects/border_cross/README.md
  3. 10
      subjects/commits_stats/README.md
  4. 4
      subjects/delete_prefix/README.md
  5. 42
      subjects/events/README.md
  6. 10
      subjects/generics/README.md
  7. 22
      subjects/lalgebra_scalar/README.md
  8. 8
      subjects/lalgebra_vector/README.md
  9. 19
      subjects/lifetimes/README.md
  10. 18
      subjects/matrix/README.md
  11. 7
      subjects/matrix_ops/README.md
  12. 8
      subjects/roman_numbers/README.md
  13. 5
      subjects/roman_numbers_iter/README.md
  14. 44
      subjects/traits/README.md
  15. 2
      subjects/vector_operations/README.md

9
subjects/blood_types/README.md

@ -2,12 +2,13 @@
### Instructions
In this exercise you will create a data model of blood types and an API to deal with blood types
In this exercise you will create a data model of blood types and an API to deal with them.
Start by copying the data representation of the blood types:
- Create the enumerator `Antigen` that has 4 possibilities: A, B, O and AB And the enumerator `RhFactor` that has two possible values: Positive and Negative
- After, copy the struct BloodType that contains two fields with the names antigen and rh_factor
- Create the enum `Antigen` that has 4 possibilities: A, B, O and AB And the enum `RhFactor` that has two possible values: Positive and Negative
- After, copy the struct `BloodType` that contains two fields with the names antigen and rh_factor
- To provide a simple way to create blood types implement the trait FromStr for BloodType (which will allow us to use the `parse` method and the associated function from_str, so we can do:
@ -85,6 +86,8 @@ impl BloodType {
Here is a program to test your function.
```rust
use blood_types::*;
fn main() {
let blood_type: BloodType = "O+".parse().unwrap();
println!("recipients of O+ {:?}", blood_type.recipients());

79
subjects/border_cross/README.md

@ -0,0 +1,79 @@
## vehicles
### Instructions
- Create the trait Vehicle with the model and year
- In a border cross you want to keep a list of all the vehicles that are waiting to enter the country. You want to keep a waiting list of the vehicle but the vehicles can be of two types: Car or Truck
- Create a function that receives a vector of structures that implements the Vehicle trait and returns all the models.
With the following structure:
### Expected Functions and Structures
```rust
#[allow(dead_code)]
pub struct Car<'a> {
pub plate_nbr: &'a str,
pub model: &'a str,
pub horse_power: u32,
pub year: u32,
}
#[allow(dead_code)]
pub struct Truck<'a> {
pub plate_nbr: &'a str,
pub model: &'a str,
pub horse_power: u32,
pub year: u32,
pub load_tons: u32,
}
pub trait Vehicle {
fn model(&self) -> &str;
fn year(&self) -> u32;
}
impl Vehicle for Truck<'_> {
}
impl Vehicle for Car<'_> {
}
fn all_models(list: Vec<&Vehicle>) -> Vec<&str> {
}
```
### Usage
Here is a program to test your function.
```rust
fn main() {
let vehicles: Vec</*there is something missing here*/Vehicle> = vec![
&Car {
plate_nbr: "A3D5C7",
model: "Model 3",
horse_power: 325,
year: 2010,
},
&Truck {
plate_nbr: "V3D5CT",
model: "Ranger",
horse_power: 325,
year: 2010,
load_tons: 40,
},
];
println!("{:?}", all_models(vehicles));
}
```
And its output
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
["Model 3", "Ranger"]
student@ubuntu:~/[[ROOT]]/test$
```

10
subjects/commits_stats/README.md

@ -1,8 +1,8 @@
## commit_stats
## commits_stats
### Instructions:
In this exercise you will be provided with a json file `commits.json` with data corresponding to git commits in GitHub (extracted using the GitHub rest API), your job is to extract the relevant data and place it in a struct called `CommitData` to get the following information:
In this exercise you will be provided with a json file `commits.json` with data corresponding to git commits in GitHub (extracted using the GitHub rest API). Your objective is to extract the relevant data and place it in a struct called `CommitData` to get the following information:
1. Number of commits per author (identified by the GitHub login).
@ -15,8 +15,8 @@ Create two functions:
- `commits_per_date`: which returns a hash map with the number of commits per week.
- Note: A week is represented by the a year followed by the number of the
week for example January 1, 2020 is in week 1 of 2020 an will be
represented by a String with the form "2020-W1".
week. For example, January 1, 2020 is in week 1 of 2020 and will be
represented by a String with the form "2020-W1".
### Notions:
@ -38,7 +38,7 @@ pub fn commits_per_author(data: &json::JsonValue) -> HashMap<String, u32> {
Here is a possible test for your function:
```rust
use commit_stats::{commits_per_week, commits_per_author};
use commits_stats::{commits_per_week, commits_per_author};
fn main() {
let contents = fs::read_to_string("commits.json").unwrap();

4
subjects/delete_prefix/README.md

@ -2,7 +2,7 @@
### Instructions
Define the function `delete_prefix(prefix, s)` that returns the string slice `s` with the `prefix` removed wrapped in Some. If `prefix ` is not contained in `s` return None
Define the function `delete_prefix(prefix, s)` which returns the string slice `s` with the `prefix` removed wrapped in `Some`. If `prefix ` is not a prefix of `s` it returns `None`.
### Expected Function
@ -24,7 +24,7 @@ fn main() {
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

42
subjects/events/README.md

@ -2,47 +2,48 @@
### Instructions
You're have to design a notification system for a platform
You have to design a notification system for a platform.
This events can be: Remainders, Registrations, Appointments or Holidays
These events can be: Remainders, Registrations, Appointments or Holidays.
- Create an event handler that depending of the type of event creates different notification: different color, different size and different position
- Create an event handler that, depending on the type of event, creates different notifications with different colors, different sizes and different positions
- The possible positions are Top, Bottom and Center: Create and Enum `Position` with those values
- Create a method called `notify` which returns a notification with the following caracteristics for each
- Remainder:
size= 50,
color= (50, 50, 50),
position= Bottom,
content= the slice associated to the enum value
size= 50,
color= (50, 50, 50),
position= Bottom,
content= the slice associated to the enum value
- Registration(chrono::Duration),
size = 30,
color = (255, 2, 22),
position = Top,
content = "You have `duration` left before the registration ends",
color = (255, 2, 22),
position = Top,
content = "You have `duration` left before the registration ends",
`durations` must be displayed in the form of {hours}:{minutes}:{seconds} left for the beginning of the event for example if there is two hours 32 minutes and 3 seconds left before the registration then the content will be `You have 2:32:2 left before the registration ends`
`durations` must be displayed in the form of {hours}:{minutes}:{seconds} left for the beginning of the event for example if there is two hours 32 minutes and 3 seconds left before the registration then the content will be `You have 2:32:2 left before the registration ends`
- Appointment(text)
size: 100
color: (200, 200, 3)
position: Center
content: text associated to the value
size: 100
color: (200, 200, 3)
position: Center
content: text associated to the value
- Holiday
size: 25
color: (0, 255, 0)
position: Top
content: "Enjoy your holiday"
color: (0, 255, 0)
position: Top
content: "Enjoy your holiday"
- Implement the std::fmt::Display trait so the text of the notification is printed in the right color in the command line
### Notions
- https://docs.rs/colored/2.0.0/colored/
- [colored crate](https://docs.rs/colored/2.0.0/colored/)
- [chrono crate](https://crates.io/crates/chrono)
### Expected Functions and Data Structures
@ -91,6 +92,9 @@ impl Event {
Here is a program to test your function.
```rust
use events::Event::*;
use chrono::Duration;
fn main() {
let remainder = Remainder("Go to the doctor");
println!("{}", remainder.notify());

10
subjects/generics/README.md

@ -2,12 +2,12 @@
### Instructions
Write a functions called identity that calculates the identity of a value (receives any data type and returns the same value)
Write a **function** called `identity` which calculates the identity of a value (receives any data type and returns the same value).
### Expected Function
### Expected Function (signature to be completed)
```rust
fn identity(v: _) -> _ {
pub fn identity(v: _) -> _ {
}
```
@ -16,13 +16,15 @@ fn identity(v: _) -> _ {
Here is a program to test your function.
```rust
use generics::*;
fn main() {
println!("{}", identity("Hello, world!"));
println!("{}", identity(3));
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

22
subjects/lalgebra_scalar/README.md

@ -2,13 +2,19 @@
### Instructions
A scalar type must implement the operations Addition, Subtraction, Multiplication and Division (you might also have to use more restrictions). For this use a trait inheritance (supertraits)
Define a `Scalar` trait which must implement the operations Addition, Subtraction, Multiplication and Division (you might also have to use more restrictions). For this use a trait inheritance (supertraits)
Another condition for a number to be a scalar is to have a zero (neutral element in the addition) and a one (neutral element in the multiplication). Therefore the Scalar trait will require 2 functions zero() and one()
Another condition for a number to be a scalar is to have a zero (neutral element in the addition) and a one (neutral element in the multiplication). Therefore the `Scalar` trait will require 2 functions zero() and one() (as shown)
After finishing implement the Scalar trait for u32, u64, i32, i64, f32, f64
After finishing completing the declaration of the trait, implement the `Scalar` trait for u32, u64, i32, i64, f32 and f64.
### Expected Function
### Notions
- [Module std::ops](https://doc.rust-lang.org/std/ops/index.html)
### Expected Function (The signature must be completed)
#### You need add the impl for each cases asked in the subject
```rust
pub trait Scalar: _ {
@ -23,17 +29,23 @@ pub trait Scalar: _ {
Here is a program to test your function.
```rust
use lalgebra_scalar::*;
fn main() {
println!("{:?}", f64::zero());
println!("{:?}", i32::zero());
println!("{:?}", f64::one());
println!("{:?}", i32::one());
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
0.0
0
1.0
1
student@ubuntu:~/[[ROOT]]/test$
```

8
subjects/lalgebra_vector/README.md

@ -2,9 +2,9 @@
### Instructions
A vector in linear algebra is define as "anything that can be added and that can be multiplied by a scalar"
A vector in linear algebra is defined as "anything that can be added and that can be multiplied by a scalar"
And the associated function dot that calculates the dot product between two vectors
Define the associated function `dot` that calculates the dot product between two vectors
The dot product between two vectors of different length it's not defined
@ -37,6 +37,8 @@ impl Vector<T> {
Here is a program to test your function.
```rust
use lalgebra_vector::*;
fn main() {
let vector_1: Vector<i64> = Vector(vec![1, 3, -5]);
let vector_2: Vector<i64> = Vector(vec![4, -2, -1]);
@ -45,7 +47,7 @@ fn main() {
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

19
subjects/lifetimes/README.md

@ -2,9 +2,20 @@
### Instructions
Create a struct called Person that has two fields: name of type string slice (&str) and age of type u8 and create the associated function new which creates a new person with age 0 and with the name given
Declare the struct called `Person` that has two fields:
### Expected Functions and Data Structures
- name of type string slice (&str)
- age of type u8
Additionaly, create the associated **function** `new` which creates a new person with age 0 and with the name given.
The expected Fucntions and Structures need to be completed.
### Notions
- [lifetimes](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
### Expected Functions and Data Structures (Both need to be completed)
```rust
#[derive(Debug)]
@ -24,6 +35,8 @@ impl Person {
Here is a program to test your function.
```rust
use lifetimes::*;
fn main() {
let person = Person::new("Leo");
@ -31,7 +44,7 @@ fn main() {
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

18
subjects/matrix/README.md

@ -2,26 +2,26 @@
### Instructions
Define a data structure to represent a matrix of any size and implement the basic operations for this you will need to follow the next steps:
Define a data structure to represent a matrix of any size and implement the basic operations for this. The next steps need to be followed:
You can use a 2 dimensional Vec<T>'s We will consider a matrix as a rectangular arrangements of scalars.
- You can use a 2 dimensional Vec<T>'s. We will consider a matrix as a rectangular arrangements of scalars.
You have to use the definition of scalars done in the last exercise: `lalgebra_scalar`
- You have to use the definition of scalars done in the exercise: `lalgebra_scalar`
Then define the associated function `identity` that returns the identity matrix of size n
- Then define the associated function `identity` that returns the identity matrix of size n
And the associated function `zero` that returns a matrix of size `row x col` with all the positions filled by zeroes
- Finally, define the associated function `zero` that returns a matrix of size `row x col` with all the positions filled by zeroes
### Notions
[Traits]( https://doc.rust-lang.org/book/ch19-03-advanced-traits.html )
[Traits](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html)
### Expected Functions and Structure
```rust
pub struct Matrix<T>(pub Vec<Vec<T>>);
impl Matrix<T> {
impl <T: Scalar<Item = T>> Matrix<T> {
pub fn new() -> Matrix<T> {
}
@ -38,6 +38,8 @@ impl Matrix<T> {
Here is a program to test your function.
```rust
use matrix::*;
fn main() {
let m: Matrix<u32> = Matrix(vec![vec![0, 0, 0, 0], vec![0, 0, 0, 0], vec![0, 0, 0, 0]]);
println!("{:?}", m);
@ -46,7 +48,7 @@ fn main() {
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

7
subjects/matrix_ops/README.md

@ -4,11 +4,14 @@
In this exercise you will define the basic operations with a matrix starting by implementing the `std::ops::Add` trait
Define the operation + (by defining the trait std::ops::Add) for two matrices remember that two matrices can only be added if they have the same size. Therefore the add method must handle the possibility of failure by returning an Option<T>
Define the operation + (by defining the trait std::ops::Add) for two matrices. Remember that two matrices can only be added if they have the same size. Therefore the add method must handle the possibility of failure by returning an Option<T>.
You will be using your own `Matrix` and `Scalar` defined in the `matrix` and the `lalgebra_scalar` exercises.
### Expected Function
```rust
use crate::{Matrix, Scalar};
use std::ops::{ Add, Sub };
impl Add for Matrix {
@ -25,6 +28,8 @@ impl Sub for Matrix {
Here is a program to test your function
```rust
use matrix_ops::*;
fn main() {
let matrix = Matrix(vec![vec![8, 1], vec![9, 1]]);
let matrix_2 = Matrix(vec![vec![1, 1], vec![1, 1]]);

8
subjects/roman_numbers/README.md

@ -1,11 +1,12 @@
## roman_numbers
### Instructions
Implement the From<u32> Trait to create a roman number from a u32 the roman number should be in subtractive notation (the common way to write roman number I, II, III, IV, V, VI, VII, VIII, IX, X ...)
Implement the `From<u32> Trait` to create a roman number from a `u32`. The roman number should be in subtractive notation (the common way to write roman number I, II, III, IV, V, VI, VII, VIII, IX, X ...)
For this start by defining the digits as `RomanDigit` with the values I, V, X, L, C, D, M and Nulla for 0
Next define RomanNumber as a wrapper to a vector of RomanDigit's And implement the Trait From<u32>
Next define `RomanNumber` as a wrapper to a vector of RomanDigit's And implement the Trait `From<u32>`.
### Expected Functions and Data Structures
@ -40,6 +41,7 @@ Here is a program to test your function.
```rust
use roman_numbers::RomanNumber;
fn main() {
println!("{:?}", RomanNumber::from(32));
println!("{:?}", RomanNumber::from(9));
@ -48,7 +50,7 @@ fn main() {
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run

5
subjects/roman_numbers_iter/README.md

@ -2,9 +2,10 @@
### Instructions
Implement the IntoIterator trait for the `RomanNumber` type to enable using a for loop notation. This implementation must allow taking ownership, borrowing and borrowing mutably
Implement the `IntoIterator` trait for the `RomanNumber` type to enable using a for loop notation. This implementation must allow taking ownership, borrowing and borrowing mutably.
1. Taking ownership (this consumes the RomanNumber)
```rust
for digit in number {
...
@ -12,6 +13,7 @@ for digit in number {
```
2. Borrowing immutably (this preserves the RomanNumber)
```rust
for digit in &number {
@ -19,6 +21,7 @@ for digit in number {
```
3. Borrowing mutably (this allow you to modify the RomanNumber without having to return the ownership)
```rust
for digit in &mut number {

44
subjects/traits/README.md

@ -2,15 +2,18 @@
### Instructions
Imagine you are designing a new video game and you have to create food that they players can take to gain strength.
Imagine you are designing a new video game and you have to create food that the players can eat to gain strength.
There are two types of food for now fruits and meet: fruits increases the strengths by 1 unit and meat increases it by 3 unit.
There are two types of food for now:
- Define both structures fruits and meat:
- Fruit: increase the strength by 4 unit per each kilogram of fruit consumed.
- Meat: has the weight in kilograms -> `weight_in_kg` (which is the weight of the whole piece) and the fat_content which corresponds to the percentage of the weight which is pure fat (the rest is consider protein) each kilogram of protein gives 4 units of `strenght` and each kilogram of fat gives 9 units of `strength`.
Define the std::fmt::Display trait of the Player structure so using the template {} inside a println! macro will print:
Define the `Food` trait for `Fruit` and `Meat`. The method require method `gives()` represents the energy that the food provides.
- In the first line the name of the player
Implement the `std::fmt::Display` trait for `Player` structure in a way that when using the template `{}` inside a println! macro it will print:
- In the first line, the name of the player
- In the second line the strength, score and the money
- In the third line the weapons
@ -20,7 +23,7 @@ Define the std::fmt::Display trait of the Player structure so using the template
#[derive(Debug)]
pub struct Player {
pub name: String,
pub strength: u32,
pub strength: f64,
pub score: i32,
pub money: i32,
pub weapons: Vec<String>,
@ -54,12 +57,17 @@ impl Food for Meat {
### Usage
Here is a program to test your function.
Here is a program to test your functions and traits.
```rust
use traits::*;
fn main() {
let apple = Fruit { weight_in_kg: 1.0 };
assert_eq!(apple.gives(), 4);
println!("this apple gives {} units of strength", apple.gives());
let steak = Meat {
weight_in_kg: 1.0,
fat_content: 1.0,
@ -67,27 +75,33 @@ fn main() {
let mut player1 = Player {
name: String::from("player1"),
strength: 1,
strength: 1.0,
score: 0,
money: 0,
weapons: vec![String::from("knife")],
};
println!("Before eating {:?}", player1);
player1.eat(apple);
println!("After eating an apple\n{:?}", player1);
println!("After eating an apple\n{}", player1);
player1.eat(steak);
println!("After eating a steak\n{:?}", player1);
println!("After eating a steak\n{}", player1);
}
```
And its output
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
Before eating Player { name: "player1", strength: 1, score: 0, money: 0, weapons: ["knife"] }
this apple gives 4 units of strength
Before eating Player { name: "player1", strength: 1.0, score: 0, money: 0, weapons: ["knife"] }
After eating an apple
Player { name: "player1", strength: 5, score: 0, money: 0, weapons: ["knife"] }
player1
Strength: 5, Score: 0, Money: 0
Weapons: ["knife"]
After eating a steak
Player { name: "player1", strength: 14, score: 0, money: 0, weapons: ["knife"] }
player1
Strength: 14, Score: 0, Money: 0
Weapons: ["knife"]
student@ubuntu:~/[[ROOT]]/test$
```

2
subjects/vector_operations/README.md

@ -2,7 +2,7 @@
### Instructions
Define the structures ThreeDvector that represents a 3 dimensional vector in (for convention in physics the vector are represented as ai + bj + ck where a, b, and c are real numbers and i, j and k represent the direction x,y and z respectively in the Cartesian plane there for we use the names i, j and k for the fields in the ThreeDVector structure
Define the structure `ThreeDvector` that represents a 3 dimensional vector in (for convention in physics the vector are represented as ai + bj + ck where a, b, and c are real numbers and i, j and k represent the direction x,y and z respectively in the Cartesian plane there for we use the names i, j and k for the fields in the ThreeDVector structure
Look how the operations Addition and Subtraction work for a 3 dimensional vector and implement them by implementing the std::ops::Add and std::ops::Sub traits

Loading…
Cancel
Save