Compare commits

...

3 Commits

Author SHA1 Message Date
Dorian 2dafc1f321 Add in a windchill calculator. 2019-11-06 17:23:25 -05:00
Dorian 8086a18181 Attempt a more complex example. 2019-11-06 09:24:35 -05:00
Dorian 790bc56831 Work towards a better example. 2019-11-06 09:01:27 -05:00
4 changed files with 66 additions and 31 deletions

View File

@ -2,7 +2,8 @@ import random
import pytest import pytest
import unit_converter import unit_converter as rust
import py_unit_converter as py
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
@ -12,13 +13,9 @@ def batch_numbers():
# e.g. return [random.random() * 100 for x in range(1000000)] # 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): 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): def test_using_rust_batch(benchmark, batch_numbers):
benchmark(unit_converter.batch_convert_celsius_to_fahrenheit, batch_numbers) benchmark(rust.batch_converter, batch_numbers)

13
py_unit_converter.py Normal file
View File

@ -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
]

View File

@ -5,33 +5,63 @@ extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
#[pyfunction] #[pyclass(module = "unit_converter")]
fn convert_celsius_to_fahrenheit(celsius: f32) -> f32 { struct Temperature {
celsius * 1.8 + 32.0 celsius: f32,
} }
#[pymethods]
impl Temperature {
#[new]
fn new(obj: &PyRawObject, temperature: f32) {
obj.init(Temperature {
celsius: temperature,
});
}
fn to_fahrenheit(&self) -> f32 {
self.celsius * 1.8 + 32.0
}
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))
}
}
// Refer to: https://www.weather.gov/epz/wxcalc_windchill
// TODO: Add a test that -20 C and 32 kph feels like -32.9
#[pyfunction] #[pyfunction]
fn batch_convert_celsius_to_fahrenheit(celsius: Vec<f32>) -> Vec<f32> { fn batch_converter(temperatures: Vec<f32>) -> Vec<f32> {
celsius temperatures
.iter() .iter()
.map(|temperature| convert_celsius_to_fahrenheit(temperature.clone())) .map(|temperature| {
let temp = Temperature {
celsius: temperature.clone(),
};
temp.to_fahrenheit()
})
.collect() .collect()
} }
#[pymodule] #[pymodule]
fn unit_converter(_py: Python, m: &PyModule) -> PyResult<()> { fn unit_converter(_py: Python, module: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(convert_celsius_to_fahrenheit))?; module.add_class::<Temperature>()?;
m.add_wrapped(wrap_pyfunction!(batch_convert_celsius_to_fahrenheit))?; module.add_wrapped(wrap_pyfunction!(batch_converter))?;
Ok(()) Ok(())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::convert_celsius_to_fahrenheit; use crate::Temperature;
#[test] #[test]
fn conversion_celsius_to_fahrenheit() { fn conversion_celsius_to_fahrenheit() {
assert_eq!(convert_celsius_to_fahrenheit(25.0), 77.0); let temperature = Temperature { celsius: 25.0 };
assert_eq!(temperature.to_fahrenheit(), 77.0);
} }
} }

21
test.py
View File

@ -1,19 +1,14 @@
import random import random
import unit_converter import unit_converter as rust
import py_unit_converter as py
def python_unit_converter(celsius):
return celsius * 1.8 + 32.0
def batch_python_unit_converter(temperatures):
return [celsius * 1.8 + 32.0 for celsius in temperatures]
def test_using_unit_converter(): def test_using_unit_converter():
assert unit_converter.convert_celsius_to_fahrenheit(25.0) == 77.0 rusty = rust.Temperature(25.0)
assert python_unit_converter(25.0) == 77.0 snakey = py.Temperature(25.0)
assert rusty.to_fahrenheit() == 77.0
assert snakey.to_fahrenheit() == 77.0
def test_using_python_constant(benchmark): def test_using_python_constant(benchmark):
@ -22,7 +17,7 @@ def test_using_python_constant(benchmark):
def test_using_rust_constant(benchmark): def test_using_rust_constant(benchmark):
result = benchmark(unit_converter.convert_celsius_to_fahrenheit, 25.0) result = benchmark(unit_converter.convert_to_fahrenheit, 25.0)
assert round(result, 3) == round(77.0, 3) assert round(result, 3) == round(77.0, 3)
@ -34,5 +29,5 @@ def test_using_python(benchmark):
def test_using_rust(benchmark): def test_using_rust(benchmark):
temperature = random.random() * 100 temperature = random.random() * 100
result = benchmark(unit_converter.convert_celsius_to_fahrenheit, temperature) result = benchmark(unit_converter.convert_to_fahrenheit, temperature)
assert round(result, 3) == round(python_unit_converter(temperature), 3) assert round(result, 3) == round(python_unit_converter(temperature), 3)