Compare commits
3 Commits
master
...
better-cla
Author | SHA1 | Date |
---|---|---|
Dorian | 2dafc1f321 | |
Dorian | 8086a18181 | |
Dorian | 790bc56831 |
10
Cargo.toml
10
Cargo.toml
|
@ -7,11 +7,7 @@ license = "Apache-2.0"
|
|||
|
||||
[lib]
|
||||
name = "unit_converter"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.8"
|
||||
|
||||
[features]
|
||||
extension-module = ["pyo3/extension-module"]
|
||||
default = ["extension-module"]
|
||||
[dependencies]
|
||||
pyo3 = { version = "0.8", features = ["extension-module"] }
|
||||
|
|
|
@ -20,13 +20,8 @@ Insure the following dependencies are in place:
|
|||
1. Build the rust crate first: `cargo build`
|
||||
1. Install dependencies and run in a virtualenv: `pipenv install && pipenv shell`
|
||||
1. Create the Python package with: `maturin build`
|
||||
1. Run the Python tests: `pytest test.py batch_test.py`
|
||||
1. Run the Rust test: `cargo test --no-default-features`
|
||||
1. Run the tests: `pytest test.py`
|
||||
|
||||
## Documentation
|
||||
|
||||
* [PyO3 Python - Rust bindings](https://pyo3.rs/master/get_started.html)
|
||||
* Windchill calculations:
|
||||
* [PDF from US Gov](https://www.weather.gov/media/epz/wxcalc/windChill.pdf)
|
||||
* [Calculation in Celsius and kph](https://www.calcunation.com/calculator/wind-chill-celsius.php)
|
||||
* [Windchill Calculator](https://www.weather.gov/epz/wxcalc_windchill)
|
||||
|
|
|
@ -2,7 +2,8 @@ import random
|
|||
|
||||
import pytest
|
||||
|
||||
import unit_converter
|
||||
import unit_converter as rust
|
||||
import py_unit_converter as py
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
|
@ -12,13 +13,9 @@ def batch_numbers():
|
|||
# e.g. return [random.random() * 100 for x in range(1000000)]
|
||||
|
||||
|
||||
def batch_python_unit_converter(temperatures):
|
||||
return [celsius * 1.8 + 32.0 for celsius in temperatures]
|
||||
|
||||
|
||||
def test_using_python_batch(benchmark, batch_numbers):
|
||||
benchmark(batch_python_unit_converter, batch_numbers)
|
||||
benchmark(py.batch_converter, batch_numbers)
|
||||
|
||||
|
||||
def test_using_rust_batch(benchmark, batch_numbers):
|
||||
benchmark(unit_converter.batch_convert_to_fahrenheit, batch_numbers)
|
||||
benchmark(rust.batch_converter, batch_numbers)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
class Temperature:
|
||||
def __init__(self, celsius):
|
||||
self.celsius = celsius
|
||||
|
||||
def to_fahrenheit(self):
|
||||
return self.celsius * 1.8 + 32.0
|
||||
|
||||
|
||||
def batch_converter(temperatures):
|
||||
return [
|
||||
Temperature(temperature).to_fahrenheit()
|
||||
for temperature in temperatures
|
||||
]
|
33
src/lib.rs
33
src/lib.rs
|
@ -24,45 +24,44 @@ impl Temperature {
|
|||
}
|
||||
|
||||
fn windchill(&self, wind_speed_kph: f32) -> f32 {
|
||||
// From https://www.weather.gov/media/epz/wxcalc/windChill.pdf
|
||||
// And https://www.calcunation.com/calculator/wind-chill-celsius.php
|
||||
13.12 + (0.6215 * self.celsius) - (11.37 * wind_speed_kph.powf(0.16))
|
||||
+ (0.3965 * self.celsius * wind_speed_kph.powf(0.16))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn convert_to_fahrenheit(celsius: f32) -> f32 {
|
||||
celsius * 1.8 + 32.0
|
||||
}
|
||||
// Refer to: https://www.weather.gov/epz/wxcalc_windchill
|
||||
// TODO: Add a test that -20 C and 32 kph feels like -32.9
|
||||
|
||||
#[pyfunction]
|
||||
fn batch_convert_to_fahrenheit(celsius: Vec<f32>) -> Vec<f32> {
|
||||
celsius
|
||||
fn batch_converter(temperatures: Vec<f32>) -> Vec<f32> {
|
||||
temperatures
|
||||
.iter()
|
||||
.map(|temperature| convert_to_fahrenheit(temperature.clone()))
|
||||
.map(|temperature| {
|
||||
let temp = Temperature {
|
||||
celsius: temperature.clone(),
|
||||
};
|
||||
temp.to_fahrenheit()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
fn unit_converter(_py: Python, module: &PyModule) -> PyResult<()> {
|
||||
module.add_wrapped(wrap_pyfunction!(convert_to_fahrenheit))?;
|
||||
module.add_wrapped(wrap_pyfunction!(batch_convert_to_fahrenheit))?;
|
||||
module.add_class::<Temperature>()?;
|
||||
module.add_wrapped(wrap_pyfunction!(batch_converter))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::{convert_to_fahrenheit, Temperature};
|
||||
use crate::Temperature;
|
||||
|
||||
#[test]
|
||||
fn conversion_celsius_to_fahrenheit() {
|
||||
assert_eq!(convert_to_fahrenheit(25.0), 77.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windchill_test() {
|
||||
let temperature = Temperature{ celsius: -20.0 };
|
||||
assert_eq!(temperature.windchill(32.0).round(), -33.0);
|
||||
let temperature = Temperature { celsius: 25.0 };
|
||||
assert_eq!(temperature.to_fahrenheit(), 77.0);
|
||||
}
|
||||
}
|
||||
|
|
18
test.py
18
test.py
|
@ -1,20 +1,14 @@
|
|||
import random
|
||||
|
||||
import unit_converter
|
||||
|
||||
|
||||
def python_unit_converter(celsius):
|
||||
return celsius * 1.8 + 32.0
|
||||
import unit_converter as rust
|
||||
import py_unit_converter as py
|
||||
|
||||
|
||||
def test_using_unit_converter():
|
||||
assert unit_converter.convert_to_fahrenheit(25.0) == 77.0
|
||||
assert python_unit_converter(25.0) == 77.0
|
||||
|
||||
|
||||
def test_windchill():
|
||||
temperature = unit_converter.Temperature(-20.0)
|
||||
assert round(temperature.windchill(32.0), 1) == -32.9
|
||||
rusty = rust.Temperature(25.0)
|
||||
snakey = py.Temperature(25.0)
|
||||
assert rusty.to_fahrenheit() == 77.0
|
||||
assert snakey.to_fahrenheit() == 77.0
|
||||
|
||||
|
||||
def test_using_python_constant(benchmark):
|
||||
|
|
Loading…
Reference in New Issue