mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +03:00
JSON Improvements, small Table stuff, Statistic in Enso not Java and few other minor bits. (#3964)
- Aligned `compare_to` so returns `Type_Error` if `that` is wrong type for `Text`, `Ordering` and `Duration`. - Add `empty_object`, `empty_array`. `get_or_else`, `at`, `field_names` and `length` to `Json`. - Fix `Json` serialisation of NaN and Infinity (to "null"). - Added `length`, `at` and `to_vector` to Pair (allowing it to be treated as a Vector). - Added `running_fold` to the `Vector` and `Range`. - Added `first` and `last` to the `Vector.Builder`. - Allow `order_by` to take a single `Sort_Column` or have a mix of `Text` and `Sort_Column.Name` in a `Vector`. - Allow `select_columns_helper` to take a `Text` value. Allows for a single field in group_by in cross_tab. - Added `Patch` and `Custom` to HTTP_Method. - Added running `Statistic` calculation and moved more of the logic from Java to Enso. Performance seems similar to pure Java version now.
This commit is contained in:
parent
3e74afca51
commit
77fe69dfd9
@ -257,6 +257,7 @@
|
||||
and fixed issue with compare_to versus Nothing][3874]
|
||||
- [Aligned `Text.match`/`Text.locate` API][3841]
|
||||
- [Added `transpose` and `cross_tab` to the In-Memory Table.][3919]
|
||||
- [Improvements to JSON, Pair, Statistics and other minor tweaks.][3964]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -404,6 +405,7 @@
|
||||
[3885]: https://github.com/enso-org/enso/pull/3885
|
||||
[3919]: https://github.com/enso-org/enso/pull/3919
|
||||
[3923]: https://github.com/enso-org/enso/pull/3923
|
||||
[3964]: https://github.com/enso-org/enso/pull/3964
|
||||
[3967]: https://github.com/enso-org/enso/pull/3967
|
||||
|
||||
#### Enso Compiler
|
||||
|
@ -49,7 +49,7 @@ type Filter_Condition
|
||||
values from the source column and the provided column are checked.
|
||||
Ends_With (suffix:Text)
|
||||
|
||||
## Does the value contain the needle (Text only)?
|
||||
## Does the value contain the substring (Text only)?
|
||||
|
||||
? Table Operations
|
||||
It accepts a Text value to check if the value contains it. In case of
|
||||
@ -57,6 +57,14 @@ type Filter_Condition
|
||||
values from the source column and the provided column are checked.
|
||||
Contains (substring:Text)
|
||||
|
||||
## Is the substring not present in the value (Text only)?
|
||||
|
||||
? Table Operations
|
||||
It accepts a Text value to check if the value contains it. In case of
|
||||
Table operations, it can accept another column - then the corresponding
|
||||
values from the source column and the provided column are checked.
|
||||
Not_Contains (substring:Text)
|
||||
|
||||
## Is equal to Nothing?
|
||||
Is_Nothing
|
||||
|
||||
@ -160,6 +168,7 @@ type Filter_Condition
|
||||
Starts_With prefix -> _.starts_with prefix
|
||||
Ends_With suffix -> _.ends_with suffix
|
||||
Contains substring -> _.contains substring
|
||||
Not_Contains substring -> v-> v.contains substring . not
|
||||
Is_Nothing -> elem -> case elem of
|
||||
Nothing -> True
|
||||
_ -> False
|
||||
|
@ -2,7 +2,9 @@ import project.Any.Any
|
||||
import project.Data.Json.Internal
|
||||
import project.Data.Map.Map
|
||||
import project.Data.Map.No_Value_For_Key
|
||||
import project.Data.Numbers.Integer
|
||||
import project.Data.Range.Extensions
|
||||
import project.Data.Text.Extensions
|
||||
import project.Data.Text.Text
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Error
|
||||
@ -113,6 +115,14 @@ type Json
|
||||
into self type_descriptor =
|
||||
Panic.recover Any (Internal.into_helper type_descriptor self)
|
||||
|
||||
## Returns an empty JSON object.
|
||||
empty_object : Json
|
||||
empty_object = Json.Object Map.empty
|
||||
|
||||
## Returns an empty JSON array.
|
||||
empty_array : Json
|
||||
empty_array = Json.Array []
|
||||
|
||||
## Returns this Json object.
|
||||
|
||||
This is a no-op on a JSON object, but is included to implement the
|
||||
@ -150,11 +160,11 @@ type Json
|
||||
|
||||
## Gets the value associated with the given key in this object.
|
||||
|
||||
Throws `No_Such_Field` if the associated key is not defined.
|
||||
|
||||
Arguments:
|
||||
- field: The name of the field from which to get the value.
|
||||
|
||||
Throws `Nothing` if the associated key is not defined.
|
||||
|
||||
> Example
|
||||
Get the "title" field from this JSON representing a book.
|
||||
|
||||
@ -162,11 +172,43 @@ type Json
|
||||
|
||||
example_get = Examples.json_object.get "title"
|
||||
get : Text -> Json ! No_Such_Field
|
||||
get self field = case self of
|
||||
Json.Object _ -> self.fields.get field . map_error case _ of
|
||||
No_Value_For_Key.Error _ -> No_Such_Field.Error field
|
||||
x -> x
|
||||
_ -> Error.throw (Illegal_Argument.Error "Json.get: self must be an Object")
|
||||
get self field = self.get_or_else field (Error.throw (No_Such_Field.Error field))
|
||||
|
||||
## Gets the value associated with the given key in this object.
|
||||
|
||||
Arguments:
|
||||
- field: The name of the field from which to get the value.
|
||||
- other: The value to return if not present. Defaults to `Json.Null`.
|
||||
get_or_else : Text -> Any -> Json
|
||||
get_or_else self field ~other=Json.Null = case self of
|
||||
Json.Object fields -> fields.get_or_else field other
|
||||
Json.Null -> other
|
||||
_ -> Error.throw (Illegal_Argument.Error "Json.get_or_else: self must be an Object.")
|
||||
|
||||
## Gets the value associated with the given index in this object.
|
||||
|
||||
Arguments:
|
||||
- index: The index position from which to get the value.
|
||||
at : Integer -> Json ! Illegal_Argument | Out_Of_Bounds
|
||||
at self index = case self of
|
||||
Json.Array array -> array.at index
|
||||
Json.String text -> Json.String (text.at index)
|
||||
Json.Null -> Json.Null
|
||||
_ -> Error.throw (Illegal_Argument.Error "Json.at: self must be a String or an Array.")
|
||||
|
||||
## Gets the set of field names for an object.
|
||||
field_names : Vector ! Illegal_Argument
|
||||
field_names self = case self of
|
||||
Json.Object map -> map.keys
|
||||
_ -> Error.throw (Illegal_Argument.Error "Json.field_name: self must be an Object.")
|
||||
|
||||
## Returns the number of items in this array or object or length of string.
|
||||
length : Integer ! Illegal_Argument
|
||||
length self = case self of
|
||||
Json.Array array -> array.length
|
||||
Json.Object map -> map.size
|
||||
Json.String text -> text.length
|
||||
_ -> Error.throw (Illegal_Argument.Error "Json.length: self must be a String, an Object, or an Array.")
|
||||
|
||||
## UNSTABLE
|
||||
|
||||
|
@ -279,7 +279,7 @@ render_helper builder json = case json of
|
||||
Json.String value ->
|
||||
builder + (Printer.json_escape value)
|
||||
Json.Number value ->
|
||||
builder + value.to_text
|
||||
builder + (if value.is_nan || value.is_infinite then "null" else value.to_text)
|
||||
Json.Boolean value ->
|
||||
val = if value then "true" else "false"
|
||||
builder + val
|
||||
|
@ -348,6 +348,12 @@ type Number
|
||||
_ : Decimal -> Double.isNaN self
|
||||
_ -> False
|
||||
|
||||
## Checks if the given number is infinite.
|
||||
is_infinite : Boolean
|
||||
is_infinite self = case self of
|
||||
_ : Decimal -> Double.isInfinite self
|
||||
_ -> False
|
||||
|
||||
## Returns the sign of the number.
|
||||
signum : Integer
|
||||
signum self =
|
||||
|
@ -1,4 +1,6 @@
|
||||
import project.Data.Numbers.Integer
|
||||
import project.Error.Common.Type_Error
|
||||
import project.Error.Error
|
||||
|
||||
## Types representing the ordering of values.
|
||||
|
||||
@ -41,7 +43,9 @@ type Ordering
|
||||
Ordering.Greater -> Ordering.Greater
|
||||
|
||||
compare_to : Ordering -> Ordering
|
||||
compare_to self other = self.to_sign.compare_to other.to_sign
|
||||
compare_to self that = case that of
|
||||
_ : Ordering -> self.to_sign.compare_to that.to_sign
|
||||
_ -> Error.throw (Type_Error.Error Ordering that "that")
|
||||
|
||||
## Converts a sign-based representation of ordering to Enso's native ordering.
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
import project.Any.Any
|
||||
import project.Data.Numbers.Integer
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Error
|
||||
import project.Error.Common.Index_Out_Of_Bounds
|
||||
|
||||
## A pair of elements.
|
||||
type Pair
|
||||
@ -30,3 +34,28 @@ type Pair
|
||||
map : (Any -> Any) -> Pair
|
||||
map self fun =
|
||||
Pair.new (fun self.first) (fun self.second)
|
||||
|
||||
## UNSTABLE
|
||||
Returns the length (2) of the Pair.
|
||||
length : Integer
|
||||
length self = 2
|
||||
|
||||
## UNSTABLE
|
||||
Returns the pair as a Vector.
|
||||
to_vector : Vector
|
||||
to_vector self = [self.first, self.second]
|
||||
|
||||
## Gets an element from the pair at a specified index (0-based).
|
||||
|
||||
Arguments:
|
||||
- index: The location in the pair to get the element from. The index is
|
||||
also allowed be negative, then the elements are indexed from the back
|
||||
of the pair, i.e. -1 will correspond to the last element.
|
||||
at : Integer -> Any
|
||||
at self index =
|
||||
case index of
|
||||
0 -> self.first
|
||||
1 -> self.second
|
||||
-1 -> self.second
|
||||
-2 -> self.first
|
||||
_ -> Error.throw (Index_Out_Of_Bounds.Error index self.length)
|
||||
|
@ -203,6 +203,25 @@ type Range
|
||||
@Tail_Call go new_acc current+self.step
|
||||
go init self.start
|
||||
|
||||
## Combines all the elements of the range, by iteratively applying the
|
||||
passed function with the next element of the range. After each step the
|
||||
value is stored resulting in a new Vector of the same size as self.
|
||||
|
||||
Arguments:
|
||||
- init: The initial value for the fold.
|
||||
- function: A function taking two elements and combining them.
|
||||
|
||||
> Example
|
||||
Compute the running sum of all of the elements in a vector
|
||||
|
||||
[1, 2, 3].running_fold 0 (+)
|
||||
running_fold : Any -> (Any -> Any -> Any) -> Vector Any
|
||||
running_fold self init function =
|
||||
wrapped builder value =
|
||||
current = if builder.length == 0 then init else builder.last
|
||||
builder.append (function current value)
|
||||
built = self.fold (Vector.new_builder self.length) wrapped
|
||||
built.to_vector
|
||||
|
||||
## Checks whether `predicate` is satisfied for all numbers in this range.
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
import project.Any.Any
|
||||
import project.Data.Array.Array
|
||||
import project.Data.Numbers.Decimal
|
||||
import project.Data.Numbers.Integer
|
||||
import project.Data.Numbers.Number
|
||||
import project.Data.Ordering.Comparator
|
||||
import project.Data.Ordering.Ordering
|
||||
import project.Data.Range.Extensions
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Error
|
||||
@ -10,6 +12,7 @@ import project.Error.Illegal_Argument.Illegal_Argument
|
||||
import project.Error.Incomparable_Values.Incomparable_Values
|
||||
import project.Meta
|
||||
import project.Nothing.Nothing
|
||||
import project.Runtime.Ref.Ref
|
||||
import project.Panic.Panic
|
||||
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
@ -123,6 +126,17 @@ type Statistic
|
||||
- predicted: the series to compute the r_squared with.
|
||||
R_Squared (predicted:Vector)
|
||||
|
||||
## Gets the order needed to compute a statistic for a moment based statistic.
|
||||
order : Integer | Nothing
|
||||
order self = case self of
|
||||
Statistic.Sum -> 1
|
||||
Statistic.Mean -> 1
|
||||
Statistic.Variance _ -> 2
|
||||
Statistic.Standard_Deviation _ -> 2
|
||||
Statistic.Skew _ -> 3
|
||||
Statistic.Kurtosis -> 4
|
||||
_ -> Nothing
|
||||
|
||||
## Compute a single statistic on a vector like object.
|
||||
|
||||
Arguments:
|
||||
@ -139,44 +153,77 @@ type Statistic
|
||||
- statistics: Set of statistics to calculate.
|
||||
compute_bulk : Vector -> Vector Statistic -> Vector Any
|
||||
compute_bulk data statistics=[Statistic.Count, Statistic.Sum] =
|
||||
count_min_max = statistics.any s->
|
||||
case s of
|
||||
Statistic.Count -> True
|
||||
Statistic.Minimum -> True
|
||||
Statistic.Maximum -> True
|
||||
_ -> False
|
||||
counter = CountMinMax.new
|
||||
|
||||
java_stats = statistics.map to_moment_statistic
|
||||
skip_java_stats = java_stats.all s->s.is_nothing
|
||||
moment_order = statistics.map .order
|
||||
skip_moments = moment_order.all s->s.is_nothing
|
||||
moments = if skip_moments then Nothing else Moments.new (moment_order.filter (v-> v != Nothing) . fold 0 .max)
|
||||
|
||||
report_invalid _ =
|
||||
statistics.map_with_index i->v->
|
||||
if java_stats.at i . is_nothing then Nothing else
|
||||
Error.throw (Illegal_Argument.Error ("Can only compute " + v.to_text + " on numerical data sets."))
|
||||
handle_unsupported = Panic.catch Unsupported_Argument_Types.Error handler=report_invalid
|
||||
result = data.fold moments current-> value-> compute_fold counter current value
|
||||
|
||||
empty_map s = if (s == Statistic.Count) || (s == Statistic.Sum) then 0 else
|
||||
if (s == Statistic.Minimum) || (s == Statistic.Maximum) then Error.throw Empty_Error else
|
||||
Number.nan
|
||||
report_error stats =
|
||||
first = 0.up_to stats.length . find i-> (moment_order.at i . is_nothing . not)
|
||||
stat = stats.at first
|
||||
Error.throw (Illegal_Argument.Error ("Can only compute " + stat.to_text + " on numerical data sets."))
|
||||
|
||||
if data.length == 0 then statistics.map empty_map else
|
||||
count_min_max_values = if count_min_max then CountMinMax.new (CountMinMax.toObjectStream data.to_array) Comparator.new else Nothing
|
||||
stats_array = if skip_java_stats then Nothing else
|
||||
handle_unsupported <| Moments.compute data.to_array java_stats.to_array
|
||||
if counter.count == 0 then statistics.map empty_value else
|
||||
if skip_moments.not && result.is_nothing then report_error statistics else
|
||||
statistics.map statistic-> case statistic of
|
||||
Statistic.Count -> counter.count
|
||||
Statistic.Minimum -> if counter.comparatorError then (Error.throw Incomparable_Values) else counter.minimum
|
||||
Statistic.Maximum -> if counter.comparatorError then (Error.throw Incomparable_Values) else counter.maximum
|
||||
Statistic.Covariance series -> calculate_correlation_statistics data series . covariance
|
||||
Statistic.Pearson series -> calculate_correlation_statistics data series . pearsonCorrelation
|
||||
Statistic.Spearman series -> calculate_spearman_rank data series
|
||||
Statistic.R_Squared series -> calculate_correlation_statistics data series . rSquared
|
||||
_ -> moments.compute (to_moment_statistic statistic)
|
||||
|
||||
statistics.map_with_index i->s->case s of
|
||||
Statistic.Count -> count_min_max_values.count
|
||||
Statistic.Minimum ->
|
||||
if count_min_max_values.comparatorError then (Error.throw Incomparable_Values) else
|
||||
count_min_max_values.minimum
|
||||
Statistic.Maximum ->
|
||||
if count_min_max_values.comparatorError then (Error.throw Incomparable_Values) else
|
||||
count_min_max_values.maximum
|
||||
Statistic.Covariance s -> calculate_correlation_statistics data s . covariance
|
||||
Statistic.Pearson s -> calculate_correlation_statistics data s . pearsonCorrelation
|
||||
Statistic.Spearman s -> calculate_spearman_rank data s
|
||||
Statistic.R_Squared s -> calculate_correlation_statistics data s . rSquared
|
||||
_ -> stats_array.at i
|
||||
## Compute a running statistics on a vector like object.
|
||||
|
||||
Arguments:
|
||||
- data: Vector like object which has a `to_array` method.
|
||||
- statistics: Set of statistics to calculate.
|
||||
running : Vector -> Statistic -> Vector Any
|
||||
running data statistic=Statistic.Sum =
|
||||
Statistic.running_bulk data [statistic] . map .first
|
||||
|
||||
## Compute a set running statistics on a vector like object.
|
||||
|
||||
Arguments:
|
||||
- data: Vector like object which has a `to_array` method.
|
||||
- statistics: Set of statistics to calculate.
|
||||
running_bulk : Vector -> Vector Statistic -> Vector Any
|
||||
running_bulk data statistics=[Statistic.Count, Statistic.Sum] =
|
||||
is_unsupported s = case s of
|
||||
Statistic.Covariance _ -> True
|
||||
Statistic.Pearson _ -> True
|
||||
Statistic.Spearman _ -> True
|
||||
Statistic.R_Squared _ -> True
|
||||
_ -> False
|
||||
|
||||
if statistics.any is_unsupported then Error.throw (Illegal_Argument.Error ("Unsupported Statistics ( " + (statistics.filter is_unsupported . to_text) ") for running calculations.")) else
|
||||
counter = CountMinMax.new
|
||||
|
||||
moment_order = statistics.map .order
|
||||
skip_moments = moment_order.all s->s.is_nothing
|
||||
moments = if skip_moments then Nothing else Moments.new (moment_order.filter (v-> v != Nothing) . fold 0 .max)
|
||||
ref_moment = Ref.new moments
|
||||
|
||||
Panic.handle_wrapped_dataflow_error <|
|
||||
output = Vector.new_builder data.length
|
||||
|
||||
data.each value->
|
||||
result = compute_fold counter ref_moment.get value
|
||||
ref_moment.put result
|
||||
|
||||
row = Panic.throw_wrapped_if_error <| statistics.map s-> case s of
|
||||
Statistic.Count -> counter.count
|
||||
Statistic.Minimum -> if counter.comparatorError then (Error.throw Incomparable_Values) else counter.minimum
|
||||
Statistic.Maximum -> if counter.comparatorError then (Error.throw Incomparable_Values) else counter.maximum
|
||||
_ -> if result.is_nothing then Error.throw (Illegal_Argument.Error ("Can only compute " + s.to_text + " on numerical data sets.")) else result.compute (to_moment_statistic s)
|
||||
output.append row
|
||||
|
||||
output.to_vector
|
||||
|
||||
## Calculate a variance-covariance matrix between the input series.
|
||||
|
||||
@ -279,3 +326,44 @@ Vector.compute self statistic=Statistic.Count =
|
||||
Vector.compute_bulk : Vector Statistic -> Vector Any
|
||||
Vector.compute_bulk self statistics=[Statistic.Count, Statistic.Sum] =
|
||||
Statistic.compute_bulk self statistics
|
||||
|
||||
## Compute a single running statistic on the vector.
|
||||
|
||||
Arguments:
|
||||
- statistic: Statistic to calculate.
|
||||
Vector.running : Statistic -> Vector Any
|
||||
Vector.running self statistic=Statistic.Count =
|
||||
Statistic.running self statistic
|
||||
|
||||
## PRIVATE
|
||||
compute_fold counter current value =
|
||||
if is_valid value . not then current else
|
||||
counter.increment
|
||||
|
||||
if counter.comparatorError.not then
|
||||
if counter.minimum.is_nothing then counter.setMinimum value else
|
||||
ordering = Incomparable_Values.handle_errors <| value.compare_to counter.minimum
|
||||
if ordering.is_error then counter.failComparator else
|
||||
if ordering == Ordering.Less then counter.setMinimum value
|
||||
if counter.maximum.is_nothing then counter.setMaximum value else
|
||||
ordering = Incomparable_Values.handle_errors <| value.compare_to counter.maximum
|
||||
if ordering.is_error then counter.failComparator else
|
||||
if ordering == Ordering.Greater then counter.setMaximum value
|
||||
|
||||
if current.is_nothing then Nothing else case value of
|
||||
_ : Number -> current.add value
|
||||
_ -> Nothing
|
||||
|
||||
## PRIVATE
|
||||
empty_value statistic = case statistic of
|
||||
Statistic.Count -> 0
|
||||
Statistic.Sum -> 0
|
||||
Statistic.Minimum -> Error.throw Empty_Error
|
||||
Statistic.Maximum -> Error.throw Empty_Error
|
||||
_ -> Number.nan
|
||||
|
||||
## PRIVATE
|
||||
is_valid v = case v of
|
||||
Nothing -> False
|
||||
_ : Number -> v.is_nan.not
|
||||
_ -> True
|
||||
|
@ -66,10 +66,11 @@ type Text
|
||||
|
||||
"a".compare_to "b"
|
||||
compare_to : Text -> Ordering
|
||||
compare_to self that =
|
||||
if that.is_nothing then Error.throw (Type_Error.Error Text that "that") else
|
||||
compare_to self that = case that of
|
||||
_ : Text ->
|
||||
comparison_result = Text_Utils.compare_normalized self that
|
||||
Ordering.from_sign comparison_result
|
||||
_ -> Error.throw (Type_Error.Error Text that "that")
|
||||
|
||||
## Checks whether `self` is equal to `that`, ignoring the case of the texts.
|
||||
|
||||
|
@ -6,6 +6,7 @@ import project.Data.Pair.Pair
|
||||
import project.Data.Time.Date_Time.Date_Time
|
||||
import project.Data.Time.Period.Period
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Common.Type_Error
|
||||
import project.Error.Error
|
||||
import project.Error.Illegal_Argument.Illegal_Argument
|
||||
import project.Error.Illegal_State.Illegal_State
|
||||
@ -197,9 +198,9 @@ type Duration
|
||||
duration_2 = (Duration.new minutes=60) + (Duration.new minutes=5)
|
||||
duration_1.compare_to duration_2
|
||||
compare_to : Duration -> Ordering
|
||||
compare_to self that =
|
||||
ensure_duration that <|
|
||||
Ordering.from_sign (self.compare_to_builtin that)
|
||||
compare_to self that = case that of
|
||||
_ : Duration -> Ordering.from_sign (self.compare_to_builtin that)
|
||||
_ -> Error.throw (Type_Error.Error Duration that "that")
|
||||
|
||||
## Get the portion of the duration expressed in nanoseconds.
|
||||
|
||||
|
@ -204,6 +204,26 @@ type Vector a
|
||||
f = acc -> ix -> function acc ix (self.at ix)
|
||||
0.up_to self.length . fold init f
|
||||
|
||||
## Combines all the elements of the vector, by iteratively applying the
|
||||
passed function with the next element of the vector. After each step the
|
||||
value is stored resulting in a new Vector of the same size as self.
|
||||
|
||||
Arguments:
|
||||
- init: The initial value for the fold.
|
||||
- function: A function taking two elements and combining them.
|
||||
|
||||
> Example
|
||||
Compute the running sum of all of the elements in a vector
|
||||
|
||||
[1, 2, 3].running_fold 0 (+)
|
||||
running_fold : Any -> (Any -> Any -> Any) -> Vector Any
|
||||
running_fold self init function =
|
||||
wrapped builder value =
|
||||
current = if builder.length == 0 then init else builder.last
|
||||
builder.append (function current value)
|
||||
built = self.fold (Vector.new_builder self.length) wrapped
|
||||
built.to_vector
|
||||
|
||||
## Combines all the elements of a non-empty vector using a binary operation.
|
||||
|
||||
Arguments:
|
||||
@ -1058,6 +1078,26 @@ type Builder
|
||||
Panic.catch IndexOutOfBoundsException (self.java_builder.get actual_index) _->
|
||||
Error.throw (Index_Out_Of_Bounds.Error index self.length)
|
||||
|
||||
## Get the first element from the vector, or an `Empty_Error` if the vector
|
||||
is empty.
|
||||
|
||||
> Example
|
||||
The following code returns 1.
|
||||
|
||||
[1, 2, 3, 4].first
|
||||
first : Vector ! Index_Out_Of_Bounds
|
||||
first self = self.at 0
|
||||
|
||||
## Get the last element of the vector, or an `Empty_Error` if the vector is
|
||||
empty.
|
||||
|
||||
> Example
|
||||
The following code returns 4.
|
||||
|
||||
[1, 2, 3, 4].last
|
||||
last : Vector ! Index_Out_Of_Bounds
|
||||
last self = self.at -1
|
||||
|
||||
## Checks whether a predicate holds for at least one element of this builder.
|
||||
|
||||
Arguments:
|
||||
|
@ -3,7 +3,8 @@ import project.Meta
|
||||
|
||||
@Builtin_Type
|
||||
type Index_Out_Of_Bounds
|
||||
## UNSTABLE
|
||||
## PRIVATE
|
||||
UNSTABLE
|
||||
|
||||
An error indicating that a requested index was out of bounds of a collection.
|
||||
|
||||
@ -21,7 +22,8 @@ type Index_Out_Of_Bounds
|
||||
|
||||
@Builtin_Type
|
||||
type Syntax_Error
|
||||
## The runtime representation of a syntax error.
|
||||
## PRIVATE
|
||||
The runtime representation of a syntax error.
|
||||
|
||||
Arguments:
|
||||
- message: A description of the erroneous syntax.
|
||||
@ -29,7 +31,8 @@ type Syntax_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Type_Error
|
||||
## The runtime representation of a type error.
|
||||
## PRIVATE
|
||||
The runtime representation of a type error.
|
||||
|
||||
Arguments:
|
||||
- expected: The expected type at the error location.
|
||||
@ -39,7 +42,8 @@ type Type_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Compile_Error
|
||||
## The runtime representation of a compilation error.
|
||||
## PRIVATE
|
||||
The runtime representation of a compilation error.
|
||||
|
||||
Arguments:
|
||||
- message: A description of the erroneous state.
|
||||
@ -47,7 +51,8 @@ type Compile_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Inexhaustive_Pattern_Match
|
||||
## The error thrown when a there is no pattern to match on the scrutinee.
|
||||
## PRIVATE
|
||||
The error thrown when a there is no pattern to match on the scrutinee.
|
||||
|
||||
Arguments:
|
||||
- scrutinee: The scrutinee that failed to match.
|
||||
@ -55,7 +60,8 @@ type Inexhaustive_Pattern_Match
|
||||
|
||||
@Builtin_Type
|
||||
type Arity_Error
|
||||
## The error thrown when the number of arguments provided to an operation
|
||||
## PRIVATE
|
||||
The error thrown when the number of arguments provided to an operation
|
||||
does not match the expected number of arguments.
|
||||
|
||||
Arguments:
|
||||
@ -66,7 +72,8 @@ type Arity_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Uninitialized_State
|
||||
## The error thrown when the program attempts to read from a state slot that has
|
||||
## PRIVATE
|
||||
The error thrown when the program attempts to read from a state slot that has
|
||||
not yet been initialized.
|
||||
|
||||
Arguments:
|
||||
@ -75,7 +82,8 @@ type Uninitialized_State
|
||||
|
||||
@Builtin_Type
|
||||
type No_Such_Method
|
||||
## The error thrown when the specified symbol does not exist as a method on
|
||||
## PRIVATE
|
||||
The error thrown when the specified symbol does not exist as a method on
|
||||
the target.
|
||||
|
||||
Arguments:
|
||||
@ -102,7 +110,8 @@ type No_Such_Method
|
||||
|
||||
@Builtin_Type
|
||||
type Polyglot_Error
|
||||
## An error that occurred across a polyglot boundary.
|
||||
## PRIVATE
|
||||
An error that occurred across a polyglot boundary.
|
||||
|
||||
Arguments:
|
||||
- cause: A polyglot object corresponding to the original error.
|
||||
@ -115,7 +124,8 @@ type Module_Not_In_Package_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Arithmetic_Error
|
||||
## An error for when an erroneous arithmetic computation takes place.
|
||||
## PRIVATE
|
||||
An error for when an erroneous arithmetic computation takes place.
|
||||
|
||||
Arguments:
|
||||
- message: A description of the error condition.
|
||||
@ -123,7 +133,8 @@ type Arithmetic_Error
|
||||
|
||||
@Builtin_Type
|
||||
type Invalid_Array_Index
|
||||
## An error that occurs when a program requests a read from an array index
|
||||
## PRIVATE
|
||||
An error that occurs when a program requests a read from an array index
|
||||
that is out of bounds in the array.
|
||||
|
||||
Arguments:
|
||||
@ -133,7 +144,8 @@ type Invalid_Array_Index
|
||||
|
||||
@Builtin_Type
|
||||
type Not_Invokable
|
||||
## An error that occurs when an object is used as a function in a function
|
||||
## PRIVATE
|
||||
An error that occurs when an object is used as a function in a function
|
||||
call, but it cannot be called.
|
||||
|
||||
Arguments:
|
||||
@ -142,7 +154,8 @@ type Not_Invokable
|
||||
|
||||
@Builtin_Type
|
||||
type Unsupported_Argument_Types
|
||||
## An error that occurs when arguments used in a function call are invalid
|
||||
## PRIVATE
|
||||
An error that occurs when arguments used in a function call are invalid
|
||||
types for the function.
|
||||
|
||||
Arguments:
|
||||
@ -152,7 +165,8 @@ type Unsupported_Argument_Types
|
||||
|
||||
@Builtin_Type
|
||||
type Module_Does_Not_Exist
|
||||
## An error that occurs when the specified module cannot be found.
|
||||
## PRIVATE
|
||||
An error that occurs when the specified module cannot be found.
|
||||
|
||||
Arguments:
|
||||
- name: The module searched for.
|
||||
@ -160,7 +174,8 @@ type Module_Does_Not_Exist
|
||||
|
||||
@Builtin_Type
|
||||
type Invalid_Conversion_Target
|
||||
## An error that occurs when the specified value cannot be converted to a given type
|
||||
## PRIVATE
|
||||
An error that occurs when the specified value cannot be converted to a given type
|
||||
|
||||
Arguments:
|
||||
- target: the type trying to be converted to.
|
||||
@ -168,7 +183,8 @@ type Invalid_Conversion_Target
|
||||
|
||||
@Builtin_Type
|
||||
type No_Such_Conversion
|
||||
## An error that occurs when the conversion from one type to another does not exist
|
||||
## PRIVATE
|
||||
An error that occurs when the conversion from one type to another does not exist
|
||||
|
||||
Arguments:
|
||||
- target: the type trying to be converted to.
|
||||
|
@ -164,7 +164,7 @@ export project.Network.URI.URI
|
||||
export project.Random
|
||||
|
||||
from project.Data.Noise export all hiding Noise, Generator, Deterministic_Random, Long, Random
|
||||
from project.Data.Statistics export all hiding to_moment_statistic, wrap_java_call, calculate_correlation_statistics, calculate_spearman_rank, calculate_correlation_statistics_matrix, Moments, MomentStatistic, CountMinMax, CorrelationStatistics, Rank, ClassCastException, NullPointerException
|
||||
from project.Data.Statistics export all hiding to_moment_statistic, wrap_java_call, calculate_correlation_statistics, calculate_spearman_rank, calculate_correlation_statistics_matrix, compute_fold, empty_value, is_valid
|
||||
|
||||
from project.Data.Index_Sub_Range.Index_Sub_Range import First, Last
|
||||
from project.Error.Problem_Behavior.Problem_Behavior import all
|
||||
|
@ -16,6 +16,9 @@ type HTTP_Method
|
||||
## The HTTP method "PUT".
|
||||
Put
|
||||
|
||||
## The HTTP method "PATCH".
|
||||
Patch
|
||||
|
||||
## The HTTP method "DELETE".
|
||||
Delete
|
||||
|
||||
@ -25,6 +28,9 @@ type HTTP_Method
|
||||
## The HTTP method "CONNECT".
|
||||
Connect
|
||||
|
||||
## Custom unsupported HTTP method.
|
||||
Custom verb:Text
|
||||
|
||||
## Convert to a Text of the HTTP method name.
|
||||
to_http_method_name : Text
|
||||
to_http_method_name self = case self of
|
||||
@ -33,6 +39,8 @@ type HTTP_Method
|
||||
HTTP_Method.Head -> "HEAD"
|
||||
HTTP_Method.Post -> "POST"
|
||||
HTTP_Method.Put -> "PUT"
|
||||
HTTP_Method.Patch -> "PATCH"
|
||||
HTTP_Method.Delete -> "DELETE"
|
||||
HTTP_Method.Trace -> "TRACE"
|
||||
HTTP_Method.Connect -> "CONNECT"
|
||||
HTTP_Method.Custom verb -> verb
|
||||
|
@ -106,11 +106,10 @@ write_file_backing_up_old_one file action = Panic.recover [File_Error.IO_Error,
|
||||
Panic.rethrow <| new_file.move_to file
|
||||
go 0
|
||||
|
||||
|
||||
## PRIVATE
|
||||
type Internal_Write_Operation_Panicked
|
||||
## PRIVATE
|
||||
Panic (cause : Caught_Panic)
|
||||
|
||||
## PRIVATE
|
||||
type Internal_Write_Operation_Errored
|
||||
## PRIVATE
|
||||
Error (cause : Any)
|
||||
|
@ -634,7 +634,7 @@ type Table
|
||||
descending order.
|
||||
|
||||
table.order_by (Sort_Column_Selector.By_Index [1, Sort_Column.Index -7 Sort_Direction.Descending])
|
||||
order_by : Text | Vector Text | Sort_Column_Selector -> Text_Ordering -> Problem_Behavior -> Table ! Incomparable_Values
|
||||
order_by : Text | Sort_Column | Vector (Text | Sort_Column) | Sort_Column_Selector -> Text_Ordering -> Problem_Behavior -> Table ! Incomparable_Values
|
||||
order_by self (columns = (Sort_Column_Selector.By_Name [(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default on_problems=Report_Warning = Panic.handle_wrapped_dataflow_error <|
|
||||
problem_builder = Problem_Builder.new
|
||||
columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder
|
||||
|
@ -19,7 +19,6 @@ component-groups:
|
||||
exports:
|
||||
- Standard.Table.Data.Table.Table.at
|
||||
- Standard.Table.Data.Table.Table.select_columns
|
||||
- Standard.Table.Data.Table.Table.rename_columns
|
||||
- Standard.Table.Data.Table.Table.remove_columns
|
||||
- Standard.Table.Data.Table.Table.reorder_columns
|
||||
- Standard.Table.Data.Table.Table.sort_columns
|
||||
@ -29,8 +28,11 @@ component-groups:
|
||||
- Standard.Table.Data.Table.Table.aggregate
|
||||
- Standard.Base.Transform:
|
||||
exports:
|
||||
- Standard.Table.Data.Table.Table.rename_columns
|
||||
- Standard.Table.Data.Table.Table.filter
|
||||
- Standard.Table.Data.Table.Table.order_by
|
||||
- Standard.Table.Data.Table.Table.to_csv
|
||||
- Standard.Table.Data.Table.Table.transpose
|
||||
- Standard.Table.Data.Table.Table.cross_tab
|
||||
- Standard.Table.Data.Column.Column.to_table
|
||||
- Standard.Base.Output:
|
||||
exports:
|
||||
|
@ -613,7 +613,7 @@ type Table
|
||||
table = Examples.inventory_table
|
||||
table.order_by (Sort_Column_Selector.By_Name ["total_stock", Sort_Column.Name "sold_stock" Sort_Direction.Descending])
|
||||
|
||||
order_by : Text | Vector Text | Sort_Column_Selector -> Text_Ordering -> Problem_Behavior -> Table ! Incomparable_Values
|
||||
order_by : Text | Sort_Column | Vector (Text | Sort_Column) | Sort_Column_Selector -> Text_Ordering -> Problem_Behavior -> Table ! Incomparable_Values
|
||||
order_by self (columns = (Sort_Column_Selector.By_Name [(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default on_problems=Report_Warning =
|
||||
problem_builder = Problem_Builder.new
|
||||
columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder
|
||||
@ -1221,7 +1221,7 @@ type Table
|
||||
`Input_Indices_Already_Matched`, with the column included the first
|
||||
time it is matched.
|
||||
- If there are no columns to transpose, a `No_Input_Columns`.
|
||||
transpose : Vector Text | Column_Selector -> Text -> Text -> Problem_Behavior -> Table
|
||||
transpose : Text | Vector Text | Column_Selector -> Text -> Text -> Problem_Behavior -> Table
|
||||
transpose self (id_fields = Column_Selector.By_Name []) (name_field="Name") (value_field="Value") (on_problems = Report_Warning) =
|
||||
columns_helper = self.columns_helper
|
||||
unique = Unique_Name_Strategy.new
|
||||
@ -1271,7 +1271,7 @@ type Table
|
||||
- If an aggregation fails, an `Invalid_Aggregation`.
|
||||
- If when concatenating values there is an quoted delimited, an `Unquoted_Delimiter`
|
||||
- If there are more than 10 issues with a single column, an `Additional_Warnings`.
|
||||
cross_tab : Vector Text | Column_Selector -> (Text | Integer | Column) -> Vector Aggregate_Column -> Problem_Behavior -> Table
|
||||
cross_tab : Text | Vector Text | Column_Selector -> (Text | Integer | Column) -> Vector Aggregate_Column -> Problem_Behavior -> Table
|
||||
cross_tab self group_by=[] name_column=self.column_names.first values=Aggregate_Column.Count (on_problems=Report_Warning) =
|
||||
columns_helper = self.columns_helper
|
||||
problem_builder = Problem_Builder.new
|
||||
|
@ -2,10 +2,10 @@ from Standard.Base import all
|
||||
|
||||
polyglot java import org.enso.table.error.ColumnCountMismatchException
|
||||
polyglot java import org.enso.table.error.ColumnNameMismatchException
|
||||
|
||||
## One or more columns not found in the input table.
|
||||
Can occur when using By_Name or By_Column.
|
||||
type Missing_Input_Columns
|
||||
## PRIVATE
|
||||
One or more columns not found in the input table.
|
||||
Can occur when using By_Name or By_Column.
|
||||
Error (criteria : [Text])
|
||||
|
||||
## PRIVATE
|
||||
@ -15,9 +15,10 @@ type Missing_Input_Columns
|
||||
to_display_text self =
|
||||
"The criteria "+self.criteria.to_text+" did not match any columns."
|
||||
|
||||
## One or more column indexes were invalid on the input table.
|
||||
Can occur when using By_Index.
|
||||
type Column_Indexes_Out_Of_Range
|
||||
## PRIVATE
|
||||
One or more column indexes were invalid on the input table.
|
||||
Can occur when using By_Index.
|
||||
Error (indexes : [Integer])
|
||||
|
||||
## PRIVATE
|
||||
@ -28,9 +29,10 @@ type Column_Indexes_Out_Of_Range
|
||||
True -> "The index " + (self.indexes.at 0).to_text + " is out of range."
|
||||
False -> "The indexes "+self.indexes.short_display_text+" are out of range."
|
||||
|
||||
## More names than the column count provided to the function.
|
||||
Can occur when using By_Position.
|
||||
type Too_Many_Column_Names_Provided
|
||||
## PRIVATE
|
||||
More names than the column count provided to the function.
|
||||
Can occur when using By_Position.
|
||||
Error (column_names : [Text])
|
||||
|
||||
## PRIVATE
|
||||
|
@ -44,6 +44,10 @@ make_filter_column source_column filter_condition = case filter_condition of
|
||||
Value_Type.expect_text source_column.value_type <|
|
||||
expect_column_or_value_as_text "substring" substring <|
|
||||
source_column.contains substring
|
||||
Not_Contains substring ->
|
||||
Value_Type.expect_text source_column.value_type <|
|
||||
expect_column_or_value_as_text "substring" substring <|
|
||||
source_column.contains substring . not
|
||||
Is_Empty ->
|
||||
Value_Type.expect_text source_column.value_type <|
|
||||
source_column.is_empty
|
||||
|
@ -1,6 +1,7 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Data.Text.Matching
|
||||
import Standard.Base.Data.Ordering.Vector_Lexicographic_Order
|
||||
import Standard.Base.Error.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Error.Illegal_State.Illegal_State
|
||||
|
||||
import project.Data.Column_Name_Mapping.Column_Name_Mapping
|
||||
@ -137,8 +138,10 @@ type Table_Column_Helper
|
||||
criterion on the list. If a single criterion's group has more than one
|
||||
element, their relative order is the same as in the input.
|
||||
- problem_builder: Encapsulates the aggregation of encountered problems.
|
||||
select_columns_helper : Vector | Column_Selector -> Boolean -> Problem_Builder -> Vector
|
||||
select_columns_helper : Text | Vector | Column_Selector -> Boolean -> Problem_Builder -> Vector
|
||||
select_columns_helper self selector reorder problem_builder = case selector of
|
||||
_ : Text ->
|
||||
self.select_columns_helper (Column_Selector.By_Name [selector]) reorder problem_builder
|
||||
_ : Vector ->
|
||||
self.select_columns_helper (Column_Selector.By_Name selector) reorder problem_builder
|
||||
Column_Selector.By_Name names matcher ->
|
||||
@ -406,24 +409,32 @@ type Column_Transform_Element
|
||||
Value column associated_selector
|
||||
|
||||
## PRIVATE
|
||||
prepare_order_by : Vector -> Text | Vector Text | Sort_Column_Selector -> Problem_Builder -> Vector Column_Transform_Element
|
||||
prepare_order_by : Vector -> Text | Sort_Column | Vector (Text | Sort_Column) | Sort_Column_Selector -> Problem_Builder -> Vector Column_Transform_Element
|
||||
prepare_order_by internal_columns column_selectors problem_builder =
|
||||
selected_elements = case column_selectors of
|
||||
_ : Text ->
|
||||
unified_name_selectors = [Sort_Column.Name column_selectors]
|
||||
select_columns_by_name internal_columns unified_name_selectors Text_Matcher.Case_Sensitive problem_builder name_extractor=(_.name)
|
||||
Sort_Column.Name _ _ -> select_columns_by_name internal_columns [column_selectors] Text_Matcher.Case_Sensitive problem_builder name_extractor=(_.name)
|
||||
Sort_Column.Index _ _ -> select_columns_by_index internal_columns [column_selectors] problem_builder index_extractor=(_.index)
|
||||
Sort_Column.Column _ _ -> select_columns_by_column_reference internal_columns [column_selectors] problem_builder column_extractor=(_.column)
|
||||
_ : Vector ->
|
||||
unified_name_selectors = column_selectors.map (Sort_Column.Name _)
|
||||
unified_name_selectors = column_selectors.map selector-> case selector of
|
||||
_ : Text -> Sort_Column.Name selector
|
||||
Sort_Column.Name _ _ -> selector
|
||||
_ -> Error.throw (Illegal_Argument.Error "Invalid column selector passed to order_by. Only Text and Sort_Column.Name are allowed as a Vector.")
|
||||
select_columns_by_name internal_columns unified_name_selectors Text_Matcher.Case_Sensitive problem_builder name_extractor=(_.name)
|
||||
Sort_Column_Selector.By_Name name_selectors matcher ->
|
||||
unified_name_selectors = name_selectors.map selector-> case selector of
|
||||
_ : Text -> Sort_Column.Name selector
|
||||
Sort_Column.Name _ _ -> selector
|
||||
_ -> Error.throw (Illegal_Argument.Error "Invalid column selector passed to order_by. Only Text and Sort_Column.Name are allowed for Sort_Column_Selector.By_Name.")
|
||||
select_columns_by_name internal_columns unified_name_selectors matcher problem_builder name_extractor=(_.name)
|
||||
Sort_Column_Selector.By_Index index_selectors ->
|
||||
unified_index_selectors = index_selectors.map selector-> case selector of
|
||||
_ : Integer -> Sort_Column.Index selector
|
||||
Sort_Column.Index _ _ -> selector
|
||||
_ -> Error.throw (Illegal_Argument.Error "Invalid column selector passed to order_by. Only Integer and Sort_Column.Index are allowed for Sort_Column_Selector.By_Index.")
|
||||
select_columns_by_index internal_columns unified_index_selectors problem_builder index_extractor=(_.index)
|
||||
Sort_Column_Selector.By_Column column_selectors ->
|
||||
unified_column_selectors = column_selectors.map selector-> case selector of
|
||||
|
@ -159,11 +159,12 @@ public final class ParseStdLibTest extends TestCase {
|
||||
Arrays.asList(
|
||||
// Files containing type expressions not supported by old parser.
|
||||
"Data/Index_Sub_Range.enso",
|
||||
"Error/Common.enso",
|
||||
"Data/Text/Regex/Regex_Mode.enso",
|
||||
"Internal/Base_Generator.enso",
|
||||
"Data/Pair.enso",
|
||||
"Data/Sort_Column_Selector.enso",
|
||||
"Data/Value_Type.enso"));
|
||||
"Data/Text/Regex/Regex_Mode.enso",
|
||||
"Data/Value_Type.enso",
|
||||
"Error/Common.enso",
|
||||
"Internal/Base_Generator.enso"));
|
||||
}
|
||||
|
||||
private static boolean isKnownToWork(String name) {
|
||||
|
@ -1,52 +1,35 @@
|
||||
package org.enso.base.statistics;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.stream.Stream;
|
||||
import org.graalvm.polyglot.Value;
|
||||
|
||||
public class CountMinMax {
|
||||
private static boolean isValid(Object v) {
|
||||
return !(v == null || (v instanceof Double && Double.isNaN((Double) v)));
|
||||
public long count;
|
||||
public boolean comparatorError;
|
||||
public Value minimum;
|
||||
public Value maximum;
|
||||
|
||||
public CountMinMax() {
|
||||
this.count = 0;
|
||||
this.comparatorError = false;
|
||||
this.minimum = Value.asValue(null);
|
||||
this.maximum = Value.asValue(null);
|
||||
}
|
||||
|
||||
public static Stream<Object> toObjectStream(Object[] array) {
|
||||
return Arrays.stream(array);
|
||||
public void increment() {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public final int count;
|
||||
public final boolean comparatorError;
|
||||
public final Object minimum;
|
||||
public final Object maximum;
|
||||
public void failComparator() {
|
||||
this.comparatorError = true;
|
||||
this.minimum = Value.asValue(null);
|
||||
this.maximum = Value.asValue(null);
|
||||
}
|
||||
|
||||
public CountMinMax(Stream<Object> values, Comparator<Object> objectComparator) {
|
||||
int count = 0;
|
||||
public void setMinimum(Value value) {
|
||||
this.minimum = value;
|
||||
}
|
||||
|
||||
boolean comparatorFailed = false;
|
||||
Object minimum = null;
|
||||
Object maximum = null;
|
||||
|
||||
Iterator<Object> iterator = values.filter(CountMinMax::isValid).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Object value = iterator.next();
|
||||
count++;
|
||||
|
||||
if (!comparatorFailed) {
|
||||
try {
|
||||
minimum =
|
||||
minimum == null || objectComparator.compare(minimum, value) > 0 ? value : minimum;
|
||||
maximum =
|
||||
maximum == null || objectComparator.compare(maximum, value) < 0 ? value : maximum;
|
||||
} catch (ClassCastException e) {
|
||||
comparatorFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.count = count;
|
||||
this.comparatorError = comparatorFailed;
|
||||
this.minimum = comparatorFailed ? null : minimum;
|
||||
this.maximum = comparatorFailed ? null : maximum;
|
||||
public void setMaximum(Value value) {
|
||||
this.maximum = value;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.enso.base.statistics;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Set of descriptive statistics for numerical data sets */
|
||||
public class Moments {
|
||||
|
||||
@ -32,38 +30,31 @@ public class Moments {
|
||||
/** Statistic to compute the sample kurtosis of the values. */
|
||||
public static final MomentStatistic KURTOSIS = new Kurtosis();
|
||||
|
||||
private long count;
|
||||
private double[] totals;
|
||||
|
||||
/**
|
||||
* Compute a set of statistics on a data set.
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param data set of values.
|
||||
* @param statistics set of statistics to compute.
|
||||
* @return computed statistics.
|
||||
* @param order the maximum order of moments to compute.
|
||||
*/
|
||||
public static double[] compute(Double[] data, MomentStatistic[] statistics) {
|
||||
if (statistics.length == 0) {
|
||||
return new double[0];
|
||||
public Moments(int order) {
|
||||
this.count = 0;
|
||||
this.totals = new double[order];
|
||||
}
|
||||
|
||||
public Moments add(double value) {
|
||||
count++;
|
||||
double v = value;
|
||||
for (int i = 0; i < totals.length; i++) {
|
||||
totals[i] += v;
|
||||
v *= value;
|
||||
}
|
||||
|
||||
int order = Arrays.stream(statistics).mapToInt(s -> s == null ? 0 : s.order()).max().getAsInt();
|
||||
return this;
|
||||
}
|
||||
|
||||
long count = 0;
|
||||
double[] totals = new double[order];
|
||||
for (Double value : data) {
|
||||
if (value == null || Double.isNaN(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
double v = value;
|
||||
for (int i = 0; i < order; i++) {
|
||||
totals[i] += v;
|
||||
v *= value;
|
||||
}
|
||||
}
|
||||
|
||||
final long _count = count;
|
||||
return Arrays.stream(statistics)
|
||||
.mapToDouble(s -> s == null ? Double.NaN : s.evaluate(_count, totals))
|
||||
.toArray();
|
||||
public double compute(MomentStatistic s) {
|
||||
return s.evaluate(count, totals);
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ bench =
|
||||
Bench.measure (random_vec.filter (x -> x % 3 == 1)) "Filter" iter_size num_iterations
|
||||
Bench.measure (random_vec.filter_with_index (i-> x-> (i+x) % 3 == 1)) "Filter With Index" iter_size num_iterations
|
||||
|
||||
random_gen = Random.new 0
|
||||
Bench.measure (random_vec . map (x -> x + random_gen.nextLong) . filter (x -> x % 3 == 1)) "Map & Filter" iter_size num_iterations
|
||||
Bench.measure (random_vec.partition (x -> x % 3 == 1)) "Partition" iter_size num_iterations
|
||||
Bench.measure (random_vec.partition_with_index (i-> x-> (i+x) % 3 == 1)) "Partition With Index" iter_size num_iterations
|
||||
|
@ -79,15 +79,17 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Between (t.at "Y") "bzzzz") . at "X" . to_vector . should_equal ["abb", "baca", "b"]
|
||||
|
||||
Test.specify "by text search (contains, starts_with, ends_with, like)" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", ["abb", "baca", "banana", Nothing, "nana"]], ["Y", ["a", "b", "b", "c", "a"]], ["Z", ["aaaaa", "bbbbb", "[ab]", "[ab]aaaa", "[ab]ccc"]]]
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", ["abb", "baca", "banana", Nothing, "nana"]], ["Y", ["a", "b", "d", "c", "a"]], ["Z", ["aaaaa", "bbbbb", "[ab]", "[ab]aaaa", "[ab]ccc"]]]
|
||||
|
||||
t.filter "X" (Filter_Condition.Starts_With "ba") on_problems=Report_Error . at "X" . to_vector . should_equal ["baca", "banana"]
|
||||
t.filter "X" (Filter_Condition.Ends_With "na") on_problems=Report_Error . at "X" . to_vector . should_equal ["banana", "nana"]
|
||||
t.filter "X" (Filter_Condition.Contains "ac") on_problems=Report_Error . at "X" . to_vector . should_equal ["baca"]
|
||||
t.filter "X" (Filter_Condition.Not_Contains "ac") on_problems=Report_Error . at "X" . to_vector . should_equal ["abb", "banana", "nana"]
|
||||
|
||||
t.filter "X" (Filter_Condition.Starts_With (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["abb", "baca", "banana"]
|
||||
t.filter "X" (Filter_Condition.Starts_With (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["abb", "baca"]
|
||||
t.filter "X" (Filter_Condition.Ends_With (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["nana"]
|
||||
t.filter "X" (Filter_Condition.Contains (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["abb", "baca", "banana", "nana"]
|
||||
t.filter "X" (Filter_Condition.Contains (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["abb", "baca", "nana"]
|
||||
t.filter "X" (Filter_Condition.Not_Contains (t.at "Y")) on_problems=Report_Error . at "X" . to_vector . should_equal ["banana"]
|
||||
|
||||
t.filter "X" (Filter_Condition.Like "%an%") on_problems=Report_Error . at "X" . to_vector . should_equal ["banana", "nana"]
|
||||
t.filter "X" (Filter_Condition.Like "_a%") on_problems=Report_Error . at "X" . to_vector . should_equal ["baca", "banana", "nana"]
|
||||
@ -109,6 +111,7 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Ends_With '\nb') on_problems=Report_Error . at "X" . to_vector . should_equal ['a\n\n\nb', 'a\nb']
|
||||
t.filter "X" (Filter_Condition.Ends_With '\n') on_problems=Report_Error . at "X" . to_vector . should_equal ['a\n\n\n', 'a\n']
|
||||
t.filter "X" (Filter_Condition.Starts_With 'c') on_problems=Report_Error . at "X" . to_vector . should_equal ['caa\nbb']
|
||||
t.filter "X" (Filter_Condition.Not_Contains '\nb') on_problems=Report_Error . at "X" . to_vector . should_equal ['a\n\n\n', 'a\n']
|
||||
|
||||
if test_selection.supports_unicode_normalization then
|
||||
t = table_builder [["X", ['śnieg', 's\u0301nieg', 'X', Nothing, 'połać', 'połac\u0301']]]
|
||||
@ -117,6 +120,7 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Contains 'ś') on_problems=Report_Error . at "X" . to_vector . should_equal ['śnieg', 's\u0301nieg']
|
||||
t.filter "X" (Filter_Condition.Ends_With 'ś') on_problems=Report_Error . at "X" . to_vector . should_equal []
|
||||
t.filter "X" (Filter_Condition.Ends_With 'ć') on_problems=Report_Error . at "X" . to_vector . should_equal ['połać', 'połac\u0301']
|
||||
t.filter "X" (Filter_Condition.Not_Contains 'ś') on_problems=Report_Error . at "X" . to_vector . should_equal ['X', 'połać', 'połac\u0301']
|
||||
|
||||
# This should be replaced with the disabled test below, once the related bug is fixed.
|
||||
t.filter "X" (Filter_Condition.Like 'ś%') on_problems=Report_Error . at "X" . to_vector . should_equal ['śnieg']
|
||||
@ -147,12 +151,14 @@ spec setup =
|
||||
check_column_type_error_handling (t.filter "X" (Filter_Condition.Contains (t.at "ix")) on_problems=_)
|
||||
check_column_type_error_handling (t.filter "X" (Filter_Condition.Like (t.at "ix")) on_problems=_)
|
||||
check_column_type_error_handling (t.filter "X" (Filter_Condition.Not_Like (t.at "ix")) on_problems=_)
|
||||
check_column_type_error_handling (t.filter "X" (Filter_Condition.Not_Contains (t.at "ix")) on_problems=_)
|
||||
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Starts_With "A") on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Ends_With "A") on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Contains "A") on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Like "A") on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Not_Like "A") on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" (Filter_Condition.Not_Contains "A") on_problems=_)
|
||||
|
||||
check_column_type_error_handling (t.filter "ix" Filter_Condition.Is_Empty on_problems=_)
|
||||
check_column_type_error_handling (t.filter "ix" Filter_Condition.Not_Empty on_problems=_)
|
||||
@ -166,6 +172,7 @@ spec setup =
|
||||
check_scalar_type_error_handling "substring" (t.filter "X" (Filter_Condition.Contains 42) on_problems=_)
|
||||
check_scalar_type_error_handling "pattern" (t.filter "X" (Filter_Condition.Like 42) on_problems=_)
|
||||
check_scalar_type_error_handling "pattern" (t.filter "X" (Filter_Condition.Not_Like 42) on_problems=_)
|
||||
check_scalar_type_error_handling "substring" (t.filter "X" (Filter_Condition.Not_Contains 42) on_problems=_)
|
||||
|
||||
Test.specify "by nulls" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4]], ["X", [Nothing, 1, Nothing, 4]]]
|
||||
@ -265,4 +272,3 @@ spec setup =
|
||||
table.at "X" . to_vector . should_equal (t.at "X" . to_vector)
|
||||
problems = [Index_Out_Of_Bounds.Error 4 1]
|
||||
Problems.test_problem_handling action problems tester
|
||||
|
||||
|
@ -35,15 +35,33 @@ spec setup =
|
||||
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
|
||||
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
|
||||
|
||||
## Assumes stable sorting on database engine.
|
||||
t2 = table.order_by (Sort_Column_Selector.By_Index [1, Sort_Column.Index -8 Sort_Direction.Descending])
|
||||
t2.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
|
||||
t2.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
|
||||
t2.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
|
||||
|
||||
Test.specify "should work with single column name" <|
|
||||
t1 = table.order_by "alpha"
|
||||
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
|
||||
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
|
||||
|
||||
t2 = table.order_by (Sort_Column_Selector.By_Index [1, Sort_Column.Index -8 Sort_Direction.Descending])
|
||||
t2.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
|
||||
t2.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
|
||||
t2.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
|
||||
Test.specify "should work with single Sort_Column" <|
|
||||
t1 = table.order_by (Sort_Column.Name "alpha")
|
||||
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
|
||||
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
|
||||
|
||||
t2 = t1.order_by (Sort_Column.Name "alpha" Sort_Direction.Descending)
|
||||
t2.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
|
||||
t2.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
|
||||
|
||||
t3 = table.order_by (Sort_Column.Index 0)
|
||||
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
|
||||
t3.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
|
||||
|
||||
t4 = t3.order_by (Sort_Column.Index 0 Sort_Direction.Descending)
|
||||
t4.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
|
||||
t4.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
|
||||
|
||||
Test.specify "should correctly handle regexes matching multiple names" <|
|
||||
t1 = table.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name ".*ta" Sort_Direction.Descending] (Regex_Matcher.Value case_sensitivity=Case_Sensitivity.Sensitive))
|
||||
@ -155,6 +173,11 @@ spec setup =
|
||||
t1.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
|
||||
t1.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
|
||||
|
||||
t1a = table.order_by ["beta", Sort_Column.Name "alpha" Sort_Direction.Ascending]
|
||||
t1a.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
|
||||
t1a.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
|
||||
t1a.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
|
||||
|
||||
t2 = table.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name "beta", Sort_Column.Name "alpha" Sort_Direction.Descending])
|
||||
t2.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
|
||||
t2.at "alpha" . to_vector . should_equal [3, 1, 2, 0]
|
||||
|
@ -340,26 +340,6 @@ spec =
|
||||
i.at "Storage Type" . to_vector . should_equal [Storage.Text, Storage.Integer, Storage.Any]
|
||||
|
||||
Test.group "Sorting Tables" <|
|
||||
df = (enso_project.data / "clothes.csv").read
|
||||
|
||||
Test.specify "should allow sorting by a single column name" <|
|
||||
r_1 = df.order_by (Sort_Column_Selector.By_Name ["Quantity"])
|
||||
r_1.at 'Id' . to_vector . should_equal [2,4,1,3,5,6]
|
||||
|
||||
r_3 = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name "Rating" Sort_Direction.Descending])
|
||||
r_3.at 'Id' . to_vector . should_equal [3,1,4,5,2,6]
|
||||
|
||||
Test.specify 'should allow sorting by multiple column names' <|
|
||||
r_1 = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'Quantity', 'Rating'])
|
||||
r_1.at 'Id' . to_vector . should_equal [2,4,1,3,6,5]
|
||||
|
||||
r_2 = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'Rating' Sort_Direction.Descending, Sort_Column.Name 'Quantity' Sort_Direction.Descending])
|
||||
r_2.at 'Id' . to_vector . should_equal [3,1,4,5,6,2]
|
||||
|
||||
Test.specify 'should allow sorting with specific by-column rules' <|
|
||||
r_1 = df.order_by (Sort_Column_Selector.By_Name ["Quantity", Sort_Column.Name "Price" Sort_Direction.Descending])
|
||||
r_1.at 'Id' . to_vector . should_equal [4,2,3,1,6,5]
|
||||
|
||||
Test.specify 'should respect defined comparison operations for custom types' <|
|
||||
c_1 = ['id', [1, 2, 3, 4, 5, 6]]
|
||||
c_2 = ['val', [My.Data 1 2, My.Data 3 4, My.Data 2 1, My.Data 5 2, My.Data 7 0, My.Data 4 -1]]
|
||||
@ -367,13 +347,6 @@ spec =
|
||||
r = df.order_by (Sort_Column_Selector.By_Name ['val'])
|
||||
r.at 'id' . to_vector . should_equal [1,3,6,2,4,5]
|
||||
|
||||
Test.specify 'should return warnings and errors when passed a non-existent column' <|
|
||||
action = df.order_by (Sort_Column_Selector.By_Name ['foobar']) on_problems=_
|
||||
tester table =
|
||||
table.at 'Id' . to_vector . should_equal [1,2,3,4,5,6]
|
||||
problems = [Missing_Input_Columns.Error [Sort_Column.Name 'foobar'], No_Input_Columns_Selected]
|
||||
Problems.test_problem_handling action problems tester
|
||||
|
||||
Test.specify 'should correctly reorder all kinds of columns and leave the original columns untouched' <|
|
||||
ord = [0, 3, 2, 4, 1]
|
||||
ints = [1, 2, 3, 4, 5]
|
||||
@ -1012,6 +985,15 @@ spec =
|
||||
t1.at "Name" . to_vector . should_equal ["Value", "Another", "Yet Another", "Value", "Another", "Yet Another", "Value", "Another", "Yet Another"]
|
||||
t1.at "Value" . to_vector . should_equal [1, 10, Nothing, 2, Nothing, "Hello", 3, 20, "World"]
|
||||
|
||||
Test.specify "should allow single id field" <|
|
||||
t = Table.new [["Key", ["x", "y", "z"]], ["Value", [1, 2, 3]], ["Another", [10, Nothing, 20]], ["Yet Another", [Nothing, "Hello", "World"]]]
|
||||
t1 = t.transpose "Key"
|
||||
t1.row_count . should_equal 9
|
||||
t1.column_count . should_equal 3
|
||||
t1.at "Key" . to_vector . should_equal ["x", "x", "x", "y", "y", "y", "z", "z", "z"]
|
||||
t1.at "Name" . to_vector . should_equal ["Value", "Another", "Yet Another", "Value", "Another", "Yet Another", "Value", "Another", "Yet Another"]
|
||||
t1.at "Value" . to_vector . should_equal [1, 10, Nothing, 2, Nothing, "Hello", 3, 20, "World"]
|
||||
|
||||
Test.specify "should allow all id fields with warning or error" <|
|
||||
t = Table.new [["Key", ["x", "y", "z"]], ["Value", [1, 2, 3]], ["Another", [10, Nothing, 20]], ["Yet Another", [Nothing, "Hello", "World"]]]
|
||||
t1 = t.transpose t.column_names
|
||||
@ -1072,6 +1054,16 @@ spec =
|
||||
t1.at "y" . to_vector . should_equal [2, 1]
|
||||
t1.at "z" . to_vector . should_equal [1, 1]
|
||||
|
||||
Test.specify "should allow a grouping by text" <|
|
||||
t = Table.new [["Group", ["A","B","A","B","A","B","A","B","A"]], ["Key", ["x", "x", "x", "x", "y", "y", "y", "z", "z"]], ["Value", [1, 2, 3, 4, 5, 6, 7, 8, 9]]]
|
||||
t1 = t.cross_tab "Group" "Key"
|
||||
t1.row_count . should_equal 2
|
||||
t1.column_count . should_equal 4
|
||||
t1.at "Group" . to_vector . should_equal ["A", "B"]
|
||||
t1.at "x" . to_vector . should_equal [2, 2]
|
||||
t1.at "y" . to_vector . should_equal [2, 1]
|
||||
t1.at "z" . to_vector . should_equal [1, 1]
|
||||
|
||||
Test.specify "should aggregate if name_field not found" <|
|
||||
t = Table.new [["Key", ["x", "x", "x", "x", "y", "y", "y", "z", "z"]], ["Value", [1, 2, 3, 4, 5, 6, 7, 8, 9]]]
|
||||
t1 = t.cross_tab [] "Name"
|
||||
|
@ -1,4 +1,6 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Error.Common.Index_Out_Of_Bounds
|
||||
import Standard.Base.Error.Illegal_Argument.Illegal_Argument
|
||||
from Standard.Base.Data.Json import Json_Parse_Error, No_Such_Field
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
@ -34,7 +36,6 @@ Text.should_render_itself self =
|
||||
|
||||
spec =
|
||||
Test.group "JSON Deserialization" <|
|
||||
|
||||
Test.specify "should parse JSON structures" <|
|
||||
"0 ".should_parse_as 0
|
||||
" 123 ".should_parse_as 123
|
||||
@ -88,7 +89,6 @@ spec =
|
||||
domain.should_equal books
|
||||
|
||||
Test.group "JSON Serialization" <|
|
||||
|
||||
Test.specify "should print JSON structures to valid json" <|
|
||||
"0".should_render_itself
|
||||
"123".should_render_itself
|
||||
@ -117,8 +117,12 @@ spec =
|
||||
fields = Map.empty . insert "type" t . insert "name" n . insert "year_of_birth" y
|
||||
Json.Object fields
|
||||
|
||||
Test.group "JSON" <|
|
||||
Test.specify "should render NaN and Infinity to null" <|
|
||||
Number.nan.to_json.to_text . should_equal "null"
|
||||
Number.positive_infinity.to_json.to_text . should_equal "null"
|
||||
Number.negative_infinity.to_json.to_text . should_equal "null"
|
||||
|
||||
Test.group "JSON" <|
|
||||
Test.specify "should allow getting object fields" <|
|
||||
object = Json.parse '''
|
||||
{ "foo": "bar",
|
||||
@ -126,6 +130,42 @@ spec =
|
||||
"y": {"z": null, "w": null} }
|
||||
|
||||
object.get "foo" . should_equal (Json.String "bar")
|
||||
object.get_or_else "foo" . should_equal (Json.String "bar")
|
||||
object.get "bar" . should_fail_with No_Such_Field.Error
|
||||
object.get_or_else "bar" . should_equal Json.Null
|
||||
object.get_or_else "bar" 1 . should_equal 1
|
||||
Json.Null.get "foo" . should_fail_with No_Such_Field.Error
|
||||
Json.Null.get_or_else "foo" . should_equal Json.Null
|
||||
Json.Null.get_or_else "foo" 1 . should_equal 1
|
||||
|
||||
Test.specify "should be able to get field_names" <|
|
||||
Json.parse '{ "foo": "bar", "baz": ["foo", "x", false] }' . field_names . should_equal ["baz", "foo"]
|
||||
Json.parse '{}' . field_names . should_equal []
|
||||
Json.parse 'null' . field_names . should_fail_with Illegal_Argument.Error
|
||||
Json.parse '[1,2,3]' . field_names . should_fail_with Illegal_Argument.Error
|
||||
|
||||
Test.specify "should be able to get a value by index" <|
|
||||
Json.parse "[1, 2, 3, 4, 5]" . at 2 . should_equal (Json.Number 3)
|
||||
Json.parse "[1, 2, 3, 4, 5]" . at -2 . should_equal (Json.Number 4)
|
||||
Json.parse "[1, 2, 3, 4, 5]" . at 5 . should_fail_with Index_Out_Of_Bounds.Error
|
||||
Json.parse '"foo"' . at 0 . should_equal (Json.String "f")
|
||||
Json.parse '"foo"' . at -1 . should_equal (Json.String "o")
|
||||
Json.parse '"foo"' . at 3 . should_fail_with Index_Out_Of_Bounds.Error
|
||||
Json.parse '{}' . at 1 . should_fail_with Illegal_Argument.Error
|
||||
|
||||
Test.specify "should be able to make empty objects and array" <|
|
||||
Json.empty_object.should_equal (Json.Object Map.empty)
|
||||
Json.empty_object.to_text.should_equal "{}"
|
||||
Json.empty_array.should_equal (Json.Array [])
|
||||
Json.empty_array.to_text.should_equal "[]"
|
||||
|
||||
Test.specify "should be able to get length" <|
|
||||
Json.empty_object.length.should_equal 0
|
||||
Json.empty_array.length.should_equal 0
|
||||
Json.parse '{ "foo": "bar", "baz": ["foo", "x", false] }' . length . should_equal 2
|
||||
Json.parse '[1, 2, 3, 4, 5]' . length . should_equal 5
|
||||
Json.parse '"foo"' . length . should_equal 3
|
||||
Json.parse '""' . length . should_equal 0
|
||||
Json.Null.length.should_fail_with Illegal_Argument.Error
|
||||
|
||||
main = Test_Suite.run_main spec
|
||||
|
@ -69,6 +69,8 @@ spec = Test.group "List" <|
|
||||
txt = ["aaa", "bbb", "abab", "cccc", "baaa", "ś"].to_list
|
||||
txt.filter (Filter_Condition.Contains "a") . should_equal ["aaa", "abab", "baaa"].to_list
|
||||
txt.filter (Filter_Condition.Contains 's\u0301') . should_equal ["ś"].to_list
|
||||
txt.filter (Filter_Condition.Not_Contains "a") . should_equal ["bbb", "cccc", "ś"].to_list
|
||||
txt.filter (Filter_Condition.Not_Contains 's\u0301') . should_equal ["aaa", "bbb", "abab", "cccc", "baaa"].to_list
|
||||
txt.filter (Filter_Condition.Starts_With "a") . should_equal ["aaa", "abab"].to_list
|
||||
txt.filter (Filter_Condition.Ends_With "a") . should_equal ["aaa", "baaa"].to_list
|
||||
txt.filter (Filter_Condition.Less than="a") . should_equal List.Nil
|
||||
|
@ -286,6 +286,9 @@ spec =
|
||||
1.0%0 . is_nan . should_be_true
|
||||
almost_max_long_times_three%0.0 . is_nan . should_be_true
|
||||
|
||||
1/0 . is_infinite . should_be_true
|
||||
-1/0 . is_infinite . should_be_true
|
||||
|
||||
Test.specify "should support less than operator" <|
|
||||
(1 < 2).should_be_true
|
||||
(1 < 1).should_be_false
|
||||
@ -440,6 +443,11 @@ spec =
|
||||
Number.positive_infinity.is_nan . should_be_false
|
||||
Number.negative_infinity.is_nan . should_be_false
|
||||
|
||||
Number.nan.is_infinite . should_be_false
|
||||
0.is_infinite . should_be_false
|
||||
Number.positive_infinity.is_infinite . should_be_true
|
||||
Number.negative_infinity.is_infinite . should_be_true
|
||||
|
||||
Number.nan==Number.nan . should_be_false
|
||||
Number.nan==0 . should_be_false
|
||||
Number.nan!=Number.nan . should_be_true
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Error.Common.Type_Error
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
@ -64,4 +65,9 @@ spec =
|
||||
Ordering.Greater.and_then Ordering.Equal . should_equal Ordering.Greater
|
||||
Ordering.Greater.and_then Ordering.Greater . should_equal Ordering.Greater
|
||||
|
||||
Test.specify "should fail with Type_Error for wrong type of that" <|
|
||||
Ordering.Less.compare_to 1 . should_fail_with Type_Error.Error
|
||||
Ordering.Less.compare_to Nothing . should_fail_with Type_Error.Error
|
||||
Ordering.Less.compare_to "Hello" . should_fail_with Type_Error.Error
|
||||
|
||||
main = Test_Suite.run_main spec
|
||||
|
23
test/Tests/src/Data/Pair_Spec.enso
Normal file
23
test/Tests/src/Data/Pair_Spec.enso
Normal file
@ -0,0 +1,23 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Error.Common.Index_Out_Of_Bounds
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
||||
spec = Test.group "Pair" <|
|
||||
Test.specify "should be created by new" <|
|
||||
Pair.new 1 2 . should_equal (Pair.Value 1 2)
|
||||
|
||||
Test.specify "should allow mapping" <|
|
||||
Pair.new 1 2 . map x->x+1 . should_equal (Pair.Value 2 3)
|
||||
|
||||
Test.specify "should act as a length 2 Vector" <|
|
||||
Pair.new "A" "B" . length . should_equal 2
|
||||
Pair.new "A" "B" . at 0 . should_equal "A"
|
||||
Pair.new "A" "B" . at -2 . should_equal "A"
|
||||
Pair.new "A" "B" . at 1 . should_equal "B"
|
||||
Pair.new "A" "B" . at -1 . should_equal "B"
|
||||
Pair.new "A" "B" . at 2 . should_fail_with Index_Out_Of_Bounds.Error
|
||||
Pair.new "A" "B" . to_vector . should_equal ["A", "B"]
|
||||
|
||||
main = Test_Suite.run_main spec
|
@ -125,6 +125,10 @@ spec = Test.group "Range" <|
|
||||
vec_mut_2.to_vector . should_equal [Pair.new 0 5, Pair.new 1 7, Pair.new 2 9]
|
||||
Test.specify "should be able to be folded" <|
|
||||
1.up_to 6 . fold 0 (+) . should_equal 15
|
||||
1.up_to 1 . fold 123 (+) . should_equal 123
|
||||
Test.specify "should be able to perform a running fold" <|
|
||||
1.up_to 6 . running_fold 0 (+) . should_equal [1, 3, 6, 10, 15]
|
||||
1.up_to 1 . running_fold 123 (+) . should_equal []
|
||||
Test.specify "should check all" <|
|
||||
1.up_to 10 . all (> 0) . should_be_true
|
||||
1.up_to 10 . all (< 0) . should_be_false
|
||||
|
@ -119,6 +119,14 @@ spec =
|
||||
values = number_set.compute_bulk stats
|
||||
vector_compare values expected
|
||||
|
||||
Test.specify "should allow running computation" <|
|
||||
number_set.running . should_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
|
||||
expected_counts = [1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16]
|
||||
expected_sums = [0.4, -18.16, -35.15, -51.58, -51.58, -38.14, -44.99, -35.31, -43.86, -43.86, -33.48, 0.37, -40.65, -38.78, -38.78, -52.65, -91.71, -65.79, -81.8, -81.8]
|
||||
missing_set.running . should_equal expected_counts
|
||||
values = missing_set.running Statistic.Sum
|
||||
vector_compare values expected_sums
|
||||
|
||||
Test.group "Statistics - empty Vector " <|
|
||||
Test.specify "should be able to count and sum on empty Vector" <|
|
||||
[].compute . should_equal 0
|
||||
@ -145,6 +153,7 @@ spec =
|
||||
text_set.compute Statistic.Variance . should_fail_with Illegal_Argument.Error
|
||||
text_set.compute Statistic.Skew . should_fail_with Illegal_Argument.Error
|
||||
text_set.compute Statistic.Kurtosis . should_fail_with Illegal_Argument.Error
|
||||
text_set.running Statistic.Sum . should_fail_with Illegal_Argument.Error
|
||||
|
||||
Test.specify "should be able to do Count, Minimum and Maximum on custom type with compare_to" <|
|
||||
ord_set.compute . should_equal 3
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Error.Common.Type_Error
|
||||
import Standard.Base.Error.Time_Error.Time_Error
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
@ -74,8 +75,8 @@ spec =
|
||||
(duration - period).should_fail_with Time_Error.Error
|
||||
(period + duration).should_fail_with Time_Error.Error
|
||||
(period - duration).should_fail_with Time_Error.Error
|
||||
(duration > period).should_fail_with Time_Error.Error
|
||||
(duration < period).should_fail_with Time_Error.Error
|
||||
(duration > period).should_fail_with Type_Error.Error
|
||||
(duration < period).should_fail_with Type_Error.Error
|
||||
|
||||
Test.specify "Date_Time supports adding and subtracting Duration" <|
|
||||
((Date_Time.new 2022 10 1 hour=10) + (Duration.new hours=2)) . should_equal (Date_Time.new 2022 10 1 hour=12)
|
||||
|
@ -113,6 +113,11 @@ spec = Test.group "Vectors" <|
|
||||
|
||||
Test.specify "should allow folding an operator over its elements" <|
|
||||
[1,2,3].fold 0 (+) . should_equal 6
|
||||
[].fold 123 (+) . should_equal 123
|
||||
|
||||
Test.specify "should allow a running fold operator over its elements" <|
|
||||
[1,2,3].running_fold 0 (+) . should_equal [1, 3, 6]
|
||||
[].running_fold 123 (+) . should_equal []
|
||||
|
||||
Test.specify "should allow to reduce elements if it is non-empty" <|
|
||||
[1,2,3].reduce (+) . should_equal 6
|
||||
@ -187,6 +192,8 @@ spec = Test.group "Vectors" <|
|
||||
txtvec = ["aaa", "bbb", "abab", "cccc", "baaa", "ś"]
|
||||
txtvec.filter (Filter_Condition.Contains "a") . should_equal ["aaa", "abab", "baaa"]
|
||||
txtvec.filter (Filter_Condition.Contains 's\u0301') . should_equal ["ś"]
|
||||
txtvec.filter (Filter_Condition.Not_Contains "a") . should_equal ["bbb", "cccc", "ś"]
|
||||
txtvec.filter (Filter_Condition.Not_Contains 's\u0301') . should_equal ["aaa", "bbb", "abab", "cccc", "baaa"]
|
||||
txtvec.filter (Filter_Condition.Starts_With "a") . should_equal ["aaa", "abab"]
|
||||
txtvec.filter (Filter_Condition.Ends_With "a") . should_equal ["aaa", "baaa"]
|
||||
txtvec.filter (Filter_Condition.Less than="a") . should_equal []
|
||||
@ -216,6 +223,7 @@ spec = Test.group "Vectors" <|
|
||||
txt3 = ['śnieg', 's\u0301nieg', 'X', 'połać', 'połac\u0301']
|
||||
txt3.filter (Filter_Condition.Starts_With 'ś') . should_equal ['śnieg', 's\u0301nieg']
|
||||
txt3.filter (Filter_Condition.Contains 'ś') . should_equal ['śnieg', 's\u0301nieg']
|
||||
txt3.filter (Filter_Condition.Not_Contains 'ś') . should_equal ['X', 'połać', 'połac\u0301']
|
||||
txt3.filter (Filter_Condition.Ends_With 'ś') . should_equal []
|
||||
txt3.filter (Filter_Condition.Ends_With 'ć') . should_equal ['połać', 'połac\u0301']
|
||||
## There is a bug with Java Regex in Unicode normalized mode (CANON_EQ) with quoting.
|
||||
|
@ -39,6 +39,7 @@ import project.Data.Ordering_Spec
|
||||
import project.Data.Ordering.Comparator_Spec
|
||||
import project.Data.Ordering.Natural_Order_Spec
|
||||
import project.Data.Ordering.Vector_Lexicographic_Order_Spec
|
||||
import project.Data.Pair_Spec
|
||||
import project.Data.Range_Spec
|
||||
import project.Data.Ref_Spec
|
||||
import project.Data.Time.Spec as Time_Spec
|
||||
@ -117,6 +118,7 @@ main = Test_Suite.run_main <|
|
||||
Process_Spec.spec
|
||||
Python_Interop_Spec.spec
|
||||
R_Interop_Spec.spec
|
||||
Pair_Spec.spec
|
||||
Range_Spec.spec
|
||||
Ref_Spec.spec
|
||||
Default_Regex_Engine_Spec.spec
|
||||
|
Loading…
Reference in New Issue
Block a user