forked from extern/nushell
Mathsqrt (#3239)
* Output error when ls into a file without permission * math sqrt * added test to check fails when ls into prohibited dir * fix lint * math sqrt with tests and doc * trigger wasm build * Update filesystem_shell.rs * always forgetting the linting * fix clippy complaining Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
This commit is contained in:
parent
b13202bbfc
commit
0fe6c7c558
@ -218,7 +218,8 @@ pub(crate) use lines::Lines;
|
||||
pub(crate) use ls::Ls;
|
||||
pub(crate) use math::{
|
||||
Math, MathAbs, MathAverage, MathCeil, MathEval, MathFloor, MathMaximum, MathMedian,
|
||||
MathMinimum, MathMode, MathProduct, MathRound, MathStddev, MathSummation, MathVariance,
|
||||
MathMinimum, MathMode, MathProduct, MathRound, MathSqrt, MathStddev, MathSummation,
|
||||
MathVariance,
|
||||
};
|
||||
pub(crate) use merge::Merge;
|
||||
pub(crate) use mkdir::Mkdir;
|
||||
|
@ -188,6 +188,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
||||
whole_stream_command(MathRound),
|
||||
whole_stream_command(MathFloor),
|
||||
whole_stream_command(MathCeil),
|
||||
whole_stream_command(MathSqrt),
|
||||
// File format output
|
||||
whole_stream_command(To),
|
||||
whole_stream_command(ToCsv),
|
||||
|
@ -10,6 +10,7 @@ pub mod min;
|
||||
pub mod mode;
|
||||
pub mod product;
|
||||
pub mod round;
|
||||
pub mod sqrt;
|
||||
pub mod stddev;
|
||||
pub mod sum;
|
||||
pub mod variance;
|
||||
@ -29,6 +30,7 @@ pub use min::SubCommand as MathMinimum;
|
||||
pub use mode::SubCommand as MathMode;
|
||||
pub use product::SubCommand as MathProduct;
|
||||
pub use round::SubCommand as MathRound;
|
||||
pub use sqrt::SubCommand as MathSqrt;
|
||||
pub use stddev::SubCommand as MathStddev;
|
||||
pub use sum::SubCommand as MathSummation;
|
||||
pub use variance::SubCommand as MathVariance;
|
||||
|
75
crates/nu-command/src/commands/math/sqrt.rs
Normal file
75
crates/nu-command/src/commands/math/sqrt.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"math sqrt"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("math sqrt")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Applies the square root function to a list of numbers"
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
operate(args).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Apply the square root function to a list of numbers",
|
||||
example: "echo [9 16] | math sqrt",
|
||||
result: Some(vec![
|
||||
UntaggedValue::int(3).into(),
|
||||
UntaggedValue::int(4).into(),
|
||||
]),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mapped = args.input.map(move |val| match val.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => sqrt_big_decimal(BigDecimal::from(val)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => sqrt_big_decimal(val),
|
||||
other => sqrt_default(other),
|
||||
});
|
||||
Ok(OutputStream::from_input(mapped))
|
||||
}
|
||||
|
||||
fn sqrt_big_decimal(val: BigDecimal) -> Value {
|
||||
let squared = val.sqrt();
|
||||
match squared {
|
||||
None => UntaggedValue::Error(ShellError::unexpected("Cant square root a negative number"))
|
||||
.into(),
|
||||
Some(val) if !val.is_integer() => UntaggedValue::decimal(val.normalized()).into(),
|
||||
Some(val) => UntaggedValue::int(val.with_scale(0).as_bigint_and_exponent().0).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn sqrt_default(_: UntaggedValue) -> Value {
|
||||
UntaggedValue::Error(ShellError::unexpected(
|
||||
"Only numerical values are supported",
|
||||
))
|
||||
.into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::SubCommand;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(SubCommand {})
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ mod avg;
|
||||
mod eval;
|
||||
mod median;
|
||||
mod round;
|
||||
mod sqrt;
|
||||
mod sum;
|
||||
|
||||
use nu_test_support::{nu, pipeline};
|
||||
|
31
crates/nu-command/tests/commands/math/sqrt.rs
Normal file
31
crates/nu-command/tests/commands/math/sqrt.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use nu_test_support::nu;
|
||||
|
||||
#[test]
|
||||
fn can_sqrt_numbers() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
"echo [0.25 2 4] | math sqrt | math sum"
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "3.914213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_sqrt_irrational() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
"echo 2 | math sqrt"
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_sqrt_perfect_square() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
"echo 4 | math sqrt"
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "2");
|
||||
}
|
@ -13,6 +13,7 @@ Currently the following functions are implemented:
|
||||
* `math min`: Finds the minimum within a list of numbers or tables
|
||||
* `math mode`: Finds the most frequent element(s) within a list of numbers or tables
|
||||
* `math round`: Applies the round function to a list of numbers
|
||||
* `math sqrt`: Applies the square root function to a list of numbers
|
||||
* `math stddev`: Finds the standard deviation of a list of numbers or tables
|
||||
* `math sum`: Finds the sum of a list of numbers or tables
|
||||
* `math product`: Finds the product of a list of numbers or tables
|
||||
@ -148,6 +149,15 @@ To get the average of the file sizes in a directory, simply pipe the size column
|
||||
───┴────
|
||||
```
|
||||
|
||||
```shell
|
||||
> echo [4 16 0.25] | math sqrt
|
||||
───┬────
|
||||
0 │ 2
|
||||
1 │ 4
|
||||
2 │ 0.5
|
||||
───┴────
|
||||
```
|
||||
|
||||
```shell
|
||||
> echo [1 -2 -3.0] | math abs
|
||||
───┬────────
|
||||
|
Loading…
Reference in New Issue
Block a user