Skip to content

Commit

Permalink
feat(sdk): adding math module (#3114)
Browse files Browse the repository at this point in the history
I had a little trouble with the `min` and `max` because JSii didn't accept the methods to receive `Set<number>`.
When I tried to use `number[]` and use it in the Wing code, it only accepted arrays.
I ended up using `any`, but I wasn't very satisfied.

@eladb, I took the liberty of adding a few more functions to the module, such as `round` and I noticed that you placed `random` and `randomInt` in the `Util` module, but I wonder if they should be part of the `Math` module instead.

```ts
preflight inflight min(arr: Set<num>): num;
preflight inflight max(arr: Set<num>): num;
preflight inflight abs(value: num): num;
preflight inflight floor(value: num): num;
preflight inflight ceil(value: num): num;

// adding to the specs
preflight inflight math.PI; // PI constant
preflight inflight math.E; // Euler's number
preflight inflight isPrimen: num): bool;
preflight inflight round(value: num, decimalPlaces?: num): num;
preflight inflight median(arr: Array<num>): num;
preflight inflight mode(arr: Array<num>): Array<num>;
preflight inflight arithmeticMean(arr: Array<num>): num;
preflight inflight geometricMean(arr: Array<num>): num;
preflight inflight harmonicMean(arr: Array<num>): num;
preflight inflight fibonacci(n: num): num;
preflight inflight factorial(n: num): num;
preflight inflight combinations(n: num, r: num): num;
```

## Checklist

- [x] Title matches [Winglang's style guide](https://docs.winglang.io/contributing/pull_requests#how-are-pull-request-titles-formatted)
- [x] Description explains motivation and solution
- [x] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Monada Contribution License](https://docs.winglang.io/terms-and-policies/contribution-license.html)*.
  • Loading branch information
marciocadev authored Jul 2, 2023
1 parent 6689cfb commit c845674
Show file tree
Hide file tree
Showing 37 changed files with 3,404 additions and 3 deletions.
12 changes: 12 additions & 0 deletions examples/tests/sdk_tests/math/abs.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
bring math;

let x = 3;
let y = 5;

assert(math.abs(y - x) == 2);
assert(math.abs(x - y) == 2);

test "inflight absolute" {
assert(math.abs(x - y) == 2);
assert(math.abs(y - x) == 2);
}
10 changes: 10 additions & 0 deletions examples/tests/sdk_tests/math/combinations.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bring math;

let population = 5;
let subset = 3;

assert(math.combinations(population, subset) == 10);

test "inflight combinations" {
assert(math.combinations(population, subset) == 10);
}
14 changes: 14 additions & 0 deletions examples/tests/sdk_tests/math/euler.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
bring math;

let interest = 0.05;
let value = 100;

let compoundOneYear = inflight (interestRate: num, currentVal: num): num => {
return currentVal * (math.E ** interestRate);
};

assert(math.round(math.E, decimalPlaces: 3) == 2.718);

test "EULER" {
assert(math.round(compoundOneYear(interest, value), decimalPlaces: 2) == 105.13);
}
17 changes: 17 additions & 0 deletions examples/tests/sdk_tests/math/factorial.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bring math;

assert(math.factorial(0) == 1);
assert(math.factorial(1) == 1);
assert(math.factorial(2) == 2);
assert(math.factorial(3) == 6);
assert(math.factorial(4) == 24);
assert(math.factorial(5) == 120);

test "inflight factorial" {
assert(math.factorial(0) == 1);
assert(math.factorial(1) == 1);
assert(math.factorial(2) == 2);
assert(math.factorial(3) == 6);
assert(math.factorial(4) == 24);
assert(math.factorial(5) == 120);
}
27 changes: 27 additions & 0 deletions examples/tests/sdk_tests/math/fibonacci.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
bring math;

assert(math.fibonacci(0) == 0);
assert(math.fibonacci(1) == 1);
assert(math.fibonacci(2) == 1);
assert(math.fibonacci(3) == 2);
assert(math.fibonacci(4) == 3);
assert(math.fibonacci(5) == 5);
assert(math.fibonacci(6) == 8);
assert(math.fibonacci(7) == 13);
assert(math.fibonacci(8) == 21);
assert(math.fibonacci(9) == 34);
assert(math.fibonacci(10) == 55);

test "inflight fibonacci" {
assert(math.fibonacci(0) == 0);
assert(math.fibonacci(1) == 1);
assert(math.fibonacci(2) == 1);
assert(math.fibonacci(3) == 2);
assert(math.fibonacci(4) == 3);
assert(math.fibonacci(5) == 5);
assert(math.fibonacci(6) == 8);
assert(math.fibonacci(7) == 13);
assert(math.fibonacci(8) == 21);
assert(math.fibonacci(9) == 34);
assert(math.fibonacci(10) == 55);
}
35 changes: 35 additions & 0 deletions examples/tests/sdk_tests/math/floor_ceil_round.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
bring math;

let x = 5.05;
let y = 5.95;

assert(math.floor(x) == 5);
assert(math.ceil(x) == 6);

assert(math.round(x) == 5);
assert(math.round(y) == 6);
assert(math.round(-x) == -5);
assert(math.round(-y) == -6);

assert(math.round(math.E) == 3);
assert(math.round(math.E, decimalPlaces: 1) == 2.7);
assert(math.round(math.E, decimalPlaces: 2) == 2.72);
assert(math.round(math.E, decimalPlaces: 3) == 2.718);
assert(math.round(math.E, decimalPlaces: 4) == 2.7183);
assert(math.round(math.E, decimalPlaces: 5) == 2.71828);

test "inflight floor/ceil/round" {
assert(math.floor(x) == 5);
assert(math.ceil(x) == 6);

assert(math.round(x) == 5);
assert(math.round(y) == 6);
assert(math.round(-x) == -5);
assert(math.round(-y) == -6);

assert(math.round(math.E, decimalPlaces: 1) == 2.7);
assert(math.round(math.E, decimalPlaces: 2) == 2.72);
assert(math.round(math.E, decimalPlaces: 3) == 2.718);
assert(math.round(math.E, decimalPlaces: 4) == 2.7183);
assert(math.round(math.E, decimalPlaces: 5) == 2.71828);
}
46 changes: 46 additions & 0 deletions examples/tests/sdk_tests/math/median_mode_mean.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
bring math;

let odd_arr = [1, 3, 3, 6, 7, 8, 9];
assert(math.median(odd_arr) == 6);

let even_arr = [1, 2, 3, 4, 5, 6, 8, 9];
assert(math.median(even_arr) == 4.5);

test "inflight median" {
assert(math.median(odd_arr) == 6);
assert(math.median(even_arr) == 4.5);
}

let modal_arr = [1, 2, 2, 3, 4, 7, 9];
assert(math.mode(modal_arr).at(0) == 2);

let bimodal_arr = [1, 2, 2, 3, 4, 7, 7, 9, 7, 2];
let bimodal = math.mode(bimodal_arr);
assert(bimodal.at(0) == 2);
assert(bimodal.at(1) == 7);

let multimodal_arr = [1, 3, 4, 7, 7, 9, 9, 2, 2];
let multimodal = math.mode(multimodal_arr);
assert(multimodal.at(0) == 2);
assert(multimodal.at(1) == 7);
assert(multimodal.at(2) == 9);

test "inflight mode" {
assert(math.mode(modal_arr).at(0) == 2);
assert(bimodal.at(0) == 2);
assert(bimodal.at(1) == 7);
assert(multimodal.at(0) == 2);
assert(multimodal.at(1) == 7);
assert(multimodal.at(2) == 9);
}

let mean_arr = [4, 36, 45, 50, 75];
assert(math.arithmeticMean(mean_arr) == 42);
assert(math.geometricMean(mean_arr) == 30);
assert(math.harmonicMean(mean_arr) == 15);

test "inflight mean" {
assert(math.arithmeticMean(mean_arr) == 42);
assert(math.geometricMean(mean_arr) == 30);
assert(math.harmonicMean(mean_arr) == 15);
}
11 changes: 11 additions & 0 deletions examples/tests/sdk_tests/math/min_max.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bring math;

let myArray = [ 1, 2, 3, 4, 5 ];

assert(math.min(myArray) == 1);
assert(math.max(myArray) == 5);

test "inflight min/max" {
assert(math.min(myArray) == 1);
assert(math.max(myArray) == 5);
}
13 changes: 13 additions & 0 deletions examples/tests/sdk_tests/math/pi.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
bring math;

let r = 10;

let circumference = inflight (radius: num): num => {
return 2 * math.PI * radius;
};

assert(math.round(math.PI, decimalPlaces: 3) == 3.142);

test "PI" {
assert(math.round(circumference(r), decimalPlaces: 2) == 62.83);
}
21 changes: 21 additions & 0 deletions examples/tests/sdk_tests/math/prime.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
bring math;

assert(math.isPrime(1) == false);
assert(math.isPrime(2) == true);
assert(math.isPrime(3) == true);
assert(math.isPrime(4) == false);

assert(math.isPrime(10) == false);
assert(math.isPrime(11) == true);
assert(math.isPrime(12) == false);

test "inflight prime numbers" {
assert(math.isPrime(1) == false);
assert(math.isPrime(2) == true);
assert(math.isPrime(3) == true);
assert(math.isPrime(4) == false);

assert(math.isPrime(10) == false);
assert(math.isPrime(11) == true);
assert(math.isPrime(12) == false);
}
1 change: 1 addition & 0 deletions libs/wingc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const WINGSDK_REDIS_MODULE: &'static str = "redis";
const WINGSDK_CLOUD_MODULE: &'static str = "cloud";
const WINGSDK_UTIL_MODULE: &'static str = "util";
const WINGSDK_HTTP_MODULE: &'static str = "http";
const WINGSDK_MATH_MODULE: &'static str = "math";

const WINGSDK_DURATION: &'static str = "std.Duration";
const WINGSDK_MAP: &'static str = "std.Map";
Expand Down
8 changes: 5 additions & 3 deletions libs/wingc/src/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use crate::diagnostic::{report_diagnostic, Diagnostic, TypeError, WingSpan};
use crate::docs::Docs;
use crate::{
dbg_panic, debug, WINGSDK_ARRAY, WINGSDK_ASSEMBLY_NAME, WINGSDK_CLOUD_MODULE, WINGSDK_DURATION, WINGSDK_HTTP_MODULE,
WINGSDK_JSON, WINGSDK_MAP, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP, WINGSDK_MUT_SET,
WINGSDK_REDIS_MODULE, WINGSDK_RESOURCE, WINGSDK_SET, WINGSDK_STD_MODULE, WINGSDK_STRING, WINGSDK_UTIL_MODULE,
WINGSDK_JSON, WINGSDK_MAP, WINGSDK_MATH_MODULE, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP,
WINGSDK_MUT_SET, WINGSDK_REDIS_MODULE, WINGSDK_RESOURCE, WINGSDK_SET, WINGSDK_STD_MODULE, WINGSDK_STRING,
WINGSDK_UTIL_MODULE,
};
use derivative::Derivative;
use indexmap::{IndexMap, IndexSet};
Expand Down Expand Up @@ -2483,7 +2484,8 @@ impl<'a> TypeChecker<'a> {
// we use the module name as the identifier.
// For example, `bring cloud` will import the `cloud` namespace from @winglang/sdk and assign it
// to an identifier named `cloud`.
WINGSDK_CLOUD_MODULE | WINGSDK_REDIS_MODULE | WINGSDK_UTIL_MODULE | WINGSDK_HTTP_MODULE => {
WINGSDK_CLOUD_MODULE | WINGSDK_REDIS_MODULE | WINGSDK_UTIL_MODULE | WINGSDK_HTTP_MODULE
| WINGSDK_MATH_MODULE => {
library_name = WINGSDK_ASSEMBLY_NAME.to_string();
namespace_filter = vec![module_name.name.clone()];
alias = identifier.as_ref().unwrap_or(&module_name);
Expand Down
1 change: 1 addition & 0 deletions libs/wingsdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * as cloud from "./cloud";
export * as core from "./core";
export * as http from "./http";
export * as math from "./math";
export * as redis from "./redis";
export * as std from "./std";
export * as testing from "./testing";
Expand Down
1 change: 1 addition & 0 deletions libs/wingsdk/src/math/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./math";
Loading

0 comments on commit c845674

Please sign in to comment.