diff --git a/rust/tests/blood_types_test/Cargo.lock b/rust/tests/blood_types_test/Cargo.lock new file mode 100644 index 00000000..aa4b693b --- /dev/null +++ b/rust/tests/blood_types_test/Cargo.lock @@ -0,0 +1,12 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blood_types" +version = "0.1.0" + +[[package]] +name = "blood_types_test" +version = "0.1.0" +dependencies = [ + "blood_types", +] diff --git a/rust/tests/blood_types_test/Cargo.toml b/rust/tests/blood_types_test/Cargo.toml new file mode 100644 index 00000000..e90cec5d --- /dev/null +++ b/rust/tests/blood_types_test/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "blood_types_test" +version = "0.1.0" +authors = ["Augusto "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +blood_types = { path = "../../../../rust-piscine-solutions/blood_types"} diff --git a/rust/tests/blood_types_test/src/main.rs b/rust/tests/blood_types_test/src/main.rs new file mode 100644 index 00000000..260cd8ba --- /dev/null +++ b/rust/tests/blood_types_test/src/main.rs @@ -0,0 +1,187 @@ +// In this exercise you will create a model of and gives an API to +// deal with blood types + +// Start creating 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, create 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: +// ```rust +// let a_neg: BloodType = "A-".parse(); +// ``` +//) + +// Implement the std::cmp::Ord trait to make possible to sort a vector +// or array of BloodType's + +// Implement the trait std::Debug for BloodType allowing to print a +// vector such as [BloodType { antigen: A, rh_factor: Positive}, +// BloodType{ antigen: B, rh_factor: Negative}] as [ A+, A-] using the +// formatting {:?} + +// Write three methods for BloodType: +// - can_receive_from(&self, other: BloodType) -> bool {}: which +// returns true if self can receive blood from `other` blood type +// - donors(&self) -> Vec: which returns +// all the blood types that can give blood to self +// - recipients(&self) -> Vec: which returns all the blood +// types that can receive blood from self + +#[allow(unused_imports)] +use blood_types::{Antigen, BloodType, RhFactor}; + +fn main() { + let blood_type: BloodType = "O+".parse().unwrap(); + println!("recipients of O+ {:?}", blood_type.recipients()); + println!("donors of O+ {:?}", blood_type.donors()); + let another_blood_type: BloodType = "A-".parse().unwrap(); + println!( + "donors of O+ can receive from {:?} {:?}", + &another_blood_type, + blood_type.can_receive_from(&another_blood_type) + ); +} + +#[test] +fn compatible_ab_neg_with_a_pos() { + let blood_type: BloodType = "AB-".parse().unwrap(); + let other_bt: BloodType = "A+".parse().unwrap(); + assert!(!blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn compatible_a_neg_with_a_pos() { + let blood_type: BloodType = "A-".parse().unwrap(); + let other_bt: BloodType = "A+".parse().unwrap(); + assert!(!blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn compatible_a_neg_with_ab_neg() { + let blood_type: BloodType = "AB-".parse().unwrap(); + let other_bt: BloodType = "A-".parse().unwrap(); + assert!(blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn compatible_ab_neg_with_o_pos() { + let blood_type: BloodType = "AB-".parse().unwrap(); + let other_bt: BloodType = "O+".parse().unwrap(); + assert!(!blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn compatible_ab_pos_with_o_pos() { + let blood_type: BloodType = "AB+".parse().unwrap(); + let other_bt: BloodType = "O+".parse().unwrap(); + assert!(blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn test_compatible_ab_neg_with_o_neg() { + let blood_type: BloodType = "AB-".parse().unwrap(); + let other_bt: BloodType = "O-".parse().unwrap(); + assert!(blood_type.can_receive_from(&other_bt)); +} + +#[test] +fn test_antigen_ab_from_str() { + let blood = "AB+"; + let blood_type: BloodType = blood.parse().unwrap(); + assert_eq!(blood_type.antigen, Antigen::AB); + assert_eq!(blood_type.rh_factor, RhFactor::Positive); +} + +#[test] +fn test_antigen_a_from_str() { + let blood = "A-"; + let blood_type = blood.parse::().unwrap(); + assert_eq!(blood_type.antigen, Antigen::A); + assert_eq!(blood_type.rh_factor, RhFactor::Negative); +} + +#[test] +#[should_panic] +fn test_unexistent_blood_type() { + let _blood_type: BloodType = "AO-".parse().unwrap(); +} + +#[test] +fn test_donors() { + let mut givers = "AB+".parse::().unwrap().donors(); + println!("Before sorting {:?}", &givers); + givers.sort(); + println!("{:?}", &givers); + let mut expected = vec![ + "AB-".parse::().unwrap(), + "A-".parse().unwrap(), + "B-".parse().unwrap(), + "O-".parse().unwrap(), + "AB+".parse().unwrap(), + "A+".parse().unwrap(), + "B+".parse().unwrap(), + "O+".parse().unwrap(), + ]; + expected.sort(); + assert_eq!(givers, expected); +} + +#[test] +fn test_a_neg_donors() { + let mut givers = "A-".parse::().unwrap().donors(); + givers.sort(); + let mut expected: Vec = vec!["A-".parse().unwrap(), "O-".parse().unwrap()]; + expected.sort(); + assert_eq!(givers, expected); +} + +#[test] +fn test_o_neg_donors() { + let mut givers = "O-".parse::().unwrap().donors(); + givers.sort(); + let mut expected: Vec = vec!["O-".parse().unwrap()]; + expected.sort(); + assert_eq!(givers, expected); +} + +#[test] +fn test_ab_pos_recipients() { + let mut recipients: Vec = "AB+".parse::().unwrap().recipients(); + recipients.sort(); + let mut expected: Vec = vec!["AB+".parse().unwrap()]; + expected.sort(); + assert_eq!(recipients, expected); +} + +#[test] +fn test_a_neg_recipients() { + let mut recipients = "A-".parse::().unwrap().recipients(); + recipients.sort(); + let mut expected: Vec = vec![ + "A-".parse().unwrap(), + "AB+".parse().unwrap(), + "A+".parse().unwrap(), + "AB-".parse().unwrap(), + ]; + expected.sort(); + assert_eq!(recipients, expected); +} + +#[test] +fn test_output() { + let blood_type: BloodType = "O+".parse().unwrap(); + println!("recipients of O+ {:?}", blood_type.recipients()); + println!("donors of O+ {:?}", blood_type.donors()); + let another_blood_type: BloodType = "A-".parse().unwrap(); + println!( + "donors of O+ can receive from {:?} {:?}", + &another_blood_type, + blood_type.can_receive_from(&another_blood_type) + ); +} diff --git a/subjects/blood_types/README.md b/subjects/blood_types/README.md new file mode 100644 index 00000000..5aba94f1 --- /dev/null +++ b/subjects/blood_types/README.md @@ -0,0 +1,109 @@ +## blood_types + +### Instructions + +In this exercise you will create a model data model of blood types and an API to deal with blood types + +Start by creating 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, create 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: + +```rust + let a_neg: BloodType = "A-".parse(); +``` + +- Implement the std::cmp::Ord trait to make possible to sort a vector or array of BloodType's + +- Implement the trait std::Debug for BloodType allowing to print a vector such as [BloodType { antigen: A, rh_factor: Positive}, BloodType{ antigen: B, rh_factor: Negative}] as [ A+, A-] using the formatting {:?} + +Write three methods for BloodType: + +- `can_receive_from`: which returns true if self can receive blood from `other` blood type +- `donors`: which returns all the blood types that can give blood to self +- `recipients`: which returns all the blood types that can receive blood from self + +### Expected Functions and Structures + +```rust +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] +pub enum Antigen { + A, + AB, + B, + O, +} + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +enum RhFactor { + Positive, + Negative, +} + +#[derive(PartialEq, Eq, PartialOrd)] +pub struct BloodType { + pub antigen: Antigen, + pub rh_factor: RhFactor, +} + +use std::cmp::{Ord, Ordering}; + +use std::str::FromStr; + +impl FromStr for Antigen { +} + +impl FromStr for RhFactor { +} + +impl Ord for BloodType { +} + +impl FromStr for BloodType { +} + +use std::fmt::{self, Debug}; + +impl Debug for BloodType { +} + +impl BloodType { + pub fn can_receive_from(&self, other: &Self) -> bool { + } + + pub fn donors(&self) -> Vec { + } + + pub fn recipients(&self) -> Vec { +} +``` + +### Usage + +Here is a program to test your function. + +```rust +fn main() { + let blood_type: BloodType = "O+".parse().unwrap(); + println!("recipients of O+ {:?}", blood_type.recipients()); + println!("donors of O+ {:?}", blood_type.donors()); + let another_blood_type: BloodType = "A-".parse().unwrap(); + println!( + "donors of O+ can receive from {:?} {:?}", + &another_blood_type, + blood_type.can_receive_from(&another_blood_type) + ); +} +``` + +And its output + +```console +student@ubuntu:~/[[ROOT]]/test$ cargo run +recipients of O+ [AB+, O+, A+, B+] +donors of O+ [O+, O-] +donors of O+ can receive from A- false +student@ubuntu:~/[[ROOT]]/test$ +``` diff --git a/subjects/lalgebra_vector/README.md b/subjects/lalgebra_vector/README.md index 24b3a6b3..d4c7fbc5 100644 --- a/subjects/lalgebra_vector/README.md +++ b/subjects/lalgebra_vector/README.md @@ -51,5 +51,5 @@ And its output student@ubuntu:~/[[ROOT]]/test$ cargo run Some(3) Some(Vector([5, 1, -6])) -tudent@ubuntu:~/[[ROOT]]/test$ +student@ubuntu:~/[[ROOT]]/test$ ```