Skip to content

Commit

Permalink
Add .sum to Vector (#1702)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamrecursion committed Apr 28, 2021
1 parent 2d88ed8 commit caa9982
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 32 deletions.
20 changes: 18 additions & 2 deletions distribution/std-lib/Standard/src/Base/Data/Range.enso
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,28 @@ type Range
not_empty : Boolean
not_empty = this.is_empty.not

## Applies a function to each element in the range, producing a vector of
results.

Arguments:
- function: The function to apply to each integer in the range.

> Example
Create a vector that contains the numbers twice that of the numbers in
the range.

1.up_to 10 . map (*2)
map : (Number -> Any) -> Vector Any
map function = this.to_vector.map function

## Applies a function for each element in the range.

Arguments:
- function: The function to apply to each integer in the range.

> Example
To print all the numbers from 1 to 100 use:
1.up_to 101 . each IO.println
1.up_to 101 . each IO.println
each : (Number -> Any) -> Nothing
each function =
it start end = if start == end then Nothing else
Expand Down Expand Up @@ -130,5 +144,7 @@ type Range
Getting a vector of the numbers 1 to 5.
1.up_to 6 . to_vector == [1, 2, 3, 4, 5]
to_vector : Vector.Vector
to_vector = Vector.new (this.end - 1) (i -> i + this.start)
to_vector =
length = Math.max 0 (this.end - this.start)
Vector.new length (i -> i + this.start)

18 changes: 18 additions & 0 deletions distribution/std-lib/Standard/src/Base/Data/Vector.enso
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ type Vector
True -> this.tail.fold this.head function
False -> Error.throw Nothing

## Computes the sum of the values in the vector.

For this method to be defined, the elements of the vector must be able to
have the `+` operator used to combine them.

> Example
In the following example, we'll compute the sum of all elements of a
vector.

[0, 1, 2].sum
sum : (Any ! Nothing)
sum =
result = Panic.recover <| this.reduce (+)
result.map_error x->case x of
No_Such_Method_Error _ _ -> Nothing
Nothing -> Nothing
_ -> Panic.throw x

## Checks whether a predicate holds for at least one element of this vector.

Arguments:
Expand Down
28 changes: 13 additions & 15 deletions distribution/std-lib/Standard/src/Visualization/Scatter_Plot.enso
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ label_field = 'label'

## PRIVATE
Represents a recognized point data field for a scatter plot visualization.
type PointData
type PointData
## PRIVATE
type PointData
## PRIVATE
Expand Down Expand Up @@ -72,15 +72,13 @@ type PointData
## PRIVATE
Returns a vector of subsequent integers beginning from 0.
iota : Number -> Vector
iota count =
# FIXME [mwu]: Adjust once https://github.com/enso-org/enso/issues/1439
# is addressed.
range = 0.up_to <| count + 1
iota count =
range = 0.up_to count
Column.from_vector here.index_name range.to_vector

## PRIVATE
lookup_in : Table -> Column
lookup_in table =
lookup_in table =
named = table.lookup_ignore_case this.name
named.catch_ <| this.fallback_column table

Expand All @@ -90,7 +88,7 @@ Table.Table.point_data : Table -> Object
Table.Table.point_data =
get_point_data field = field.lookup_in this . rename field.name
columns = PointData.all_fields.filter_map get_point_data
(0.up_to <| this.row_count + 1).to_vector.map <| row_n->
(0.up_to this.row_count).to_vector.map <| row_n->
pairs = columns.map column->
value = column.at row_n . catch_ Nothing
[column.name, value]
Expand All @@ -100,7 +98,7 @@ Table.Table.point_data =
Generates JSON that describes plot axes.
Table.Table.axes : Table -> Object
Table.Table.axes =
describe_axis field =
describe_axis field =
col_name = field.lookup_in this . name
label = Json.from_pairs [[here.label_field, col_name]]
[field.name, label]
Expand All @@ -114,33 +112,33 @@ Table.Table.axes =

## PRIVATE
Vector.Vector.point_data : Vector -> Object
Vector.Vector.point_data =
this.map_with_index <| i-> elem->
Vector.Vector.point_data =
this.map_with_index <| i-> elem->
Json.from_pairs [[X.name,i],[Y.name,elem]]

## PRIVATE

json_from_table table =
json_from_table table =
data = table.point_data
axes = table.axes
Json.from_pairs <| [[here.data_field,data], [here.axis_field, axes]]

## PRIVATE
json_from_vector vec =
json_from_vector vec =
data = [here.data_field, vec.point_data]
axes = [here.axis_field, Nothing]
Json.from_pairs [data, axes]

## PRIVATE

Default preprocessor for the scatterplot visualization.

Generates JSON text describing the scatterplot visualization.

Arguments:
- value: the value to be visualized.
process_to_json_text : Any -> Text
process_to_json_text value =
process_to_json_text value =
json = case value of
Column.Column _ -> here.json_from_table value.to_table
Table.Table _ -> here.json_from_table value
Expand Down
5 changes: 5 additions & 0 deletions test/Tests/src/Data/Range_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ spec = Test.group "Range" <|
0.up_to -100 . not_empty . should_be_false
0.up_to 1 . not_empty . should_be_true
0.up_to 5 . not_empty . should_be_true
Test.specify "should be able to be mapped over to make a Vector" <|
empty = 0.up_to 0
empty.map *2 . should_equal []
elements = 0.up_to 10
elements.map *2 . should_equal [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Test.specify "should allow iteration" <|
vec_mut = Vector.new_builder
1.up_to 6 . each (i -> vec_mut.append i)
Expand Down
5 changes: 5 additions & 0 deletions test/Tests/src/Data/Vector_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ spec = Test.group "Vectors" <|
[1,2,3].reduce (+) . should_equal 6
[].reduce (+) . should_fail_with Nothing

Test.specify "should allow summing elements if they define +" <|
[1,2,3].sum . should_equal 6
[].sum . should_fail_with Nothing
[T 1 2, T 3 4].sum . should_fail_with Nothing

Test.specify "should check exists" <|
vec = [1, 2, 3, 4, 5]
vec.exists (ix -> ix > 3) . should_be_true
Expand Down
14 changes: 7 additions & 7 deletions test/Visualization_Tests/src/Histogram_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Standard.Test
import Standard.Visualization.Histogram
import Visualization_Tests

spec =
spec =
expect value expected_label expected_values =
text = Histogram.process_to_json_text value
json = Json.parse text
Expand All @@ -20,7 +20,7 @@ spec =
json.should_equal expected_json

Test.group "Histogram Visualization" <|

Test.specify "deals with an empty table" <|
table = Table.from_rows [] []
expect table Nothing []
Expand All @@ -30,14 +30,14 @@ spec =
row_1 = [11 , 10 ]
row_2 = [21 , 20 ]
table = Table.from_rows header [row_1, row_2]
expect table 'α' [11,21]
expect table 'α' [11,21]

Test.specify "plots first column if none recognized even if index" <|
header = ['α']
row_1 = [11 ]
row_2 = [21 ]
table = Table.from_rows header [row_1, row_2] . set_index 'α'
expect table 'α' [11,21]
expect table 'α' [11,21]

Test.specify "plots 'value' numeric column if present" <|
header = ['α', 'value']
Expand All @@ -55,12 +55,12 @@ spec =

Test.specify "plots column" <|
column = Column.from_vector 'my_name' [1,4,6]
expect column 'my_name' [1,4,6]
expect column 'my_name' [1,4,6]

Test.specify "plots vector" <|
vector = [1,2,3]
expect vector Nothing vector

Test.specify "plots range" <|
vector = 2.up_to 4
vector = 2.up_to 5
expect vector Nothing [2,3,4]
16 changes: 8 additions & 8 deletions test/Visualization_Tests/src/Scatter_Plot_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Standard.Visualization.Scatter_Plot
import Visualization_Tests

spec =
expect value axis_expected_text data_expected_text =
expect value axis_expected_text data_expected_text =
text = Scatter_Plot.process_to_json_text value
json = Json.parse text
json.fields.keys.should_equal ['axis','data']
Expand All @@ -24,37 +24,37 @@ spec =
no_labels = 'null'

Test.group "Scatter Plot Visualization" <|

Test.specify "deals with an empty table" <|
table = Table.from_rows [] []
expect table 'null' '[]'

Test.specify "plots first column if none recognized" <|
header = ['α', 'ω']
row_1 = [11 , 10 ]
row_2 = [21 , 20 ]
table = Table.from_rows header [row_1, row_2]
expect table (labels index 'α') '[{"x":0,"y":11},{"x":1,"y":21}]'

Test.specify "plots 'y' against indices when no 'x' recognized" <|
header = ['α', 'y']
row_1 = [11 , 10 ]
row_2 = [21 , 20 ]
table = Table.from_rows header [row_1, row_2]
expect table (labels index 'y') '[{"x":0,"y":10},{"x":1,"y":20}]'

Test.specify "recognizes all relevant columns" <|
header = ['x' , 'y' , 'size' , 'shape' , 'label' , 'color' ]
row_1 = [11 , 10 , 50 , 'square' , 'label' , 'ff0000']
table = Table.from_rows header [row_1]
expect table (labels 'x' 'y') '[{"color":"ff0000","label":"label","shape":"square","size":50,"x":11,"y":10}]'

Test.specify "is case insensitive" <|
header = ['X' , 'Y' , 'Size' , 'Shape' , 'Label' , 'Color' ]
row_1 = [11 , 10 , 50 , 'square' , 'label' , 'ff0000']
table = Table.from_rows header [row_1]
expect table (labels 'X' 'Y') '[{"color":"ff0000","label":"label","shape":"square","size":50,"x":11,"y":10}]'

Test.specify "uses first unrecognized numeric column as `y` fallback" <|
header = ['x' , 'size' , 'name' , 'z' , 'ω']
row_1 = [11 , 50 , 'circul' , 20 , 30]
Expand Down Expand Up @@ -99,5 +99,5 @@ spec =
expect column (labels 'index' 'some_col') '[{"x":0,"y":10},{"x":1,"y":2},{"x":2,"y":3}]'

Test.specify "using indices for x if given a range" <|
value = 2.up_to 4
value = 2.up_to 5
expect value no_labels '[{"x":0,"y":2},{"x":1,"y":3},{"x":2,"y":4}]'

0 comments on commit caa9982

Please sign in to comment.