diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9ffc6d3..2efdd1d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,6 +16,8 @@ jobs: - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@v2 + with: + version: 1.2.475 - name: Render and Publish uses: quarto-dev/quarto-actions/publish@v2 diff --git a/_feidlambda/feid b/_feidlambda/feid_.sc similarity index 62% rename from _feidlambda/feid rename to _feidlambda/feid_.sc index 61bfaea..65dd22f 100644 --- a/_feidlambda/feid +++ b/_feidlambda/feid_.sc @@ -1,11 +1,49 @@ /* -feidlambda v0.3.1 - LOGIC / UTILITIES FUNCTIONS BY FIAKO ENGINEERING -OFFICIAL GIST (feidlambda v0.3.x): https://gist.github.com/taruma/92bd33600a3d42dc9aead87558404a12 -REPOSITORY: https://github.com/fiakoenjiniring/feidlambda -AUTHOR: @taruma -TESTED: Microsoft Excel v2211 +feidlambda v0.4.0 - LOGIC / UTILITIES FUNCTIONS BY FIAKO ENGINEERING +OFFICIAL GIST (feidlambda v0.4.x): + https://gist.github.com/taruma/b4df638ecb7af48ab63691951481d6b2 +REPOSITORY: + https://github.com/fiakoenjiniring/feidlambda +CONTRIBUTOR: @taruma, @iingLK +TESTED: Microsoft Excel 365 v2304 */ +// BATAS MAKSMIMUM LAYAR EDITOR -------------------------------------------# + +/* +---- APPLY ---- +*/ + +// NONE --> APPLY_COLUMN +APPLY_COLUMN = LAMBDA(array, index_vector, LAMBDA_FUNCTION, + LET( + index_vector, SORT(index_vector), + selected_array, CHOOSECOLS(array, index_vector), + applied_array, LAMBDA_FUNCTION(selected_array), + sequence_vector, SEQUENCE(COLUMNS(array)), + logical_vector, BYROW( + sequence_vector, + LAMBDA(row, OR(row = index_vector)) + ), + scan_vector, SCAN( + 0, + logical_vector, + LAMBDA(acc, curr, IF(curr, acc + 1, acc)) + ), + position_vector, scan_vector + COLUMNS(array), + all_array, HSTACK(array, applied_array), + selected_vector, MAP( + logical_vector, + sequence_vector, + position_vector, + LAMBDA(logical_el, seq_el, pos_el, + IF(logical_el, pos_el, seq_el) + ) + ), + CHOOSECOLS(all_array, selected_vector) + ) +); + /* ---- FILTER ---- */ @@ -17,7 +55,10 @@ FILTER_DROP_ROWS = LAMBDA(array, row_index, row_index_clean, FILTER(row_index, NOT(ISBLANK(row_index))), nrows, ROWS(array), row_sequence, SEQUENCE(nrows), - selected_row, BYROW(row_sequence, LAMBDA(each_row, OR(each_row = row_index_clean))), + selected_row, BYROW( + row_sequence, + LAMBDA(each_row, OR(each_row = row_index_clean)) + ), FILTER(array, NOT(selected_row)) ) ); @@ -26,10 +67,16 @@ FILTER_DROP_ROWS = LAMBDA(array, row_index, FILTER_DROP_COLUMNS = LAMBDA(array, column_index, LET( column_index, TOROW(column_index), - column_index_clean, FILTER(column_index, NOT(ISBLANK(column_index))), + column_index_clean, FILTER( + column_index, + NOT(ISBLANK(column_index)) + ), ncols, COLUMNS(array), col_sequence, SEQUENCE(1, ncols), - selected_col, BYCOL(col_sequence, LAMBDA(each_col, OR(each_col = column_index_clean))), + selected_col, BYCOL( + col_sequence, + LAMBDA(each_col, OR(each_col = column_index_clean)) + ), FILTER(array, NOT(selected_col)) ) ); @@ -44,24 +91,45 @@ FILTER_FUNC_COLUMN = LAMBDA( [label_function], [take_first_only], LET( - take_first_only, IF(ISOMITTED(take_first_only), FALSE, take_first_only), + take_first_only, IF( + ISOMITTED(take_first_only), + FALSE, + take_first_only + ), column_index, IF(ISOMITTED(column_index), 1, column_index), label_col, IF(ISOMITTED(label_col), column_index, label_col), with_label, IF(ISOMITTED(with_label), FALSE, with_label), function, IF(ISOMITTED(function), LAMBDA(x, MAX(x)), function), - label_function, IF(ISOMITTED(label_function), "func", label_function), + label_function, IF( + ISOMITTED(label_function), + "func", + label_function + ), selected_vector, CHOOSECOLS(array, column_index), func_value, function(selected_vector), selected_logical, selected_vector = func_value, array_filter, FILTER(array, selected_logical), - array_func, IF(take_first_only, TAKE(array_filter, 1), array_filter), - label, MAKEARRAY(ROWS(array_func), 1, LAMBDA(x, y, CONCAT(label_col, "_", label_function))), + array_func, IF( + take_first_only, + TAKE(array_filter, 1), + array_filter + ), + label, MAKEARRAY( + ROWS(array_func), + 1, + LAMBDA(x, y, CONCAT(label_col, "_", label_function)) + ), IF(with_label, HSTACK(label, array_func), array_func) ) ); // FILTER_FUNC_COLUMN --> FILTER_MINMAX_COLUMN -FILTER_MINMAX_COLUMN = LAMBDA(array, [column_index], [with_label], [label_col], [take_first_only], +FILTER_MINMAX_COLUMN = LAMBDA( + array, + [column_index], + [with_label], + [label_col], + [take_first_only], LET( func_1, LAMBDA(x, MIN(x)), label_func_1, "min", @@ -99,16 +167,40 @@ _RECURSIVE_FILTER_MINMAX = LAMBDA( [label_vector], [take_first_only], LET( - ignore_first_column, IF(ISOMITTED(ignore_first_column), FALSE, ignore_first_column), + ignore_first_column, IF( + ISOMITTED(ignore_first_column), + FALSE, + ignore_first_column + ), stop_col, IF(ignore_first_column, 2, 1), - label_vector, IF(ISOMITTED(label_vector), SEQUENCE(1, COLUMNS(array)), label_vector), - new_label, IF(stop_col = 2, HSTACK({" "}, label_vector), label_vector), + label_vector, IF( + ISOMITTED(label_vector), + SEQUENCE(1, COLUMNS(array)), + label_vector + ), + new_label, IF( + stop_col = 2, + HSTACK({" "}, label_vector), + label_vector + ), label_col, CHOOSECOLS(new_label, ntry), IF( ntry = stop_col, - FILTER_MINMAX_COLUMN(array, ntry, with_label, label_col, take_first_only), + FILTER_MINMAX_COLUMN( + array, + ntry, + with_label, + label_col, + take_first_only + ), LET( - results, FILTER_MINMAX_COLUMN(array, ntry, with_label, label_col, take_first_only), + results, FILTER_MINMAX_COLUMN( + array, + ntry, + with_label, + label_col, + take_first_only + ), next_try, ntry - 1, VSTACK( _RECURSIVE_FILTER_MINMAX( @@ -127,7 +219,12 @@ _RECURSIVE_FILTER_MINMAX = LAMBDA( ); // _RECURSIVE_FILTER_MINMAX --> FILTER_MINMAX_ARRAY -FILTER_MINMAX_ARRAY = LAMBDA(array, [ignore_first_column], [with_label], [label_vector], [take_first_only], +FILTER_MINMAX_ARRAY = LAMBDA( + array, + [ignore_first_column], + [with_label], + [label_vector], + [take_first_only], _RECURSIVE_FILTER_MINMAX( array, COLUMNS(array), @@ -145,7 +242,11 @@ FILTER_MINMAX_ARRAY = LAMBDA(array, [ignore_first_column], [with_label], [label_ // NONE --> GET_INDEX_2D GET_INDEX_2D = LAMBDA(lookup_value, array, [return_as_order], LET( - return_as_order, IF(ISOMITTED(return_as_order), FALSE, return_as_order), + return_as_order, IF( + ISOMITTED(return_as_order), + FALSE, + return_as_order + ), nrows, ROWS(array), ncols, COLUMNS(array), size, nrows * ncols, @@ -162,6 +263,72 @@ GET_INDEX_2D = LAMBDA(lookup_value, array, [return_as_order], ) ); +// _RECURSIVE_LOOKUP --> _RECURSIVE_LOOKUP +_RECURSIVE_LOOKUP = LAMBDA( + ntry, + lookup_value, + lookup_vector, + return_array, + [if_not_found], + [match_mode], + [search_mode], + LET( + lookup_value, TOCOL(lookup_value), + LET( + selected_value, VALUE( + ARRAYTOTEXT(CHOOSEROWS(lookup_value, ntry)) + ), + result, XLOOKUP( + selected_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ), + IF( + ntry = 1, + result, + VSTACK( + _RECURSIVE_LOOKUP( + ntry - 1, + lookup_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ), + result + ) + ) + ) + ) +); + +// _RECURSIVE_LOOKUP --> GET_XLOOKUP +GET_XLOOKUP = LAMBDA( + lookup_value, + lookup_vector, + return_array, + [if_not_found], + [match_mode], + [search_mode], + LET( + lookup_value, TOCOL(lookup_value), + ntry, ROWS(lookup_value), + _RECURSIVE_LOOKUP( + ntry, + lookup_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ) + ) +); + /* ---- IS ---- */ @@ -170,7 +337,12 @@ GET_INDEX_2D = LAMBDA(lookup_value, array, [return_as_order], IS_ALL_IN_VECTOR = LAMBDA(lookup_vector, array, LET( lookup_vector, TOCOL(lookup_vector), - MAP(array, LAMBDA(element, OR(BYROW(lookup_vector, LAMBDA(lookup, element = lookup))))) + MAP( + array, + LAMBDA(element, + OR(BYROW(lookup_vector, LAMBDA(lookup, element = lookup))) + ) + ) ) ); @@ -184,7 +356,10 @@ IS_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, IF( ncols_array = ncols_vector, LET( - repeat_array, CHOOSEROWS(lookup_vector, SEQUENCE(nrows_array, , 1, 0)), + repeat_array, CHOOSEROWS( + lookup_vector, + SEQUENCE(nrows_array, , 1, 0) + ), MAP(array, repeat_array, LAMBDA(x, y, x = y)) ), "N/A" @@ -195,7 +370,11 @@ IS_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, // IS_COLS_EQUAL_LOOKUP_VECTOR --> IS_ALL_COLS_EQUAL_LOOKUP_VECTOR IS_ALL_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), array_boolean, IS_COLS_EQUAL_VECTOR(lookup_vector, array), BYROW(array_boolean, LAMBDA(each_row, logical_function(each_row))) ) @@ -204,7 +383,11 @@ IS_ALL_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, [logical_function], // NONE --> IS_ROWS_LOGICAL IS_ROWS_LOGICAL = LAMBDA(logical_array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), BYROW(logical_array, LAMBDA(each_row, logical_function(each_row))) ) ); @@ -212,7 +395,11 @@ IS_ROWS_LOGICAL = LAMBDA(logical_array, [logical_function], // NONE --> IS_COLUMNS_LOGICAL IS_COLUMNS_LOGICAL = LAMBDA(logical_array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), BYCOL(logical_array, LAMBDA(each_col, logical_function(each_col))) ) ); @@ -222,11 +409,19 @@ IS_COLUMNS_LOGICAL = LAMBDA(logical_array, [logical_function], */ // _RECURSIVE_MAKE_SEQUENCE --> _RECURSIVE_MAKE_SEQUENCE -_RECURSIVE_MAKE_SEQUENCE = LAMBDA(start_vector, end_vector, ntry, [stack_horizontally], +_RECURSIVE_MAKE_SEQUENCE = LAMBDA( + start_vector, + end_vector, + ntry, + [stack_horizontally], LET( seq_start, INDEX(start_vector, ntry), seq_end, INDEX(end_vector, ntry), - stack_horizontally, IF(ISOMITTED(stack_horizontally), FALSE, stack_horizontally), + stack_horizontally, IF( + ISOMITTED(stack_horizontally), + FALSE, + stack_horizontally + ), IF( ntry = 1, SEQUENCE(seq_end - seq_start + 1, , seq_start), @@ -236,11 +431,21 @@ _RECURSIVE_MAKE_SEQUENCE = LAMBDA(start_vector, end_vector, ntry, [stack_horizon IF( stack_horizontally, HSTACK( - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, next_try, stack_horizontally), + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + next_try, + stack_horizontally + ), results ), VSTACK( - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, next_try, stack_horizontally), + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + next_try, + stack_horizontally + ), results ) ) @@ -250,8 +455,16 @@ _RECURSIVE_MAKE_SEQUENCE = LAMBDA(start_vector, end_vector, ntry, [stack_horizon ); // _RECURSIVE_MAKE_SEQUENCE --> MAKE_SEQUENCE_FROM_VECTOR -MAKE_SEQUENCE_FROM_VECTOR = LAMBDA(start_vector, end_vector, [stack_horizontally], - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, ROWS(start_vector), stack_horizontally) +MAKE_SEQUENCE_FROM_VECTOR = LAMBDA( + start_vector, + end_vector, + [stack_horizontally], + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + ROWS(start_vector), + stack_horizontally + ) ); /* @@ -263,7 +476,11 @@ REPEAT_ARRAY = LAMBDA(array, [num_repeat], [by_row], LET( by_row, IF(ISOMITTED(by_row), TRUE, by_row), num_repeat, IF(ISOMITTED(num_repeat), 2, num_repeat), - IF(by_row, REPEAT_ARRAY_BY_ROW(array, num_repeat), REPEAT_ARRAY_BY_COLUMN(array, num_repeat)) + IF( + by_row, + REPEAT_ARRAY_BY_ROW(array, num_repeat), + REPEAT_ARRAY_BY_COLUMN(array, num_repeat) + ) ) ); @@ -274,7 +491,10 @@ REPEAT_ARRAY_BY_ROW = LAMBDA(array, [num_repeat], IF( num_repeat = 1, array, - LET(next_repeat, num_repeat - 1, VSTACK(REPEAT_ARRAY_BY_ROW(array, next_repeat), array)) + LET( + next_repeat, num_repeat - 1, + VSTACK(REPEAT_ARRAY_BY_ROW(array, next_repeat), array) + ) ) ) ); @@ -286,7 +506,10 @@ REPEAT_ARRAY_BY_COLUMN = LAMBDA(array, [num_repeat], IF( num_repeat = 1, array, - LET(next_repeat, num_repeat - 1, HSTACK(REPEAT_ARRAY_BY_COLUMN(array, next_repeat), array)) + LET( + next_repeat, num_repeat - 1, + HSTACK(REPEAT_ARRAY_BY_COLUMN(array, next_repeat), array) + ) ) ) ); @@ -305,9 +528,15 @@ RESHAPE_BY_COLUMNS = LAMBDA(array, [num_split], MOD(ncols, num_split) = 0, LET( divider, ncols / num_split, - divider_sequence, CHOOSEROWS(SEQUENCE(1, divider), SEQUENCE(num_split, , 1, 0)), + divider_sequence, CHOOSEROWS( + SEQUENCE(1, divider), + SEQUENCE(num_split, , 1, 0) + ), divider_flatten, TOCOL(divider_sequence, , TRUE), - divider_repeat, CHOOSEROWS(TOROW(divider_flatten), SEQUENCE(nrows, , 1, 0)), + divider_repeat, CHOOSEROWS( + TOROW(divider_flatten), + SEQUENCE(nrows, , 1, 0) + ), divider_repeat_col, TOCOL(divider_repeat), array_flatten, TOCOL(array), array_sorted, SORTBY(array_flatten, divider_repeat_col), @@ -327,7 +556,11 @@ ROTATE_VECTOR = LAMBDA(vector, num_rotation, [as_column_vector], LET( vector, TOCOL(vector), rotated_array, IFS( - OR(num_rotation = 0, num_rotation >= ROWS(vector), num_rotation <= -ROWS(vector)), + OR( + num_rotation = 0, + num_rotation >= ROWS(vector), + num_rotation <= -ROWS(vector) + ), vector, num_rotation > 0, VSTACK(DROP(vector, num_rotation), TAKE(vector, num_rotation)), @@ -412,7 +645,14 @@ _RECURSIVE_TEXT_SPLIT = LAMBDA( selected_row, ARRAYTOTEXT(INDEX(text_vector, ntry)), IF( ntry = 1, - TEXTSPLIT(selected_row, col_delimiter, row_delimiter, ignore_empty, match_mode, pad_with), + TEXTSPLIT( + selected_row, + col_delimiter, + row_delimiter, + ignore_empty, + match_mode, + pad_with + ), LET( next_try, ntry - 1, results, TEXTSPLIT( diff --git a/_feidlambda/feid_APPLY.sc b/_feidlambda/feid_APPLY.sc new file mode 100644 index 0000000..e864a11 --- /dev/null +++ b/_feidlambda/feid_APPLY.sc @@ -0,0 +1,29 @@ +// NONE --> APPLY_COLUMN +APPLY_COLUMN = LAMBDA(array, index_vector, LAMBDA_FUNCTION, + LET( + index_vector, SORT(index_vector), + selected_array, CHOOSECOLS(array, index_vector), + applied_array, LAMBDA_FUNCTION(selected_array), + sequence_vector, SEQUENCE(COLUMNS(array)), + logical_vector, BYROW( + sequence_vector, + LAMBDA(row, OR(row = index_vector)) + ), + scan_vector, SCAN( + 0, + logical_vector, + LAMBDA(acc, curr, IF(curr, acc + 1, acc)) + ), + position_vector, scan_vector + COLUMNS(array), + all_array, HSTACK(array, applied_array), + selected_vector, MAP( + logical_vector, + sequence_vector, + position_vector, + LAMBDA(logical_el, seq_el, pos_el, + IF(logical_el, pos_el, seq_el) + ) + ), + CHOOSECOLS(all_array, selected_vector) + ) +); diff --git a/_feidlambda/feid_FILTER b/_feidlambda/feid_FILTER.sc similarity index 61% rename from _feidlambda/feid_FILTER rename to _feidlambda/feid_FILTER.sc index 6b8edfb..a52c3da 100644 --- a/_feidlambda/feid_FILTER +++ b/_feidlambda/feid_FILTER.sc @@ -5,7 +5,10 @@ FILTER_DROP_ROWS = LAMBDA(array, row_index, row_index_clean, FILTER(row_index, NOT(ISBLANK(row_index))), nrows, ROWS(array), row_sequence, SEQUENCE(nrows), - selected_row, BYROW(row_sequence, LAMBDA(each_row, OR(each_row = row_index_clean))), + selected_row, BYROW( + row_sequence, + LAMBDA(each_row, OR(each_row = row_index_clean)) + ), FILTER(array, NOT(selected_row)) ) ); @@ -14,10 +17,16 @@ FILTER_DROP_ROWS = LAMBDA(array, row_index, FILTER_DROP_COLUMNS = LAMBDA(array, column_index, LET( column_index, TOROW(column_index), - column_index_clean, FILTER(column_index, NOT(ISBLANK(column_index))), + column_index_clean, FILTER( + column_index, + NOT(ISBLANK(column_index)) + ), ncols, COLUMNS(array), col_sequence, SEQUENCE(1, ncols), - selected_col, BYCOL(col_sequence, LAMBDA(each_col, OR(each_col = column_index_clean))), + selected_col, BYCOL( + col_sequence, + LAMBDA(each_col, OR(each_col = column_index_clean)) + ), FILTER(array, NOT(selected_col)) ) ); @@ -32,24 +41,45 @@ FILTER_FUNC_COLUMN = LAMBDA( [label_function], [take_first_only], LET( - take_first_only, IF(ISOMITTED(take_first_only), FALSE, take_first_only), + take_first_only, IF( + ISOMITTED(take_first_only), + FALSE, + take_first_only + ), column_index, IF(ISOMITTED(column_index), 1, column_index), label_col, IF(ISOMITTED(label_col), column_index, label_col), with_label, IF(ISOMITTED(with_label), FALSE, with_label), function, IF(ISOMITTED(function), LAMBDA(x, MAX(x)), function), - label_function, IF(ISOMITTED(label_function), "func", label_function), + label_function, IF( + ISOMITTED(label_function), + "func", + label_function + ), selected_vector, CHOOSECOLS(array, column_index), func_value, function(selected_vector), selected_logical, selected_vector = func_value, array_filter, FILTER(array, selected_logical), - array_func, IF(take_first_only, TAKE(array_filter, 1), array_filter), - label, MAKEARRAY(ROWS(array_func), 1, LAMBDA(x, y, CONCAT(label_col, "_", label_function))), + array_func, IF( + take_first_only, + TAKE(array_filter, 1), + array_filter + ), + label, MAKEARRAY( + ROWS(array_func), + 1, + LAMBDA(x, y, CONCAT(label_col, "_", label_function)) + ), IF(with_label, HSTACK(label, array_func), array_func) ) ); // FILTER_FUNC_COLUMN --> FILTER_MINMAX_COLUMN -FILTER_MINMAX_COLUMN = LAMBDA(array, [column_index], [with_label], [label_col], [take_first_only], +FILTER_MINMAX_COLUMN = LAMBDA( + array, + [column_index], + [with_label], + [label_col], + [take_first_only], LET( func_1, LAMBDA(x, MIN(x)), label_func_1, "min", @@ -87,16 +117,40 @@ _RECURSIVE_FILTER_MINMAX = LAMBDA( [label_vector], [take_first_only], LET( - ignore_first_column, IF(ISOMITTED(ignore_first_column), FALSE, ignore_first_column), + ignore_first_column, IF( + ISOMITTED(ignore_first_column), + FALSE, + ignore_first_column + ), stop_col, IF(ignore_first_column, 2, 1), - label_vector, IF(ISOMITTED(label_vector), SEQUENCE(1, COLUMNS(array)), label_vector), - new_label, IF(stop_col = 2, HSTACK({" "}, label_vector), label_vector), + label_vector, IF( + ISOMITTED(label_vector), + SEQUENCE(1, COLUMNS(array)), + label_vector + ), + new_label, IF( + stop_col = 2, + HSTACK({" "}, label_vector), + label_vector + ), label_col, CHOOSECOLS(new_label, ntry), IF( ntry = stop_col, - FILTER_MINMAX_COLUMN(array, ntry, with_label, label_col, take_first_only), + FILTER_MINMAX_COLUMN( + array, + ntry, + with_label, + label_col, + take_first_only + ), LET( - results, FILTER_MINMAX_COLUMN(array, ntry, with_label, label_col, take_first_only), + results, FILTER_MINMAX_COLUMN( + array, + ntry, + with_label, + label_col, + take_first_only + ), next_try, ntry - 1, VSTACK( _RECURSIVE_FILTER_MINMAX( @@ -115,7 +169,12 @@ _RECURSIVE_FILTER_MINMAX = LAMBDA( ); // _RECURSIVE_FILTER_MINMAX --> FILTER_MINMAX_ARRAY -FILTER_MINMAX_ARRAY = LAMBDA(array, [ignore_first_column], [with_label], [label_vector], [take_first_only], +FILTER_MINMAX_ARRAY = LAMBDA( + array, + [ignore_first_column], + [with_label], + [label_vector], + [take_first_only], _RECURSIVE_FILTER_MINMAX( array, COLUMNS(array), diff --git a/_feidlambda/feid_GET b/_feidlambda/feid_GET deleted file mode 100644 index 0046d46..0000000 --- a/_feidlambda/feid_GET +++ /dev/null @@ -1,19 +0,0 @@ -// NONE --> GET_INDEX_2D -GET_INDEX_2D = LAMBDA(lookup_value, array, [return_as_order], - LET( - return_as_order, IF(ISOMITTED(return_as_order), FALSE, return_as_order), - nrows, ROWS(array), - ncols, COLUMNS(array), - size, nrows * ncols, - array_flatten, TOCOL(array, , TRUE), - index_sequence, SEQUENCE(nrows, ncols, 1, 1), - rows_sequence, MAKEARRAY(nrows, ncols, LAMBDA(x, y, x)), - columns_sequence, MAKEARRAY(nrows, ncols, LAMBDA(x, y, y)), - rows_flatten, TOCOL(rows_sequence, , TRUE), - columns_flatten, TOCOL(columns_sequence, , TRUE), - index_flatten, TOCOL(index_sequence, , TRUE), - lookup_table, HSTACK(index_flatten, rows_flatten, columns_flatten), - lookup_result, FILTER(lookup_table, array_flatten = lookup_value), - IF(return_as_order, CHOOSECOLS(lookup_result, 1), lookup_result) - ) -); diff --git a/_feidlambda/feid_GET.sc b/_feidlambda/feid_GET.sc new file mode 100644 index 0000000..e904723 --- /dev/null +++ b/_feidlambda/feid_GET.sc @@ -0,0 +1,89 @@ +// NONE --> GET_INDEX_2D +GET_INDEX_2D = LAMBDA(lookup_value, array, [return_as_order], + LET( + return_as_order, IF( + ISOMITTED(return_as_order), + FALSE, + return_as_order + ), + nrows, ROWS(array), + ncols, COLUMNS(array), + size, nrows * ncols, + array_flatten, TOCOL(array, , TRUE), + index_sequence, SEQUENCE(nrows, ncols, 1, 1), + rows_sequence, MAKEARRAY(nrows, ncols, LAMBDA(x, y, x)), + columns_sequence, MAKEARRAY(nrows, ncols, LAMBDA(x, y, y)), + rows_flatten, TOCOL(rows_sequence, , TRUE), + columns_flatten, TOCOL(columns_sequence, , TRUE), + index_flatten, TOCOL(index_sequence, , TRUE), + lookup_table, HSTACK(index_flatten, rows_flatten, columns_flatten), + lookup_result, FILTER(lookup_table, array_flatten = lookup_value), + IF(return_as_order, CHOOSECOLS(lookup_result, 1), lookup_result) + ) +); + +// _RECURSIVE_LOOKUP --> _RECURSIVE_LOOKUP +_RECURSIVE_LOOKUP = LAMBDA( + ntry, + lookup_value, + lookup_vector, + return_array, + [if_not_found], + [match_mode], + [search_mode], + LET( + lookup_value, TOCOL(lookup_value), + LET( + selected_value, VALUE( + ARRAYTOTEXT(CHOOSEROWS(lookup_value, ntry)) + ), + result, XLOOKUP( + selected_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ), + IF( + ntry = 1, + result, + VSTACK( + _RECURSIVE_LOOKUP( + ntry - 1, + lookup_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ), + result + ) + ) + ) + ) +); + +// _RECURSIVE_LOOKUP --> GET_XLOOKUP +GET_XLOOKUP = LAMBDA( + lookup_value, + lookup_vector, + return_array, + [if_not_found], + [match_mode], + [search_mode], + LET( + lookup_value, TOCOL(lookup_value), + ntry, ROWS(lookup_value), + _RECURSIVE_LOOKUP( + ntry, + lookup_value, + lookup_vector, + return_array, + if_not_found, + match_mode, + search_mode + ) + ) +); diff --git a/_feidlambda/feid_IS b/_feidlambda/feid_IS.sc similarity index 63% rename from _feidlambda/feid_IS rename to _feidlambda/feid_IS.sc index f9609a9..6f2224a 100644 --- a/_feidlambda/feid_IS +++ b/_feidlambda/feid_IS.sc @@ -2,7 +2,12 @@ IS_ALL_IN_VECTOR = LAMBDA(lookup_vector, array, LET( lookup_vector, TOCOL(lookup_vector), - MAP(array, LAMBDA(element, OR(BYROW(lookup_vector, LAMBDA(lookup, element = lookup))))) + MAP( + array, + LAMBDA(element, + OR(BYROW(lookup_vector, LAMBDA(lookup, element = lookup))) + ) + ) ) ); @@ -16,7 +21,10 @@ IS_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, IF( ncols_array = ncols_vector, LET( - repeat_array, CHOOSEROWS(lookup_vector, SEQUENCE(nrows_array, , 1, 0)), + repeat_array, CHOOSEROWS( + lookup_vector, + SEQUENCE(nrows_array, , 1, 0) + ), MAP(array, repeat_array, LAMBDA(x, y, x = y)) ), "N/A" @@ -27,7 +35,11 @@ IS_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, // IS_COLS_EQUAL_LOOKUP_VECTOR --> IS_ALL_COLS_EQUAL_LOOKUP_VECTOR IS_ALL_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), array_boolean, IS_COLS_EQUAL_VECTOR(lookup_vector, array), BYROW(array_boolean, LAMBDA(each_row, logical_function(each_row))) ) @@ -36,7 +48,11 @@ IS_ALL_COLS_EQUAL_VECTOR = LAMBDA(lookup_vector, array, [logical_function], // NONE --> IS_ROWS_LOGICAL IS_ROWS_LOGICAL = LAMBDA(logical_array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), BYROW(logical_array, LAMBDA(each_row, logical_function(each_row))) ) ); @@ -44,7 +60,11 @@ IS_ROWS_LOGICAL = LAMBDA(logical_array, [logical_function], // NONE --> IS_COLUMNS_LOGICAL IS_COLUMNS_LOGICAL = LAMBDA(logical_array, [logical_function], LET( - logical_function, IF(ISOMITTED(logical_function), LAMBDA(x, OR(x)), logical_function), + logical_function, IF( + ISOMITTED(logical_function), + LAMBDA(x, OR(x)), + logical_function + ), BYCOL(logical_array, LAMBDA(each_col, logical_function(each_col))) ) ); diff --git a/_feidlambda/feid_MAKE b/_feidlambda/feid_MAKE deleted file mode 100644 index bdef3be..0000000 --- a/_feidlambda/feid_MAKE +++ /dev/null @@ -1,32 +0,0 @@ -// _RECURSIVE_MAKE_SEQUENCE --> _RECURSIVE_MAKE_SEQUENCE -_RECURSIVE_MAKE_SEQUENCE = LAMBDA(start_vector, end_vector, ntry, [stack_horizontally], - LET( - seq_start, INDEX(start_vector, ntry), - seq_end, INDEX(end_vector, ntry), - stack_horizontally, IF(ISOMITTED(stack_horizontally), FALSE, stack_horizontally), - IF( - ntry = 1, - SEQUENCE(seq_end - seq_start + 1, , seq_start), - LET( - next_try, ntry - 1, - results, SEQUENCE(seq_end - seq_start + 1, , seq_start), - IF( - stack_horizontally, - HSTACK( - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, next_try, stack_horizontally), - results - ), - VSTACK( - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, next_try, stack_horizontally), - results - ) - ) - ) - ) - ) -); - -// _RECURSIVE_MAKE_SEQUENCE --> MAKE_SEQUENCE_FROM_VECTOR -MAKE_SEQUENCE_FROM_VECTOR = LAMBDA(start_vector, end_vector, [stack_horizontally], - _RECURSIVE_MAKE_SEQUENCE(start_vector, end_vector, ROWS(start_vector), stack_horizontally) -); diff --git a/_feidlambda/feid_MAKE.sc b/_feidlambda/feid_MAKE.sc new file mode 100644 index 0000000..37b9cd9 --- /dev/null +++ b/_feidlambda/feid_MAKE.sc @@ -0,0 +1,58 @@ +// _RECURSIVE_MAKE_SEQUENCE --> _RECURSIVE_MAKE_SEQUENCE +_RECURSIVE_MAKE_SEQUENCE = LAMBDA( + start_vector, + end_vector, + ntry, + [stack_horizontally], + LET( + seq_start, INDEX(start_vector, ntry), + seq_end, INDEX(end_vector, ntry), + stack_horizontally, IF( + ISOMITTED(stack_horizontally), + FALSE, + stack_horizontally + ), + IF( + ntry = 1, + SEQUENCE(seq_end - seq_start + 1, , seq_start), + LET( + next_try, ntry - 1, + results, SEQUENCE(seq_end - seq_start + 1, , seq_start), + IF( + stack_horizontally, + HSTACK( + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + next_try, + stack_horizontally + ), + results + ), + VSTACK( + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + next_try, + stack_horizontally + ), + results + ) + ) + ) + ) + ) +); + +// _RECURSIVE_MAKE_SEQUENCE --> MAKE_SEQUENCE_FROM_VECTOR +MAKE_SEQUENCE_FROM_VECTOR = LAMBDA( + start_vector, + end_vector, + [stack_horizontally], + _RECURSIVE_MAKE_SEQUENCE( + start_vector, + end_vector, + ROWS(start_vector), + stack_horizontally + ) +); diff --git a/_feidlambda/feid_REPEAT b/_feidlambda/feid_REPEAT.sc similarity index 62% rename from _feidlambda/feid_REPEAT rename to _feidlambda/feid_REPEAT.sc index 621c0ee..a48a394 100644 --- a/_feidlambda/feid_REPEAT +++ b/_feidlambda/feid_REPEAT.sc @@ -3,7 +3,11 @@ REPEAT_ARRAY = LAMBDA(array, [num_repeat], [by_row], LET( by_row, IF(ISOMITTED(by_row), TRUE, by_row), num_repeat, IF(ISOMITTED(num_repeat), 2, num_repeat), - IF(by_row, REPEAT_ARRAY_BY_ROW(array, num_repeat), REPEAT_ARRAY_BY_COLUMN(array, num_repeat)) + IF( + by_row, + REPEAT_ARRAY_BY_ROW(array, num_repeat), + REPEAT_ARRAY_BY_COLUMN(array, num_repeat) + ) ) ); @@ -14,7 +18,10 @@ REPEAT_ARRAY_BY_ROW = LAMBDA(array, [num_repeat], IF( num_repeat = 1, array, - LET(next_repeat, num_repeat - 1, VSTACK(REPEAT_ARRAY_BY_ROW(array, next_repeat), array)) + LET( + next_repeat, num_repeat - 1, + VSTACK(REPEAT_ARRAY_BY_ROW(array, next_repeat), array) + ) ) ) ); @@ -26,7 +33,10 @@ REPEAT_ARRAY_BY_COLUMN = LAMBDA(array, [num_repeat], IF( num_repeat = 1, array, - LET(next_repeat, num_repeat - 1, HSTACK(REPEAT_ARRAY_BY_COLUMN(array, next_repeat), array)) + LET( + next_repeat, num_repeat - 1, + HSTACK(REPEAT_ARRAY_BY_COLUMN(array, next_repeat), array) + ) ) ) -); \ No newline at end of file +); diff --git a/_feidlambda/feid_RESHAPE b/_feidlambda/feid_RESHAPE.sc similarity index 68% rename from _feidlambda/feid_RESHAPE rename to _feidlambda/feid_RESHAPE.sc index b9afefc..6f6667b 100644 --- a/_feidlambda/feid_RESHAPE +++ b/_feidlambda/feid_RESHAPE.sc @@ -8,9 +8,15 @@ RESHAPE_BY_COLUMNS = LAMBDA(array, [num_split], MOD(ncols, num_split) = 0, LET( divider, ncols / num_split, - divider_sequence, CHOOSEROWS(SEQUENCE(1, divider), SEQUENCE(num_split, , 1, 0)), + divider_sequence, CHOOSEROWS( + SEQUENCE(1, divider), + SEQUENCE(num_split, , 1, 0) + ), divider_flatten, TOCOL(divider_sequence, , TRUE), - divider_repeat, CHOOSEROWS(TOROW(divider_flatten), SEQUENCE(nrows, , 1, 0)), + divider_repeat, CHOOSEROWS( + TOROW(divider_flatten), + SEQUENCE(nrows, , 1, 0) + ), divider_repeat_col, TOCOL(divider_repeat), array_flatten, TOCOL(array), array_sorted, SORTBY(array_flatten, divider_repeat_col), diff --git a/_feidlambda/feid_ROTATE b/_feidlambda/feid_ROTATE.sc similarity index 87% rename from _feidlambda/feid_ROTATE rename to _feidlambda/feid_ROTATE.sc index c622d04..98e2745 100644 --- a/_feidlambda/feid_ROTATE +++ b/_feidlambda/feid_ROTATE.sc @@ -3,7 +3,11 @@ ROTATE_VECTOR = LAMBDA(vector, num_rotation, [as_column_vector], LET( vector, TOCOL(vector), rotated_array, IFS( - OR(num_rotation = 0, num_rotation >= ROWS(vector), num_rotation <= -ROWS(vector)), + OR( + num_rotation = 0, + num_rotation >= ROWS(vector), + num_rotation <= -ROWS(vector) + ), vector, num_rotation > 0, VSTACK(DROP(vector, num_rotation), TAKE(vector, num_rotation)), diff --git a/_feidlambda/feid_SWAP b/_feidlambda/feid_SWAP.sc similarity index 100% rename from _feidlambda/feid_SWAP rename to _feidlambda/feid_SWAP.sc diff --git a/_feidlambda/feid_TEXT b/_feidlambda/feid_TEXT.sc similarity index 89% rename from _feidlambda/feid_TEXT rename to _feidlambda/feid_TEXT.sc index e84e033..52f08cc 100644 --- a/_feidlambda/feid_TEXT +++ b/_feidlambda/feid_TEXT.sc @@ -12,7 +12,14 @@ _RECURSIVE_TEXT_SPLIT = LAMBDA( selected_row, ARRAYTOTEXT(INDEX(text_vector, ntry)), IF( ntry = 1, - TEXTSPLIT(selected_row, col_delimiter, row_delimiter, ignore_empty, match_mode, pad_with), + TEXTSPLIT( + selected_row, + col_delimiter, + row_delimiter, + ignore_empty, + match_mode, + pad_with + ), LET( next_try, ntry - 1, results, TEXTSPLIT( diff --git a/_feidmath/feidmath_.sc b/_feidmath/feidmath_.sc new file mode 100644 index 0000000..9592b29 --- /dev/null +++ b/_feidmath/feidmath_.sc @@ -0,0 +1,233 @@ +/* +feidmath v0.1.0 - MATH FUNCTIONS BY FIAKO ENGINEERING +OFFICIAL GIST (feidmath v0.1.x): + https://gist.github.com/taruma/8b0978227dffbee50c3a9d56e31d34f3 +REPOSITORY: + https://github.com/fiakoenjiniring/feidlambda +CONTRIBUTOR: @taruma, @iingLK +TESTED: Microsoft Excel 365 v2304 +*/ + +// BATAS MAKSMIMUM LAYAR EDITOR -------------------------------------------# + +/* +---- INTERPOLATION ---- +*/ + +// NONE ---> _INTERPOLATION_LINEAR +_INTERPOLATION_LINEAR = LAMBDA(x, known_ys, known_xs, + LET( + known_xs, TOCOL(known_xs), + known_ys, TOCOL(known_ys), + nrow, ROWS(known_ys), + known_table, HSTACK(known_xs, known_ys), + sorted_table, SORT(known_table, 1), + sorted_xs, CHOOSECOLS(sorted_table, 1), + sorted_ys, CHOOSECOLS(sorted_table, 2), + nearest_x, IFS( + x > MAX(sorted_xs), + XMATCH(x, sorted_xs, -1), + x < MIN(sorted_xs), + XMATCH(x, sorted_xs, 1), + TRUE, + XMATCH(x, sorted_xs, -1) + ), + index_ys, IF( + nearest_x < nrow, + VSTACK(nearest_x, nearest_x + 1), + VSTACK(nearest_x - 1, nearest_x) + ), + select_ys, CHOOSEROWS(sorted_ys, index_ys), + select_xs, CHOOSEROWS(sorted_xs, index_ys), + FORECAST.LINEAR(x, select_ys, select_xs) + ) +); + +// _INTERPOLATION_LINEAR ---> INTERPOLATION_LINEAR +INTERPOLATION_LINEAR = LAMBDA(x_vector, known_ys, known_xs, + LET( + x_vector, TOCOL(x_vector), + y_vector, BYROW( + x_vector, + LAMBDA(x, _INTERPOLATION_LINEAR(x, known_ys, known_xs)) + ), + y_vector + ) +); + +/* +---- LINEAR ALGEBRA (LINALG) ---- +*/ + +// NONE ---> LINALG_ROTATION_MATRIX +LINALG_ROTATION_MATRIX = LAMBDA(theta_x, theta_y, theta_z, [num_digits], + LET( + round_number, IF(ISOMITTED(num_digits), 0, num_digits), + angle_x, RADIANS(theta_x), + angle_y, RADIANS(theta_y), + angle_z, RADIANS(theta_z), + cos_x, COS(angle_x), + sin_x, SIN(angle_x), + rotation_x, VSTACK( + HSTACK(1, 0, 0), + HSTACK(0, cos_x, -sin_x), + HSTACK(0, sin_x, cos_x) + ), + cos_y, COS(angle_y), + sin_y, SIN(angle_y), + rotation_y, VSTACK( + HSTACK(cos_y, 0, sin_y), + HSTACK(0, 1, 0), + HSTACK(-sin_y, 0, cos_y) + ), + cos_z, COS(angle_z), + sin_z, SIN(angle_z), + rotation_z, VSTACK( + HSTACK(cos_z, -sin_z, 0), + HSTACK(sin_z, cos_z, 0), + HSTACK(0, 0, 1) + ), + rotation_matrix, MMULT(rotation_z, MMULT(rotation_y, rotation_x)), + IF( + round_number, + ROUND(rotation_matrix, round_number), + rotation_matrix + ) + ) +); + +// LINALG_ROTATION_MATRIX ---> LINALG_ROTATE_POINT +LINALG_ROTATE_POINT = LAMBDA( + point_vector, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + LET( + active_rotation, IF( + ISOMITTED(active_rotation), + TRUE, + active_rotation + ), + rotation_matrix, LINALG_ROTATION_MATRIX( + theta_x, + theta_y, + theta_z, + num_digits + ), + point_vector, TOCOL(point_vector), + final_rotation, IF( + active_rotation, + rotation_matrix, + TRANSPOSE(rotation_matrix) + ), + point_rotation, MMULT(final_rotation, point_vector), + TOROW(point_rotation) + ) +); + +// LINALG_ROTATE_POINT ---> _RECURSIVE_ROTATE_POINTS +// _RECURSIVE_ROTATE_POINTS ---> _RECURSIVE_ROTATE_POINTS +_RECURSIVE_ROTATE_POINTS = LAMBDA( + ntry, + data_points, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + LET( + selected_row, CHOOSEROWS(data_points, ntry), + IF( + ntry = 1, + LINALG_ROTATE_POINT( + selected_row, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + LET( + next_try, ntry - 1, + result, LINALG_ROTATE_POINT( + selected_row, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + VSTACK( + _RECURSIVE_ROTATE_POINTS( + next_try, + data_points, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + result + ) + ) + ) + ) +); + +// _RECURSIVE_ROTATE_POINTS ---> LINALG_ROTATE_POINT_ARRAY +LINALG_ROTATE_POINT_ARRAY = LAMBDA( + data_points, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + _RECURSIVE_ROTATE_POINTS( + ROWS(data_points), + data_points, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ) +); + +/* +---- GEOMETRY ---- +*/ + +// NONE ---> GEOMETRY_IS_POINT_IN_POLYGON +GEOMETRY_IS_POINT_IN_POLYGON = LAMBDA(point_vector, data_polygon, + LET( + point_vector, TOCOL(point_vector), + xp, INDEX(point_vector, 1), + yp, INDEX(point_vector, 2), + data_1, DROP(data_polygon, -1), + data_2, DROP(data_polygon, 1), + data_joined, HSTACK(data_1, data_2), + _x1, CHOOSECOLS(data_joined, 1), + _y1, CHOOSECOLS(data_joined, 2), + _x2, CHOOSECOLS(data_joined, 3), + _y2, CHOOSECOLS(data_joined, 4), + first_condition, (yp < _y1) <> (yp < _y2), + second_condition, xp < + (_x1 + (((yp - _y1) / (_y2 - _y1)) * (_x2 - _x1))), + final_condition, IFERROR( + (first_condition * second_condition) = 1, + FALSE + ), + is_inside, MOD(SUM(INT(final_condition)), 2) = 1, + is_inside + ) +); + +// GEOMETRY_IS_POINT_IN_POLYGON ---> GEOMETRY_ARE_POINTS_IN_POLYGON +GEOMETRY_ARE_POINTS_IN_POLYGON = LAMBDA(data_points, polygon_points, + BYROW( + data_points, + LAMBDA(row, GEOMETRY_IS_POINT_IN_POLYGON(row, polygon_points)) + ) +); \ No newline at end of file diff --git a/_feidmath/feidmath_GEOMETRY.sc b/_feidmath/feidmath_GEOMETRY.sc new file mode 100644 index 0000000..9755c18 --- /dev/null +++ b/_feidmath/feidmath_GEOMETRY.sc @@ -0,0 +1,32 @@ +// NONE ---> GEOMETRY_IS_POINT_IN_POLYGON +GEOMETRY_IS_POINT_IN_POLYGON = LAMBDA(point_vector, data_polygon, + LET( + point_vector, TOCOL(point_vector), + xp, INDEX(point_vector, 1), + yp, INDEX(point_vector, 2), + data_1, DROP(data_polygon, -1), + data_2, DROP(data_polygon, 1), + data_joined, HSTACK(data_1, data_2), + _x1, CHOOSECOLS(data_joined, 1), + _y1, CHOOSECOLS(data_joined, 2), + _x2, CHOOSECOLS(data_joined, 3), + _y2, CHOOSECOLS(data_joined, 4), + first_condition, (yp < _y1) <> (yp < _y2), + second_condition, xp < + (_x1 + (((yp - _y1) / (_y2 - _y1)) * (_x2 - _x1))), + final_condition, IFERROR( + (first_condition * second_condition) = 1, + FALSE + ), + is_inside, MOD(SUM(INT(final_condition)), 2) = 1, + is_inside + ) +); + +// GEOMETRY_IS_POINT_IN_POLYGON ---> GEOMETRY_ARE_POINTS_IN_POLYGON +GEOMETRY_ARE_POINTS_IN_POLYGON = LAMBDA(data_points, polygon_points, + BYROW( + data_points, + LAMBDA(row, GEOMETRY_IS_POINT_IN_POLYGON(row, polygon_points)) + ) +); diff --git a/_feidmath/feidmath_INTERPOLATION.sc b/_feidmath/feidmath_INTERPOLATION.sc new file mode 100644 index 0000000..2ef8220 --- /dev/null +++ b/_feidmath/feidmath_INTERPOLATION.sc @@ -0,0 +1,40 @@ +// NONE ---> _INTERPOLATION_LINEAR +_INTERPOLATION_LINEAR = LAMBDA(x, known_ys, known_xs, + LET( + known_xs, TOCOL(known_xs), + known_ys, TOCOL(known_ys), + nrow, ROWS(known_ys), + known_table, HSTACK(known_xs, known_ys), + sorted_table, SORT(known_table, 1), + sorted_xs, CHOOSECOLS(sorted_table, 1), + sorted_ys, CHOOSECOLS(sorted_table, 2), + nearest_x, IFS( + x > MAX(sorted_xs), + XMATCH(x, sorted_xs, -1), + x < MIN(sorted_xs), + XMATCH(x, sorted_xs, 1), + TRUE, + XMATCH(x, sorted_xs, -1) + ), + index_ys, IF( + nearest_x < nrow, + VSTACK(nearest_x, nearest_x + 1), + VSTACK(nearest_x - 1, nearest_x) + ), + select_ys, CHOOSEROWS(sorted_ys, index_ys), + select_xs, CHOOSEROWS(sorted_xs, index_ys), + FORECAST.LINEAR(x, select_ys, select_xs) + ) +); + +// _INTERPOLATION_LINEAR ---> INTERPOLATION_LINEAR +INTERPOLATION_LINEAR = LAMBDA(x_vector, known_ys, known_xs, + LET( + x_vector, TOCOL(x_vector), + y_vector, BYROW( + x_vector, + LAMBDA(x, _INTERPOLATION_LINEAR(x, known_ys, known_xs)) + ), + y_vector + ) +); diff --git a/_feidmath/feidmath_LINALG.sc b/_feidmath/feidmath_LINALG.sc new file mode 100644 index 0000000..7c7d532 --- /dev/null +++ b/_feidmath/feidmath_LINALG.sc @@ -0,0 +1,135 @@ +// NONE ---> LINALG_ROTATION_MATRIX +LINALG_ROTATION_MATRIX = LAMBDA(theta_x, theta_y, theta_z, [num_digits], + LET( + round_number, IF(ISOMITTED(num_digits), 0, num_digits), + angle_x, RADIANS(theta_x), + angle_y, RADIANS(theta_y), + angle_z, RADIANS(theta_z), + cos_x, COS(angle_x), + sin_x, SIN(angle_x), + rotation_x, VSTACK( + HSTACK(1, 0, 0), + HSTACK(0, cos_x, -sin_x), + HSTACK(0, sin_x, cos_x) + ), + cos_y, COS(angle_y), + sin_y, SIN(angle_y), + rotation_y, VSTACK( + HSTACK(cos_y, 0, sin_y), + HSTACK(0, 1, 0), + HSTACK(-sin_y, 0, cos_y) + ), + cos_z, COS(angle_z), + sin_z, SIN(angle_z), + rotation_z, VSTACK( + HSTACK(cos_z, -sin_z, 0), + HSTACK(sin_z, cos_z, 0), + HSTACK(0, 0, 1) + ), + rotation_matrix, MMULT(rotation_z, MMULT(rotation_y, rotation_x)), + IF( + round_number, + ROUND(rotation_matrix, round_number), + rotation_matrix + ) + ) +); + +// LINALG_ROTATION_MATRIX ---> LINALG_ROTATE_POINT +LINALG_ROTATE_POINT = LAMBDA( + point_vector, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + LET( + active_rotation, IF( + ISOMITTED(active_rotation), + TRUE, + active_rotation + ), + rotation_matrix, LINALG_ROTATION_MATRIX( + theta_x, + theta_y, + theta_z, + num_digits + ), + point_vector, TOCOL(point_vector), + final_rotation, IF( + active_rotation, + rotation_matrix, + TRANSPOSE(rotation_matrix) + ), + point_rotation, MMULT(final_rotation, point_vector), + TOROW(point_rotation) + ) +); + +// LINALG_ROTATE_POINT ---> _RECURSIVE_ROTATE_POINTS +// _RECURSIVE_ROTATE_POINTS ---> _RECURSIVE_ROTATE_POINTS +_RECURSIVE_ROTATE_POINTS = LAMBDA( + ntry, + data_points, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + LET( + selected_row, CHOOSEROWS(data_points, ntry), + IF( + ntry = 1, + LINALG_ROTATE_POINT( + selected_row, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + LET( + next_try, ntry - 1, + result, LINALG_ROTATE_POINT( + selected_row, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + VSTACK( + _RECURSIVE_ROTATE_POINTS( + next_try, + data_points, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ), + result + ) + ) + ) + ) +); + +// _RECURSIVE_ROTATE_POINTS ---> LINALG_ROTATE_POINT_ARRAY +LINALG_ROTATE_POINT_ARRAY = LAMBDA( + data_points, + theta_x, + theta_y, + theta_z, + [active_rotation], + [num_digits], + _RECURSIVE_ROTATE_POINTS( + ROWS(data_points), + data_points, + theta_x, + theta_y, + theta_z, + active_rotation, + num_digits + ) +); diff --git a/_quarto.yml b/_quarto.yml index 23985a0..fd10db8 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -42,11 +42,17 @@ website: - text: feidlambda menu: - href: release/source-code.qmd + - href: release/feidlambda-0-4.qmd - href: release/feidlambda-0-3.qmd - href: release/feidlambda-0-2-0.qmd - href: release/feidlambda-0-1-0.qmd + - text: feid* + menu: + - href: release/feidmath-0-1.qmd - text: Dokumentasi menu: + - text: LAMBDA Stlye Guide + href: docs/lambda-style-guide.qmd - href: docs/install.qmd - href: docs/glossary.qmd - text: Artikel diff --git a/docs/docs-style.css b/docs/docs-style.css new file mode 100644 index 0000000..67470c9 --- /dev/null +++ b/docs/docs-style.css @@ -0,0 +1,5 @@ +section[id^="sec-"] img { + border-radius: 1%; + border: 1px solid; + box-shadow: 2px 2px 4px #888888; +} diff --git a/docs/img-install/install-01.png b/docs/img-install/install-01.png new file mode 100644 index 0000000..2875dd1 Binary files /dev/null and b/docs/img-install/install-01.png differ diff --git a/docs/img-install/install-02.png b/docs/img-install/install-02.png new file mode 100644 index 0000000..2bc6a18 Binary files /dev/null and b/docs/img-install/install-02.png differ diff --git a/docs/img-install/install-03.png b/docs/img-install/install-03.png new file mode 100644 index 0000000..ad210a5 Binary files /dev/null and b/docs/img-install/install-03.png differ diff --git a/docs/install-afe.qmd b/docs/install-afe.qmd new file mode 100644 index 0000000..1527882 --- /dev/null +++ b/docs/install-afe.qmd @@ -0,0 +1,64 @@ +--- +title: | + Instalasi feidlambda +subtitle: | + Panduan pemasangan `feidlambda` v0.3+ (AFE v1.1) +author: Taruma Sakti Megariansyah +date: 2022-10-20 +date-modified: 2023-01-06 +date-format: full +lang: id + +toc: true +toc-location: right +number-sections: true +link-external-newwindow: true +layout: article +sidebar: side-docs + +--- + +Panduan ini untuk __Advanced Formula Environment__ v1.1. + +## **Advanced Formula Environment** + +_Install_ add-ins **Advanced Formula Environment** dari menu `Insert` > `Get Add-ins` > Cari **Advanced Formula Environment** (AFE). + +::: {.column-page} +![Menambahkan **Advanced Formula Environment** _Add-ins_](https://user-images.githubusercontent.com/1007910/192432581-0fd50e59-b0d0-4d9a-b802-81fda91060cb.png) +::: + +## _Import_ menggunakan AFE + +Setelah AFE terpasang di Microsoft Excel, lakukan _import_ dengan membuka AFE melalui `Formula` > `Advanced Formula Environment` > `Import`. + +::: {.column-page} +![Melakukan _import_ di AFE](https://user-images.githubusercontent.com/1007910/210946239-4c14ea78-eb85-42b3-a2f6-976e3f6b2704.png) + +::: + +## Salin _Github Gist URL_ + +Isi "Github Gist URL" dengan link koleksi lambda yang tersedia. _Checklist_ ✅ bagian "_Add formulas to new module_" dan isi nama _module_ dengan nama koleksi (contoh: `feid`). + +![Isi _GitHub Gist URL_ dan nama _module_](https://user-images.githubusercontent.com/1007910/210946750-5b2563aa-3e23-4147-8771-d7ab7a40a5e4.png) + +## _Save_ / _Sync_ module + +Setelah _import_ seluruh koleksi yang digunakan dan berhasil, lakukan _saving_ (_sync_) yang bertujuan untuk menerapkan module ke lembar kerja Excel. Shortcut untuk _save_ yaitu `Ctrl + S`. + +![_Save_ / _Apply module_ ke lembar kerja](https://user-images.githubusercontent.com/1007910/210946979-d64c1d4a-b61b-4ab1-ab7b-b2d2c6ae4e1c.png) + +## Gunakan koleksi lambda + +Selesai _save_, fungsi **feidlambda** bisa langsung digunakan. + +::: {.column-page} +![Gunakan koleksi lambda yang telah di-_import_](https://user-images.githubusercontent.com/1007910/210947524-d4a8bce7-d33d-47b4-8a72-6cf5244c9651.png) +::: + +## Baca dokumentasi **feidlambda** + +Dokumentasi feidlambda versi terbaru (v0.4) bisa baca di halaman [feidlambda (latest)](/release/latest.html). API atau struktur LAMBDA sudah dibuat konsisten sejak versi v0.3+. Panduan migrasi dari v0.2 ke v0.3 bisa baca di halaman [Migrasi feidlambda v0.2 ke v0.3](/article/migration-v0-2-to-v0-3.qmd). + +Jangan lupa juga untuk membaca [Daftar istilah](/docs/glossary.qmd) yang digunakan dalam pada dokumentasi dan pengembangan feidlambda. \ No newline at end of file diff --git a/docs/install.qmd b/docs/install.qmd index cec9929..5207b05 100644 --- a/docs/install.qmd +++ b/docs/install.qmd @@ -1,11 +1,11 @@ --- title: | - Instalasi feidlambda + Instalasi koleksi feidlambda subtitle: | - Panduan pemasangan `feidlambda` v0.3+ + Panduan pemasangan koleksi feidlambda menggunakan Excel Labs: Advanced Formula Environment. author: Taruma Sakti Megariansyah date: 2022-10-20 -date-modified: 2023-01-06 +date-modified: 2023-05-26 date-format: full lang: id @@ -19,44 +19,65 @@ sidebar: side-docs aliases: - penggunaan.html +format: + html: + css: docs-style.css + --- -Panduan ini untuk __Advanced Formula Environment__ v1.1. +::: {.callout-important} -## **Advanced Formula Environment** +Sejak April 2023, add-ins Advanced Formula Environment menjadi bagian fitur dari add-ins Excel Labs. Excel Labs sendiri adalah add-ins yang menyediakan fitur eksperimental oleh tim Microsoft Excel. -_Install_ add-ins **Advanced Formula Environment** dari menu `Insert` > `Get Add-ins` > Cari **Advanced Formula Environment** (AFE). +::: -::: {.column-page} -![Menambahkan **Advanced Formula Environment** _Add-ins_](https://user-images.githubusercontent.com/1007910/192432581-0fd50e59-b0d0-4d9a-b802-81fda91060cb.png) +Panduan ini untuk instalasi dan penggunaan __Excel Labs: Advanced Formula Environment__. + +## **Excel Labs** {#sec-excel-labs} + +[**Excel Labs**](https://appsource.microsoft.com/en-us/product/office/WA200003696?exp=ubp8&tab=Overview) merupakan add-ins berisikan fitur eksperimental oleh tim Microsoft Excel. Pada add-ins ini tersedia _Advanced Formula Environment_ untuk memudahkan pengembangan dan penggunaan fungsi LAMBDA atau manipulasi formula di dalam Microsoft Excel. Add-ins tersebut wajib dipasang untuk dapat menggunakan koleksi feidlambda. Fitur LABS.GENERATIVEAI, saat ini tidak digunakan dalam penggunaan feidlambda. + +- _Install_ add-ins **Excel Labs** dari menu `Insert` > `Get Add-ins` > Cari **Excel Labs** (AFE). + +::: {.column-body} +![Menambahkan **Excel Labs** _Add-ins_](img-install/install-01.png) ::: -## _Import_ menggunakan AFE +## **Advanced Formula Environment** {#sec-afe} -Setelah AFE terpasang di Microsoft Excel, lakukan _import_ dengan membuka AFE melalui `Formula` > `Advanced Formula Environment` > `Import`. +Advanced Formula Environment (AFE) adalah add-in untuk Excel yang memungkinkan Anda melihat, memformat dan mengedit rumus atau fungsi Excel. Sejak April 2023, add-in Advanced Formula Environment tergabung dalam satu add-ins bernama Excel Labs. -::: {.column-page} -![Melakukan _import_ di AFE](https://user-images.githubusercontent.com/1007910/210946239-4c14ea78-eb85-42b3-a2f6-976e3f6b2704.png) +- Untuk memulai penggunaan AFE, buka Excel Labs melalui menu ribbon `Home` > `Excel Labs`. +- Pada _feature gallery_, terdapat ada dua fitur yaitu _Advanced Formula Environment_ dan _`LABS.GENERATIVEAI` function_. +- Centang _"Remember this choice"_ kemudian buka AFE dengan mengklik _"Open"_ disamping tulisan AFE. +::: {.column-body} +![Membuka **Advanced Formula Environment (AFE)**](img-install/install-02.png) ::: -## Salin _Github Gist URL_ +_Feature gallery_ bisa dibuka melalui menu burger dan memilih _feature gallery_. + +## _Import_ menggunakan AFE {#sec-import-afe} + +Setelah AFE terpasang di Microsoft Excel, lakukan _import_ dengan membuka AFE melalui `Home` > `Excel Labs` > (AFE) > `Modules` > `Import`. + +::: {.column-body} +![Melakukan _import_ di AFE](img-install/install-03.png) +::: -Isi "Github Gist URL" dengan link koleksi lambda yang tersedia. _Checklist_ ✅ bagian "_Add formulas to new module_" dan isi nama _module_ dengan nama koleksi (contoh: `feid`). Berikut link feidlambda v0.3.x: +## Salin _Github Gist URL_ {#sec-copy-to-gist} -```default -https://gist.github.com/taruma/92bd33600a3d42dc9aead87558404a12 -``` +Isi "Github Gist URL" dengan link koleksi lambda yang tersedia. _Checklist_ ✅ bagian "_Add formulas to new module_" dan isi nama _module_ dengan nama koleksi (contoh: `feid`). ![Isi _GitHub Gist URL_ dan nama _module_](https://user-images.githubusercontent.com/1007910/210946750-5b2563aa-3e23-4147-8771-d7ab7a40a5e4.png) -## _Save_ / _Sync_ module +## _Save_ / _Sync_ module {#sec-sync} Setelah _import_ seluruh koleksi yang digunakan dan berhasil, lakukan _saving_ (_sync_) yang bertujuan untuk menerapkan module ke lembar kerja Excel. Shortcut untuk _save_ yaitu `Ctrl + S`. ![_Save_ / _Apply module_ ke lembar kerja](https://user-images.githubusercontent.com/1007910/210946979-d64c1d4a-b61b-4ab1-ab7b-b2d2c6ae4e1c.png) -## Gunakan koleksi lambda +## Gunakan koleksi lambda {#sec-using} Selesai _save_, fungsi **feidlambda** bisa langsung digunakan. @@ -64,8 +85,8 @@ Selesai _save_, fungsi **feidlambda** bisa langsung digunakan. ![Gunakan koleksi lambda yang telah di-_import_](https://user-images.githubusercontent.com/1007910/210947524-d4a8bce7-d33d-47b4-8a72-6cf5244c9651.png) ::: -## Baca dokumentasi **feidlambda** v0.3 +## Baca dokumentasi **feidlambda** -Dokumentasi feidlambda v0.3 bisa baca di halaman [feidlambda v0.3](/release/feidlambda-0-3.qmd). Dan panduan migrasi bisa baca di halaman [Migrasi feidlambda v0.2 ke v0.3](/article/migration-v0-2-to-v0-3.qmd). +Dokumentasi feidlambda versi terbaru (v0.4) bisa baca di halaman [feidlambda (latest)](/release/latest.html). API atau struktur LAMBDA sudah dibuat konsisten sejak versi v0.3+. Panduan migrasi dari v0.2 ke v0.3 bisa baca di halaman [Migrasi feidlambda v0.2 ke v0.3](/article/migration-v0-2-to-v0-3.qmd). -Jangan lupa juga untuk membaca [Daftar istilah](/docs/glossary.qmd) yang digunakan dalam pada dokumentasi dan pengembangan feidlambda. \ No newline at end of file +Jangan lupa juga untuk membaca [daftar istilah](/docs/glossary.qmd) yang digunakan dalam pada dokumentasi dan pengembangan feidlambda. \ No newline at end of file diff --git a/docs/lambda-style-guide.qmd b/docs/lambda-style-guide.qmd new file mode 100644 index 0000000..f7c5420 --- /dev/null +++ b/docs/lambda-style-guide.qmd @@ -0,0 +1,585 @@ +--- +title: | + FIAKO LAMBDA Style Guide v1.0 +subtitle: | + Panduan penulisan fungsi LAMBDA di Microsoft Excel yang digunakan oleh FIAKO Engineering. +author: Taruma Sakti Megariansyah +abstract: | + Panduan ini mencakup berbagai prinsip penulisan, desain dan praktik terbaik untuk membuat dan mengolah fungsi LAMBDA di Microsoft Excel. +abstract-title: Abstrak +date: 2023-05-26 +# date-modified: 2023-01-06 +lang: id + +toc: true +toc-title: Daftar Isi +toc-expand: 3 +toc-location: right +number-sections: false +link-external-newwindow: true +layout: article +sidebar: false +fig-responsive: true +css: lambda-style.css +aliases: + - latest-FLSG.html + - lambda-style-guide-v1.html +--- + +::: {.callout-note} + +Panduan ini dibuat dengan bantuan chatGPT (GPT-4) dengan penyesuaian oleh penulis. + +::: + +# 📖 FIAKO LAMBDA Style Guide (FSG-LAMBDA) {#sec-introduction} + +**FIAKO LAMBDA Style Guide** (FLSG / FSG-LAMBDA) adalah panduan penulisan fungsi LAMBDA untuk Microsoft Excel yang digunakan di FIAKO Engineering. Panduan ini dirancang untuk memberikan kerangka kerja yang konsisten dan mudah dipahami dalam mengembangkan, mengoptimalkan, dan memelihara fungsi LAMBDA yang efisien dan mudah dibaca. Panduan ini mencakup berbagai aspek, mulai dari format, konvensi penamaan, penanganan argumen, penanganan kesalahan, hingga tips keterbacaan dan kinerja fungsi LAMBDA. + +Adapun manfaat mengembangkan fungsi LAMBDA di Microsoft Excel yaitu: + +- **Fleksibilitas**: Fungsi LAMBDA memungkinkan pengguna untuk membuat fungsi kustom yang dapat diadaptasi sesuai kebutuhan spesifik dan digunakan berulang kali dalam berbagai situasi. +- **Pengurangan kompleksitas**: Dengan menggunakan fungsi LAMBDA, pengguna dapat menggabungkan beberapa fungsi yang ada menjadi satu fungsi yang lebih sederhana, sehingga memudahkan pembacaan dan pemahaman fungsi yang digunakan di dalam Microsoft Excel. +- **Pemeliharaan yang lebih mudah**: Fungsi LAMBDA yang ditulis dengan baik memudahkan pemeliharaan dan pengembangan lebih lanjut, karena struktur yang jelas dan konvensi penamaan yang konsisten. +- **Penggunaan berulang**: Fungsi LAMBDA yang dibuat dapat digunakan kembali di seluruh workbook atau bahkan di workbook lain, yang meningkatkan efisiensi dalam mengembangkan solusi Excel yang canggih. +- **Kolaborasi dan berbagi**: Memudahkan pengguna untuk berbagi fungsi kustom dengan rekan kerja atau komunitas pengguna Excel, sehingga mengurangi pengulangaan pekerjaan yang sama dan meningkatkan kolaborasi. + +Panduan ini disusun untuk membantu pengguna menguasai berbagai aspek penulisan fungsi LAMBDA yang efektif. + +# 📚 Prasyarat {#sec-requirements} + +Sebelum mulai mengembangkan fungsi LAMBDA dan menggunakan panduan ini, terdapat yang harus dipersiapkan yaitu dari perangkat yang digunakan dan pengetahuan yang dibutuhkan. + +## 💻 Perangkat {#sec-rec-device} + +Dalam mengembangkan fungsi LAMBDA dan mengikuti panduan ini berikut daftar perangkat dan _add-ins_ yang digunakan dalam pengembangan LAMBDA: + +- **Microsoft Excel 365**: Pastikan menggunakan **Microsoft Excel 365**, karena saat ini, fungsi LAMBDA hanya tersedia di Microsoft Excel 365. +- **Excel Labs** _add-ins_: Fitur _Advanced Formula Environment_ yang tersedia di _add-ins_ ini direkomendasikan sebagai standar editor untuk pengembangan fungsi LAMBDA. Untuk panduan instalasi, silakan lihat [panduan instalasi](install.qmd). + +Fungsi LAMBDA dan beberapa fungsi _dynamic array_ terbaru lainnya juga tersedia di Microsoft Excel for Web. Oleh karena itu, jika Anda belum berlangganan, Anda dapat bereksperimen dengan fungsi LAMBDA melalui Microsoft Excel for Web. + +## 🧠 Pengetahuan {#sec-rec-knowledge} + +Fungsi LAMBDA dapat diterapkan oleh pengguna Microsoft Excel dengan berbagai tingkat keahlian, mulai dari pemula hingga mahir. Tingkat pengetahuan yang dibutuhkan dalam pengembangan fungsi LAMBDA di Microsoft Excel tergantung pada kompleksitas fungsi yang akan dikembangkan. Berikut ini adalah pengetahuan atau pemahaman yang diperlukan untuk memahami fungsi LAMBDA dan menerapkan FIAKO LAMBDA Style Guide: + +- **Pemahaman dasar tentang Microsoft Excel**: Pastikan memahami cara menggunakan sel, baris, kolom, serta mengedit rumus. Anda bisa belajar lebih lanjut di [Excel untuk Pemula](https://support.microsoft.com/id-id/office/excel-for-beginners-9bc05390-e94c-46af-a5b3-d7c22f6990bb). +- **Dasar-dasar bahasa pemrograman**: Kuasai konsep dasar pemrograman seperti variabel, fungsi, dan logika bersyarat. Pelajari lebih lanjut di [Pemrograman Dasar](https://www.codecademy.com/learn/learn-how-to-code). +- **Fungsi Excel yang umum**: Kembangkan kemampuan untuk menggunakan dan memahami fungsi Excel seperti SUM, AVERAGE, VLOOKUP, IF, AND, OR, INDEX, dan MATCH. Lihat [Fungsi Excel yang Harus Diketahui](https://exceljet.net/articles/101-excel-functions). +- **Dasar-dasar penanganan kesalahan dalam Excel**: Pahami cara menggunakan fungsi IFERROR dan IFNA untuk mengatasi kesalahan. Pelajari lebih lanjut di [Penanganan Kesalahan di Excel](https://www.excel-easy.com/examples/iferror.html). +- **Fungsi LAMBDA**: Mengerti tujuan dan cara kerja fungsi LAMBDA dalam menciptakan fungsi kustom di Microsoft Excel. Baca lebih lanjut di [Pengantar Fungsi LAMBDA](https://support.microsoft.com/en-us/office/lambda-function-bd212d27-1cd1-4321-a34a-ccbf254b8b67). +- **Pengetahuan tentang Dynamic Array di Microsoft Excel**: Kuasai konsep dan cara kerja fitur Dynamic Array dalam mengolah data berbentuk array. Informasi lebih lanjut dapat ditemukan di [Perilaku _Dynamic Arrays_ dan _spilled array_](https://support.microsoft.com/en-us/office/dynamic-array-formulas-and-spilled-array-behavior-205c6b06-03ba-4151-89a1-87a7eb36e531). + +Dengan memenuhi prasyarat di atas, diharapkan untuk lebih siap untuk menggunakan fungsi LAMBDA dan memahami panduan ini secara efisien dan efektif. Pastikan untuk menggunakan alat yang sesuai dan menguasai pengetahuan yang dibutuhkan guna mengoptimalkan proses pengembangan fungsi LAMBDA dan penerapan panduan ini. + +## 🧩 _Advanced Formula Environment_ (_Add-ins_ **Excel Lab**) {#sec-rec-adv-formula-env} + +Dalam panduan ini, disarankan untuk menggunakan _Advanced Formula Environment_ (AFE) dari Excel Labs sebagai editor saat mengembangkan fungsi LAMBDA. AFE sangat membantu pengguna dalam mengembangkan dan mengelola fungsi LAMBDA. Berikut beberapa fitur unggulan AFE^[Berdasarkan informasi yang tertera di [halaman GitHub AFE](https://github.com/microsoft/advanced-formula-environment)]: + +- Melihat, memformat, dan mengedit rumus yang telah didefinisikan dalam kisi dengan bilah rumus yang lebih canggih. +- Mendefinisikan dan mengedit fungsi yang diberi nama, rentang, dan rumus yang dapat disinkronkan dengan Manajer Nama. +- Membuat koleksi fungsi yang diberi nama, disebut modul, yang didefinisikan sebagai kode dan disimpan sebagai bagian dari Buku Kerja. +- Mengimpor modul LAMBDA secara cepat langsung dari GitHub Gist. + +AFE juga mendukung fitur-fitur tambahan seperti _autocomplete_, _refactoring_, _formatting_, dan lainnya, yang akan memudahkan Anda dalam proses pengembangan fungsi LAMBDA. Pastikan Anda menggunakan AFE untuk meningkatkan efisiensi dan kenyamanan saat mengikuti panduan ini. + +Dalam menggunakan fungsi LAMBDA, langkah yang umum digunakan adalah menuliskan fungsi LAMBDA pada Formula Name Manager. Akan tetapi, untuk panduan ini pengembangan fungsi LAMBDA akan menggunakan AFE. Semenjak AFE v1.1+, fungsi LAMBDA disimpan dalam dokumen excel dan muncul di Formula Name Manager ketika dilakukan sinkronisasi. Hanya saja, sifatnya satu arah, yaitu fungsi LAMBDA yang ditulis di AFE akan tersimpan juga pada Formula Name Manager, tapi tidak sebaliknya. Jadi fungsi LAMBDA yang dikembangkan secara manual di Formula Name Manager tidak akan muncul di AFE. + +Pada umumnya pada tutorial formula lambda ditulis sebagai berikut: + +```scala +=LAMBDA(x, y, z, x+y+z) +``` + +kemudian formula tersebut disimpan dalam Formula Name Manager dengan namanya, misalkan fungsi `JUMLAH`. Akan tetapi, dengan menggunakan AFE sebagai editor, dalam panduan ini penulisannya sebagai berikut: + +```scala +JUMLAH = =LAMBDA(x, y, z, x+y+z); +``` + +Sehingga, kode yang terlampir dalam panduan ini adalah potongan kode yang cocok disalin ke editor AFE (Excel Labs). + +# 📐 Format dan Organisasi {#sec-format} + +Mengatur kode dengan baik sangat penting untuk memastikan mudah dibaca dan dipahami. Untuk melakukan formatting, dapat dilakukan secara otomatis di AFE dengan menggunakan perintah `Format` (`Ctrl + Shift + F`). Akan tetapi berikut beberapa aspek yang dapat diperhatikan dalam Format dan Organisasi pada fungsi LAMBDA jika tidak menggunakan _autoformatting_: + +## ➡️ Indentasi {#sec-format-indentation} + +Menggunakan indentasi yang konsisten akan membantu meningkatkan keterbacaan kode. Gunakan 4 spasi untuk indentasi. Indentasi otomatis dengan AFE akan menyesuaikan dengan lebar layar editor (disarankan maksimal 77 karakter). Gunakan potongan komentar kode dibawah ini sebagai indikator lebar layar editor maksimum. + +```scala +// BATAS MAKSMIMUM LAYAR EDITOR -------------------------------------------# +``` + +## ↩️ Pemisahan Baris {#sec-format-line-break} + +Menggunakan pemisahan baris yang konsisten akan membantu memisahkan bagian kode yang berbeda dan memudahkan pemahaman. + +Contoh indentasi dan pemisahan baris yang baik: + +```scala +MY_FUNCTION = LAMBDA(x, y, // variabel input + IF( /* operasi dimulai di baris baru */ + x > y, + "X lebih besar", + IF(x < y, "Y lebih besar", "X dan Y sama") + ) +); +``` + +## 📏 Spasi untuk Kejelasan {#sec-format-spacing} + +Menggunakan spasi secara konsisten dalam kode LAMBDA akan membantu meningkatkan keterbacaan dan memudahkan pemahaman struktur kode. Pertimbangkan untuk menambahkan spasi di sekitar operator, seperti tanda kurung, koma, dan operator matematika: + +Contoh penggunaan spasi yang baik: + +```scala +MY_FUNCTION = LAMBDA(a, b, c, IF(a > b, a, IF(b > c, b, c))); +``` + +## 💬 Komentar dan Catatan {#sec-format-comments} + +Menambahkan komentar atau catatan di sekitar kode LAMBDA dapat membantu menjelaskan logika atau maksud di balik kode tersebut. Meskipun Excel tidak mendukung komentar langsung dalam rumus, Anda dapat menggunakan komentar pada editor AFE dengan `// komentar` (satu baris) atau `/* komentar */` (lebih dari satu baris). + +## ⏭️ Urutan Operasi {#sec-format-operation-order} + +Urutan operasi sangat penting untuk memastikan hasil yang benar dari kode LAMBDA. Oleh karena itu, selalu pastikan urutan operasi dalam kode Anda jelas dan mudah dipahami. Jika perlu, gunakan tanda kurung untuk mengklarifikasi prioritas operasi. + +Contoh urutan operasi yang baik: + +```scala +MY_FUNCTION = LAMBDA(x, y, (x + y) * (x - y)); +``` + +Dengan memperhatikan aspek-aspek ini dalam bagian Format dan Organisasi, panduan gaya fungsi LAMBDA akan membantu pengguna menciptakan kode yang lebih rapi, konsisten, dan mudah dipahami. Selalu pastikan untuk mengikuti panduan ini dengan konsisten sepanjang kode Anda agar hasilnya optimal. + +# 🏷️ Konvensi Penamaan {#sec-naming-convention} + +Saat mengembangkan fungsi LAMBDA di Microsoft Excel, penting untuk mengikuti konvensi penamaan yang konsisten. Konvensi penamaan yang baik membantu meningkatkan keterbacaan dan pemahaman kode oleh pengembang lain, termasuk diri sendiri di masa depan. Dengan mengikuti konvensi penamaan yang baik, kode akan lebih mudah dipelajari, dipahami, dan dipelihara oleh orang lain. Sebagai catatan, nama variabel ataupun fungsi di Excel bersifat **_case-insensitive_**, yang artinya huruf besar dan kecil merujuk ke hal yang sama. Berikut adalah beberapa pedoman untuk konvensi penamaan dalam fungsi LAMBDA di Excel. + +## 🆔 Penamaan Variabel {#sec-naming-variables} + +1. Gunakan huruf kecil: Saat menamai variabel dalam fungsi LAMBDA, gunakan huruf kecil untuk mengindikasikan bahwa itu adalah variabel. Terlepas sifat _case-insenstive_, disarankan untuk membedakan antara nama variabel (huruf kecil) dan nama fungsi (huruf besar) Contoh: + + ```scala + MY_FUNCTION = LAMBDA(x, y, x+y) + ``` + + Di sini, `x` dan `y` adalah nama variabel yang ditulis dalam huruf kecil. + +2. Gunakan penamaan yang deskriptif: Pilih nama variabel yang mendeskripsikan data yang diwakili oleh variabel tersebut. Ini membantu meningkatkan pemahaman kode. Contoh: + + ```scala + MY_FUNCTION = LAMBDA(item_count, unit_price, item_count * unit_price) + ``` + + Dalam contoh ini, `item_count` dan `unit_price` adalah nama variabel yang menjelaskan data yang digunakan dalam perhitungan. + +3. Hindari menggunakan nama variabel yang diakhiri angka: Hal tersebut untuk menghindari keserupaan dengan nama sel (Tiga karakter yang diikuti angka seperti `C1`, `XY35`, `UDS3213`). Untuk menghindari gunakan nama deskriptif atau menambahkan garis bawah (_underscore_ `_`) sebelum angka. Contoh: + + ```scala + MY_FUNCTION = LAMBDA(x_1, vec_23, x_1 * vec_23) + ``` + + `x_1` dan `vec_23` adalah nama variabel yang tidak bentrok dengan nama sel (`X1`, `VEC23`) karena diberi tambahan garis bawah (`x_1`, `vec_23`). + +## 📋 Penamaan Fungsi {#sec-naming-functions} + +1. Gunakan huruf besar: Saat menamai fungsi LAMBDA, gunakan huruf besar untuk memberikan indikator yang berbeda antara fungsi dan variabel. Contoh: + + ```scala + MY_FUNCTION = LAMBDA(x, y, MAX(x, y)) + ``` + + Di sini, `MY_FUNCTION`, `LAMBDA`, `MAX` adalah nama fungsi, sedangkan `x` dan `y` adalah parameter yang diterima oleh fungsi LAMBDA yang kita definisikan atau dapat disebut variabel. + +2. Gunakan penamaan fungsi yang deskriptif: Pilih nama yang mencerminkan tujuan atau operasi yang dilakukan oleh fungsi tersebut. Nama yang jelas dan deskriptif membantu memahami fungsi saat dilihat atau digunakan di tempat lain. Contoh: + + ```scala + TOTAL_PRICE = LAMBDA(item_count, unit_price, item_count * unit_price) + ``` + + Dalam contoh ini, fungsi `TOTAL_PRICE` menggambarkan total harga dari perhitungan perkalian `item_count` dengan `unit_price`. + +3. Gunakan pemisahan kata dengan garis bawah: Jika nama fungsi terdiri dari beberapa kata, gunakan garis bawah sebagai pemisah di awal setiap kata untuk memisahkannya. Contoh: + + ```scala + CALCULATE_TOTAL_PRICE = LAMBDA(item_count, unit_price, item_count * unit_price) + ``` + + Di sini, `CALCULATE_TOTAL_PRICE` adalah nama fungsi yang terdiri dari beberapa kata, dan mengikuti panduan sebelumnya, semuanya menggunakan huruf besar. + +# 👀 Keterbacaan dan Efisiensi {#sec-readability-efficiency} + +Keterbacaan dan efisiensi adalah dua faktor penting dalam penulisan kode yang baik, termasuk saat menggunakan fungsi LAMBDA di Excel. Keterbacaan merujuk pada sejauh mana kode dapat dipahami dengan mudah oleh orang lain atau oleh penulis sendiri di masa mendatang. Ini melibatkan struktur, penamaan, dan organisasi kode. Sementara itu, efisiensi merujuk pada sejauh mana kode melakukan tugas dengan cepat dan efektif, tanpa penggunaan sumber daya yang berlebihan atau tidak perlu. Dalam konteks fungsi LAMBDA, ini dapat mencakup pemilihan fungsi yang tepat, penggunaan variabel, dan struktur kode. Dalam bagian ini, akan dibahas beberapa prinsip dan teknik untuk meningkatkan keterbacaan dan efisiensi saat menggunakan fungsi LAMBDA. + +## 🔗 Rantai Fungsi {#sec-function-chaining} + +Rantai fungsi dalam LAMBDA memungkinkan penulisan kode yang singkat dan ringkas. Namun, perlu diingat bahwa terlalu banyak fungsi yang dirantai dapat membingungkan. Sebaiknya batasi jumlah fungsi yang dirantai dan pisahkan dengan baris baru jika perlu. + +Contoh berikut menggambarkan rantai fungsi dalam LAMBDA: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, SUM(PRODUCT(x, y), z)); +``` + +Namun, untuk meningkatkan keterbacaan, bisa dipisahkan menjadi: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, + LET( + calcProduct, PRODUCT(x, y), + SUM(calcProduct, z) + ) +) +``` + +## 🛠️ Fungsi Pembantu {#sec-helper-functions} + +Fungsi pembantu adalah cara yang baik untuk memisahkan logika dan membuat kode lebih mudah dibaca. Fungsi pembantu ini bisa melakukan tugas-tugas kecil yang membuat kode utama menjadi lebih bersih dan mudah dipahami. + +Berikut adalah contoh fungsi pembantu dalam LAMBDA: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, + LET( + calcProduct, PRODUCT(x, y), + SUM(calcProduct, z) + ) +) +``` + +## 🟢 Tanda Kurung untuk Kejelasan {#sec-parentheses-for-clarity} + +Tanda kurung dapat meningkatkan keterbacaan dengan memisahkan bagian-bagian fungsi. Namun, hindari penggunaan tanda kurung yang berlebihan karena dapat membuat kode lebih sulit dipahami. + +Contoh berikut menggambarkan penggunaan tanda kurung yang efektif dalam LAMBDA: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, SUM((PRODUCT(x, y)), z)); +``` + +## 🧮 Menjaga fungsi tetap sederhana {#sec-keeping-functions-simple} + +Menggunakan fungsi LAMBDA yang sederhana dan mudah dipahami adalah kunci untuk keterbacaan dan efisiensi. Sebaiknya batasi jumlah fungsi dalam satu baris dan pisahkan tugas-tugas kecil ke dalam fungsi pembantu jika memungkinkan. + +Berikut adalah contoh bagaimana fungsi LAMBDA dapat disederhanakan: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, + LET( + calcProduct, PRODUCT(x, y), + result, SUM(calcProduct, z), + result + ) +); +``` + +## ✏️ Penamaan Variabel {#sec-variable-naming} + +Penamaan variabel yang jelas dan deskriptif dapat membantu meningkatkan keterbacaan kode. Variabel harus diberi nama yang mencerminkan tujuan atau nilai yang mereka simpan. Menggunakan singkatan atau kode yang tidak jelas dapat membuat kode lebih sulit dipahami. + +Contoh berikut menunjukkan penggunaan penamaan variabel yang baik dalam LAMBDA: + +```scala +MY_FUNCTION = LAMBDA(length, width, height, + LET( + volume, PRODUCT(length, width, height), + volume + ) +); +``` + +Dalam contoh ini, variabel `volume` jelas menunjukkan bahwa ia menyimpan nilai volume dari suatu objek. + +## 💭 Penggunaan Komentar {#sec-comment-usage} + +Penggunaan komentar dalam kode dapat membantu meningkatkan keterbacaan, terutama jika kode tersebut kompleks atau membingungkan. Namun, perlu diingat bahwa komentar harus digunakan dengan bijaksana. Komentar yang berlebihan atau tidak jelas bisa justru membuat kode lebih sulit dipahami. + +Penggunaan komentar dapat menggunakan `//` (untuk satu baris) atau `/* KOMENTAR */` (untuk satu blok). Disarankan untuk menghindari komentar di dalam fungsi untuk membuat mudah dibaca. Deskripsi cara kerja atau instruksi lebih lanjut mengenai fungsi bisa ditulis dibagian dokumentasinya. + +Contoh penggunaan komentar: + +```scala +MY_FUNCTION = LAMBDA(length, width, height, + LET( // Digunakan LET untuk memudahkan pembacaan + volume, PRODUCT(length, width, height), + volume + ) +); +``` + +# 📜 Penanganan Argumen {#sec-argument-handling} + +Penanganan argumen merupakan aspek yang sangat krusial dalam penulisan dan penggunaan fungsi LAMBDA di Microsoft Excel. Memahami bagaimana argumen didefinisikan, dipanggil, dan divalidasi tidak hanya mempengaruhi akurasi dan efisiensi fungsi, tetapi juga dapat mencegah berbagai kesalahan yang dapat terjadi. Selain itu, penanganan argumen yang baik dapat meningkatkan keterbacaan dan pemahaman fungsi, membuatnya lebih mudah digunakan dan dikelola. Oleh karena itu, membahas penanganan argumen dalam panduan gaya penulisan fungsi LAMBDA sangat penting untuk membantu pembaca dalam menulis fungsi yang lebih efektif dan efisien. + +## 🔀 Urutan argumen yang konsisten {#sec-argument-order} + +Argumen fungsi LAMBDA di Microsoft Excel harus disusun dengan hati-hati. Urutan argumen berperan penting dalam menentukan hasil fungsi. Setiap argumen dalam fungsi LAMBDA ditulis secara berurutan, dipisahkan oleh tanda koma. + +Sebagai contoh, jika fungsi LAMBDA memiliki tiga argumen: A, B, dan C, maka urutan penulisannya dalam fungsi adalah sebagai berikut: + +```scala +MY_FUNCTION = LAMBDA(A, B, C, ...) +``` + +Urutan argumen ini nantinya akan mempengaruhi cara fungsi tersebut dipanggil. Jika fungsi `MY_FUNCTION` dipanggil dengan tiga nilai, misalnya 1, 2, dan 3, maka nilai-nilai tersebut akan diberikan kepada argumen sesuai dengan urutannya. Dalam hal ini, A akan mendapatkan nilai 1, B mendapatkan nilai 2, dan C mendapatkan nilai 3. + +Fungsi yang bersifat memanipulasi input maka argumen pertamanya merupakan input tersebut. Contoh, fungsi `APPLY_COLUMN` menerapkan fungsi LAMBDA pada kolom tertentu, maka urutan argumen dimulai dari inputnya yaitu _array_, indeks kolom, dan fungsi LAMBDA. Sehingga penulisan argumen fungsi sebagai berikut: + +```scala +APPLY_COLUMN = LAMBDA(array, column_index, LAMBDA_FUNCTION, ...) +``` + +Jika fungsi LAMBDA yang dibuat menyerupai fungsi yang tersedia di Excel, gunakan urutan yang menyerupai fungsi tersebut agar bisa merujuk fungsi utama. Contoh: fungsi `XLOOKUP` memiliki urutan yang dimulai dari `lookup_value`, `lookup_vector`, `return_array`, dst. Maka fungsi buatan `XLOOKUP_EXTENDER` memiliki urutan yang serupa juga dengan fungsi `XLOOKUP`. + +```scala +XLOOKUP_EXTENDER = LAMBDA(lookup_value, lookup_vector, return_array, ...) +``` + +## ➕ Argumen Opsional {#sec-optional-arguments} + +Argumen opsional adalah argumen yang tidak harus disertakan saat memanggil fungsi. Argumen ini biasanya ditandai dengan tanda kurung siku (`[]`). Contoh penulisan argumen opsional dalam fungsi LAMBDA adalah sebagai berikut: + +```scala +MY_FUNCTION = LAMBDA(A, [B], + LET( + B, IF(ISOMITTED(B), 2, B), + A * B + ) +); +``` + +Dalam contoh ini, `MY_FUNCTION` adalah fungsi yang menerima dua argumen: A dan B. Namun, B adalah argumen opsional. Jika B tidak diberikan saat memanggil fungsi, maka B akan dianggap sebagai 2 (lihat fungsi `IF(ISOMITTED(B), 2, B)`). Gunakan fungsi `ISOMITTED()` untuk pengaturan nilai argumen opsional. + +Berikut adalah contoh pemanggilan fungsi `MY_FUNCTION` dengan dan tanpa argumen opsional: + +```scala +MY_FUNCTION(2, 3) // Hasilnya adalah 6, karena 2 * 3 = 6 +MY_FUNCTION(2) // Hasilnya adalah 4, karena B dianggap sebagai 2, sehingga 2 * 2 = 2 +``` + +Dalam contoh ini, perhatikan bahwa pemanggilan fungsi tanpa menyertakan argumen opsional tidak menyebabkan kesalahan. Argumen opsional memberikan fleksibilitas saat memanggil fungsi, tetapi harus digunakan dengan hati-hati untuk menghindari kebingungan. + +# ❗ Penanganan ERROR {#sec-error-handling} + +Penanganan ERROR bisa dikembangkan dalam suatu fungsi LAMBDA menggunakan `IFERROR()` atau `IFNA()`, akan tetapi disarankan untuk menghindari penggunaan fungsi tersebut dengan membuat dokumentasi yang lengkap mengenai tipe argumen/variabel yang dapat diterima oleh fungsi LAMBDA. Penanganan ERROR hanya baik digunakan saat tahap pengembangan dan bukan saat tahap penyebaran (_deployment_). + +# 📝 Dokumentasi {#sec-documentation} + +Dokumentasi adalah bagian krusial dalam setiap kode atau fungsi, termasuk fungsi LAMBDA di Excel. Dokumentasi tidak hanya membantu pengguna lain memahami apa yang dilakukan oleh kode dan bagaimana cara menggunakannya, tetapi juga membantu penulis kode tersebut dalam memahami dan mengingat detail dan logika di balik kode tersebut. + +## 📑 Membuat dokumen atau lembar khusus untuk deskripsi fungsi LAMBDA {#sec-documenting-lambda-functions} + +Setiap fungsi LAMBDA yang dibuat harus memiliki dokumentasi yang rinci dan mudah dipahami. Dokumentasi tersebut sebaiknya ditempatkan dalam dokumen atau lembar khusus yang mudah diakses dan ditemukan. Dokumentasi tersebut harus mencakup detail tentang fungsi tersebut, termasuk: + +- Nama fungsi dan versinya (jika ada) +- Deskripsi singkat tentang apa yang dilakukan oleh fungsi tersebut +- Daftar argumen yang diperlukan oleh fungsi dan deskripsi singkat tentang apa yang dilakukan oleh setiap argumen +- Jenis input/argumen yang digunakan dalam fungsi +- Contoh penggunaan fungsi dan hasil yang dihasilkan +- Setiap perubahan yang telah dibuat pada fungsi dari versi sebelumnya + +## 📄 Kiat untuk membuat deskripsi yang jelas, singkat, dan informatif {#sec-tips-for-clear-descriptions} + +Berikut adalah beberapa kiat untuk membuat deskripsi fungsi LAMBDA yang jelas, singkat, dan informatif: + +- **Gunakan bahasa yang mudah dipahami:** Hindari jargon dan istilah teknis yang rumit kecuali jika perlu. Tujuannya adalah untuk membuat dokumentasi yang dapat dipahami oleh semua orang, termasuk mereka yang tidak memiliki pengetahuan teknis yang mendalam. +- **Jelaskan apa yang dilakukan oleh fungsi:** Ini adalah bagian yang paling penting dari dokumentasi. Pengguna harus dapat memahami apa yang dilakukan oleh fungsi hanya dengan membaca deskripsi singkatnya. +- **Jelaskan argumen fungsi:** Deskripsikan setiap argumen dan jelaskan perannya dalam fungsi. Jika argumen memiliki nilai default, sebutkan juga nilai tersebut. +- **Berikan contoh penggunaan:** Contoh penggunaan yang konkret dapat membantu pengguna memahami cara kerja fungsi dan bagaimana cara menggunakannya. +- **Jaga dokumentasi tetap up-to-date:** Setiap kali Anda membuat perubahan pada fungsi, pastikan untuk juga memperbarui dokumentasi. + +Berikut adalah contoh dokumentasi kode fungsi `SWAP_COLUMNS` di feidlambda v0.3 yang dapat digunakan untuk menukar posisi kolom ke-`from_index` dengan kolom ke-`to_index`: + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: SWAP_COLUMNS(array, [from_index], [to_index]) + +_Output_ +: _vector_ atau _array_ +::: + +--- + +`array := [row vector | array]` +: Data dapat berupa _array_ atau _row vector_. + +`[from_index] := 1 :: [integer]` +: **_(Change in v0.3.1)_**. Nilai _default_ yaitu `1`. Posisi _index_ kolom yang ingin dipindahkan. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +`[to_index] := -1 :: [integer]` +: **_(Change in v0.3.1)_**. Nilai _default_ yaitu `-1`. Posisi _index_ tujuan kolom. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +::::: + +Contoh penggunaannya dapat berbentuk dalam gambar atau gif. Disarankan untuk menyediakan lembar kerja yang menguji fungsi tersebut. Ingatlah bahwa dokumentasi yang baik adalah investasi. Waktu yang dihabiskan untuk membuat dan merawat dokumentasi akan terbayar ketika orang lain (atau Anda sendiri di masa depan) perlu memahami atau menggunakan fungsi yang telah Anda buat. + +# 🚀 Kinerja dan Skalabilitas {#sec-performance-scalability} + +Mempertimbangkan kinerja dan skalabilitas sangat penting dalam membangun fungsi LAMBDA di Microsoft Excel. Berikut adalah beberapa strategi untuk memastikan fungsi Anda berjalan dengan efisiensi dan dapat menangani peningkatan ukuran data atau kompleksitas tugas. + +## ⏱️ Mengoptimalkan kinerja {#sec-optimizing-performance} + +Optimalisasi kinerja dapat dilakukan dengan menghindari pengulangan yang tidak perlu dan menggunakan fungsi bawaan Excel kapan pun mungkin. Misalnya, fungsi `SEQUENCE` dan `LET` bisa digunakan untuk mengurangi pengulangan dan meningkatkan kinerja. + +```scala +// Menggunakan SEQUENCE dan LET untuk mengurangi pengulangan +SUM_ODD_NUMBERS = LAMBDA(n, + LET( + sequence, SEQUENCE(n), + odd_sequence, IF(MOD(sequence, 2) = 1, sequence, 0), + SUM(odd_sequence) + ) +); +``` + +## 🔠 Menggunakan huruf besar dan huruf kecil yang konsisten {#sec-consistent-case-usage} + +Konsistensi penamaan variabel penting untuk memudahkan pembacaan kode. Ini tidak mempengaruhi kinerja, tetapi penting untuk pemeliharaan dan kolaborasi kode. Rekomendasi penulisan terkait ini antara lain: + +- Huruf besar digunakan untuk fungsi seperti `SEQUENCE()`, `LAMBDA()`. +- Huruf kecil digunakan untuk variabel/nama argumen/parameter seperti `input_number`, `odd_sequence`. + +## 🧪 Menguji fungsi secara menyeluruh {#sec-thorough-function-testing} + +Pengujian fungsi secara menyeluruh penting untuk memastikan kinerja optimal dan menghindari kesalahan. Anda dapat melakukan ini dengan menguji fungsi Anda di berbagai skenario dan ukuran data. + +Misalnya, jika Anda memiliki fungsi `SUM_ODD_NUMBERS`, Anda dapat mengujinya dengan berbagai input, mulai dari 1 sampai 1.000.000, dan memeriksa apakah outputnya sesuai dengan yang diharapkan. + +## 📈 Pertimbangkan skalabilitas {#sec-considering-scalability} + +Fungsi harus dirancang dengan pertimbangan bahwa ukuran data mungkin akan meningkat di masa mendatang. Misalnya, jika fungsi mengambil array sebagai argumen, pastikan bahwa ia dapat menangani array dengan jumlah elemen yang besar. + +```scala +// Fungsi yang dirancang untuk menangani array dengan jumlah elemen yang besar +IS_ALL_IN_VECTOR = LAMBDA(lookup_vector, array, + LET( + lookup_vector, TOCOL(lookup_vector), + MAP(array, LAMBDA(element, OR(BYROW(lookup_vector, LAMBDA(lookup, element = lookup))))) + ) +); +``` + +Oleh karena itu gunakan konsep pengembangan fungsi dengan vektorisasi. Vektorisasi mengacu pada teknik di mana operasi diterapkan pada seluruh array, bukan hanya pada elemen individual, yang dapat secara signifikan meningkatkan kinerja dan efisiensi. Excel mendukung vektorisasi melalui banyak fungsi bawaannya dan kemampuan untuk menerapkan operasi pada seluruh array dalam satu operasi. + +Sebagai contoh, berikut ini adalah perbandingan antara fungsi yang dirancang dengan vektorisasi dan tanpa vektorisasi. Kedua fungsi memiliki tujuan yang sama, yaitu menghitung kuadrat dari setiap angka dalam array. + +```scala +// Tanpa vektorisasi +SQUARE_EACH_NUMBER = LAMBDA(array, + LET( + nrows, ROWS(array), + ncols, COLUMNS(array), + row_sequence, SEQUENCE(nrows), + col_sequence, SEQUENCE(, ncols), + result, IFERROR(INDEX(array, row_sequence, col_sequence)^2, ""), + result + ) +); + +// Dengan vektorisasi +SQUARE_EACH_NUMBER_VECTORIZED = LAMBDA(array, + array^2 +); +``` + +Dalam contoh ini, fungsi `SQUARE_EACH_NUMBER_VECTORIZED` akan jauh lebih cepat dan efisien dibandingkan dengan `SQUARE_EACH_NUMBER`, terutama saat bekerja dengan array yang berukuran besar. + +## 🎁 Memanfaatkan fungsi bawaan {#sec-utilizing-built-in-functions} + +Fungsi bawaan Excel biasanya lebih optimal dan efisien daripada fungsi yang dibuat secara kustom. Oleh karena itu, sebisa mungkin gunakan fungsi bawaan dalam implementasi fungsi LAMBDA Anda. Berikut adalah contoh fungsi untuk interpolasi linear antara dua titik. Satu fungsi tidak menggunakan fungsi bawaan dan satu lagi menggunakan fungsi `FORECAST.LINEAR()` di Excel. + +Tanpa menggunakan fungsi bawaan: + +```scala +// Custom function for linear interpolation +LINEAR_INTERPOLATION_CUSTOM = LAMBDA(x, x1, y1, x2, y2, + y1 + ((x - x1) * (y2 - y1)) / (x2 - x1) +); +``` + +Di sini, `x` adalah nilai yang ingin kita interpolasi, `(x1, y1)` dan `(x2, y2)` adalah dua titik yang diketahui. Fungsi ini menghitung nilai y yang sesuai dengan x berdasarkan garis yang ditarik antara dua titik yang diberikan. + +Sekarang, mari kita buat fungsi yang sama menggunakan fungsi bawaan `FORECAST.LINEAR()`: + +```scala +// Using built-in Excel function for linear interpolation +LINEAR_INTERPOLATION_FORECAST = LAMBDA(x, known_y's, known_x's, + FORECAST.LINEAR(x, known_y's, known_x's) +); +``` + +Di sini, `x` adalah nilai yang ingin kita interpolasi, `known_y's` dan `known_x's` adalah array y dan x yang diketahui. Fungsi `FORECAST.LINEAR()` menghitung, atau meramalkan, nilai y yang sesuai dengan x berdasarkan data x dan y yang diberikan. + +## 💹 Memanfaatkan _dynamic array_ dan fungsinya {#sec-utilizing-dynamic-arrays} + +Rumus array memungkinkan Anda untuk melakukan operasi pada seluruh array atau rentang data sekaligus, bukan pada setiap nilai secara individual. Ini sangat penting dalam mempercepat pengolahan dan analisis data, terutama jika Anda bekerja dengan dataset yang besar. + +Konsep ini sering kali terkait dengan vektorisasi, sebuah teknik di mana operasi diterapkan pada seluruh array, bukan hanya pada elemen individual. Ini dapat secara signifikan meningkatkan kinerja dan efisiensi. + +Ada dua jenis fungsi utama dalam Excel: fungsi scalar dan fungsi dynamic array. Fungsi scalar hanya mengembalikan satu nilai pada waktu tertentu. Di sisi lain, fungsi dynamic array mampu menghasilkan serangkaian nilai (atau array) sebagai output, dan jika ditempatkan di sel top-left, outputnya akan "mengisi" area yang sesuai di sekitar sel tersebut. + +Sebagai contoh, misalkan kita ingin menghitung kuadrat dari setiap angka dalam tabel. Biasanya, kita membuat kolom baru dimana formulanya sebagai berikut `=baris_kolom_angka^2` yang mengisi setiap baris di kolom kuadratnya. Formulasi tersebut dianggap sebagai fungsi scalar karena hanya menghasilkan satu nilai pada setiap baris. Solusinya adalah memanfaatkan _dynamic array_ dimana input fungsi merupakan array. + +```scala +// Fungsi dynamic array +SQUARE_DYNAMIC_ARRAY = LAMBDA(array, + array^2 +); +``` + +Berbeda dengan fungsi scalar, fungsi dynamic array di atas dapat menghitung kuadrat dari setiap angka dalam array sekaligus, karena operasi kuadrat diterapkan pada seluruh array, bukan hanya pada elemen individual. Ini adalah contoh penggunaan vektorisasi dalam rumus array. Secara umum, menggunakan fungsi dynamic array dan memanfaatkan vektorisasi dalam rumus array dapat meningkatkan kinerja dan efisiensi pengolahan data Anda di Excel. + +## 🚫 Menghindari fungsi rekursif atau dependensi yang tidak perlu {#sec-avoiding-recursive-references} + +Fungsi rekursif atau dependensi yang tidak perlu dapat menyebabkan fungsi berjalan lebih lambat dan mengakibatkan kesalahan. Pastikan untuk menghindari ini ketika merancang fungsi Anda. Akan tetapi, jika ingin melakukan _looping_ setiap elemen/baris/kolom di suatu array, bisa memanfaatkan fungsi recursive. Hanya saja, fungsi rekursif ini akan sulit dibaca dibandingkan fungsi LAMBDA yang kompleks. Beberapa kasus dapat memanfaatkan fungsi rekursif, akan tetapi lebih baik untuk menjauhi fungsi yang bersifat rekursif. + +# 🤝 Kolaborasi dan Pemeliharaan {#sec-collaboration-maintenance} + +Kolaborasi dan pemeliharaan adalah bagian penting dari siklus hidup pengembangan fungsi LAMBDA. Ini melibatkan berbagi fungsi dengan rekan kerja, melakukan perbaikan dan peningkatan fungsi, serta menerapkan praktek-praktek terbaik dalam penulisan dan pengaturan kode. Dalam bagian ini, dibahas berbagai aspek penting dalam proses kolaborasi dan pemeliharaan kode. + +## 🔄 Berbagi fungsi LAMBDA dengan rekan kerja {#sec-sharing-lambda-functions} + +Untuk berbagi fungsi LAMBDA dengan rekan kerja, Anda dapat menggunakan fasilitas dalam Microsoft Excel seperti *sharing* dan *co-authoring*. Anda juga dapat menyimpan fungsi dalam workbook yang dapat diakses oleh semua pengguna yang berkolaborasi. Workbook ini kemudian dapat disimpan di tempat yang aman dan mudah diakses seperti SharePoint atau OneDrive. + +Rekomendasi untuk membagikan fungsi LAMBDA yaitu dengan menggunakan GitHub Gist dan AFE. GitHub Gist adalah layanan berbagi potongan kode dan catatan yang disediakan oleh GitHub. Ini memungkinkan pengguna untuk menyimpan, berbagi, dan berkolaborasi pada potongan kode secara mudah. Import fungsi LAMBDA dari GitHub Gist juga sudah [di dukung dengan AFE](install.qmd#sec-import-afe). Paket feidlambda menggunakan GitHub Gist untuk mendistribusikan dan menyebarkan fungsi LAMBDA-nya. + +Jika fungsi LAMBDA berupa formula sederhana dapat langsung menyalinkan formula LAMBDA-nya sebagai nama fungsinya di Formula Name Manager. Dengan format seperti berikut: + +```scala +=LAMBDA(x, y, z, x + y + z) +``` + +Jika rekannya menggunakan AFE, bisa juga langsung mengambil dari editor AFE. Sehingga formatnya sebagai berikut: + +```scala +MY_FUNCTION = LAMBDA(x, y, z, x + y + z); +``` + +Salah satu tantangan dalam menciptakan rangkaian fungsi LAMBDA tanpa memanfaatkan _Advanced Formula Environment_ (AFE) adalah ketiadaan kemampuan untuk memberi tahu nama fungsi tersebut secara eksplisit. Sebagai contoh, penulisan fungsi LAMBDA tanpa AFE akan muncul seperti ini: `=LAMBDA(x, y, z, x + y + z)`. Untuk menggunakan fungsi tersebut, kita harus menyampaikan nama fungsi ini kepada rekan kerja kita secara terpisah. Namun, dengan AFE, kita dapat mendefinisikan nama fungsi secara langsung dalam formula, seperti ini: `MY_FUNCTION = LAMBDA(x, y, z, x + y +z);`. Oleh karena itu, kami sangat menyarankan untuk mulai berkolaborasi dan berbagi fungsi LAMBDA melalui add-ins Excel Labs dengan AFE, demi peningkatan keterbacaan dan produktivitas. + +## 📜 Mengimplementasikan kontrol versi {#sec-implementing-version-control} + +Alat kontrol versi seperti Git bisa digunakan untuk melacak perubahan, memudahkan pemulihan kode saat terjadi kesalahan, dan memantau kontribusi dari anggota tim yang berbeda. Ini juga memfasilitasi peninjauan kode. Oleh karena itu, disarankan dalam pengembangan ataupun penyebaran menggunakan GitHub Gist atau GitHub Repository sehingga dapat melacak setiap perubahan yang terjadi. + +Mendistribusikan koleksi fungsi LAMBDA melalui GitHub Gist/Repository memudahkan pengguna dan pengembang lain dalam meninjau penggunaan kumpulan fungsi LAMBDA tersebut dalam lembar kerja mereka. Penerapan kontrol versi sangat dianjurkan ketika kumpulan fungsi LAMBDA tersebut diharapkan untuk dikembangkan atau ditingkatkan lebih lanjut. + +Sebagai contoh, lihat [github feidlambda](https://github.com/fiakoenjiniring/feidlambda). Repository ini digunakan sebagai tempat utama untuk pengembangan dan pelacakan saat ada penambahan atau perbaikan pada kumpulan fungsi LAMBDA di feidlambda. Setelah versi terbaru dirilis, isi GitHub GIST diperbarui untuk versi minor pada setiap rilis (x.1, x.2, x.3). + +## 📚 Mengelompokkan fungsi yang terkait {#sec-grouping-related-functions} + +Pengelompokan fungsi yang terkait dapat membantu dalam keterbacaan dan pemeliharaan kode. Misalnya, fungsi yang berhubungan dengan manipulasi data dapat dikelompokkan bersama. Contoh pengelompokkan ini dapat dilihat [proyek feidlambda](https://lambda.fiako.engineering) sejak versi v0.3+. Pengelompokkan ini akan memudahkan dan mengisolasi interaksi/hubungan antar fungsi LAMBDA dalam koleksinya. + +Dalam pengelompokkan disarankan untuk menghilangkan ketergantungan/_dependency_ pada fungsi diluar kelompok tersebut. Hal ini untuk memudahkan saat mengevaluasi fungsi dan memudahkan distribusi jika ingin menggunakan koleksi fungsi LAMBDA pada kelompok tertentu saja. Pengelompokkan ini disaranakn mengubah penamaan nama fungsi yang diawali dengan kelompok fungsi LAMBDA-nya seperti `SWAP_*(...)` untuk [kelompok fungsi `SWAP`](/release/feidlambda-0-4.html#sec-swap). + +## 🧩 Modularisasi kode {#sec-code-modularization} + +Modularisasi kode melibatkan pemisahan fungsi atau operasi ke dalam modul-modul yang lebih kecil dan dapat dipertukarkan. Ini membantu dalam keterbacaan, pemeliharaan, dan pengujian kode. + +## ⚖️ Menyeimbangkan kinerja dan keterbacaan {#sec-balancing-performance-readability} + +Ketika mengoptimalkan kode, penting untuk menemukan keseimbangan antara kinerja dan keterbacaan. Kode yang sangat dioptimalkan tetapi sulit dibaca dapat mengakibatkan kesulitan dalam pemeliharaan dan penyebaran kode. + diff --git a/docs/lambda-style.css b/docs/lambda-style.css new file mode 100644 index 0000000..1838af9 --- /dev/null +++ b/docs/lambda-style.css @@ -0,0 +1,4 @@ +h1 { + text-align: center !important; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/index.qmd b/index.qmd index b4d8ebc..0e55ea9 100644 --- a/index.qmd +++ b/index.qmd @@ -27,33 +27,34 @@ anchor-sections: false ::: {.text-center} ---- - [](/docs/install.qmd) -[](/release/feidlambda-0-3.qmd) +[](/release/latest.html) [](/release/source-code.qmd) [](https://gist.github.com/taruma/92bd33600a3d42dc9aead87558404a12) ---- +::: + +::: {.text-center} -### OFFICAL GIST URL (feidlambda v0.3.x) +## OFFICIAL GIST + +### feidlambda v0.4.x ```default -https://gist.github.com/taruma/92bd33600a3d42dc9aead87558404a12 +https://gist.github.com/taruma/b4df638ecb7af48ab63691951481d6b2 ``` -::: +### feidmath v0.1.x -::: {.text-center .callout-tip appearance="minimal"} -## **STATUS PENGEMBANGAN** +```default +https://gist.github.com/taruma/8b0978227dffbee50c3a9d56e31d34f3 +``` --- -**feidlambda v0.3** sudah siap digunakan oleh publik. Dengan catatan masih banyak yang perlu dipelajari, perbaiki, dan dikembangkan sehingga status feidlambda masih bersifat **eksperimental**. - ::: ::: {.text-center .callout-warning appearance="minimal"} -Halaman *greenhorn* untuk sementara tidak tersedia di _navigation bar_. Untuk mengakses presentasi bisa mengunjungi [link ini](/greenhorn/feidlambda-2/presentation.qmd){target="_blank"}. +Halaman *greenhorn* untuk sementara tidak tersedia di _navigation bar_ (akan dialihkan ke [fiako-manual](https://manual.fiako.engineering)). Untuk mengakses presentasi bisa mengunjungi [link ini](/greenhorn/feidlambda-2/presentation.qmd){target="_blank"}. ::: diff --git a/release/excel/RELEASE_feidlambda_v0_4_0.xlsx b/release/excel/RELEASE_feidlambda_v0_4_0.xlsx new file mode 100644 index 0000000..70387c6 Binary files /dev/null and b/release/excel/RELEASE_feidlambda_v0_4_0.xlsx differ diff --git a/release/excel/RELEASE_feidmath_v0_1_0.xlsx b/release/excel/RELEASE_feidmath_v0_1_0.xlsx new file mode 100644 index 0000000..1e7be61 Binary files /dev/null and b/release/excel/RELEASE_feidmath_v0_1_0.xlsx differ diff --git a/release/feidlambda-0-3.qmd b/release/feidlambda-0-3.qmd index 2a945f1..1ce053e 100644 --- a/release/feidlambda-0-3.qmd +++ b/release/feidlambda-0-3.qmd @@ -30,7 +30,6 @@ crossref: aliases: - feidlambda-0-3-0.html - feidlambda-0-3-1.html - - latest.html --- @@ -125,7 +124,7 @@ Fungsi utama kategori `FILTER_*` yaitu `FILTER_DROP_ROWS()`, `FILTER_DROP_COLUMN
_Source Code_ `FILTER_*` -```{.scala include="../_feidlambda/feid_FILTER" } +```{.scala include="../_feidlambda/feid_FILTER.sc" } ```
@@ -254,7 +253,7 @@ Dari @fig-dep-get, diketahui untuk versi v0.3 hanya tersedia fungsi `GET_INDEX_2
_Source Code_ `GET_*` -```{.scala include="../_feidlambda/feid_GET" } +```{.scala include="../_feidlambda/feid_GET.sc" } ```
@@ -319,7 +318,7 @@ Seluruh fungsi yang tersedia di kategori ini akan dijelaskan.
_Source Code_ `IS_*` -```{.scala include="../_feidlambda/feid_IS" } +```{.scala include="../_feidlambda/feid_IS.sc" } ```
@@ -489,7 +488,7 @@ Fungsi utama pada kategori ini adalah `MAKE_SEQUENCE_FROM_VECTOR()`.
_Source Code_ `MAKE_*` -```{.scala include="../_feidlambda/feid_MAKE" } +```{.scala include="../_feidlambda/feid_MAKE.sc" } ```
@@ -550,7 +549,7 @@ Seluruh fungsi yang tersedia di kategori ini akan dijelaskan.
_Source Code_ `REPEAT_*` -```{.scala include="../_feidlambda/feid_REPEAT" } +```{.scala include="../_feidlambda/feid_REPEAT.sc" } ```
@@ -666,7 +665,7 @@ Fungsi utama yang tersedia saat ini hanya `RESHAPE_BY_COLUMNS()`.
_Source Code_ `RESHAPE_*` -```{.scala include="../_feidlambda/feid_RESHAPE" } +```{.scala include="../_feidlambda/feid_RESHAPE.sc" } ```
@@ -723,7 +722,7 @@ Seluruh fungsi yang tersedia di kategori ini akan dijelaskan.
_Source Code_ `ROTATE_*` -```{.scala include="../_feidlambda/feid_ROTATE" } +```{.scala include="../_feidlambda/feid_ROTATE.sc" } ```
@@ -814,7 +813,7 @@ Seluruh fungsi yang tersedia di kategori ini akan dijelaskan.
_Source Code_ `SWAP_*` -```{.scala include="../_feidlambda/feid_SWAP" } +```{.scala include="../_feidlambda/feid_SWAP.sc" } ```
@@ -901,7 +900,7 @@ Seluruh fungsi yang tersedia di kategori ini akan dijelaskan.
_Source Code_ `TEXT_*` -```{.scala include="../_feidlambda/feid_TEXT" } +```{.scala include="../_feidlambda/feid_TEXT.sc" } ```
diff --git a/release/feidlambda-0-4.qmd b/release/feidlambda-0-4.qmd new file mode 100644 index 0000000..c475098 --- /dev/null +++ b/release/feidlambda-0-4.qmd @@ -0,0 +1,1091 @@ +--- +title: | + feidlambda v0.4 +subtitle: | + Koleksi LAMBDA feidlambda v0.4 +author: "Taruma Sakti Megariansyah" +date: 2023-05-26 +# date-modified: 2023-04-19 +date-format: full +lang: id + +toc: true +toc-location: right +number-sections: false +number-offset: [0, 0] +link-external-newwindow: true + +fig-responsive: true + +filters: + - "../include-code-files.lua" + +format: + html: + mermaid-format: js + css: feidstyle.css + +crossref: + chapters: true + +aliases: + - latest.html + +--- + +::: {.callout-important icon="false" .text-center appearance="minimal"} +## Official GIST **feidlambda** (v0.4.x) + +```default +https://gist.github.com/taruma/b4df638ecb7af48ab63691951481d6b2 +``` +::: + +::: {.text-center} + +[](/docs/install.qmd) +[](https://github.com/fiakoenjiniring/feidlambda/releases/download/v0.4.0/RELEASE_feidlambda_v0_4_0.xlsx) + +::: + +feidlambda v0.4 merupakan pengembangan lebih lanjut dari versi v0.3 sehingga fitur/fungsi yang telah tersedia di feidlambda v0.3 tersedia di versi feidlambda v0.4. Dan dengan dirilisnya feidlambda v0.4, tersedia paket feidlambda baru bernama `feidmath`. feidmath v0.1 merupakan kumpulan fungsi LAMBDA yang fokus menyelesaikan beberapa permasalahan matematika seperti perkalian matriks, rotasi, interpolasi, dlsbnya. [Kunjungi halaman rilis feidmath](feidmath-0-1.qmd). + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Update Log v0.4.x {#update-log} + +_Update Log_ merupakan catatan pembaruan feidlambda. Berikut catatan perubahan/pembaruan secara umum beserta penjelasan perubahan/pembaruan. Untuk perubahan berdasarkan fungsinya, bisa dilihat di bagian [_Changelog_](#changelog). + +- **Update v0.4.0 (2023-05-26)** + - Kategori baru bernama `APPLY_*`. + - Fungsi baru `APPLY_COLUMN()` yang dapat digunakan untuk menerapkan fungsi LAMBDA pada kolom tertentu di dataset. + - Fungsi baru di kategori `GET_*`: + - Fungsi baru `GET_XLOOKUP()` yang merupakan fungsi peningkatan dari fungsi bawaan `XLOOKUP()`. Fungsi `GET_XLOOKUP()` menerima input vector. + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Fungsi feidlambda v0.4.x {#sec-feid-v04} + +Pada feidlambda v0.4.x, setiap fungsi dikategorikan sesuai kegunaannya. Berikut kategori yang tersedia di feidlambda v0.4.x: + +- [NEW]{.f-new} `APPLY_*`: Memanipulasi data dengan menerapkan fungsi pada subset atau kolom tertentu. +- `FILTER_*`: Melakukan _filtering_ atau _subsetting_ (memilah) dari data. +- [NEW]{.f-new} `GET_*`: Mengambil informasi dari data. +- `IS_*`: Fungsi _logical_ tambahan. +- `MAKE_*`: Membangkitkan data. +- `REPEAT_*`: Mengulangi/merepetisi data. +- `RESHAPE_*`: Mengubah dimensi data. +- `ROTATE_*`: Merubah posisi data dengan diputar. +- `SWAP_*`: Menukar posisi data. +- `TEXT_*`: Fungsi tambahan yang berkaitan dengan teks. + +Download excel demonstrasi [RELEASE_feidlambda_v0_4_0.xlsx](https://github.com/fiakoenjiniring/feidlambda/releases/download/v0.4.0/RELEASE_feidlambda_v0_4_0.xlsx), untuk memudahkan mengeksplorasi fungsi baru di feidlambda v0.4.x. + +::: {.callout-note} +Gambar yang ditampilkan pada halaman ini terdapat dari versi sebelumnya (feidlambda v0.3.x) dan tidak diperbarui jika fungsi tersebut tidak memiliki perubahan signifikan. Oleh karena itu, disarankan untuk mengeksplorasi langsung dari dokumen yang telah dilampirkan. +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `APPLY_*` {#sec-apply} + +[NEW v0.4]{.f-new} Kategori `APPLY_*` merupakan kumpulan fungsi yang menerapkan fungsi LAMBDA pada kolom spesifik atau _subset_ tertentu. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-apply. + +```{mermaid} +%%| label: fig-dep-apply +%%| fig-cap: Grafik _dependencies_ kategori `APPLY_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> APPLY_COLUMN +``` + +Fungsi utama kategori `APPLY_*` yaitu `APPLY_COLUMN()`. + +
+_Source Code_ `APPLY_*` +```{.scala include="../_feidlambda/feid_APPLY.sc" } +``` +
+ +### `APPLY_COLUMN()` {#sec-apply-column} + +[NEW v0.4]{.f-new} Fungsi `APPLY_COLUMN(array, index_vector, LAMBDA_FUNCTION)` digunakan untuk menerapkan fungsi LAMBDA (`LAMBDA_FUNCTION()`) pada kolom tertentu di dalam _array_. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: APPLY_COLUMN(array, index_vector, LAMBDA_FUNCTION) + +_Output_ +: _array_ +::: + +--- + +`array := [array]` +: Data berupa _array_ yang memiliki kolom lebih dari satu. + +`index_vector := [integer number | integer vector]` +: Indeks kolom yang ingin diterapkan fungsi lambda. + +`LAMBDA_FUNCTION := [LAMBDA FUNCTION]` +: Fungsi LAMBDA yang ingin diterapkan pada kolom. Fungsi harus berupa formula LAMBDA (`=LAMBDA(...)`). Dapat berupa nama fungsi atau formula LAMBDA. + +::::: + +::: {.column-page-left} +![Demonstrasi `APPLY_COLUMN()`](img-0-4-0/feidlambda-APPLY-01.gif){#fig-apply-column} +::: + + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `FILTER_*` {#sec-filter} + +Kategori `FILTER_*` merupakan kumpulan fungsi yang melakukan _filtering_ atau _subsetting_ (memilah) data berupa _vector_ ataupun _array_. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-filter. + +```{mermaid} +%%| label: fig-dep-filter +%%| fig-cap: Grafik _dependencies_ kategori `FILTER_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> FILTER_DROP_ROWS + NONE --> FILTER_DROP_COLUMNS + NONE --> FILTER_FUNC_COLUMN + FILTER_FUNC_COLUMN --> FILTER_MINMAX_COLUMN + FILTER_MINMAX_COLUMN --> _RECURSIVE_FILTER_MINMAX + _RECURSIVE_FILTER_MINMAX --> _RECURSIVE_FILTER_MINMAX + _RECURSIVE_FILTER_MINMAX --> FILTER_MINMAX_ARRAY +``` + +Fungsi utama kategori `FILTER_*` yaitu `FILTER_DROP_ROWS()`, `FILTER_DROP_COLUMNS()`, dan `FILTER_MINMAX_ARRAY()`. + +
+_Source Code_ `FILTER_*` +```{.scala include="../_feidlambda/feid_FILTER.sc" } +``` +
+ +### `FILTER_DROP_ROWS()` {#sec-filter-drop-rows} + +Fungsi `FILTER_DROP_ROWS(array, row_index)` digunakan untuk menghapus baris dari data. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: FILTER_DROP_ROWS(array, row_index) + +_Output_ +: _array_ +::: + +--- + +`array := [array | vector]` +: Data berupa _array_ atau _vector_ yang memiliki baris lebih dari satu. + +`row_index := [integer number | integer vector]` +: Indeks baris yang ingin dihapus. + +::::: + +::: {.column-page-left} +![Demonstrasi `FILTER_DROP_ROWS()`](img-0-3-0/feidlambda-v03-01-filter-1.gif){#fig-filter-drop-rows} +::: + +### `FILTER_DROP_COLUMNS()` {#sec-filter-drop-columns} + +Fungsi `FILTER_DROP_COLUMNS(array, column_index)` digunakan untuk menghapus kolom dari data. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} + +_Syntax_ +: FILTER_DROP_COLUMNS(array, column_index) + +_Output_ +: _array_ + +::: + +--- + +`array := [array | vector]` +: Data berupa _array_ atau _vector_ yang memiliki kolom lebih dari satu. + +`column_index := [integer number | integer vector]` +: Indeks kolom yang ingin dihapus. + +::::: + +::: {.column-page-left} +![Demonstrasi `FILTER_DROP_COLUMNS()`](img-0-3-0/feidlambda-v03-01-filter-2.gif){#fig-filter-drop-columns} +::: + +### `FILTER_MINMAX_ARRAY()` {#sec-filter-minmax-array} + +Fungsi `FILTER_MINMAX_ARRAY(array, [ignore_first_column], [with_label], [label_vector], [take_first_only])` digunakan untuk melakukan _filtering_ (memilah) data berdasarkan nilai minimum dan maksimum setiap kolomnya dan mengeluarkan hasil dalam berupa _dynamic array_. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} + +_Syntax_ +: FILTER_MINMAX_ARRAY(array, [ignore_first_column], [with_label], [label_vector], [take_first_only]) + +_Output_ +: _array_ + +::: + +--- + +`array := [array | numeric array]` +: Data berupa _array_ dengan ketentuan `array` berisikan angka kecuali kolom pertama jika menggunakan opsi `ignore_first_column`. + +`[ignore_first_column] := FALSE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `FALSE`. Jika `TRUE`, maka kolom pertama dari `array` akan diabaikan dan tidak dilakukan _filtering_ nilai minimum/maksimum. + +`[with_label] := FALSE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `FALSE`. Jika `TRUE`, maka kolom pertama dari _output_ adalah label informasi minimum dan maksimum seperti `1_min`, `1_max`, atau `no.column_min` dan `no.column_max`. Untuk menggunakan label sendiri, masukin _vector_ label di argumen `label_vector`. + +`[label_vector] := NONE :: [vector]` +: Nilai _default_ yaitu `NONE`. Jika `NONE`, maka label setiap baris akan dinomori berdasarkan kolomnya (`1_min`, `1_max`). Jika ingin menggunakan label dari nama kolom, jumlah elemen _vector_ harus sama dengan jumlah kolom dari `array`. Untuk menggunakan label nilai `with_label` harus `TRUE`. + +`[take_first_only] := FALSE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `FALSE`. Jika `TRUE`, maka hanya baris pertama yang diambil dari hasil pencarian nilai minimum/maksimum. + +::::: + +::: {#fig-filter-minmax-array .column-screen-inset layout="[[1,1]]" layout-valign="bottom"} +![](img-0-3-0/feidlambda-v03-01-filter-3.gif) + +![](img-0-3-0/feidlambda-v03-01-filter-4.gif) + +Demonstrasi `FILTER_MINMAX_ARRAY()` +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `GET_*` {#sec-get} + +Kategori `GET_*` merupakan kumpulan fungsi yang digunakan untuk mengambil informasi dari suatu data. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-get. + +```{mermaid} +%%| label: fig-dep-get +%%| fig-cap: Grafik _dependencies_ kategori `GET_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> GET_INDEX_2D + _RECURSIVE_LOOKUP --> _RECURSIVE_LOOKUP + _RECURSIVE_LOOKUP --> GET_XLOOKUP +``` + +Dari @fig-dep-get, diketahui untuk versi v0.4 tersedia fungsi utama `GET_INDEX_2D()` dan `GET_XLOOKUP()`. + +
+_Source Code_ `GET_*` +```{.scala include="../_feidlambda/feid_GET.sc" } +``` +
+ +### `GET_INDEX_2D()` + +Fungsi `GET_INDEX_2D(lookup_value, array, [return_as_order])` dapat digunakan untuk mengambil informasi urutan nilai yang dicari ataupun posisi baris/kolom dari `array`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} + +_Syntax_ +: GET_INDEX_2D(lookup_value, array, [return_as_order]) + +_Output_ +: _array_ ([_order_, _row index_, _column index_]) atau _number vector_ (_order_) + +::: + +--- + +`lookup_value := [scalar]` +: Nilai yang dicari dalam `array`. Nilai `lookup_value` adalah nilai tunggal berupa _scalar_. + +`array := [array]` +: Data berupa _array_. + +`[return_as_order] := FALSE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `FALSE`. Jika `TRUE`, hasil fungsi memberikan urutan angka nilai yang dicari. Urutan dimulai dari horizontal kiri teratas sampai kanan terbawah. Jika `FALSE`, maka _output_ terdiri dari nomor urut, indeks kolom, dan indeks baris. + +::::: + +::: {.column-page-left} +![Demonstrasi `GET_INDEX_2D()`](img-0-3-0/feidlambda-v03-02-get-1.gif){#fig-get-index-2d} +::: + +### `GET_XLOOKUP()` + +Fungsi `GET_XLOOKUP(lookup_value, lookup_vector, return_array, [if_not_found], [match_mode], [search_mode])` dapat digunakan sebagai pengganti fungsi `XLOOKUP()` bagi input berupa _vector_. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} + +_Syntax_ +: GET_XLOOKUP(lookup_value, lookup_vector, return_array, [if_not_found], [match_mode], [search_mode]) + +_Output_ +: _array_ + +::: + +--- + +`lookup_value := [vector]` +: Nilai yang akan dicari. Menerima input berupa _vector_. + +`lookup_array := [array]` +: _Array_ atau rentang untuk dicari. + +`return_array := [array]` +: _Array_ atau rentang yang akan dikembalikan + +`[if_not_found] := #N/A :: [text]` +: Jika kecocokan valid tidak ditemukan, kembalikan teks `[if_not_found]` yang Anda masukkan. Jika kecocokan valid tidak ditemukan, dan `[if_not_found]` hilang, `#N/A` dikembalikan. + +`[match_mode] := 0 :: [0 | -1 | 1 | 2]` +: Tentukan tipe yang cocok: + +> - `0` - Persis cocok. Jika tidak ditemukan, kembalikan `#N/A`. Ini adalah pengaturan **default**. +> - `-1 ` - Persis cocok. Jika tidak ada yang ditemukan, kembalikan item berikutnya yang lebih kecil. +> - `1` - Persis sama. Jika tidak ditemukan, kembalikan item berikutnya yang lebih besar. +> - `2` - A wildcard match where *, ?, and ~ have special meaning. + +`[search_mode] := 1 :: [1 | -1 | 2 | -2]` +: Tentukan mode pencarian yang akan digunakan: + +> - `1` - Melakukan pencarian dimulai dari item pertama. Ini adalah pengaturan default. +> - `-1` - Melakukan pencarian terbalik dimulai dari item terakhir. +> - `2` - Melakukan pencarian biner yang bergantung pada lookup_array diurutkan dalam urutan naik . Jika tidak diurutkan, hasil yang tidak valid akan dikembalikan. +> - `-2` - Melakukan pencarian biner yang mengandalkan lookup_array diurutkan dalam urutan menurun . Jika tidak diurutkan, hasil yang tidak valid akan dikembalikan. + +::::: + +Penjelasan parameter diambil dari [halaman bantuan `XLOOKUP()`](https://support.microsoft.com/id-id/office/fungsi-xlookup-b7fd680e-6d10-43e6-84f9-88eae8bf5929) + +::: {.column-page-left} +![Demonstrasi `GET_XLOOKUP()`](img-0-4-0/feidlambda-GET-XLOOKUP-01.gif){#fig-get-xlookup} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `IS_*` {#sec-is} + +Kategori `IS_*` merupakan kumpulan fungsi yang dapat digunakan untuk melakukan fungsi logical di data. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-is. + +```{mermaid} +%%| label: fig-dep-is +%%| fig-cap: Grafik _dependencies_ kategori `IS_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> IS_ALL_IN_LOOKUP_VECTOR + NONE --> IS_COLS_EQUAL_LOOKUP_VECTOR + IS_COLS_EQUAL_LOOKUP_VECTOR --> IS_ALL_COLS_EQUAL_LOOKUP_VECTOR + NONE --> IS_ROWS_LOGICAL + NONE --> IS_COLUMNS_LOGICAL +``` + +Seluruh fungsi yang tersedia di kategori ini akan dijelaskan. + +
+_Source Code_ `IS_*` +```{.scala include="../_feidlambda/feid_IS.sc" } +``` +
+ +### `IS_ALL_IN_VECTOR()` + +Fungsi `IS_ALL_IN_VECTOR(lookup_vector, array)` digunakan untuk memeriksa apakah setiap elemen di `array` termasuk dari `lookup_vector`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: IS_ALL_IN_VECTOR(lookup_vector, array) + +_Output_ +: _logical array_ +::: + +--- + +`lookup_vector := [scalar | vector]` +: _Vector_ yang terdiri dari nilai yang ingin dicocokkan. + +`array := [array | vector]` +: Data berupa _array_ atau _vector_. + +::::: + +::: {.column-page-left} +![Demonstrasi `IS_ALL_IN_VECTOR()`](img-0-3-0/feidlambda-v03-03-is-1.gif){#fig-is-all-in-vector} +::: + +### `IS_COLS_EQUAL_VECTOR()` + +Fungsi `IS_COLS_EQUAL_VECTOR(lookup_vector, array)` digunakan untuk memeriksa apakah setiap kolom di `array` termasuk dari setiap elemen di `lookup_vector`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: IS_COLS_EQUAL_VECTOR(lookup_vector, array) + +_Output_ +: _logical array_ +::: + +--- + +`lookup_vector := [vector]` +: _Vector_ yang terdiri dari nilai yang ingin dicocokkan. Jumlah elemen `lookup_vector` harus sama dengan jumlah kolom `array`. + +`array := [array | vector]` +: Data berupa _array_ . + +::::: + +::: {.column-page-left} +![Demonstrasi `IS_COLS_EQUAL_VECTOR()`](img-0-3-0/feidlambda-v03-03-is-2.gif){#fig-is-cols-equal-vector} +::: + + +### `IS_ALL_COLS_EQUAL_VECTOR()` + +Fungsi `IS_ALL_COLS_EQUAL_VECTOR(lookup_vector, array, [logical_function])` digunakan untuk memeriksa apakah setiap kolom di `array` termasuk dari setiap elemen di `lookup_vector`, dan diperiksa apakah setiap barisnya sesuai dengan `logical_function`. Fungsi ini menggunakan fungsi `IS_COLS_EQUAL_VECTOR()`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: IS_ALL_COLS_EQUAL_VECTOR(lookup_vector, array, [logical_function]) + +_Output_ +: _column logical vector_ +::: + +--- + +`lookup_vector := [scalar | vector]` +: _Vector_ yang terdiri dari nilai yang ingin dicocokkan. Jumlah elemen `lookup_vector` harus sama dengan jumlah kolom `array`. + +`array := [array | vector]` +: Data berupa _array_ . + +`logical_function := OR() :: [LAMBDA scalar function]` +: Nilai _default_ adalah fungsi _lambda_ `OR()`. Fungsi _logical_ yang digunakan untuk mengaggregasi setiap barisnya. + +::::: + +::: {.column-page-left} +![Demonstrasi `IS_ALL_COLS_EQUAL_VECTOR()`](img-0-3-0/feidlambda-v03-03-is-3.gif){#fig-is-all-cols-equal-vector} +::: + + +### `IS_ROWS_LOGICAL()` + +Fungsi `IS_ROWS_LOGICAL(logical_array, [logical_function])` mengaggregasi setiap baris dari `logical_array` menggunakan fungsi `logical_function`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: IS_ROWS_LOGICAL(logical_array, [logical_function]) + +_Output_ +: _column vector_ +::: + +--- + +`logical_array := [logical array]` +: Data berupa _logical array_ . + +`[logical_function] := OR() [LAMBDA scalar function]` +: Nilai _default_ adalah fungsi _lambda_ `OR()`. Fungsi _logical_ yang digunakan untuk mengaggregasi setiap barisnya. + +::::: + +### `IS_COLUMNS_LOGICAL()` + +Fungsi `IS_COLUMNS_LOGICAL(logical_array, [logical_function])` mengaggregasi setiap kolom dari `logical_array` menggunakan fungsi `logical_function`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: IS_COLUMNS_LOGICAL(logical_array, [logical_function]) + +_Output_ +: _row vector_ +::: + +--- + +`logical_array := [logical array]` +: Data berupa _logical array_ . + +`[logical_function] := OR() [LAMBDA scalar function]` +: Nilai _default_ adalah fungsi _lambda_ `OR()`. Fungsi _logical_ yang digunakan untuk mengaggregasi setiap kolomnya. + +::::: + +::: {.column-page} +![Demonstrasi `IS_ROWS_LOGICAL()` dan `IS_COLUMNS_LOGICAL()`](img-0-3-0/feidlambda-v03-03-is-4.gif){#fig-is-rows-cols-logical} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `MAKE_*` {#sec-make} + +Kategori `MAKE_*` merupakan kumpulan fungsi yang membangkitkan (_generate_) data. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-make. + +```{mermaid} +%%| label: fig-dep-make +%%| fig-cap: Grafik _dependencies_ kategori `MAKE_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + _RECURSIVE_MAKE_SEQUENCE --> _RECURSIVE_MAKE_SEQUENCE + _RECURSIVE_MAKE_SEQUENCE --> MAKE_SEQUENCE_FROM_VECTOR +``` + +Fungsi utama pada kategori ini adalah `MAKE_SEQUENCE_FROM_VECTOR()`. + +
+_Source Code_ `MAKE_*` +```{.scala include="../_feidlambda/feid_MAKE.sc" } +``` +
+ +### `MAKE_SEQUENCE_FROM_VECTOR()` + +Fungsi `MAKE_SEQUENCE_FROM_VECTOR(start_vector, end_vector, [stack_horizontally])` digunakan untuk mebangkitkan _sequence_ dari setiap baris/elemen di `start_vector` dan `end_vector`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: MAKE_SEQUENCE_FROM_VECTOR(start_vector, end_vector, [stack_horizontally]) + +_Output_ +: _column vector_ atau _array_ +::: + +--- + +`start_vector := [integer vector]` +: _Vector_ yang terdiri dari bilangan bulat memulai _sequence_. + +`end_vector := [integer vector]` +: _Vector_ yang terdiri dari bilangan bulat akhir _sequence_. + +`[stack_horizontally] := FALSE :: [TRUE | FALSE]` +: Nilai _default_ yaitu FALSE. Jika `TRUE`, maka setiap _sequence_ yang dibangkitkan akan disusun horizontal. + +::::: + +::: {.column-page-left} +![Demonstrasi `MAKE_SEQUENCE_FROM_VECTOR()`](img-0-3-0/feidlambda-v03-04-make-1.gif){#fig-make-sequence-from-vector} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `REPEAT_*` {#sec-repeat} + +Kategori `REPEAT_*` merupakan kumpulan fungsi yang digunakan untuk melakukan pengulangan _array_ ataupun _vector_ dan menghasilkannya dalam bentuk _dynamic array_. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-repeat. + +```{mermaid} +%%| label: fig-dep-repeat +%%| fig-cap: Grafik _dependencies_ kategori `REPEAT_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + REPEAT_ARRAY_BY_ROW & REPEAT_ARRAY_BY_COLUMN --> REPEAT_ARRAY + REPEAT_ARRAY_BY_ROW --> REPEAT_ARRAY_BY_ROW + REPEAT_ARRAY_BY_COLUMN --> REPEAT_ARRAY_BY_COLUMN +``` + +Seluruh fungsi yang tersedia di kategori ini akan dijelaskan. + +
+_Source Code_ `REPEAT_*` +```{.scala include="../_feidlambda/feid_REPEAT.sc" } +``` +
+ +### `REPEAT_ARRAY_BY_ROW()` + +Fungsi `REPEAT_ARRAY_BY_ROW(array, [num_repeat])` digunakan untuk mengulangi `array` sepanjang baris (ke bawah). + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: REPEAT_ARRAY_BY_ROW(array, [num_repeat]) + +_Output_ +: _array_ +::: + +--- + +`array := [scalar | vector | array]` +: Data dapat berupa _scalar_, _vector_, ataupun _array_. + +`[num_repeat] := 2 :: [integer]` +: Nilai _default_ yaitu 2. Jumlah pengulangannya. + +::::: + +::: {.column-page-left} +![Demonstrasi `REPEAT_ARRAY_BY_ROW()`](img-0-3-0/feidlambda-v03-05-repeat-1.gif){#fig-repeat-array-by-row} +::: + +### `REPEAT_ARRAY_BY_COLUMN()` + +Fungsi `REPEAT_ARRAY_BY_COLUMN(array, [num_repeat])` digunakan untuk mengulangi `array` sepanjang kolom (ke kanan). + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: REPEAT_ARRAY_BY_COLUMN(array, [num_repeat]) + +_Output_ +: _array_ +::: + +--- + +`array := [scalar | vector | array]` +: Data dapat berupa _scalar_, _vector_, ataupun _array_. + +`[num_repeat] := 2 :: [integer]` +: Nilai _default_ yaitu 2. Jumlah pengulangannya. + +::::: + +::: {.column-page-left} +![Demonstrasi `REPEAT_ARRAY_BY_COLUMN()`](img-0-3-0/feidlambda-v03-05-repeat-2.gif){#fig-repeat-array-by-column} +::: + + +### `REPEAT_ARRAY()` + +Fungsi `REPEAT_ARRAY(array, [num_repeat], [by_row])` digunakan untuk mengulangi `array` sepanjang baris/kolom (ke bawah/ke kanan). + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: REPEAT_ARRAY(array, [num_repeat], [by_row]) + +_Output_ +: _array_ +::: + +--- + +`array := [scalar | vector | array]` +: Data dapat berupa _scalar_, _vector_, ataupun _array_. + +`[num_repeat] := 2 :: [integer]` +: Nilai _default_ yaitu 2. Jumlah pengulangannya. + +`[by_row] := TRUE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `TRUE`. Jika `TRUE`, maka pengulangan akan sepanjang baris (ke bawah), dan berlaku sebaliknya juga. + +::::: + +::: {.column-page} +![Demonstrasi `REPEAT_ARRAY()`](img-0-3-0/feidlambda-v03-05-repeat-3.gif){#fig-repeat-array} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `RESHAPE_*` {#sec-reshape} + +Kategori `RESHAPE_*` merupakan kumpulan fungsi yang dapat digunakan untuk melakukan fungsi logical di data. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-reshape. + +```{mermaid} +%%| label: fig-dep-reshape +%%| fig-cap: Grafik _dependencies_ kategori `RESHAPE_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> RESHAPE_BY_COLUMNS +``` + +Fungsi utama yang tersedia saat ini hanya `RESHAPE_BY_COLUMNS()`. + +
+_Source Code_ `RESHAPE_*` +```{.scala include="../_feidlambda/feid_RESHAPE.sc" } +``` +
+ +### `RESHAPE_BY_COLUMNS()` + +Fungsi `RESHAPE_BY_COLUMNS(array, [num_split])` digunakan untuk mengubah dimensi (transformasi) `array` berdasarkan jumlah pembagi kolomnya. Jika tidak jumlah kolom tidak habis dibagi oleh `num_split` akan mengeluarkan hasil `#N/A`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: RESHAPE_BY_COLUMNS(array, [num_split]) + +_Output_ +: _array_ +::: + +--- + +`array := [array]` +: Data berupa _array_ atau _vector_. + +`[num_split] := 2 :: [integer]` +: Nilai _default_ yaitu 2. Jumlah pembagi kolom. Jumlah kolom `array` harus habis dibagi (`MOD()`) dengan `num_split`. + +::::: + +::: {.column-page} +![Demonstrasi `RESHAPE_BY_COLUMNS()`](img-0-3-0/feidlambda-v03-06-reshape-1.gif){#fig-reshape-by-columns} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `ROTATE_*` {#sec-rotate} + +Kategori `ROTATE_*` merupakan kumpulan fungsi yang digunakan untuk menggeser atau memutar _array_ ataupun _vector_. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-rotate. + +```{mermaid} +%%| label: fig-dep-rotate +%%| fig-cap: Grafik _dependencies_ kategori `ROTATE_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> ROTATE_VECTOR + ROTATE_VECTOR --> ROTATE_ARRAY +``` + +Seluruh fungsi yang tersedia di kategori ini akan dijelaskan. + +
+_Source Code_ `ROTATE_*` +```{.scala include="../_feidlambda/feid_ROTATE.sc" } +``` +
+ +### `ROTATE_VECTOR()` + +Fungsi `ROTATE_VECTOR(vector, num_rotation, [as_column_vector])` digunakan untuk menggeser/memutar elemen yang ada di _vector_ sebanyak `num_rotation`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: ROTATE_VECTOR(vector, num_rotation, [as_column_vector]) + +_Output_ +: _vector_ +::: + +--- + +`vector := [vector]` +: Data berupa _vector_ (_column vector_ atau _row vector_). + +`num_rotation := [integer]` +: Jumlah berapa kali _vector_ diputar/digeser. Nilai negatif untuk digeser berlawanan arah. + +`[as_column_vector] := TRUE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `TRUE`. Jika `TRUE`, maka _output_ berupa _column vector_. + +::::: + +::: {.column-page-left} +![Demonstrasi `ROTATE_VECTOR()`](img-0-3-0/feidlambda-v03-07-rotate-1.gif){#fig-rotate-vector} +::: + +### `ROTATE_ARRAY()` + +Fungsi `ROTATE_ARRAY(array, num_rotation, [rotate_columns])` digunakan untuk menggeser/memutar elemen yang ada di _array_ sebanyak `num_rotation` berdasarkan baris atau kolom. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: ROTATE_ARRAY(array, num_rotation, [rotate_columns]) + +_Output_ +: _array_ +::: + +--- + +`array := [array]` +: Data berupa _array_. + +`num_rotation := [scalar | vector]` +: Jumlah berapa kali _vector_ diputar/digeser. Nilai negatif untuk digeser berlawanan arah. + +`[rotate_columns] := TRUE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `TRUE`. Jika `TRUE`, maka `array` diputar berdasarkan kolom. Jika `FALSE`, maka `array` diputar berdasarkan baris. + +::::: + +::: {.column-page-left} +![Demonstrasi `ROTATE_ARRAY()`](img-0-3-0/feidlambda-v03-07-rotate-2.gif){#fig-rotate-array} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `SWAP_*` {#sec-swap} + +Kategori `SWAP_*` merupakan kumpulan fungsi yang digunakan untuk mengganti atau mengubah posisi elemen atau _vector_. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-swap. + +```{mermaid} +%%| label: fig-dep-swap +%%| fig-cap: Grafik _dependencies_ kategori `SWAP_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE --> SWAP_COLUMNS + NONE --> SWAP_ROWS +``` + +Seluruh fungsi yang tersedia di kategori ini akan dijelaskan. + +
+_Source Code_ `SWAP_*` +```{.scala include="../_feidlambda/feid_SWAP.sc" } +``` +
+ +### `SWAP_COLUMNS()` + +Fungsi `SWAP_COLUMNS(array, [from_index], [to_index])` digunakan untuk menukar posisi kolom ke-`from_index` dengan kolom ke-`to_index`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: SWAP_COLUMNS(array, [from_index], [to_index]) + +_Output_ +: _vector_ atau _array_ +::: + +--- + +`array := [row vector | array]` +: Data dapat berupa _array_ atau _row vector_. + +`[from_index] := 1 :: [integer]` +: Nilai _default_ yaitu `1`. Posisi _index_ kolom yang ingin dipindahkan. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +`[to_index] := -1 :: [integer]` +: Nilai _default_ yaitu `-1`. Posisi _index_ tujuan kolom. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +::::: + +### `SWAP_ROWS()` + +Fungsi `SWAP_ROWS(array, [from_index], [to_index])` digunakan untuk menukar posisi baris ke-`from_index` dengan baris ke-`to_index`. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: SWAP_COLUMNS(array, [from_index], [to_index]) + +_Output_ +: _vector_ atau _array_ +::: + +--- + +`array := [column vector | array]` +: Data dapat berupa _array_ atau _column vector_. + +`[from_index] := 1 :: [integer]` +: Nilai _default_ yaitu `1`. Posisi _index_ baris yang ingin dipindahkan. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +`[to_index] := -1 :: [integer]` +: Nilai _default_ yaitu `-1`. Posisi _index_ tujuan baris. Jika menggunakan indeks negatif, maka posisi diambil dari belakang. + +::::: + +::: {.column-page} +![Demonstrasi `SWAP_COLUMNS()` dan `SWAP_ROWS()`](img-0-3-0/feidlambda-v03-08-swap-1.gif){#fig-swap-columns-rows} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `TEXT_*` {#sec-text} + +Kategori `TEXT_*` merupakan kumpulan fungsi yang digunakan untuk memproses data teks. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-text. + +```{mermaid} +%%| label: fig-dep-text +%%| fig-cap: Grafik _dependencies_ kategori `TEXT_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + _RECURSIVE_TEXT_SPLIT --> _RECURSIVE_TEXT_SPLIT + _RECURSIVE_TEXT_SPLIT --> TEXT_SPLIT_VECTOR +``` + +Seluruh fungsi yang tersedia di kategori ini akan dijelaskan. + +
+_Source Code_ `TEXT_*` +```{.scala include="../_feidlambda/feid_TEXT.sc" } +``` +
+ +### `TEXT_SPLIT_VECTOR()` + +Fungsi `TEXT_SPLIT_VECTOR(text_vector, [col_delimiter], [row_delimiter], [ignore_empty], [match_mode], [pad_with], [replace_na])` merupakan fungsi pengembangan lanjutan dari `TEXTSPLIT()` yang mampu menerima _input_ data berupa _vector_ dan menghasilkan dalam bentuk _dynamic array_. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: TEXT_SPLIT_VECTOR(text_vector, [col_delimiter], [row_delimiter], [ignore_empty], [match_mode], [pad_with], [replace_na]) + +_Output_ +: _array_ +::: + +--- + +`text_vector := [text vector]` +: Data harus berupa _text column vector_. + +`[col_delimiter] := " " :: [text]` +: Nilai _default_ yaitu `" "` (spasi). Teks pemisah untuk setiap kolomnya. + +`[row_delimiter] := "" :: [text]` +: Nilai _default_ yaitu `""` (tidak ada). Teks pemisah untuk setiap barisnya. + +`[ignore_empty] := FALSE :: [TRUE | FALSE]` +: Tentukan `TRUE` untuk mengabaikan pemisah berurutan. Default ke `FALSE`, yang membuat sel kosong. Opsional. + +`[match_mode] := 0 :: [0 | 1]` +: Tentukan `1` untuk melakukan kecocokan yang tidak peka huruf besar kecil. Default ke `0`, yang melakukan kecocokan peka huruf besar kecil. Opsional. + +`[pad_with] := #N/A :: [text | number]` +: Nilai untuk mengalihkan hasil. Defaultnya adalah `#N/A`. + +`[replace_na] := #N/A :: [text | number]` +: Nilai untuk menggantikan nilai `#N/A` dari hasil akhir. Defaultnya adalah `#N/A`. Nilai `#N/A` yang ada dikarenakan proses `VSTACK()` yang memiliki dimensi hasil `TEXTSPLIT()` yang berbeda-beda. + +::::: + +Deskripsi `ignore_empty`, `match_mode`, dan `pad_with` diambil dari halaman [Fungsi TEXTSPLIT](https://support.microsoft.com/id-id/office/fungsi-textsplit-b1ca414e-4c21-4ca0-b1b7-bdecace8a6e7). + +#### Limitasi `TEXT_SPLIT_VECTOR()` + +- Hindari menggunakan `TEXT_SPLIT_VECTOR()` dengan jumlah baris yang banyak ataupun dimensi _output_ yang besar. Pastikan hasil _output_ fungsi memiliki dimensi yang kecil seperti jumlah kolom $\le 10$ dan jumlah baris $\le 1,000$. +- Ukuran `text_vector` masih bisa lebih besar dari batasan diatas, akan tetapi disarankan untuk penggunaan `TEXT_SPLIT_VECTOR()` selalu bertahap, yaitu dari jumlah baris yang sedikit sampai jumlah baris optimal yang tidak menampilkan _error_ atau _crash_. +- Jika melebihi kemampuan, akan menghasilkan nilai _error_ berupa `#NUM` / `#CALC`. + +::: {.column-page} +![Demonstrasi `TEXT_SPLIT_VECTOR` (outdated)](img-0-3-0/feidlambda-v03-09-text-1.gif){#fig-text-split-vector} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +Jika ada ide untuk pengembangan feidlambda atau fungsi baru bisa langsung disampaikan dengan membuat [isu di github](https://github.com/fiakoenjiniring/feidlambda/issues/new). Dan jika bertemu masalah saat penggunaan feidlambda v0.4, bisa juga membuat [isu di github](https://github.com/fiakoenjiniring/feidlambda/issues/new). + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Changelog + +- **2023-05-26 (v0.4.0)** + - Rilis feidlambda v0.4 + diff --git a/release/feidmath-0-1.qmd b/release/feidmath-0-1.qmd new file mode 100644 index 0000000..3c4ae5f --- /dev/null +++ b/release/feidmath-0-1.qmd @@ -0,0 +1,394 @@ +--- +title: | + feidmath v0.1 +subtitle: | + Koleksi LAMBDA feidmath v0.1 +author: "Taruma Sakti Megariansyah" +date: 2023-05-26 +# date-modified: 2023-04-19 +date-format: full +lang: id + +toc: true +toc-location: right +number-sections: false +number-offset: [0, 0] +link-external-newwindow: true + +fig-responsive: true + +filters: + - "../include-code-files.lua" + +format: + html: + mermaid-format: js + css: feidstyle.css + +crossref: + chapters: true + +aliases: + - feidmath-latest.html + +--- + +::: {.callout-tip icon="false" .text-center appearance="minimal"} +## Official GIST **feidmath** (v0.1.x) + +```default +https://gist.github.com/taruma/b4df638ecb7af48ab63691951481d6b2 +``` +::: + +::: {.text-center} + +[](/docs/install.qmd) +[](https://github.com/fiakoenjiniring/feidlambda/releases/download/v0.4.0/RELEASE_feidmath_v0_1_0.xlsx) + +::: + +`feidlambda-math` atau **feidmath** merupakan kumpulan fungsi LAMBDA yang fokus menyelesaikan beberapa permasalahan matematis seperti perkalian matriks, rotasi, interpolasi, dlsbnya. Pengembangan feidmath diusahakan tidak memerlukan fungsi dari feidlambda sehingga fungsi yang tersedia feidmath terisolasi dan dapat digunakan secara langsung sesuai kebutuhan. feidmath dibuat untuk fokus pengembangan yang bersifat penerapan dengan fungsi matematika. feidmath merupakan langkah awal untuk pengembangan koleksi LAMBDA lainnya yang bersifat terapan. + +feidmath v0.1 di rilis bersamaan dengan feidlambda v0.4. + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Fungsi feidmath v0.1.x {#sec-feid} + +Mengikuti panduan [FIAKO LAMBDA Style Guide](/docs/lambda-style-guide.qmd) dan [feidlambda v0.4](feidlambda-0-4.qmd), feidmath dipisahkan dengan kategori yang sesuai dengan fungsi yang tersedia. Berikut kategori yang tersedia di feidmath v0.1.x: + +- [NEW]{.f-new} `INTERPOLATION_*`: Kategori ini berisi fungsi untuk estimasi nilai berdasarkan data yang sudah diketahui. +- [NEW]{.f-new} `LINALG_*`: Ini mencakup fungsi-fungsi yang berkaitan dengan aljabar linear, seperti operasi pada vektor dan matriks +- [NEW]{.f-new} `GEOMETRY_*`: Kategori ini melibatkan fungsi geometri, termasuk mengidentifikasi titik berada di dalam/luar poligon. + +Download excel demonstrasi [RELEASE_feidmath_v0_1_0.xlsx](https://github.com/fiakoenjiniring/feidlambda/releases/download/v0.4.0/RELEASE_feidmath_v0_1_0.xlsx), untuk memudahkan mengeksplorasi fungsi baru di feidmath v0.1.x. + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `INTERPOLATION_*` {#sec-interpolation} + +[NEW v0.1]{.f-new} Kategori `INTERPOLATION_*` merupakan kumpulan fungsi untuk mengestimasi nilai berdasarkan data yang sudah diketahui. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-interpolation. + +```{mermaid} +%%| label: fig-dep-interpolation +%%| fig-cap: Grafik _dependencies_ kategori `INTERPOLATION_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE ---> _INTERPOLATION_LINEAR + _INTERPOLATION_LINEAR ---> INTERPOLATION_LINEAR +``` + +Fungsi utama kategori `INTERPOLATION_*` yaitu `INTERPOLATION_LINEAR()`. + +
+_Source Code_ `INTERPOLATION_*` +```{.scala include="../_feidmath/feidmath_INTERPOLATION.sc" } +``` +
+ +### `INTERPOLATION_LINEAR()` {#sec-interpolation-linear} + +Fungsi `INTERPOLATION_LINEAR(x_vector, known_y, known_x)` digunakan untuk mencari nilai interpolasi linear. Fungsi ini dikembangkan menggunakan fungsi bawaan `FORECAST.LINEAR(...)`. Fungsi ini bisa menerima input _scalar_ maupun _vector_. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: INTERPOLATION_LINEAR(x_vector, known_y, known_x) + +_Output_ +: _scalar_ / _vector_ +::: + +--- + +`x_vector := [scalar | vector]` +: Poin data yang ingin Anda prediksikan nilainya. + +`known_ys := [vector]` +: _vector_ atau rentang data terikat. + +`known_xs := [vector]` +: _vector_ atau rentang data terikat. + +::::: + +::: {#fig-interpolation-linear .column-screen-inset layout="[[1,1]]" layout-valign="bottom"} +![_scalar_ sebagai input](img-feidmath-0-1/feidmath-interpolation-01.gif) + +![_vector_ sebagai input](img-feidmath-0-1/feidmath-interpolation-02.gif) + +Demonstrasi `INTERPOLATION_LINEAR()` +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `LINALG_*` {#sec-linalg} + +[NEW v0.1]{.f-new} Kategori `LINALG_*` merupakan kumpulan fungsi yang berkaitan dengan aljabar linear seperti operasi pada vektor atau matriks. `LINALG` merupakan singkatan dari `LINEAR ALGEBRA`. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-linalg. + +```{mermaid} +%%| label: fig-dep-linalg +%%| fig-cap: Grafik _dependencies_ kategori `LINALG_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE ---> LINALG_ROTATION_MATRIX + LINALG_ROTATION_MATRIX ---> LINALG_ROTATE_POINT + LINALG_ROTATE_POINT ---> _RECURSIVE_ROTATE_POINTS + _RECURSIVE_ROTATE_POINTS ---> _RECURSIVE_ROTATE_POINTS + _RECURSIVE_ROTATE_POINTS ---> LINALG_ROTATE_POINT_ARRAY +``` + +Fungsi utama kategori `LINALG_*` yaitu `LINALG_ROTATION_MATRIX()`, `LINALG_ROTATE_POINT()`, dan `LINALG_ROTATE_POINT_ARRAY()`. + +
+_Source Code_ `LINALG_*` +```{.scala include="../_feidmath/feidmath_LINALG.sc" } +``` +
+ +### `LINALG_ROTATION_MATRIX()` {#sec-linalg-rotation-matrix} + +Fungsi `LINALG_ROTATION_MATRIX(theta_x, theta_y, theta_z, [num_digits])` digunakan untuk menghasilkan matriks rotasi berdasarkan tiga sudut rotasi ($\theta_x$, $\theta_y$, dan $\theta_z$) yang ditentukan dalam derajat. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: LINALG_ROTATION_MATRIX(theta_x, theta_y, theta_z, [num_digits]) + +_Output_ +: $3 \times 3$ array +::: + +--- + +`theta_x | theta_y | theta_z := [number]` +: Rotasi terhadap sumbu-nya dalam satuan derajat. + +`[num_digits] := 0 :: [number]` +: Nilai _default_ yaitu `0` (tidak dibulatkan). Jumlah digit presisi yang diinginkan. + +::::: + +::: {#fig-linalg-rotation-matrix .column-screen-inset layout="[[1,1]]" layout-valign="bottom"} +![menghitung matriks rotasi](img-feidmath-0-1/feidmath-linalg-01.gif) + +![implementasi rotasi pada titik](img-feidmath-0-1/feidmath-linalg-02.gif) + +Demonstrasi `LINALG_ROTATION_MATRIX()` +::: + +### `LINALG_ROTATE_POINT()` {#sec-linalg-rotate-point} + +Fungsi `LINALG_ROTATE_POINT(point_vector, theta_x, theta_y, theta_z, [active_rotation], [num_digits])` digunakan untuk melakukan rotasi pada titik dalam ruang tiga dimensi. Fungsi ini menerima input dalam bentuk vektor dengan tiga nilai yaitu $x$, $y$, dan $z$. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: LINALG_ROTATE_POINT(point_vector, theta_x, theta_y, theta_z, [active_rotation], [num_digits]) + +_Output_ +: vector +::: + +--- + +`point_vector := [number vector]` +: Koordinat titik dalam bentuk vektor ($x$, $y$, $z$). + +`theta_x | theta_y | theta_z := [number]` +: Rotasi terhadap sumbu-nya dalam satuan derajat. + +`[active_rotation] := TRUE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `TRUE`. Rotasi aktif akan mengubah posisi objek, sedangkan rotasi pasif akan mengubah sistem koordinat. + +`[num_digits] := 0 :: [number]` +: Nilai _default_ yaitu `0` (tidak dibulatkan). Jumlah digit presisi yang diinginkan. + +::::: + +::: {.column-page-left} +![Demonstrasi `LINALG_ROTATE_POINT()`](img-feidmath-0-1/feidmath-linalg-03.gif){#fig-linalg-rotate-point} +::: + +### `LINALG_ROTATE_POINT_ARRAY()` {#sec-linalg-rotate-point-array} + +Fungsi `LINALG_ROTATE_POINT_ARRAY(data_points, theta_x, theta_y, theta_z, [active_rotation], [num_digits])` digunakan untuk melakukan rotasi pada sekumpulan titik dalam ruang tiga dimensi. Fungsi `LINALG_ROTATE_POINT_ARRAY()` sama dengan `LINALG_ROTATE_POINT()` tetapi dirancang untuk merotasikan sekumpulan titik sekaligus. Argumen `data_points` harus berupa array yang setiap barisnya merepresentasikan titik di ruang 3D. Fungsi ini menerima array dengan tiga kolom yaitu $x$, $y$, dan $z$. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: LINALG_ROTATE_POINT_ARRAY(data_points, theta_x, theta_y, theta_z, [active_rotation], [num_digits]) + +_Output_ +: $m \times 3$ array +::: + +--- + +`data_points := [number array]` +: Sekumpulan koordinat titik dalam bentuk array dengan kolom $x$, $y$, $z$. + +`theta_x | theta_y | theta_z := [number]` +: Rotasi terhadap sumbu-nya dalam satuan derajat. + +`[active_rotation] := TRUE :: [TRUE | FALSE]` +: Nilai _default_ yaitu `TRUE`. Rotasi aktif akan mengubah posisi objek, sedangkan rotasi pasif akan mengubah sistem koordinat. + +`[num_digits] := 0 :: [number]` +: Nilai _default_ yaitu `0` (tidak dibulatkan). Jumlah digit presisi yang diinginkan. + +::::: + +::: {.column-page-left} +![Demonstrasi `LINALG_ROTATE_POINT()`](img-feidmath-0-1/feidmath-linalg-04.gif){#fig-linalg-rotate-point-array} +::: + +### Visualisasi Aktif vs. Pasif {#sec-linalg-viz-rotation} + +Berikut visualisasi perbedaan antara merotasikan objek (aktif) dan koordinatnya (pasif). Rotasi terhadap sumbu $z$ dengan grafik hubungan $x$ dan $y$. + +::: {#fig-linalg-viz-rotation .column-screen-inset layout="[[1,1]]" layout-valign="bottom"} +![rotasi aktif (objek)](img-feidmath-0-1/feidmath-linalg-05.gif) + +![rotasi pasif (koordinat)](img-feidmath-0-1/feidmath-linalg-06.gif) + +Demonstrasi Rotasi Aktif dan Pasif +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Kategori `GEOMETRY_*` {#sec-geometry} + +[NEW v0.1]{.f-new} Kategori `GEOMETRY_*` berisikan fungsi geometri seperti mengidentifikasi titik berada di dalam/luar poligon. Hubungan antar fungsi di kategori ini bisa dilihat di @fig-dep-geometry. + +```{mermaid} +%%| label: fig-dep-geometry +%%| fig-cap: Grafik _dependencies_ kategori `GEOMETRY_*` +%%| fig-height: 100% +%%{ init: { 'theme': 'forest' } }%% + +flowchart LR + NONE ---> GEOMETRY_IS_POINT_IN_POLYGON + GEOMETRY_IS_POINT_IN_POLYGON ---> GEOMETRY_ARE_POINTS_IN_POLYGON +``` + +Fungsi utama kategori `GEOMETRY_*` yaitu `GEOMETRY_POINT_IN_POLYGON()` dan `GEOMETRY_ARE_POINTS_IN_POLYGON()`. + +
+_Source Code_ `GEOMETRY_*` +```{.scala include="../_feidmath/feidmath_GEOMETRY.sc" } +``` +
+ +### `GEOMETRY_IS_POINT_IN_POLYGON()` {#sec-geometry-is-point-in-polygon} + +Fungsi `GEOMETRY_IS_POINT_IN_POLYGON(point_vector, polygon_points)` digunakan untuk menentukan apakah sebuah titik berada di dalam atau di luar sebuah poligon yang tertutup. Titik yang akan dicek dinyatakan oleh `point_vector`, sedangkan `polygon_points` adalah array yang setiap barisnya merepresentasikan titik dari poligon. Fungsi ini mengembalikan nilai `boolean`/`logical`, yaitu `TRUE` jika titik berada di dalam poligon, dan `FALSE` jika tidak. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: GEOMETRY_IS_POINT_IN_POLYGON(point_vector, polygon_points) + +_Output_ +: _logical_ +::: + +--- + +`point_vector := [number vector]` +: Koordinat titik yang ingin dicek dalam bentuk vektor ($x$, $y$). + +`polygon_points := [number array]` +: Sekumpulan koordinat titik yang membentuk poligon dalam bentuk array dengan kolom $x$, $y$. + +::::: + +::: {.column-page-left} +![Demonstrasi `GEOMETRY_IS_POINT_IN_POLYGON()`](img-feidmath-0-1/feidmath-geometry-01.gif){#fig-geometry-is-point-in-polygon} +::: + +### `GEOMETRY_ARE_POINTS_IN_POLYGON()` {#sec-geometry-are-points-in-polygon} + +Fungsi `GEOMETRY_ARE_POINTS_IN_POLYGON(data_points, polygon_points)` sama dengan `GEOMETRY_IS_POINT_IN_POLYGON()` tetapi dirancang untuk mengecek sejumlah titik sekaligus. Argumen data_points harus berupa array yang setiap barisnya merepresentasikan titik yang akan dicek. Seperti halnya fungsi `GEOMETRY_IS_POINT_IN_POLYGON()`, fungsi ini mengembalikan array nilai `boolean`, yaitu `TRUE` untuk titik-titik yang berada di dalam poligon dan `FALSE` untuk titik-titik yang berada di luar poligon. + +::::: {.border .p-3 .my-3 .justify} + +::: {.text-center .syntax} +_Syntax_ +: GEOMETRY_ARE_POINTS_IN_POLYGON(data_points, polygon_points) + +_Output_ +: _logical vector_ +::: + +--- + +`data_points := [number array]` +: Sekumpulan koordinat titik yang ingin dicek dalam bentuk array $m \times 2$ dengan kolom ($x$, $y$). + +`polygon_points := [number array]` +: Sekumpulan koordinat titik yang membentuk poligon dalam bentuk array dengan kolom $x$, $y$. + +::::: + +::: {.column-page-left} +![Demonstrasi `GEOMETRY_ARE_POINTS_IN_POLYGON()`](img-feidmath-0-1/feidmath-geometry-02.gif){#fig-geometry-are-points-in-polygon} +::: + +::: {.column-screen-inset-shaded} + +--- + +::: + +Fungsi feidmath v0.1 memiliki $3$ kategori dengan total $6$ fungsi utama. + +Jika memiliki ide untuk pengembangan feidlambda atau fungsi baru bisa langsung disampaikan dengan membuat [isu di github](https://github.com/fiakoenjiniring/feidlambda/issues/new). Dan jika bertemu masalah saat penggunaan feidmath v0.1, bisa juga membuat [isu di github](https://github.com/fiakoenjiniring/feidlambda/issues/new). + +::: {.column-screen-inset-shaded} + +--- + +::: + +# Changelog + +- **2023-05-26 (v0.1.0)** + - Rilis feidmath v0.1 + - Kategori baru: `INTERPOLATION` + - Fungsi baru: `INTERPOLATION_LINEAR()` + - Kategori baru: `LINALG` (LINEAR ALGEBRA) + - Fungsi baru: `LINALG_ROTATION_MATRIX()` + - Fungsi baru: `LINALG_ROTATE_POINT()` + - Fungsi baru: `LINALG_ROTATE_POINT_ARRAY()` + - Kategori baru: `GEOMETRY` + - Fungsi baru: `GEOMETRY_IS_POINT_IN_POLYGON()` + - Fungsi baru: `GEOMETRY_ARE_POINTS_IN_POLYGON()` + + diff --git a/release/feidstyle.css b/release/feidstyle.css new file mode 100644 index 0000000..06b7fc0 --- /dev/null +++ b/release/feidstyle.css @@ -0,0 +1,41 @@ +.f-new, +.f-patch, +.f-note { + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border: 2px solid black; + font-family: 'Fira Code', 'Courier New', Courier, monospace; + font-size: small; + margin-left: 2px; + margin-right: 2px; + font-weight: bolder; + vertical-align: middle; + box-shadow: 2px 2px 4px #888888; +} + + +.f-new { + background-color: #ffff00; +} + +.f-patch { + background-color: #c65911; + color: white; +} + +.f-note { + background-color: #0070c0; + color: white; +} + +section[id^="sec-"] img { + border-radius: 1%; + border: 1px solid; + box-shadow: 2px 2px 4px #888888; +} + +p { + text-align: justify; +} \ No newline at end of file diff --git a/release/img-0-4-0/feidlambda-APPLY-01.gif b/release/img-0-4-0/feidlambda-APPLY-01.gif new file mode 100644 index 0000000..70c6167 Binary files /dev/null and b/release/img-0-4-0/feidlambda-APPLY-01.gif differ diff --git a/release/img-0-4-0/feidlambda-GET-XLOOKUP-01.gif b/release/img-0-4-0/feidlambda-GET-XLOOKUP-01.gif new file mode 100644 index 0000000..54e7fcc Binary files /dev/null and b/release/img-0-4-0/feidlambda-GET-XLOOKUP-01.gif differ diff --git a/release/img-feidmath-0-1/feidmath-geometry-01.gif b/release/img-feidmath-0-1/feidmath-geometry-01.gif new file mode 100644 index 0000000..37cee04 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-geometry-01.gif differ diff --git a/release/img-feidmath-0-1/feidmath-geometry-02.gif b/release/img-feidmath-0-1/feidmath-geometry-02.gif new file mode 100644 index 0000000..2ce9aa1 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-geometry-02.gif differ diff --git a/release/img-feidmath-0-1/feidmath-interpolation-01.gif b/release/img-feidmath-0-1/feidmath-interpolation-01.gif new file mode 100644 index 0000000..0893d2c Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-interpolation-01.gif differ diff --git a/release/img-feidmath-0-1/feidmath-interpolation-02.gif b/release/img-feidmath-0-1/feidmath-interpolation-02.gif new file mode 100644 index 0000000..080fe4e Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-interpolation-02.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-01.gif b/release/img-feidmath-0-1/feidmath-linalg-01.gif new file mode 100644 index 0000000..51fa0eb Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-01.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-02.gif b/release/img-feidmath-0-1/feidmath-linalg-02.gif new file mode 100644 index 0000000..71c3669 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-02.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-03.gif b/release/img-feidmath-0-1/feidmath-linalg-03.gif new file mode 100644 index 0000000..94acc61 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-03.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-04.gif b/release/img-feidmath-0-1/feidmath-linalg-04.gif new file mode 100644 index 0000000..87030a1 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-04.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-05.gif b/release/img-feidmath-0-1/feidmath-linalg-05.gif new file mode 100644 index 0000000..c4401a5 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-05.gif differ diff --git a/release/img-feidmath-0-1/feidmath-linalg-06.gif b/release/img-feidmath-0-1/feidmath-linalg-06.gif new file mode 100644 index 0000000..44a9178 Binary files /dev/null and b/release/img-feidmath-0-1/feidmath-linalg-06.gif differ diff --git a/release/source-code.qmd b/release/source-code.qmd index ed8bc76..c58f255 100644 --- a/release/source-code.qmd +++ b/release/source-code.qmd @@ -2,9 +2,10 @@ title: | _Source Code_ subtitle: | - _Source Code_ feidlambda v0.3 + _Source Code_ feidlambda & feidmath # author: fiakodev -toc: false +toc: true +toc-location: body link-external-newwindow: true layout: article license: MIT LICENSE @@ -17,8 +18,14 @@ code-line-numbers: true filters: - "../include-code-files.lua" - --- -```{.scala include="../_feidlambda/feid"} +# feidlambda v0.4 + +```{.scala include="../_feidlambda/feid_.sc"} +``` + +# feidmath v0.1 + +```{.scala include="../_feidmath/feidmath_.sc"} ``` \ No newline at end of file