diff --git a/RELEASES.md b/RELEASES.md index 407fa8102c44..744d0da021c9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,7 +12,8 @@ - Overhauled the examples throughout the standard library ([#1707](https://github.com/enso-org/enso/pull/1707), - [#1725](https://github.com/enso-org/enso/pull/1725)). These examples all now + [#1725](https://github.com/enso-org/enso/pull/1725), and + [#1731](https://github.com/enso-org/enso/pull/1731)). These examples all now conform to a standard format and have been tested to work. - Made some miscellaneous fixes to the `HTTP` portion of the `Base` library that fix a few bugs ([#1722](https://github.com/enso-org/enso/pull/1722)). diff --git a/distribution/std-lib/Standard/data/food_shop_inventory.csv b/distribution/std-lib/Standard/data/food_shop_inventory.csv index c699512ae5bb..34d08b19964c 100644 --- a/distribution/std-lib/Standard/data/food_shop_inventory.csv +++ b/distribution/std-lib/Standard/data/food_shop_inventory.csv @@ -1,10 +1,10 @@ -item_name , price , stock -Pavlova Cake (Whole) , 10.50 , 10 -Gruyere (Wheel) , 50 , 3 -Strawberries (Punnett) , 4.50 , 50 -Tomatoes (Whole) , 0.5 , 100 -Tomato and Egg Sandwich , 1.75 , 20 -Lobster Thermidor , 15.50 , 10 -Syrniki , 1.99 , 25 -Bacon and Sausage Sandwich , 1.75 , 15 +item_id , item_name , price , total_stock , sold_stock +001 , Pavlova Cake (Whole) , 10.50 , 10 , 7 +002 , Gruyere (Wheel) , 50 , 3 , 1 +003 , Strawberries (Punnett) , 4.50 , 50 , 47 +004 , Tomatoes (Whole) , 0.5 , 100 , 32 +005 , Tomato and Egg Sandwich , 1.75 , 20 , 7 +006 , Lobster Thermidor , 15.50 , 10 , 9 +007 , Syrniki , 1.99 , 25 , 11 +008 , Bacon and Sausage Sandwich , 1.75 , 15 , 12 diff --git a/distribution/std-lib/Standard/data/food_shop_popularity.csv b/distribution/std-lib/Standard/data/food_shop_popularity.csv new file mode 100644 index 000000000000..d8101c97e6d2 --- /dev/null +++ b/distribution/std-lib/Standard/data/food_shop_popularity.csv @@ -0,0 +1,9 @@ +item_id , popularity +001 , 5 +002 , 2 +003 , 5 +004 , 3 +005 , 1 +006 , 2 +007 , 3 +008 , 4 diff --git a/distribution/std-lib/Standard/data/food_shop_transactions.csv b/distribution/std-lib/Standard/data/food_shop_transactions.csv new file mode 100644 index 000000000000..04a00edafef9 --- /dev/null +++ b/distribution/std-lib/Standard/data/food_shop_transactions.csv @@ -0,0 +1,13 @@ +transaction_id , item_id , quantity +001 , 001 , 1 +001 , 008 , 2 +002 , 005 , 4 +003 , 003 , 2 +003 , 004 , 1 +003 , 007 , 8 +004 , 002 , 1 +005 , 006 , 2 +006 , 001 , 1 +007 , 005 , 2 +008 , 003 , 5 + diff --git a/distribution/std-lib/Standard/src/Examples.enso b/distribution/std-lib/Standard/src/Examples.enso index 11c109367479..428af70ed574 100644 --- a/distribution/std-lib/Standard/src/Examples.enso +++ b/distribution/std-lib/Standard/src/Examples.enso @@ -4,8 +4,10 @@ import Standard.Base.Data.Time import Standard.Base.Network.Http import Standard.Base.System.Platform import Standard.Image.Codecs +import Standard.Table -# Renamed to avoid clashing with an uppercase name resolution for `duration`. +# Renamed to avoid clashing with an uppercase name resolution for the relevant +# items in this file. import Standard.Base.Data.Json as Enso_Json import Standard.Base.Data.List as Enso_List import Standard.Base.Data.Map as Enso_Map @@ -14,25 +16,6 @@ import Standard.Base.Network.Uri as Enso_Uri import Standard.Image as Enso_Image import Standard.Image.Data.Matrix as Enso_Matrix -# Can do the top-level examples directory. - -# Fine to not provide examples for some APIs (e.g. Database). - -# Examples with HTTP should note this clearly in the example text. - -# Image source should only download if it doesn't exist. We can say that the # -# user can put it there. - -# > Example -# Frobnicate the doobly do -# -# import Standard.Examples -# -# my_example = -# x = dlksaldjks -# y = x + 1 -# ... - ## An example error type used in a number of examples. Arguments: @@ -181,3 +164,93 @@ image = Enso_Image.read here.image_file [Codecs.Read_Alpha_Channel] matrix : Enso_Matrix.Matrix matrix = here.image.to_matrix +## A silly little function that adds one to the provided number. +add_1_to : Number -> Number +add_1_to n = n + 1 + +## A function that just returns a constant boolean value. +get_boolean : Boolean +get_boolean = False + +## A simple small piece of JSON that can easily be converted into a table. +simple_table_json : Enso_Json.Json +simple_table_json = + row_1 = Enso_Json.from_pairs [['foo', 20], ['bar', 'baz'], ['baz', False]] + row_2 = Enso_Json.from_pairs [['bar', 'xyz'], ['baz', True]] + row_3 = Enso_Json.from_pairs [['baz', False], ['foo', 13]] + [row_1, row_2, row_3].to_json + +## The headers for the columns in the JSON table `here.simple_table_json`. +simple_table_json_headers : Vector Text +simple_Table_json_headers = ["foo", "bar", "baz"] + +## Some simple GeoJSON. +geo_json : Enso_Json.Json +geo_json = Enso_Json.parse <| ''' + { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { "foo": 1, "bar": "value2"}, + "geometry": { "type": "Point", "coordinates": [ -118.58, 34.19 ] } + }, + { + "type": "Feature", + "properties": { "foo": 2, "baz": 3}, + "geometry": { "type": "Point", "coordinates": [ 10.11, 4.88, 19 ] } + } + ] + } + +## A small table column containing integers. +integer_column : Table.Column.Column +integer_column = Table.Column.from_vector "Integer" [1, 4, 8, 2, 5] + +## A small table column containing decimal numbers. +decimal_column : Table.Column.Column +decimal_column = Table.Column.from_vector "Decimal" [2.30, -2.1, Nothing, -10.1, 1.0] + +## A small table column containing booleans. +bool_column_1 : Table.Column.Column +bool_column_1 = Table.Column.from_vector "Bools" [True, True, False, True, False] + +## A small table column containing booleans. +bool_column_2 : Table.Column.Column +bool_column_2 = Table.Column.from_vector "Bools" [False, True, Nothing, True, True] + +## A small table column containing text. +text_column_1 : Table.Column.Column +text_column_1 = Table.Column.from_vector "Text" ["Hello,", "my", "name", "is", "Enso"] + +## A small table column containing text. +text_column_2 : Table.Column.Column +text_column_2 = Table.Column.from_vector "Text" ["He,", "he", "he", "i", "so"] + +## An aggregate column for the relevant examples. +aggregate_column : Table.Column.Aggregate_Column +aggregate_column = here.aggregate_table.at "transaction_id" + +## A simple table that contains basic shop inventory data for the food shop. +inventory_table : Table.Table +inventory_table = Table.from_csv here.csv . set_index "item_id" + +## A simple table that contains basic item popularity data for the food shop. +popularity_table : Table.Table +popularity_table = + table = Table.from_csv <| Enso_Project.data / "food_shop_popularity.csv" + table.set_index "item_id" + +## A simple tablethat contains basic transaction data for the food shop. +transactions_table : Table.Table +transactions_table = + Table.from_csv <| Enso_Project.data / "food_shop_transactions.csv" + +## An aggregate table for the relevant examples. +aggregate_table : Table.Aggregate_Table +aggregate_table = + transactions = Examples.transactions_table + item_names = Examples.inventory_table.at "item_name" + with_names = transactions.join item_names on="item_id" + with_names.group by="item_name" + diff --git a/distribution/std-lib/Standard/src/Table.enso b/distribution/std-lib/Standard/src/Table.enso index b0bd0e14da5e..36145c0b3cfd 100644 --- a/distribution/std-lib/Standard/src/Table.enso +++ b/distribution/std-lib/Standard/src/Table.enso @@ -33,6 +33,18 @@ from Standard.Table.Data.Order_Rule export Order_Rule and elevation. - Nested properties are not supported and not included in the resulting dataframe. + + > Example + Converts a JSON array containing key-value pairs into a table for the + provided headers. + + import Standard.Examples + import Standard.Table + + example_to_table = + json = Examples.simple_table_json + headers = Examples.simple_table_json_headers + json.to_table headers Json.Array.to_table : Vector -> Table Json.Array.to_table fields = case this of Json.Array items -> @@ -63,6 +75,17 @@ Json.Array.to_table fields = case this of and elevation. - Nested properties are not supported and not included in the resulting dataframe. + + > Example + Convert a GeoJSON object into a dataframe by looking up the necessary keys + in the input item. + + import Standard.Examples + import Standard.Table + + example_to_table = + json = Examples.geo_json + json.to_table Json.Object.to_table : Vector -> Table ! Nothing Json.Object.to_table fields=Nothing = if this.get_type != Geo_Json.Feature_Collection.to_text then Error.throw Nothing else @@ -83,3 +106,4 @@ Json.Object.to_table fields=Nothing = Table.new cols _ -> Error.throw Nothing + diff --git a/distribution/std-lib/Standard/src/Table/Data/Column.enso b/distribution/std-lib/Standard/src/Table/Data/Column.enso index 5ddef3738114..0f020199f2c2 100644 --- a/distribution/std-lib/Standard/src/Table/Data/Column.enso +++ b/distribution/std-lib/Standard/src/Table/Data/Column.enso @@ -11,12 +11,22 @@ polyglot java import org.enso.table.operations.OrderBuilder Arguments: - name: The name of the column to create. - items: The elements to contain in the column. + + > Example + Create a new column called "My Column" from a vector of numbers. + + import Standard.Table + + example_from_vector = + Table.Column.from_vector "My Column" [1, 2, 3, 4, 5] from_vector : Text -> Vector -> Column from_vector name items = Column (Java_Column.fromItems name items.to_array) type Column - ## A representation of a column in a Table. + ## PRIVATE + + A representation of a column in a Table. Arguments: - java_column: The internal representation of the column. @@ -27,6 +37,13 @@ type Column Arguments: - show_rows: the number of initial rows that should be displayed. - format_terminal: whether ANSI-terminal formatting should be used + + > Example + Convert a column to a pretty-printed text representation. + + import Standard.Examples + + example_display = Examples.integer_column.display display : Integer -> Boolean -> Text display show_rows=10 format_terminal=False = java_col = this.java_column @@ -44,10 +61,20 @@ type Column missing = '\n\u2026 and ' + (num_rows - display_rows).to_text + ' hidden rows.' table + missing - ## Prints an ASCII-art table with this data to the standard output. + ## TEXT_ONLY + + Prints an ASCII-art table with this data to the standard output. Arguments: - show_rows: the number of initial rows that should be displayed. + + > Example + Convert a column to a pretty-printed text representation and print it + to the console. + + import Standard.Examples + + example_display = Examples.integer_column.print print : Integer -> Nothing print show_rows=10 = IO.println (this.display show_rows format_terminal=True) @@ -62,6 +89,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise equality. + + import Standard.Examples + + example_eq = Examples.integer_column == Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_eq = Examples.integer_column == 1 == : Column | Any -> Column == other = here.run_vectorized_binary_op this "==" (==) other @@ -75,6 +116,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise inequality. + + import Standard.Examples + + example_neq = Examples.integer_column != Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_neq = Examples.integer_column != 1 != : Column | Any -> Column != other = (this == other).not @@ -87,6 +142,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise greater-than-or-equal. + + import Standard.Examples + + example_geq = Examples.integer_column >= Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_geq = Examples.integer_column >= 1 >= : Column | Any -> Column >= other = here.run_vectorized_binary_op this ">=" (>=) other @@ -100,6 +169,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise less-than-or-equal. + + import Standard.Examples + + example_leq = Examples.integer_column <= Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_leq = Examples.integer_column <= 1 <= : Column | Any -> Column <= other = here.run_vectorized_binary_op this "<=" (<=) other @@ -113,6 +196,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise greater-than. + + import Standard.Examples + + example_gt = Examples.integer_column > Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_gt = Examples.integer_column > 1 > : Column | Any -> Column > other = here.run_vectorized_binary_op this ">" (>) other @@ -126,6 +223,20 @@ type Column Returns a column with results of comparing this column's elements against `other`. + + > Example + Compare two columns for pairwise less-than. + + import Standard.Examples + + example_lt = Examples.integer_column < Examples.decimal_column + + > Example + Compare a column with a number. + + import Standard.Examples + + example_lt = Examples.integer_column < 1 < : Column | Any -> Column < other = here.run_vectorized_binary_op this "<" (<) other @@ -138,6 +249,20 @@ type Column Returns a column with results of adding `other` from each element of `this`. + + > Example + Add two columns to each other. + + import Standard.Examples + + example_plus = Examples.decimal_column + Examples.integer_column + + > Example + Add a single value to each item in a column. + + import Standard.Examples + + example_plus = Examples.integer_column + 10 + : Column | Any -> Column + other = here.run_vectorized_binary_op this '+' (+) other @@ -150,6 +275,20 @@ type Column Returns a column with results of subtracting `other` from each element of `this`. + + > Example + Subtract one column from another. + + import Standard.Examples + + example_minus = Examples.decimal_column - Examples.integer_column + + > Example + Subtract a single value from each item in a column. + + import Standard.Examples + + example_minus = Examples.integer_column - 10 - : Column | Any -> Column - other = here.run_vectorized_binary_op this '-' (-) other @@ -162,6 +301,20 @@ type Column Returns a column containing the result of multiplying each element of `this` by `other`. + + > Example + Multiply the elements of two columns together. + + import Standard.Examples + + example_mul = Examples.decimal_column * Examples.integer_column + + > Example + Multiply each value in a column by a single value. + + import Standard.Examples + + example_mul = Examples.integer_column * 10 * : Column | Any -> Column * other = here.run_vectorized_binary_op this '*' (*) other @@ -174,6 +327,20 @@ type Column Returns a column containing the result of dividing each element of `this` by `other`. + + > Example + Divide the elements of one column by the elements of another. + + import Standard.Examples + + example_div = Examples.decimal_column / Examples.integer_column + + > Example + Multiply each value in a column by a single value. + + import Standard.Examples + + example_div = Examples.integer_column / 10 / : Column | Any -> Column / other = here.run_vectorized_binary_op this '/' (/) other @@ -186,6 +353,21 @@ type Column Returns a column containing the result of performing boolean `and` on each element of `this` and `other`. + + > Example + Compute the pairwise logical conjunction to two columns. + + import Standard.Examples + + example_and = Examples.bool_column_1 && Examples.bool_column_2 + + > Example + Compute the logical conjunction of each value in a column with a single + value. + + import Standard.Examples + + example_and = Examples.bool_column_1 && True && : Column | Any -> Column && other = here.run_vectorized_binary_op this "&&" (&&) other @@ -199,22 +381,57 @@ type Column Returns a column containing the result of performing the boolean `or` on each element of `this` and `other`. + + > Example + Compute the pairwise logical disjunction to two columns. + + import Standard.Examples + + example_or = Examples.bool_column_1 || Examples.bool_column_2 + + > Example + Compute the logical disjunction of each value in a column with a single + value. + + import Standard.Examples + + example_or = Examples.bool_column_1 || True || : Column | Any -> Column || other = here.run_vectorized_binary_op this "||" (||) other ## Boolean negation of each element in this column. + + > Example + Negate the elements of a column. + + import Standard.Examples + + example_not = Examples.bool_column_1.not not : Column - not = - here.run_vectorized_unary_op this "not" .not + not = here.run_vectorized_unary_op this "not" .not ## Returns a column of booleans, with `True` items at the positions where this column contains a `Nothing`. + + > Example + Check a column for missing values. + + import Standard.Examples + + example_is_missing = Examples.decimal_column.is_missing is_missing : Column is_missing = here.run_vectorized_unary_op this "is_missing" (== Nothing) ## Returns a column of booleans, with `True` items at the positions where this column does not contain a `Nothing`. + + > Example + Check a column for present values. + + import Standard.Examples + + example_is_present = Examples.decimal_column.is_present is_present : Column is_present = this.is_missing.not @@ -223,6 +440,13 @@ type Column Arguments: - default: The value to replace missing values with. + + > Example + Fill missing values in a column with the value 20.5. + + import Standard.Examples + + example_fill_missing = Examples.decimal_column.fill_missing 20.5 fill_missing : Any -> Column fill_missing default = storage = this.java_column.getStorage @@ -233,6 +457,13 @@ type Column Column col ## Returns a new column without rows that had missing values. + + > Example + Drop missing values from a column. + + import Standard.Examples + + example_drop_missing = Examples.decimal_column.drop_missing drop_missing : Any -> Column drop_missing = this.where this.is_missing.not @@ -243,6 +474,22 @@ type Column - other: The value to compare `this` with. If `other` is a column, the operation is performed pairwise between corresponding elements of `this` and `other`. + + > Example + Check the elements of a column for starting with the elements of + another column. + + import Standard.Examples + + example_starts_with = + Examples.text_column_1.starts_with Examples.text_column_2 + + > Example + Check the elements of a column for starting with a value. + + import Standard.Examples + + example_starts_with = Examples.text_column_1.starts_with "hell" starts_with : Column | Text -> Column starts_with other = here.run_vectorized_binary_op this "starts_with" (a -> b -> a.starts_with b) other @@ -253,6 +500,22 @@ type Column - other: The value to compare `this` with. If `other` is a column, the operation is performed pairwise between corresponding elements of `this` and `other`. + + > Example + Check the elements of a column for ending with the elements of another + column. + + import Standard.Examples + + example_ends_with = + Examples.text_column_1.ends_with Examples.text_column_2 + + > Example + Check the elements of a column for ending with a value. + + import Standard.Examples + + example_ends_with = Examples.text_column_1.ends_with "hell" ends_with : Column | Text -> Column ends_with other = here.run_vectorized_binary_op this "ends_with" (a -> b -> a.ends_with b) other @@ -263,6 +526,22 @@ type Column - other: The value to compare `this` with. If `other` is a column, the operation is performed pairwise between corresponding elements of `this` and `other`. + + > Example + Check the elements of a column for containing the elements of another + column. + + import Standard.Examples + + example_contains = + Examples.text_column_1.contains Examples.text_column_2 + + > Example + Check the elements of a column for containing a value. + + import Standard.Examples + + example_contains = Examples.text_column_1.contains "hell" contains : Column | Text -> Column contains other = here.run_vectorized_binary_op this "contains" (a -> b -> a.contains b) other @@ -272,6 +551,13 @@ type Column Arguments: - function: The function to apply to each element of `this` column. + + > Example + Multiply each element of the column by itself. + + import Standard.Examples + + example_map = Examples.integer_column.map (x -> x * x) map : (Any -> Any) -> Column map function = storage = this.java_column.getStorage @@ -287,6 +573,14 @@ type Column - that: The column to zip with `this`. - function: A binary function that is applied to corresponding pairs of elements of `this` and `that` to produce a value. + + > Example + Zip two columns together as pairs. + + import Standard.Examples + + example_zip = + Examples.integer_column.zip Examples.text_column_1 [_, _] zip : Column -> (Any -> Any -> Any) -> Column zip that function = s1 = this.java_column.getStorage @@ -300,28 +594,66 @@ type Column Arguments: - name: The new name for the column. + + > Example + Rename a column. + + import Standard.Examples + + example_rename = Examples.integer_column.rename "My Numbers" rename : Text -> Column rename name = Column (this.java_column.rename name) ## Returns the name of this column. + + > Example + Get the name of a column. + + import Standard.Examples + + example_name = Examples.text_column_2.name name : Text name = this.java_column.getName ## Returns the length of this column. + + > Example + Get the length of a column. + + import Standard.Examples + + example_length = Examples.text_column_2.length length : Integer length = this.java_column . getSize ## Returns the number of missing items in this column. + + > Example + Count the number of missing values in a column. + + import Standard.Examples + + example_count_missing = Examples.text_column_2.count_missing count_missing : Integer count_missing = this.java_column.getStorage.countMissing ## Returns the number of non-null items in this column. + + > Example + Count the number of not missing values in a column. + + import Standard.Examples + + example_count = Examples.text_column_2.count count : Integer count = this.length - this.count_missing ## Returns the index of this column, as a column (indexed by itself). Throws `No_Index_Set_Error` if there is no index set. + + > Example + Get the index from a column. index : Column ! Table.No_Index_Set_Error index = case this.java_column.getIndex.toColumn of Nothing -> Error.throw Table.No_Index_Set_Error @@ -334,6 +666,13 @@ type Column If the value is an NA then this method returns nothing. If the index is not an index in the column it returns an `Index_Out_Of_Bounds_Error`. + + > Example + Get the first element from a column. + + import Standard.Examples + + example_at = Examples.integer_column.at 0 at : Integer -> (Any | Nothing) ! Index_Out_Of_Bounds_Error at index = valid_index = (index >= 0) && (index < this.length) @@ -352,18 +691,36 @@ type Column This is useful for filtering the rows by given predicate. > Example - Select only the rows of `my_column` where the `status_column` column - has the value `"Valid"` - my_column.where (status_column == "Valid") + Select only the rows of the column where the length of the text exceeds + 2. + + import Standard.Examples + + example_where = + Examples.text_column_1.where (Examples.text_column_1.map .length > 2) where : Column -> Column where indexes = Column (this.java_column.mask indexes.java_column) ## Returns a vector containing all the elements in this column. + + > Example + Get the elements of a column as a vector. + + import Standard.Examples + + example_to_vector = Examples.integer_column.to_vector to_vector : Vector to_vector = Vector.Vector this.java_column.getStorage.toList ## Returns the underlying storage type of this column. + + > Example + Get the storage type of a column. + + import Standard.Examples + + example_storage_type = Examples.integer_column.storage_type storage_type : Storage.Type storage_type = tp = this.java_column.getStorage.getType @@ -373,7 +730,16 @@ type Column if tp == Storage_Type_Bool then Storage.Boolean else Storage.Any - ## Converts this column to JSON. + ## UNSTABLE + + Converts this column to JSON. + + > Example + Get a JSON representation of the column. + + import Standard.Examples + + example_to_json = Examples.integer_column.to_json to_json : Json to_json = col = this.java_column @@ -407,11 +773,25 @@ type Column `other` with matching indexes. If the index values in `other` are not unique, the corresponding rows of `this` will be duplicated in the result. + + > Example + Join two columns on their indices. + + import Standard.Examples + + example_join = Examples.integer_column.join Examples.bool_column_1 join : Table.Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = this.to_table.join other on drop_unmatched left_suffix right_suffix ## Converts this column into a single-column table. + + > Example + Convert a column to a table. + + import Standard.Examples + + example_to_table = Examples.integer_column.to_table to_table : Table.Table to_table = Table.Table this.java_column.toTable @@ -429,20 +809,48 @@ type Column Json.from_pairs [size, name, data] . to_text ## Sums the values in this column. + + > Example + Sum the values in a column. + + import Standard.Examples + + example_sum = Examples.integer_column.sum sum : Any sum = this.java_column.aggregate 'sum' (x-> Vector.Vector x . reduce (+)) True ## Computes the maximum element of this column. + + > Example + Compute the maximum value of a column. + + import Standard.Examples + + example_max = Examples.integer_column.max max : Any max = this.java_column.aggregate 'max' (x-> Vector.Vector x . reduce Math.max) True ## Computes the minimum element of this column. + + > Example + Compute the minimum value of a column. + + import Standard.Examples + + example_min = Examples.integer_column.min min : Any min = this.java_column.aggregate 'min' (x-> Vector.Vector x . reduce Math.min) True ## Computes the mean of non-missing elements of this column. + + > Example + Compute the mean value of a column. + + import Standard.Examples + + example_mean = Examples.integer_column.mean mean : Any mean = vec_mean v = if v.length == 0 then Nothing else @@ -464,19 +872,30 @@ type Column (`.compare_to`) ordering. > Example - Sorting `column` in ascending order. - column.sort + Sorting a column in ascending order. + + import Standard.Examples + + example_sort = Examples.integer_column.sort > Example - Sorting `column` in descending order, placing missing values at the + Sorting a column in descending order, placing missing values at the top of the resulting column. - column.sort order=Sort_Order.Descending missing_last=False + + import Standard.Examples + + example_sort = + Examples.integer_column.sort order=Sort_Order.Descending missing_last=False > Example Sorting `column` in ascending order, using a custom comparator function. - manhattan_comparator a b = (a.x.abs + a.y.abs) . compare_to (b.x.abs + b.y.abs) - column.sort comparator=manhattan_comparator + + import Standard.Examples + + example_sort = + my_comparator a b = a.abs.compare_to b.abs + Examples.decimal_column.sort comparator=my_comparator sort : Sort_Order -> Boolean -> (Any -> Any -> Ordering) | Nothing -> Column sort order=Sort_Order.Ascending missing_last=True comparator=Nothing = order_bool = case order of @@ -500,6 +919,13 @@ type Column If `this` has a number of items in it less than `count`, the entire column will be returned. + + > Example + Take the first 2 elements of a column. + + import Standard.Examples + + example_take_start = Examples.integer_column.take_start 2 take_start : Integer -> Column take_start count = Column (this.java_column.slice 0 count) @@ -513,6 +939,13 @@ type Column If `this` has a number of items in it less than `count`, the entire column will be returned. + + > Example + Take the last 2 elements of a column. + + import Standard.Examples + + example_take_end = Examples.integer_column.take_end 2 take_end : Integer -> Column take_end count = start_point = Math.max (this.length - count) 0 @@ -524,6 +957,13 @@ type Column If the column is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the first element of a column. + + import Standard.Examples + + example_first = Examples.integer_column.first first : Any ! Nothing first = this.at 0 . catch (_ -> Error.throw Nothing) @@ -533,6 +973,13 @@ type Column If the column is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the first element of a column. + + import Standard.Examples + + example_head = Examples.integer_column.head head : Any ! Nothing head = this.first @@ -542,6 +989,13 @@ type Column If the column is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the last element of a column. + + import Standard.Examples + + example_last = Examples.integer_column.last last : Any ! Nothing last = this.at (this.length - 1) . catch (_ -> Error.throw Nothing) @@ -549,6 +1003,13 @@ type Column Returns a column containing the values of `this` column with their order reversed. + + > Example + Reverse the values of a column to produce a new column. + + import Standard.Examples + + example_reverse = Examples.integer_column.reverse reverse : Column reverse = mask = OrderBuilder.buildReversedMask this.length @@ -557,6 +1018,8 @@ type Column ## Wraps a column grouped by its index. Allows performing aggregation operations on the contained values. type Aggregate_Column + + ## PRIVATE type Aggregate_Column java_column ## Converts this aggregate column into a column, aggregating groups @@ -569,6 +1032,15 @@ type Aggregate_Column groups. - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Convert an aggregate column of transaction ids into a column by + counting the number of transactions. per item. + + import Standard.Examples + + example_reduce = + Examples.aggregate_column.reduce .length . rename "transaction_count" reduce : (Vector.Vector -> Any) -> Boolean -> Text -> Column reduce function skip_missing=True name_suffix="_result" = f arr = function (Vector.Vector arr) @@ -580,6 +1052,14 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Convert an aggregate column of transaction ids into a column by summing + the transaction IDs together. + + import Standard.Examples + + example_sum = Examples.aggregate_column.sum . rename "id_sum" sum : Text -> Column sum name_suffix='_sum' = r = this.java_column.aggregate 'sum' name_suffix (x-> Vector.Vector x . reduce (+)) True @@ -590,6 +1070,13 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Get the latest (maximum ID) transaction id for each item. + + import Standard.Examples + + example_max = Examples.aggregate_column.max . rename "latest_transaction" max : Text -> Column max name_suffix='_max' = r = this.java_column.aggregate 'max' name_suffix (x-> Vector.Vector x . reduce Math.max) True @@ -600,6 +1087,13 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Get the earliest (mimumum ID) transaction id for each item. + + import Standard.Examples + + example_min = Examples.aggregate_column.min . rename "first_transaction" min : Text -> Column min name_suffix='_min' = r = this.java_column.aggregate 'min' name_suffix (x-> Vector.Vector x . reduce Math.min) True @@ -610,6 +1104,14 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Count the number of non-missing elements in each group in the column, + which gives the number of transactions in which a given item was sold. + + import Standard.Examples + + example_count = Examples.aggregate_column.count . rename "transaction_count" count : Text -> Column count name_suffix='_count' = r = this.java_column.aggregate 'count' name_suffix (x-> x.length) True @@ -620,6 +1122,13 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Get the mean transaction id for each item. + + import Standard.Examples + + example_mean = Examples.aggregate_column.mean mean : Text -> Column mean name_suffix='_mean' = vec_mean v = if v.length == 0 then Nothing else @@ -633,11 +1142,51 @@ type Aggregate_Column Arguments: - name_suffix: a suffix that will be appended to the original column name to generate the resulting column name. + + > Example + Gather the values of the aggregate column together. + + import Standard.Examples + + example_values = Examples.aggregate_column.values values : Text -> Column values name_suffix='_values' = r = this.java_column.aggregate Nothing name_suffix Vector.Vector False Column r + ## Prints an ASCII-art column with this data to the standard output. + + Arguments: + - show_rows: the number of initial rows that should be displayed. + + > Example + Pretty-print an aggregate column and display it using the standard + output. + + import Standard.Examples + + example_print = Examples.aggregate_column.print + print : Nothing + print = this.values.print + +## UNSTABLE + + A type representing an error for an out-of-bounds index in a column. + + Arguments: + - index: The index of the element requested. + - length: The length of the column in which `index` was out of bounds. +type Index_Out_Of_Bounds_Error index length + +## UNSTABLE + + Pretty-prints the index out of bounds error. +Index_Out_Of_Bounds_Error.to_display_text : Text +Index_Out_Of_Bounds_Error.to_display_text = + ix_text = this.index.to_text + len_text = this.length.to_text + "The index " + ix_text + " is out of bounds in a column of length " + len_text + "." + ## PRIVATE Executes a vectorized binary operation over the provided column. @@ -726,16 +1275,3 @@ get_item_string column ix = if tp == Storage_Type_String then column.getItem ix else column.getItem ix . to_text -## A type representing an error for an out-of-bounds index in a column. - - Arguments: - - index: The index of the element requested. - - length: The length of the column in which `index` was out of bounds. -type Index_Out_Of_Bounds_Error index length - -## Pretty-prints the index out of bounds error. -Index_Out_Of_Bounds_Error.to_display_text : Text -Index_Out_Of_Bounds_Error.to_display_text = - ix_text = this.index.to_text - len_text = this.length.to_text - "The index " + ix_text + " is out of bounds in a column of length " + len_text + "." diff --git a/distribution/std-lib/Standard/src/Table/Data/Order_Rule.enso b/distribution/std-lib/Standard/src/Table/Data/Order_Rule.enso index 0c0168ed880a..4bf9fb8c4d25 100644 --- a/distribution/std-lib/Standard/src/Table/Data/Order_Rule.enso +++ b/distribution/std-lib/Standard/src/Table/Data/Order_Rule.enso @@ -8,18 +8,18 @@ type Order_Rule Arguments: - column: a value representing the data dimension by which this rule is - sorting. This type does not specify the underlying representation of a + sorting. This type does not specify the underlying representation of a column, assuming that the sorting engine defines its own column representation. - - comparator: a function taking two elements of the data being sorted on - and returning an `Ordering`. The function may be `Nothing`, in which - case a natural ordering will be used. Note that certain table backends + - comparator: a function taking two elements of the data being sorted on + and returning an `Ordering`. The function may be `Nothing`, in which + case a natural ordering will be used. Note that certain table backends (such us database connectors) may not support this field being set to a non-`Nothing` value. - - order: specifies whether the table should be sorted in an ascending or - descending order. The default value of `Nothing` delegates the decision - to the sorting function. Can be set to `Sort_Order.Ascending` or - `Sort_Order.Descending` from the `Base` library, to specify the + - order: specifies whether the table should be sorted in an ascending or + descending order. The default value of `Nothing` delegates the decision + to the sorting function. Can be set to `Sort_Order.Ascending` or + `Sort_Order.Descending` from the `Base` library, to specify the ordering. - missing_last: whether the missing values should be placed at the beginning or end of the sorted table. Note that this argument is @@ -28,3 +28,4 @@ type Order_Rule The default value of `Nothing` delegates the decision to the sorting function. type Order_Rule column comparator=Nothing order=Nothing missing_last=Nothing + diff --git a/distribution/std-lib/Standard/src/Table/Data/Table.enso b/distribution/std-lib/Standard/src/Table/Data/Table.enso index 4dd3167d836c..3c4c78e1680b 100644 --- a/distribution/std-lib/Standard/src/Table/Data/Table.enso +++ b/distribution/std-lib/Standard/src/Table/Data/Table.enso @@ -9,14 +9,25 @@ from Standard.Table.Data.Order_Rule as Order_Rule_Module import Order_Rule polyglot java import org.enso.table.data.table.Table as Java_Table polyglot java import org.enso.table.operations.OrderBuilder -## An error returned when a non-existent column is being looked up. +## Creates a new table from a vector of `[name, items]` pairs. Arguments: - - column_name: The name of the column that doesn't exist. -type No_Such_Column_Error column_name + - columns: The `[name, items]` pairs to construct a new table from. -## An error returned when getting an index but no index is set for that table. -type No_Index_Set_Error + > Example + Create a new table with the given columns. + + import Standard.Table + + example_new = + first_column = ["count", [1, 2, 3]] + second_column = ["is_valid", [True, False, True]] + Table.new [first_column, second_column] +new : Vector -> Table +new columns = + cols = columns.map c-> + Column.from_vector (c.at 0) (c.at 1) . java_column + here.from_columns cols ## Creates a new table from a vector of column names and a vector of vectors specifying row contents. @@ -27,33 +38,22 @@ type No_Index_Set_Error length of each element of `rows` must be equal in length to `header`. > Example - The code below creates a table with 3 columns, named `foo`, `bar`, and - `baz`, containing `[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`, - respectively. - header = [ 'foo' , 'bar' , 'baz' ] - row_1 = [ 1 , True , 'a' ] - row_2 = [ 2 , False , 'b' ] - row_3 = [ 3 , True , 'c' ] - Table.from_rows header [row_1, row_2, row_3] + Create a table with 3 columns, named `foo`, `bar`, and `baz`, containing + `[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`, respectively. + + import Standard.Table + + example_from_rows = + header = [ 'foo' , 'bar' , 'baz' ] + row_1 = [ 1 , True , 'a' ] + row_2 = [ 2 , False , 'b' ] + row_3 = [ 3 , True , 'c' ] + Table.from_rows header [row_1, row_2, row_3] from_rows : Vector.Vector -> Vector.Vector -> Table from_rows header rows = columns = header.map_with_index i-> name-> [name, rows.map (_.at i)] here.new columns -## Creates a new table from a vector of `[name, items]` pairs. - - Arguments: - - columns: The `[name, items]` pairs to construct a new table from. - - > Example - Create a new table with the given in two columns: - Table.new [["foo", [1, 2, 3]], ["bar", [True, False, True]]] -new : Vector -> Table -new columns = - cols = columns.map c-> - Column.from_vector (c.at 0) (c.at 1) . java_column - here.from_columns cols - ## Joins a vector of tables (or columns) into a single table, using each table's index as the join key. @@ -62,6 +62,18 @@ new columns = Particularly useful for joining multiple columns derived from one original table into a new table. + + > Example + Join multiple tables together. It joins tables on their indices, so we need + to make sure the indices are correct. + + import Standard.Examples + import Standard.Table + + example_join = + table_1 = Examples.inventory_table + table_2 = Examples.popularity_table + Table.join [table_1, table_2] join : Vector -> Table join tables = tables.reduce .join @@ -69,7 +81,9 @@ join tables = ## Represents a column-oriented table data structure. type Table - ## A table. + ## PRIVATE + + A table. Arguments: - java_table: The internal java representation of the table. @@ -80,6 +94,13 @@ type Table Arguments: - show_rows: the number of initial rows that should be displayed. - format_terminal: whether ANSI-terminal formatting should be used + + > Example + Convert the table to a pretty-printed representation. + + import Standard.Examples + + example_display = Examples.inventory_table.display display : Integer -> Boolean -> Text display show_rows=10 format_terminal=False = cols = Vector.Vector this.java_table.getColumns @@ -101,11 +122,26 @@ type Table Arguments: - show_rows: the number of initial rows that should be displayed. + + > Example + Convert the table to a pretty-printed representation and print it to + the console. + + import Standard.Examples + + example_print = Examples.inventory_table.print print show_rows=10 = IO.println (this.display show_rows format_terminal=True) IO.println '' ## Converts this table to a JSON structure. + + > Example + Convert a table to a corresponding JSON representation. + + import Standard.Examples + + example_to_json = Examples.inventory_table.to_json to_json : Json to_json = col_jsons = this.columns.map .to_json @@ -134,6 +170,13 @@ type Table Arguments: - name: The name of the column being looked up. + + > Example + Get the names of all of the items from the shop inventory. + + import Standard.Examples + + example_at = Examples.inventory_table.at "item_name" at : Text -> Column ! No_Such_Column_Error at name = case this.java_table.getColumnOrIndexByName name of Nothing -> Error.throw (No_Such_Column_Error name) @@ -150,9 +193,14 @@ type Table This is useful for filtering the rows by given predicate. > Example - Select only the rows of `my_table` where the `"Status"` column has the - value `"Valid"` - my_table.where (my_table.at "Status" == "Valid") + Select only the items where more than half the stock has been sold. + + import Standard.Examples + + example_where = + table = Examples.inventory_table + mask = (table.at "sold_stock" > (table.at "total_stock" / 2)) + table.where mask where : Column -> Table where indexes = Table (this.java_table.mask indexes.java_column) @@ -165,6 +213,17 @@ type Table If a column with the given name already exists, it will be replaced. Otherwise a new column is added. + + > Example + Create a table where the values of the total stock in the inventory is + doubled. + + import Standard.Examples + + example_set = + table = Examples.inventory_table + double_inventory = table.at "total_stock" * 2 + table.set "total_stock" double_inventory set : Text -> Column.Column | Vector.Vector -> Table set name column = case column of Vector.Vector _ -> @@ -173,28 +232,55 @@ type Table Table (this.java_table.addOrReplaceColumn (column.rename name . java_column)) ## Returns the vector of columns contained in this table. + + > Examples + Get a vector containing the columns in the table. + + import Standard.Examples + + example_columns = Examples.inventory_table.columns columns : Vector - columns = - Vector.Vector this.java_table.getColumns . map Column.Column + columns = Vector.Vector this.java_table.getColumns . map Column.Column ## Sets the index of this table, using the column with the provided name. Arguments: - index: The name of the column to use as the index in this table. + + > Example + Set the index of the inventory table to be the item name. + + import Standard.Examples + + example_set_index = Examples.inventory_table.set_index "item_name" set_index : Text -> Table - set_index index = - Table (this.java_table.indexFromColumn index) + set_index index = Table (this.java_table.indexFromColumn index) ## Returns the index of this table, as a column that is indexed by itself. Throws `No_Index_Set_Error` if there is no index set in the table it is being called on. + + > Example + Get the column that is used as the index for a table. + + import Standard.Examples + + example_index = Examples.inventory_table.index index : Column.Column ! No_Index_Set_Error index = case this.java_table.getIndex.toColumn of Nothing -> Error.throw No_Index_Set_Error i -> Column.Column i ## Selects a subset of columns from this table by name. + + > Example + Get the item name and price columns from the shop inventory. + + import Standard.Examples + + example_select = + Examples.inventory_table.select ["item_name", "price"] select : Vector -> Table select columns = Table (this.java_table.selectColumns columns.to_array) @@ -216,6 +302,15 @@ type Table `other` with matching indexes. If the index values in `other` are not unique, the corresponding rows of `this` will be duplicated in the result. + + > Example + Join the popularity table and the inventory table to see the relative + popularities of the items in the shop inventory. + + import Standard.Examples + + example_join = + Examples.inventory_table.join Examples.popularity_table join : Table | Column.Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = case other of @@ -236,6 +331,14 @@ type Table False -> this ## Returns a new Table without columns that contained any missing values. + + > Example + Remove any columns that contain missing values from the table. + + import Standard.Examples + + example_drop_missing_cols = + Examples.inventory_table.drop_missing_columns drop_missing_columns : Table drop_missing_columns = non_missing = this.columns . filter (col -> col.count_missing == 0) @@ -243,10 +346,24 @@ type Table Table (Java_Table.new (non_missing.map .java_column . to_array) index) ## Returns the number of rows in this table. + + > Example + Count the number of rows in the table. + + import Standard.Examples + + example_row_count = Examples.inventory_table.row_count row_count : Integer row_count = this.java_table.rowCount ## Returns the number of rows in this table. + + > Example + Count the number of rows in the table. + + import Standard.Examples + + example_length = Examples.inventory_table.length length : Integer length = this.row_count @@ -254,6 +371,13 @@ type Table The table lists all columns, counts of non-null items and storage types of each column. + + > Example + Get information about a table. + + import Standard.Examples + + example_info = Examples.inventory_table.info info : Table info = cols = this.columns @@ -267,19 +391,19 @@ type Table is not set, the index is used for grouping instead. > Example - Creates a simple table and computes aggregation statistics: - name = ['name', ["foo", "bar", "foo", "baz", "foo", "bar", "quux"]] - price = ['price', [0.4, 3.5, Nothing, 6.7, Nothing, 97, Nothing]] - quantity = ['quantity', [10, 20, 30, 40, 50, 60, 70]] - t = Table.new [name, price, quantity] - - agg = t.group by='name' - - records_num = agg.count - total_quantity = agg.at 'quantity' . sum - mean_price = agg.at 'price' . mean - - Table.join [records_num, total_quantity, mean_price] + Compute the number of transactions that each item has participated in, + as well as the number of each item sold across those transactions. + + import Standard.Examples + import Standard.Table + + example_group = + transactions = Examples.transactions_table + item_names = Examples.inventory_table.at "item_name" + aggregated = transactions.group by="item_id" + num_transactions = aggregated.at "transaction_id" . reduce .length . rename "transaction_count" + num_sold = aggregated.at "quantity" . reduce .sum . rename "num_sold" + Table.join [item_names, num_transactions, num_sold] group : Text | Nothing -> Aggregate_Table group by=Nothing = Aggregate_Table (this.java_table.group by) @@ -312,36 +436,69 @@ type Table according to this rule, ignoring the ascending / descending setting. > Example - Sorting `table` in ascending order by the value in column `'Quantity'` - table.sort by='Quantity' + Sorting the shop inventory based on the per-item price in ascending + order. + + import Standard.Examples + + example_sort = Examples.inventory_table.sort by="price" > Example - Sorting `table` in descending order by the value in column `'Quantity'`, - placing missing values at the top of the table. - table.sort by='Quantity' order=Sort_Order.Descending missing_last=False + Sort the shop inventory based on the per-item price in descending order + and placing missing values at the top of the table. + + import Standard.Examples + + example_sort = + table = Examples.inventory_table + table.sort by="price" order=Sort_Order.Descending missing_last = false > Example - Sorting `table` in ascending order by the value in column `'Quantity'`, - using the value in column `'Rating'` for breaking ties. - table.sort by=['Quantity', 'Rating'] + Sort the shop inventory based on the total stock, using the number sold + to break ties in descending order. + + import Standard.Examples + + example_sort = + table = Examples.inventory_table + table.sort by=["total_stock", "sold_stock"] order=Sort_Order.Descending > Example - Sorting `table` in ascending order by the value in column `'Quantity'`, - using the value in column `'Rating'` in descending order for breaking - ties. - table.sort by=['Quantity', Order_Rule 'Rating' (order=Sort_Order.Descending)] + Sort the shop inventory in ascending order by the total stock, using + the number of items sold in descending order to break ties. + + import Standard.Examples + import Standard.Table + + example_sort = + table = Examples.inventory_table + sold_stock_rule = Table.Order_Rule "sold_stock" order=Sort_Order.Descending + table.sort by=["total_stock", sold_stock_rule] > Example - Sorting `table` in ascending order by the value in an externally - computed column, using the value in column `'Rating'` for breaking + Sorting the inventory in descending order based on the percentage of + the total stock sold, using the popularity of the product to break ties. - quality_ratio = table.at 'Rating' / table.at 'Price' - table.sort by=[quality_ratio, 'Rating'] - > Sorting `table` in ascending order, by the value in column - `'position'`, using a custom comparator function. - manhattan_comparator a b = (a.x.abs + a.y.abs) . compare_to (b.x.abs + b.y.abs) - table.sort by=(Order_Rule 'position' comparator=manhattan_comparator) + import Standard.Examples + import Standard.Table + + example_sort = + table = Examples.inventory_table.join Examples.popularity_table + percentage_sold = table.at "sold_stock" / table.at "total_stock" + table.sort by=[percentage_sold, "popularity"] order=Sort_Order.Descending + + > Example + Sort the inventory by the price using a custom comparator function. + + import Standard.Examples + import Standard.Table + + example_sort = + table = Examples.inventory_table + comparator a b = a.compare_to b*2 + price_rule = Table.Order_Rule "price" comparator=comparator + table.sort by=price_rule sort : Text | Column.Column | Order_Rule | Vector.Vector (Text | Column.Column | Order_Rule) -> Sort_Order -> Boolean -> Table sort by order=Sort_Order.Ascending missing_last=True = Panic.recover <| rules = this.build_java_order_rules by order missing_last @@ -409,6 +566,14 @@ type Table Any column that is present in one table, but missing in another, will be `Nothing`-padded in the positions corresponding to the missing column. + + > Example + Concatenate two tables together. + + import Standard.Examples + + example_concat = + Examples.inventory_table.concat Examples.popularity_table concat : Table -> Table concat other = Table (this.java_table.concat other.java_table) @@ -422,6 +587,13 @@ type Table If `this` has a number of rows in it less than `count`, the entire table will be returned. + + > Example + Get the first four rows from the table. + + import Standard.Examples + + example_take_start = Examples.inventory_table.take_start 4 take_start : Integer -> Table take_start count = Table (this.java_table.slice 0 count) @@ -434,6 +606,13 @@ type Table If `this` has a number of rows in it less than `count`, the entire table will be returned. + + > Example + Get the last four rows from the table. + + import Standard.Examples + + example_take_end = Examples.inventory_table.take_end 4 take_end : Integer -> Table take_end count = start_point = Math.max (this.row_count - count) 0 @@ -445,6 +624,13 @@ type Table If the table is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the first row from the table. + + import Standard.Examples + + example_first = Examples.inventory_table.first first : Table ! Nothing first = table = this.take_start 1 @@ -456,6 +642,13 @@ type Table If the table is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the first row from the table. + + import Standard.Examples + + example_head = Examples.inventory_table.head head : Table ! Nothing head = this.first @@ -465,6 +658,13 @@ type Table If the table is empty, this method will return a dataflow error containing `Nothing`. + + > Example + Get the last row from the table. + + import Standard.Examples + + example_last = Examples.inventory_table.last last : Table ! Nothing last = table = this.take_end 1 @@ -474,42 +674,61 @@ type Table Returns a table containing the rows of `this` table with their order reversed. + + > Example + Reverse the rows in a table. + + import Standard.Examples + + example_reverse = Examples.inventory_table.reverse reverse : Table reverse = mask = OrderBuilder.buildReversedMask this.row_count Table <| this.java_table.applyMask mask -## PRIVATE - - Wraps the Enso comparator function so it's usable in Java. - - Arguments: - - cmp: The Enso comparator function. - - x: The left operand to the compartor. - - y: The right operand to the comparator. -comparator_to_java : (Any -> Any -> Ordering) -> Any -> Any -> Integer -comparator_to_java cmp x y = cmp x y . to_sign - ## Represents a table with grouped rows. type Aggregate_Table - ## A table type with grouped rows. + ## PRIVATE + + A table type with grouped rows. Arguments: - java_table: The internal representation of the table. type Aggregate_Table java_table ## Returns a vector of aggregate columns in this table. + + > Example + Get a vector of aggregate columns from this table. + + import Standard.Examples + + example_columns = Examples.aggregate_table.columns columns : Vector.Vector columns = Vector.Vector this.java_table.getColumns . map Column.Aggregate_Column ## Returns a table containing columns resulting from calling `values` on each column in `this`. + + > Example + Get the values table from an aggregate table. + + import Standard.Examples + + example_values = Examples.aggregate_table.values values : Table values = this.columns . map (_.values name_suffix='') . reduce .join ## Returns a column containing the number of elements in each group of the aggregate table. + + > Examples + Get the counts for an aggregate table. + + import Standard.Examples + + example_count = Examples.aggregate_table.count count : Column count = Column.Column this.java_table.count @@ -517,6 +736,13 @@ type Aggregate_Table Arguments: - name: The name of the aggregate column to get. + + > Example + Get the transaction ids column from the aggregate table. + + import Standard.Examples + + example_at = Examples.aggregate_table.at "transaction_id" at : Text -> Column ! Nothing at name = case this.java_table.getColumnByName name of Nothing -> Error.throw Nothing @@ -526,9 +752,42 @@ type Aggregate_Table Arguments: - show_rows: the number of initial rows that should be displayed. + + > Example + Pretty-print and display an aggregate table in the console. + + import Standard.Examples + + example_print = Examples.aggregate_table.print print : Integer -> Nothing print show_rows=10 = this.values.print show_rows +## UNSTABLE + + An error returned when a non-existent column is being looked up. + + Arguments: + - column_name: The name of the column that doesn't exist. +type No_Such_Column_Error column_name + +## UNSTABLE + + Create a human-readable version of the no such column error. +No_Such_Column_Error.to_display_text : Text +No_Such_Column_Error.to_display_text = + "The column " + this.column_name + " does not exist." + +## UNSTABLE + + An error returned when getting an index but no index is set for that table. +type No_Index_Set_Error + +## UNSTABLE + + Create a human-readable version of the no such column error. +No_Index_Set_Error.to_display_text : Text +No_Index_Set_Error.to_display_text = "The table does not have an index set." + ## PRIVATE from_columns cols = Table (Java_Table.new cols.to_array) @@ -585,3 +844,14 @@ print_table header rows indices_count format_term = " " + y ([" " + header_line, divider] + row_lines).join '\n' +## PRIVATE + + Wraps the Enso comparator function so it's usable in Java. + + Arguments: + - cmp: The Enso comparator function. + - x: The left operand to the compartor. + - y: The right operand to the comparator. +comparator_to_java : (Any -> Any -> Ordering) -> Any -> Any -> Integer +comparator_to_java cmp x y = cmp x y . to_sign + diff --git a/distribution/std-lib/Standard/src/Table/Io/Csv.enso b/distribution/std-lib/Standard/src/Table/Io/Csv.enso index 911fb7e5e6a2..a23d5d409bab 100644 --- a/distribution/std-lib/Standard/src/Table/Io/Csv.enso +++ b/distribution/std-lib/Standard/src/Table/Io/Csv.enso @@ -15,6 +15,14 @@ polyglot java import java.io.ByteArrayInputStream names. For example, if `prefix` is set to `X`, the columns will be named `X0`, `X1`, etc. This argument has no effect if the storage name is inferred from the CSV header row or set manually. + + > Example + Read a CSV from disk and convert it into a table. + + import Standard.Table + import Standard.Examples + + example_csv_to_table = Examples.csv.read_csv File.File.read_csv : Boolean -> Text -> Table File.File.read_csv has_header=True prefix='C' = here.from_csv this has_header prefix @@ -33,7 +41,6 @@ File.File.read_csv has_header=True prefix='C' = > Example Read a CSV from disk and convert it into a table. - from Standard.Base import all import Standard.Table import Standard.Examples @@ -44,7 +51,6 @@ File.File.read_csv has_header=True prefix='C' = > Example Read a CSV from memory and convert it into a table. - from Standard.Base import all import Standard.Table example_csv_to_table = diff --git a/distribution/std-lib/Standard/src/Test.enso b/distribution/std-lib/Standard/src/Test.enso index 7f899ce83fca..c6af7cafe5ca 100644 --- a/distribution/std-lib/Standard/src/Test.enso +++ b/distribution/std-lib/Standard/src/Test.enso @@ -1,5 +1,7 @@ from Standard.Base import all +import Builtins + ## Creates a new test group, desribing properties of the object described by `this`. @@ -7,7 +9,11 @@ from Standard.Base import all - specs: An action encapsulating a number of test specs or groups. > Example - Suite.run_main <| + Building a basic test suite. + + import Standard.Test + + example_run_main = Test.Suite.run_main <| Test.group "Number" <| Test.specify "should define addition" <| 2+3 . should_equal 5 @@ -26,7 +32,11 @@ Suite.run_main ~specs = - specs: An action encapsulating a number of test specs or groups. > Example - Suite.run <| + Building a basic test suite. + + import Standard.Test + + example_run = Test.Suite.run <| Test.group "Number" <| Test.specify "should define addition" <| 2+3 . should_equal 5 @@ -49,12 +59,12 @@ Suite.run ~specs = pending. > Example - Suite.run <| - Test.group "Number" <| - Test.specify "should define addition" <| - 2+3 . should_equal 5 - Test.specify "should define multiplication" <| - 2*3 . should_equal 6 + Adding a test group. + + import Standard.Test + + example_group = Test.Suite.run <| + Test.group "Number" <| Nothing group : Text -> Any -> (Text | Nothing) -> Nothing group name ~behaviors pending=Nothing = case pending of @@ -79,12 +89,23 @@ group name ~behaviors pending=Nothing = pending. > Example - Suite.run <| - describe "Number" <| - it "should define addition" <| + Adding a specification to the test group. + + import Standard.Test + + example_group = Test.Suite.run <| + Test.group "Number" <| + Test.specify "should define addition" <| + 2+3 . should_equal 5 + > Example + Adding a pending specification to the test group. + + import Standard.Test + + example_group = Test.Suite.run <| + Test.group "Number" <| + Test.specify "should define addition" pending="Reason" <| 2+3 . should_equal 5 - it "should define multiplication" <| - 2*3 . should_equal 6 specify : Text -> Any -> (Text | Nothing) -> Nothing specify label ~behavior pending=Nothing = result = case pending of @@ -94,7 +115,9 @@ specify label ~behavior pending=Nothing = new_spec = Spec spec.name (Cons (Behavior label result) spec.behaviors) State.put Spec new_spec -## Asserts a property about the receiver. +## PRIVATE + + Asserts a property about the receiver. Arguments: - verb: The property (see `Verbs`) being asserted @@ -106,6 +129,13 @@ Any.should verb argument = verb Verbs this argument Arguments: - message: The message printed when failing the test. + + > Example + Failing a test manually. + + import Standard.Test + + example_fail = Test.fail "Something went wrong." fail : Text -> Assertion fail message = Panic.throw (Failure message) @@ -113,6 +143,15 @@ fail message = Panic.throw (Failure message) Arguments: - matcher: The expected type of dataflow error contained in `this`. + + > Example + Assert that a compuation should return an error of a given type. + + import Standard.Examples + import Standard.Test + + example_should_fail_with = + Examples.throw_error . should_fail_with Examples.My_Error Any.should_fail_with : Any -> Assertion Any.should_fail_with matcher = here.fail ("Expected an error " + matcher.to_text + " but none occurred.") @@ -121,6 +160,15 @@ Any.should_fail_with matcher = Arguments: - matcher: The expected type of dataflow error contained in `this`. + + > Example + Assert that a compuation should return an error of a given type. + + import Standard.Examples + import Standard.Test + + example_should_fail_with = + Examples.throw_error . should_fail_with Examples.My_Error Error.should_fail_with : Any -> Assertion Error.should_fail_with matcher = caught = this.catch x->x @@ -132,6 +180,15 @@ Error.should_fail_with matcher = Arguments: - action: The action to evaluate that is expected to fail with a panic. - matcher: The expected type of the panic thrown by `action`. + + > Example + Expect that a computation should panic as part of a test. + + import Standard.Examples + import Standard.Test + + example_expect_panic_with = + Test.expect_panic_with Examples.throw_panic Examples.My_Error expect_panic_with : Any -> Any -> Assertion expect_panic_with ~action matcher = res = Panic.recover action @@ -145,6 +202,14 @@ expect_panic_with ~action matcher = Arguments: - that: The value to check `this` for equality with. + + > Example + Assert that one value should equal another, + + import Standard.Examples + import Standard.Test + + example_should_equal = Examples.add_1_to 1 . should_equal 2 Any.should_equal : Any -> Assertion Any.should_equal that = case this == that of True -> Success @@ -157,6 +222,14 @@ Any.should_equal that = case this == that of Arguments: - _: The value to check `this` for equality with. + + > Example + Assert that one value should equal another, + + import Standard.Examples + import Standard.Test + + example_should_equal = Examples.add_1_to 1 . should_equal 2 Error.should_equal : Any -> Assertion. Error.should_equal _ = Panic.throw (Matched_On_Error this) @@ -165,6 +238,21 @@ Error.should_equal _ = Panic.throw (Matched_On_Error this) Arguments: - that: The value to compare `this` for equality with. - epsilon: The epislon for comparing two decimal numbers. + + > Example + Compare two decimal values. + + import Standard.Test + + example_should_equal = 1.1 . should_equal 1.1 + + > Example + Compare two decimal values with an epsilon (tolerance). + + import Standard.Test + + example_should_equal = + 1.00000001 . should_equal 1.00000002 epsilon=0.0001 Decimal.should_equal : Decimal -> Decimal -> Assertion Decimal.should_equal that (epsilon = 0) = case this.equals that epsilon of True -> Success @@ -174,6 +262,14 @@ Decimal.should_equal that (epsilon = 0) = case this.equals that epsilon of Panic.throw (Failure msg) ## Asserts that the given `Boolean` is `True` + + > Example + Assert that a boolean value is true. + + import Standard.Examples + import Standard.Test + + example_should_be_true = Examples.get_boolean . should_be_true Boolean.should_be_true : Assertion Boolean.should_be_true = case this of True -> Success @@ -182,10 +278,26 @@ Boolean.should_be_true = case this of Panic.throw (Failure "Expected False to be True (at "+loc+").") ## Asserts that the given `Boolean` is `True`. + + > Example + Assert that a boolean value is true. + + import Standard.Examples + import Standard.Test + + example_should_be_true = Examples.get_boolean . should_be_true Error.should_be_true : Assertion Error.should_be_true = Panic.throw (Matched_On_Error this) ## Asserts that the given `Boolean` is `False` + + > Example + Assert that a boolean value is false. + + import Standard.Examples + import Standard.Test + + example_should_be_false = Examples.get_boolean . should_be_false Boolean.should_be_false : Assertion Boolean.should_be_false = case this of True -> @@ -194,15 +306,60 @@ Boolean.should_be_false = case this of False -> Success ## Asserts that the given `Boolean` is `False` + + > Example + Assert that a boolean value is false. + + import Standard.Examples + import Standard.Test + + example_should_be_false = Examples.get_boolean . should_be_false Error.should_be_false : Assertion Error.should_be_false = Panic.throw (Matched_On_Error this) +## Asserts that a value is of a given type. + + Arguments: + - typ: The type to assert that `this` is a value of. + + > Examples + Assert that 1 is of type Boolean. + + import Standard.Test + + example_should_be_a = 1.should_be_a Boolean +Any.should_be_a : Any -> Assertion +Any.should_be_a typ = if this.is_a typ then Success else + loc = Meta.get_source_location 0 + expected_type = Meta.get_qualified_type_name typ + actual_type = Meta.get_qualified_type_name this + message = "Expected a value of type " + expected_type + " but got a value of type " + actual_type + " instead (at " + loc + ")." + Panic.throw <| Failure message + +## Asserts that a value is of a given type. + + Arguments: + - typ: The type to assert that `this` is a value of. + + > Examples + Assert that 1 is of type Integer. + + import Standard.Test + + example_should_be_an = 1.should_be_an Integer +Any.should_be_an : Any -> Assertion +Any.should_be_an typ = this.should_be_a typ + type Verbs - ## Verbs that describe how tests should execute. + ## PRIVATE + + Verbs that describe how tests should execute. type Verbs - ## Checks if the `subject` starts with `argument`. + ## PRIVATE + + Checks if the `subject` starts with `argument`. Arguments: - subject: The value to check. It must have a `.starts_with` method. @@ -212,7 +369,9 @@ type Verbs if subject.starts_with argument then Success else here.fail (subject.to_text + " did not start with " + argument.to_text)) - ## Checks if the `subject` is equal to the `argument`. + ## PRIVATE + + Checks if the `subject` is equal to the `argument`. Arguments: - subject: The value to check for equality against the provided value. @@ -224,7 +383,9 @@ type Verbs msg = subject.to_text + " did not equal " + argument.to_text + "." here.fail msg - ## Checks if `subject` is `argument`. + ## PRIVATE + + Checks if `subject` is `argument`. Arguments: - subject: The value to check for equality against the provided value. @@ -233,7 +394,9 @@ type Verbs be : Any -> Any -> Assertion be subject argument = this.equal subject argument - ## Checks if `subject` contains `argument`. + ## PRIVATE + + Checks if `subject` contains `argument`. Arguments: - subject: The collection type to check if `argument` is contained in it. diff --git a/distribution/std-lib/Standard/src/Test/Bench.enso b/distribution/std-lib/Standard/src/Test/Bench.enso index 1b6163387192..1f462393ce64 100644 --- a/distribution/std-lib/Standard/src/Test/Bench.enso +++ b/distribution/std-lib/Standard/src/Test/Bench.enso @@ -1,5 +1,37 @@ from Standard.Base import all +## Measure the amount of time it takes to execute a given computation. + + Arguments: + - act: The action to perform. + - label: A name for the measurement. + - iter_size: The number of runs per iteration. + - num_iters: The number of iterations per measurement. + + > Example + Measure a computation called "foo" with an iteration size of 2 and a number + of iterations of 1. + + import Standard.Examples + import Standard.Test.Bench + + example_measure = + Bench.measure Examples.get_boolean "foo" iter_size=2 num_iters=1 +measure : Any -> Text -> Integer -> Integer -> Nothing +measure = ~act -> label -> iter_size -> num_iters -> + single_call = _ -> + x1 = System.nano_time + Runtime.no_inline act + x2 = System.nano_time + x2 - x1 + iteration = it_num -> + act_it_num = num_iters - it_num + res = iter_size.times single_call + avg = here.avg_list res + fmt = (avg / 1000000).format "%.2f" + IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms") + num_iters.times iteration + ## PRIVATE Reverses the provided list. @@ -65,25 +97,3 @@ Number.times act = res = here.reverse_list (go Nil this) res -## Measure the amount of time it takes to execute a given computation. - - Arguments: - - act: The action to perform. - - label: A name for the measurement. - - iter_size: The number of runs per iteration. - - num_iters: The number of iterations per measurement. -measure : Any -> Text -> Integer -> Integer -> Nothing -measure = ~act -> label -> iter_size -> num_iters -> - single_call = _ -> - x1 = System.nano_time - Runtime.no_inline act - x2 = System.nano_time - x2 - x1 - iteration = it_num -> - act_it_num = num_iters - it_num - res = iter_size.times single_call - avg = here.avg_list res - fmt = (avg / 1000000).format "%.2f" - IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms") - num_iters.times iteration - diff --git a/distribution/std-lib/Standard/src/Visualization/Geo_Map.enso b/distribution/std-lib/Standard/src/Visualization/Geo_Map.enso index 3bf73771d15d..5c2821a05399 100644 --- a/distribution/std-lib/Standard/src/Visualization/Geo_Map.enso +++ b/distribution/std-lib/Standard/src/Visualization/Geo_Map.enso @@ -7,29 +7,29 @@ import Standard.Visualization.Helpers ## PRIVATE Construct JSON describing table geo map visualization. - + Arguments: - table: the Table to be visualized. json_from_table : Table.Table -> Object -json_from_table table = +json_from_table table = names = ['label', 'latitude', 'longitude', 'radius', 'color'] - pairs = names.filter_map <| name-> + pairs = names.filter_map <| name-> column = table.lookup_ignore_case name column.when_valid ["df_" + name, column.to_vector] - + Json.from_pairs pairs ## PRIVATE Default preprocessor for the geo map visualization, generating JSON text describing the geo map 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 Table.Table _ -> here.json_from_table value _ -> value.to_json - + json.to_text diff --git a/distribution/std-lib/Standard/src/Visualization/Helpers.enso b/distribution/std-lib/Standard/src/Visualization/Helpers.enso index 39467248ff31..f8f0b0154b18 100644 --- a/distribution/std-lib/Standard/src/Visualization/Helpers.enso +++ b/distribution/std-lib/Standard/src/Visualization/Helpers.enso @@ -10,7 +10,7 @@ import Standard.Table.Data.Table Arguments: - f: unary invokable that is applied to each vector element. Non-error - values are returned in the resulting vector. Error values are dropped. + values are returned in the resulting vector. Error values are dropped. Vector.Vector.filter_map : Any -> Vector Vector.Vector.filter_map f = this.map f . filter .is_valid @@ -68,7 +68,7 @@ Error.map_valid _ = this Recovers from the error by returning the parameter value. - The error contents will be ignored. + The error contents will be ignored. Arguments: - val: a value that will be evaluated and returned if `this` is an error. @@ -79,7 +79,7 @@ Any.catch_ ~val = this.catch (_-> val) Recovers from the error by returning the parameter value. - The error contents will be ignored. + The error contents will be ignored. Arguments: - val: a value that will be evaluated and returned if `this` is an error. @@ -95,8 +95,8 @@ recover_errors ~body = ## PRIVATE - Returns all the columns in the table, including indices. - + Returns all the columns in the table, including indices. + Index columns are placed before other columns. Table.Table.all_columns : Vector Table.Table.all_columns = @@ -108,15 +108,15 @@ Table.Table.all_columns = ## PRIVATE - Looks for a column by a given name. - + Looks for a column by a given name. + Unlike `Table.at` looks into index columns and name comparison is case-insensitive. Arguments: - text: the case-insensitive name of the searched column. Table.Table.lookup_ignore_case : Text -> Column ! Nothing Table.Table.lookup_ignore_case name = - ret = this.all_columns.find <| col-> + ret = this.all_columns.find <| col-> col.name.equals_ignore_case name ret diff --git a/distribution/std-lib/Standard/src/Visualization/Histogram.enso b/distribution/std-lib/Standard/src/Visualization/Histogram.enso index 987f06de44b5..605f7570512d 100644 --- a/distribution/std-lib/Standard/src/Visualization/Histogram.enso +++ b/distribution/std-lib/Standard/src/Visualization/Histogram.enso @@ -5,27 +5,32 @@ import Standard.Table.Data.Table import Standard.Visualization.Helpers ## PRIVATE + Get first numeric column of the table. Table.Table.first_numeric : Table -> Column ! Nothing Table.Table.first_numeric = this.all_columns.find _.is_numeric ## PRIVATE + Get the value column - the column that will be used to create histogram. Table.Table.value_column : Table -> Column ! Nothing -Table.Table.value_column = +Table.Table.value_column = named_col = this.lookup_ignore_case 'value' named_col.catch_ this.first_numeric ## PRIVATE + Information that are placed in an update sent to a visualization. type Update + ## PRIVATE type Update values label ## PRIVATE + Generate JSON that can be consumed by the visualization. to_json : Object - to_json = + to_json = data = ['data', Json.from_pairs [['values', this.values]]] axis = ['axis', Json.from_pairs [['x', Json.from_pairs [['label', this.label]]]]] ret_pairs = case this.label of @@ -35,7 +40,7 @@ type Update ## PRIVATE from_table : Table -> Update -from_table table = +from_table table = col = table.value_column label = col.name.catch_ Nothing values = col.to_vector.catch_ [] @@ -43,12 +48,12 @@ from_table table = ## PRIVATE from_vector : Vector -> Update -from_vector vector = +from_vector vector = Update vector Nothing ## PRIVATE from_value : Any -> Update -from_value value = +from_value value = case value of Table.Table _ -> here.from_table value Vector.Vector _ -> here.from_vector value @@ -64,6 +69,6 @@ from_value value = Arguments: - value: the value to be visualized. process_to_json_text : Any -> Text -process_to_json_text value = +process_to_json_text value = update = here.from_value value update.to_json.to_text diff --git a/distribution/std-lib/Standard/src/Visualization/Scatter_Plot.enso b/distribution/std-lib/Standard/src/Visualization/Scatter_Plot.enso index 56ee87aba127..113161599ba2 100644 --- a/distribution/std-lib/Standard/src/Visualization/Scatter_Plot.enso +++ b/distribution/std-lib/Standard/src/Visualization/Scatter_Plot.enso @@ -5,7 +5,8 @@ import Standard.Table.Data.Table import Standard.Visualization.Helpers ## PRIVATE - Name of the index column that may be generated to plot against. + + Name of the index column that may be generated to plot against. index_name : Text index_name = 'index' @@ -22,24 +23,33 @@ label_field : Text label_field = 'label' ## PRIVATE + Represents a recognized point data field for a scatter plot visualization. type PointData + ## PRIVATE type PointData + ## PRIVATE type X + ## PRIVATE type Y + ## PRIVATE type Color + ## PRIVATE type Shape + ## PRIVATE type Label + ## PRIVATE type Size ## PRIVATE + Returns all recognized point data fields. all_fields : Vector all_fields = [X,Y,Color,Shape,Label,Size] @@ -70,6 +80,7 @@ type PointData _ -> Error.throw Nothing ## PRIVATE + Returns a vector of subsequent integers beginning from 0. iota : Number -> Vector iota count = @@ -83,7 +94,8 @@ type PointData named.catch_ <| this.fallback_column table ## PRIVATE - Generates JSON that describes points data. + + Generates JSON that describes points data. Table.Table.point_data : Table -> Object Table.Table.point_data = get_point_data field = field.lookup_in this . rename field.name @@ -95,7 +107,8 @@ Table.Table.point_data = Json.from_pairs pairs ## PRIVATE - Generates JSON that describes plot axes. + + Generates JSON that describes plot axes. Table.Table.axes : Table -> Object Table.Table.axes = describe_axis field = @@ -117,13 +130,14 @@ Vector.Vector.point_data = Json.from_pairs [[X.name,i],[Y.name,elem]] ## PRIVATE - +json_from_table : Table -> Json 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 : Vector Any -> Json json_from_vector vec = data = [here.data_field, vec.point_data] axes = [here.axis_field, Nothing] @@ -146,3 +160,4 @@ process_to_json_text value = _ -> here.json_from_vector value.to_vector json.to_text + diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetQualifiedTypeNameNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetQualifiedTypeNameNode.java index ac1a61dfeb28..abc843e0458d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetQualifiedTypeNameNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetQualifiedTypeNameNode.java @@ -1,6 +1,7 @@ package org.enso.interpreter.node.expression.builtin.meta; import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.dsl.AcceptsError; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.data.text.Text; import org.enso.interpreter.runtime.type.Types; @@ -10,7 +11,7 @@ name = "get_qualified_type_name", description = "Returns a qualified type name of the given value.") public class GetQualifiedTypeNameNode extends Node { - Text execute(Object _this, Object value) { + Text execute(@AcceptsError Object _this, Object value) { var typeName = Types.getName(value); return Text.create(typeName); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetSimpleTypeNameNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetSimpleTypeNameNode.java index 0bd95c7bbe61..96d04f139d92 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetSimpleTypeNameNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/GetSimpleTypeNameNode.java @@ -2,6 +2,7 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.dsl.AcceptsError; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; import org.enso.interpreter.runtime.data.text.Text; @@ -10,7 +11,7 @@ public class GetSimpleTypeNameNode extends Node { @Child @CompilationFinal TypeToDisplayTextNode displayTypeNode = TypeToDisplayTextNode.build(); - Text execute(Object _this, Object value) { + Text execute(@AcceptsError Object _this, Object value) { return Text.create(displayTypeNode.execute(value)); } } diff --git a/test/Tests/src/Examples_Spec.enso b/test/Tests/src/Examples_Spec.enso new file mode 100644 index 000000000000..102e536d9823 --- /dev/null +++ b/test/Tests/src/Examples_Spec.enso @@ -0,0 +1,119 @@ +from Standard.Base import all + +import Standard.Base.System.File +import Standard.Examples + +import Standard.Test + +# While we're lacking the ability to run the documentation examples +# automatically (#1706), these tests at least check that each of the examples +# executes without an error resulting. + +spec = Test.group "Examples" <| + Test.specify "should allow construction of Example_Error_Type" <| + val = Examples.Example_Error_Type "Oh, no! Something went wrong!" + val.should_be_an Examples.Example_Error_Type + + Test.specify "should allow getting the examples data directory" <| + dir = Examples.data_dir + dir.exists.should_be_true + + Test.specify "should allow getting an example CSV file" <| + Examples.csv.exists.should_be_true + + Test.specify "should provide access to the CSV path" <| + (Examples.csv_path.length > 0) . should_be_true + + Test.specify "should provide access to a scratch file location" <| + # It is deleted every time it is requested. + Examples.scratch_file.exists.should_be_false + + Test.specify "should provide access to a simple duration" <| + Examples.duration + + Test.specify "should provide some basic JSON text" <| + Json.parse Examples.json_text + + Test.specify "should provide some basic JSON" <| + Examples.json + + Test.specify "should provide a JSON object" <| + Examples.json_object + + Test.specify "should provide a basic cons list" <| + Examples.list.length . should_equal 3 + + Test.specify "should provide a basic KV map" <| + Examples.map.size . should_equal 3 + + Test.specify "should provide a type with no methods" <| + Examples.No_Methods.should_be_an Examples.No_Methods + + Test.specify "should provide a no method error value" <| + Examples.no_such_method + + Test.specify "should provide a dummy error type" <| + Examples.My_Error + + Test.specify "should provide a method that throws an error" <| + Examples.throw_error.should_fail_with Examples.My_Error + + Test.specify "should provide a method that throws a panic" <| + Test.expect_panic_with Examples.throw_panic Examples.My_Error + + Test.specify "should provide a URL for some geo data" <| + (Examples.geo_data_url.length > 0) . should_be_true + + Test.specify "should provide an HTTP response" <| + Examples.get_response + + Test.specify "should provide a response containing geo data" <| + Examples.get_geo_data + + Test.specify "should provide a basic HTTP client" <| + Examples.http_client + + Test.specify "should provide an example URI" <| + Examples.uri + + Test.specify "should provide an image file" <| + Examples.image_file + + Test.specify "should provide an image" <| + Examples.image + + Test.specify "should provide a matrix" <| + Examples.matrix + + Test.specify "should provide a silly function" <| + Examples.add_1_to 4 . should_equal 5 + + Test.specify "should provide a boolean" <| + Examples.get_boolean + + Test.specify "should provide a simple json table" <| + Examples.simple_table_json + Examples.simple_table_json_headers + + Test.specify "should provide some geo_json" <| + Examples.geo_json + + Test.specify "should provide various table columns" <| + Examples.integer_column + Examples.decimal_column + Examples.bool_column_1 + Examples.bool_column_2 + Examples.text_column_1 + Examples.text_column_2 + + Test.specify "should provide an aggregate column" <| + Examples.aggregate_column + + Test.specify "should provide various example tables" <| + Examples.inventory_table + Examples.popularity_table + Examples.transactions_table + + Test.specify "should provide an aggregate table" <| + Examples.aggregate_table + diff --git a/test/Tests/src/Main.enso b/test/Tests/src/Main.enso index 5d17559241cf..fbad042f0fe4 100644 --- a/test/Tests/src/Main.enso +++ b/test/Tests/src/Main.enso @@ -40,12 +40,15 @@ import Tests.Network.Uri_Spec import Tests.System.File_Spec import Tests.System.Process_Spec +import Tests.Examples_Spec + main = Test.Suite.run_main <| Any_Spec.spec Array_Spec.spec Case_Spec.spec Deep_Export_Spec.spec Error_Spec.spec + Examples_Spec.spec File_Spec.spec Http_Header_Spec.spec Http_Request_Spec.spec