Loading prj_rust_training_1...
rustup doc --std 'slice') Une fonction susceptible d'échouer doit fournir un résultat reposant sur le type standard Result afin de donner une valeur utile (Ok(value)) en cas de succès et une donnée matérialisant l'erreur (Err("error message!")?) en cas d'échec.
rustup doc --std 'f64') Dans un style fonctionnel, la somme d'une séquence de valeurs s'obtient simplement par l'appel
.sum::<T>()(où T représente le type de la somme attendue) accolé à l'itérateur qui fournit les éléments.
"{:?}"qui offre un formatage lisible pour une très grande variété de types.
"{:?}"qui offre un formatage lisible pour une très grande variété de types.
rustup doc --std 'slice') Une fonction susceptible d'échouer doit fournir un résultat reposant sur le type standard Result afin de fournir un résultat utile (Ok(value)) en cas de succès et une donnée matérialisant l'erreur (Err("error message!")?) en cas d'échec.
"{:?}"qui offre un formatage lisible pour une très grande variété de types.
let (left, right) = my_slice.split_at_mut(position);
rustup doc --std 'std::mem::swap'. Lors de la mise au point de cette réalisation, il faudra compléter la fonction principale du programme de la façon suivante :
rustup doc --std 'slice') Pour obtenir un itérateur permettant un parcours en modification d'une séquence d'éléments, nous appliquons la fonction .iter_mut() à cette séquence (une slice ici).
"{:?}"qui offre un formatage lisible pour une très grande variété de types.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! This is the training_1 library
pub mod deeper;
/// Returns the full name of this function at the /// root of the library /// /// # Examples /// ``` /// use training_1::here; /// /// assert_eq!(here(), "training_1::here()"); /// ``` pub fn here() -> &'static str { "training_1::here()" } /* pub fn here_() -> String { "training_1::here()".to_owned() } */
//~~~~ First variant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Returns the mean and the standard deviation of a slice of real values. /// /// The result provides a pair of real values: the mean, then the standard /// deviation.<br> /// If the slice is empty, an error is provided instead of this pair. /// /// # Examples /// ``` /// use training_1::mean_and_std_dev; /// /// let r1 = mean_and_std_dev(&[]); /// assert!(r1.is_err()); /// let r2 = mean_and_std_dev(&[3.0, 3.0]).unwrap(); /// assert_eq!(r2, (3.0, 0.0)); /// let r3 = mean_and_std_dev(&[3.0, 3.0, 9.0, 25.0]).unwrap(); /// assert_eq!(r3, (10.0, 9.0)); /// ``` pub fn mean_and_std_dev( values: &[f64] ) -> Result<(f64, f64), Box<dyn std::error::Error>> { if values.is_empty() { Err("no values for mean_and_std_dev()")?; } let divisor = values.len() as f64; if false { // one possible solution (explicit loops) let mut accum_values = 0.0; for v in values.iter() { accum_values += *v; } let mean = accum_values / divisor; let mut accum_delta_square = 0.0; for v in values.iter() { let delta = *v - mean; accum_delta_square += delta * delta; } let variance = accum_delta_square / divisor; Ok((mean, variance.sqrt())) } else { // a more concise solution (functional style) let mean = values.iter().sum::<f64>() / divisor; let variance = values .iter() .map(|v| { let delta = *v - mean; delta * delta }) .sum::<f64>() / divisor; Ok((mean, variance.sqrt())) } }
/// Adjusts a slice of real values to some expected mean and standard /// deviation. /// /// # Examples /// ``` /// use training_1::{mean_and_std_dev, normalise}; /// /// let mut values = [3.0, 3.0, 9.0, 25.0]; /// let expected_mean = 4.0; /// let expected_std_dev = 4.5; /// normalise(values.as_mut_slice(), expected_mean, expected_std_dev); /// let r = mean_and_std_dev(values.as_slice()).unwrap(); /// assert_eq!(r, (expected_mean, expected_std_dev)); /// ``` pub fn normalise( values: &mut [f64], expected_mean: f64, expected_std_dev: f64, ) { if let Ok((mean, std_dev)) = mean_and_std_dev(values) { let factor = if std_dev != 0.0 { expected_std_dev / std_dev } else { 1.0 }; for v in values.iter_mut() { *v -= mean; *v *= factor; *v += expected_mean; } } }
//~~~~ Second variant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Checks if two slices of integer values are identical but in reverse order. /// /// If the slices are both empty, an error is provided instead of a boolean. /// /// # Examples /// ``` /// use training_1::check_reversed; /// /// assert!(check_reversed(&[], &[]).is_err()); /// assert!(!check_reversed(&[1, 2, 3, 4, 5], &[]).unwrap()); /// assert!(!check_reversed(&[1, 2, 3, 4, 5], &[1, 2, 3, 4, 5]).unwrap()); /// assert!(check_reversed(&[1, 2, 3, 4, 5], &[5, 4, 3, 2, 1]).unwrap()); /// ``` pub fn check_reversed( values1: &[i32], values2: &[i32], ) -> Result<bool, Box<dyn std::error::Error>> { if values1.is_empty() && values2.is_empty() { Err("empty sequences in check_reversed()")? } if false { // one possible solution (explicit loops) if values1.len() != values2.len() { return Ok(false); } for (v1, v2) in values1.iter().zip(values2.iter().rev()) { if v1 != v2 { return Ok(false); } } Ok(true) } else { // a more concise solution (functional style) Ok(values1.len() == values2.len() && values1 .iter() .zip(values2.iter().rev()) .all(|(v1, v2)| v1 == v2)) } }
/// Reverses the order of the integer values in a slice. /// /// # Examples /// ``` /// use training_1::reverse; /// /// let mut values = [1, 2, 3, 4, 5]; /// reverse(values.as_mut_slice()); /// assert_eq!(values, [5, 4, 3, 2, 1]); /// ``` pub fn reverse(values: &mut [i32]) { let (left, right) = values.split_at_mut(values.len() / 2); for (v1, v2) in left.iter_mut().zip(right.iter_mut().rev()) { // one possible solution (explicit usage of a temporary value) // let tmp = *v1; // *v1 = *v2; // *v2 = tmp; // a more concise solution (generic standard feature) std::mem::swap(v1, v2); } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! This is the deeper module
/// Returns the full name of this function in its module /// /// # Examples /// ``` /// use training_1::deeper::there; /// /// assert_eq!(there(), "training_1::deeper::there()"); /// ``` pub fn there() -> &'static str { "training_1::deeper::there()" } /* pub fn there() -> String { "training_1::deeper::there()".to_owned() } */
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fn main() { use training_1::{deeper::there, here}; println!("here() ~~> {}", here()); println!("there() ~~> {}", there());
//~~~~ First variant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use training_1::{mean_and_std_dev, normalise};
fn show_stats(values: &[f64]) { println!( "mean and standard deviation of {:?} ~~> {:?}", values, mean_and_std_dev(values) ); }
let mut values = Vec::new(); show_stats(values.as_slice());
values.push(3.0); values.push(3.0); show_stats(values.as_slice());
values.push(9.0); values.push(25.0); show_stats(values.as_slice());
normalise(values.as_mut_slice(), 4.0, 4.5); show_stats(values.as_slice());
//~~~~ Second variant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use training_1::{check_reversed, reverse};
fn show_reversed( values1: &[i32], values2: &[i32], ) { println!( "{:?} is reversed {:?} ~~> {:?}", values1, values2, check_reversed(values1, values2) ); }
let mut values1 = Vec::new(); let mut values2 = Vec::new(); show_reversed(values1.as_slice(), values2.as_slice()); values1 = vec![1, 2, 3, 4, 5]; show_reversed(values1.as_slice(), values2.as_slice()); values2 = vec![1, 2, 3, 4, 5]; show_reversed(values1.as_slice(), values2.as_slice()); // values2 = vec![5, 4, 3, 2, 1]; reverse(values2.as_mut_slice()); show_reversed(values1.as_slice(), values2.as_slice()); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#[test] fn here_and_there() { use training_1::{deeper::there, here};
assert_ne!(here(), there()); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~