From 9bbee41b98248903411432cab636782c049cbb9e Mon Sep 17 00:00:00 2001 From: Ali Ghahremani Date: Sun, 20 Oct 2024 21:32:38 +0330 Subject: [PATCH 1/6] feat: length_conversion implemented --- src/conversions/length_conversion.rs | 107 +++++++++++++++++++++++++++ src/conversions/mod.rs | 2 + 2 files changed, 109 insertions(+) create mode 100644 src/conversions/length_conversion.rs diff --git a/src/conversions/length_conversion.rs b/src/conversions/length_conversion.rs new file mode 100644 index 00000000000..ac1fce6f497 --- /dev/null +++ b/src/conversions/length_conversion.rs @@ -0,0 +1,107 @@ +/// Author : https://github.com/ali77gh +/// Conversion of length units. +/// +/// Available Units: +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Millimeter +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Centimeter +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Meter +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Kilometer +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Inch +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Foot +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Yard +/// -> Wikipedia reference: https://en.wikipedia.org/wiki/Mile + +/// Universal Units on Length +pub enum LengthUnit { + Millimeter, + Centimeter, + Meter, + Kilometer, + Inch, + Foot, + Yard, + Mile, +} + +/// Private methods +/// This is a n*n problem +/// It's gonna be 56 functions or 56 cases in match statement +/// It's hard to write code for every unit to unit so I solve this problem +/// by converting input to meter and than convert it to output +impl LengthUnit { + /// This function give you a number (let's call it n) + /// So if you multiple a value in this unit to n you will get meters + /// + /// m * in-unit = meter + fn get_unit_to_meter_multiplier(&self) -> f64 { + match self { + LengthUnit::Millimeter => 0.001, + LengthUnit::Centimeter => 0.01, + LengthUnit::Meter => 1.0, + LengthUnit::Kilometer => 1000.0, + LengthUnit::Inch => 0.0254, + LengthUnit::Foot => 0.3048, + LengthUnit::Yard => 0.9144, + LengthUnit::Mile => 1609.34, + } + } + + /// This function give you a number (let's call it n) + /// So if you multiple a value in meters to n you will get unit + /// + /// m * meter = in-unit + fn get_unit_from_meter_multiplier(&self) -> f64 { + 1.0 / self.get_unit_to_meter_multiplier() + } +} + +/// This function will convert a value in unit of [from] to value in unit of [to] +/// by first converting it to meter and than convert it to destination unit +pub fn length_conversion(input: f64, from: LengthUnit, to: LengthUnit) -> f64 { + input * from.get_unit_to_meter_multiplier() * to.get_unit_from_meter_multiplier() +} + +#[cfg(test)] +mod length_conversion_tests { + use super::LengthUnit::*; + use super::*; + + #[test] + fn meter_to_other() { + assert_eq!(length_conversion(4f64, Meter, Millimeter), 4000.0); + assert_eq!(length_conversion(4f64, Meter, Foot), 13.123359580052492); + assert_eq!(length_conversion(1.0, Meter, Kilometer), 0.001); + } + + #[test] + fn other_to_meter() { + assert_eq!(length_conversion(4f64, Millimeter, Meter), 0.004); + assert_eq!(length_conversion(2.0, Foot, Meter), 0.6096); + assert_eq!(length_conversion(1.0, Inch, Meter), 0.0254); + assert_eq!(length_conversion(4.0, Yard, Meter), 3.6576); + assert_eq!(length_conversion(3.0, Foot, Meter), 0.9144000000000001); + } + + #[test] + fn other_to_other() { + // --------------- + assert_eq!(length_conversion(1.0, Kilometer, Inch), 39370.07874015748); + assert_eq!(length_conversion(3.0, Kilometer, Mile), 1.8641182099494205); + assert_eq!(length_conversion(4.0, Foot, Yard), 1.3333333333333335); + assert_eq!(length_conversion(2.0, Inch, Mile), 3.156573502181019e-5); + assert_eq!(length_conversion(2.0, Centimeter, Millimeter), 20.0); + assert_eq!( + length_conversion(2.0, Centimeter, Yard), + 0.021872265966754158 + ); + assert_eq!(length_conversion(4.0, Yard, Kilometer), 0.0036576); + assert_eq!(length_conversion(3.0, Foot, Inch), 36.00000000000001); + assert_eq!(length_conversion(4.0, Mile, Kilometer), 6.43736); + assert_eq!(length_conversion(2.0, Mile, Inch), 126719.68503937007); + assert_eq!(length_conversion(3.0, Millimeter, Centimeter), 0.3); + assert_eq!( + length_conversion(3.0, Millimeter, Inch), + 0.11811023622047245 + ); + } +} diff --git a/src/conversions/mod.rs b/src/conversions/mod.rs index af02e16a631..f93cb7f3422 100644 --- a/src/conversions/mod.rs +++ b/src/conversions/mod.rs @@ -4,6 +4,7 @@ mod decimal_to_binary; mod decimal_to_hexadecimal; mod hexadecimal_to_binary; mod hexadecimal_to_decimal; +mod length_conversion; mod octal_to_binary; mod octal_to_decimal; pub use self::binary_to_decimal::binary_to_decimal; @@ -12,5 +13,6 @@ pub use self::decimal_to_binary::decimal_to_binary; pub use self::decimal_to_hexadecimal::decimal_to_hexadecimal; pub use self::hexadecimal_to_binary::hexadecimal_to_binary; pub use self::hexadecimal_to_decimal::hexadecimal_to_decimal; +pub use self::length_conversion::length_conversion; pub use self::octal_to_binary::octal_to_binary; pub use self::octal_to_decimal::octal_to_decimal; From da6b3e3141d711ba5cc7edad0ab6e246dd0fd4f1 Mon Sep 17 00:00:00 2001 From: Ali Ghahremani Date: Sun, 20 Oct 2024 21:42:30 +0330 Subject: [PATCH 2/6] link: added to DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index f4e1fa0e58c..8ba43992084 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -55,6 +55,7 @@ * [Hexadecimal To Decimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/hexadecimal_to_decimal.rs) * [Octal To Binary](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/octal_to_binary.rs) * [Octal To Decimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/octal_to_decimal.rs) + * [Length Conversions](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/length_conversion.rs) * Data Structures * [Avl Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/avl_tree.rs) * [B Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/b_tree.rs) From ef7fe077548f70e8a98d0a18eccfdb04ee7fbcf8 Mon Sep 17 00:00:00 2001 From: Ali Ghahremani Date: Wed, 23 Oct 2024 23:24:31 +0330 Subject: [PATCH 3/6] test: zero_to_zero test added --- src/conversions/length_conversion.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/conversions/length_conversion.rs b/src/conversions/length_conversion.rs index ac1fce6f497..95610c72feb 100644 --- a/src/conversions/length_conversion.rs +++ b/src/conversions/length_conversion.rs @@ -12,6 +12,7 @@ /// -> Wikipedia reference: https://en.wikipedia.org/wiki/Mile /// Universal Units on Length +#[derive(Clone, Copy)] pub enum LengthUnit { Millimeter, Centimeter, @@ -84,7 +85,6 @@ mod length_conversion_tests { #[test] fn other_to_other() { - // --------------- assert_eq!(length_conversion(1.0, Kilometer, Inch), 39370.07874015748); assert_eq!(length_conversion(3.0, Kilometer, Mile), 1.8641182099494205); assert_eq!(length_conversion(4.0, Foot, Yard), 1.3333333333333335); @@ -104,4 +104,17 @@ mod length_conversion_tests { 0.11811023622047245 ); } + + #[test] + fn zero_to_zero() { + let units = vec![ + Millimeter, Centimeter, Meter, Kilometer, Inch, Foot, Yard, Mile, + ]; + + for u1 in units.clone() { + for u2 in units.clone() { + assert_eq!(length_conversion(0f64, u1, u2), 0f64); + } + } + } } From b52319777108bd6317a880a25b0e35628a816326 Mon Sep 17 00:00:00 2001 From: Ali Ghahremani Date: Wed, 23 Oct 2024 23:51:01 +0330 Subject: [PATCH 4/6] test: length_of_one_meter added --- src/conversions/length_conversion.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/conversions/length_conversion.rs b/src/conversions/length_conversion.rs index 95610c72feb..541f032258f 100644 --- a/src/conversions/length_conversion.rs +++ b/src/conversions/length_conversion.rs @@ -12,7 +12,7 @@ /// -> Wikipedia reference: https://en.wikipedia.org/wiki/Mile /// Universal Units on Length -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum LengthUnit { Millimeter, Centimeter, @@ -64,6 +64,8 @@ pub fn length_conversion(input: f64, from: LengthUnit, to: LengthUnit) -> f64 { #[cfg(test)] mod length_conversion_tests { + use std::collections::HashMap; + use super::LengthUnit::*; use super::*; @@ -117,4 +119,21 @@ mod length_conversion_tests { } } } + + #[test] + fn length_of_one_meter() { + let map = HashMap::from([ + (Millimeter, 1000f64), + (Centimeter, 100f64), + (Kilometer, 0.001f64), + (Inch, 39.37007874015748f64), + (Foot, 3.280839895013123f64), + (Yard, 1.0936132983377078f64), + (Mile, 0.0006213727366498068f64), + ]); + + for (k, v) in map { + assert_eq!(length_conversion(1f64, Meter, k), v); + } + } } From ea60fed02ae820e8968b6c8ce8e7c205cd6f66b1 Mon Sep 17 00:00:00 2001 From: Ali Ghahremani Date: Sat, 26 Oct 2024 22:28:47 +0330 Subject: [PATCH 5/6] fix: apply @vil02 suggestions --- src/conversions/length_conversion.rs | 97 +++++++++------------------- 1 file changed, 31 insertions(+), 66 deletions(-) diff --git a/src/conversions/length_conversion.rs b/src/conversions/length_conversion.rs index 541f032258f..42dc10132f3 100644 --- a/src/conversions/length_conversion.rs +++ b/src/conversions/length_conversion.rs @@ -29,37 +29,35 @@ pub enum LengthUnit { /// It's gonna be 56 functions or 56 cases in match statement /// It's hard to write code for every unit to unit so I solve this problem /// by converting input to meter and than convert it to output -impl LengthUnit { - /// This function give you a number (let's call it n) - /// So if you multiple a value in this unit to n you will get meters - /// - /// m * in-unit = meter - fn get_unit_to_meter_multiplier(&self) -> f64 { - match self { - LengthUnit::Millimeter => 0.001, - LengthUnit::Centimeter => 0.01, - LengthUnit::Meter => 1.0, - LengthUnit::Kilometer => 1000.0, - LengthUnit::Inch => 0.0254, - LengthUnit::Foot => 0.3048, - LengthUnit::Yard => 0.9144, - LengthUnit::Mile => 1609.34, - } +/// This function give you a number (let's call it n) +/// So if you multiple a value in this unit to n you will get meters +/// +/// m * in-unit = meter +fn unit_to_meter_multiplier(from: LengthUnit) -> f64 { + match from { + LengthUnit::Millimeter => 0.001, + LengthUnit::Centimeter => 0.01, + LengthUnit::Meter => 1.0, + LengthUnit::Kilometer => 1000.0, + LengthUnit::Inch => 0.0254, + LengthUnit::Foot => 0.3048, + LengthUnit::Yard => 0.9144, + LengthUnit::Mile => 1609.34, } +} - /// This function give you a number (let's call it n) - /// So if you multiple a value in meters to n you will get unit - /// - /// m * meter = in-unit - fn get_unit_from_meter_multiplier(&self) -> f64 { - 1.0 / self.get_unit_to_meter_multiplier() - } +fn unit_to_meter(input: f64, from: LengthUnit) -> f64 { + input * unit_to_meter_multiplier(from) +} + +fn meter_to_unit(input: f64, to: LengthUnit) -> f64 { + input / unit_to_meter_multiplier(to) } /// This function will convert a value in unit of [from] to value in unit of [to] /// by first converting it to meter and than convert it to destination unit pub fn length_conversion(input: f64, from: LengthUnit, to: LengthUnit) -> f64 { - input * from.get_unit_to_meter_multiplier() * to.get_unit_from_meter_multiplier() + meter_to_unit(unit_to_meter(input, from), to) } #[cfg(test)] @@ -69,44 +67,6 @@ mod length_conversion_tests { use super::LengthUnit::*; use super::*; - #[test] - fn meter_to_other() { - assert_eq!(length_conversion(4f64, Meter, Millimeter), 4000.0); - assert_eq!(length_conversion(4f64, Meter, Foot), 13.123359580052492); - assert_eq!(length_conversion(1.0, Meter, Kilometer), 0.001); - } - - #[test] - fn other_to_meter() { - assert_eq!(length_conversion(4f64, Millimeter, Meter), 0.004); - assert_eq!(length_conversion(2.0, Foot, Meter), 0.6096); - assert_eq!(length_conversion(1.0, Inch, Meter), 0.0254); - assert_eq!(length_conversion(4.0, Yard, Meter), 3.6576); - assert_eq!(length_conversion(3.0, Foot, Meter), 0.9144000000000001); - } - - #[test] - fn other_to_other() { - assert_eq!(length_conversion(1.0, Kilometer, Inch), 39370.07874015748); - assert_eq!(length_conversion(3.0, Kilometer, Mile), 1.8641182099494205); - assert_eq!(length_conversion(4.0, Foot, Yard), 1.3333333333333335); - assert_eq!(length_conversion(2.0, Inch, Mile), 3.156573502181019e-5); - assert_eq!(length_conversion(2.0, Centimeter, Millimeter), 20.0); - assert_eq!( - length_conversion(2.0, Centimeter, Yard), - 0.021872265966754158 - ); - assert_eq!(length_conversion(4.0, Yard, Kilometer), 0.0036576); - assert_eq!(length_conversion(3.0, Foot, Inch), 36.00000000000001); - assert_eq!(length_conversion(4.0, Mile, Kilometer), 6.43736); - assert_eq!(length_conversion(2.0, Mile, Inch), 126719.68503937007); - assert_eq!(length_conversion(3.0, Millimeter, Centimeter), 0.3); - assert_eq!( - length_conversion(3.0, Millimeter, Inch), - 0.11811023622047245 - ); - } - #[test] fn zero_to_zero() { let units = vec![ @@ -122,7 +82,7 @@ mod length_conversion_tests { #[test] fn length_of_one_meter() { - let map = HashMap::from([ + let meter_in_different_units = HashMap::from([ (Millimeter, 1000f64), (Centimeter, 100f64), (Kilometer, 0.001f64), @@ -131,9 +91,14 @@ mod length_conversion_tests { (Yard, 1.0936132983377078f64), (Mile, 0.0006213727366498068f64), ]); - - for (k, v) in map { - assert_eq!(length_conversion(1f64, Meter, k), v); + for (input_unit, input_value) in &meter_in_different_units { + for (target_unit, target_value) in &meter_in_different_units { + assert!( + num_traits::abs( + length_conversion(*input_value, *input_unit, *target_unit) - *target_value + ) < 0.0000001 + ); + } } } } From e8c582168e7ba8bee2471a559bc915a0af4d8dfe Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Sun, 27 Oct 2024 20:51:15 +0100 Subject: [PATCH 6/6] docs: remove redundant comments --- src/conversions/length_conversion.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/conversions/length_conversion.rs b/src/conversions/length_conversion.rs index 42dc10132f3..4a056ed3052 100644 --- a/src/conversions/length_conversion.rs +++ b/src/conversions/length_conversion.rs @@ -11,7 +11,6 @@ /// -> Wikipedia reference: https://en.wikipedia.org/wiki/Yard /// -> Wikipedia reference: https://en.wikipedia.org/wiki/Mile -/// Universal Units on Length #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum LengthUnit { Millimeter, @@ -24,15 +23,6 @@ pub enum LengthUnit { Mile, } -/// Private methods -/// This is a n*n problem -/// It's gonna be 56 functions or 56 cases in match statement -/// It's hard to write code for every unit to unit so I solve this problem -/// by converting input to meter and than convert it to output -/// This function give you a number (let's call it n) -/// So if you multiple a value in this unit to n you will get meters -/// -/// m * in-unit = meter fn unit_to_meter_multiplier(from: LengthUnit) -> f64 { match from { LengthUnit::Millimeter => 0.001,