Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add iter/cartesian-power #1350

Conversation

TheNourhan
Copy link
Contributor

@TheNourhan TheNourhan commented Feb 22, 2024

Resolves #1336

Description

What is the purpose of this pull request?

The purpose of this pull request is to implement the iterCartesianPower function, which generates the Cartesian power of an input array-like object.

This pull request:

  • Implementation of the iterCartesianPower function in the lib folder.
  • Documentation updates in the docs folder, including:
    • Writing REPL usage examples in the docs/repl.txt file.
    • Writing TypeScript type definitions in the docs/types folder.
  • Writing a README.md file for the iterCartesianPower function.

Related Issues

Does this pull request have any related issues?

This pull request:

Questions

Any questions for reviewers of this pull request?

No.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

No.

Checklist

Please ensure the following tasks are completed before submitting this pull request.


@stdlib-js/reviewers

Copy link
Contributor

@stdlib-bot stdlib-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Hi there! 👋

And thank you for opening your first pull request! We will review it shortly. 🏃 💨

@kgryte kgryte added the Feature Issue or pull request for adding a new feature. label Feb 22, 2024
@kgryte kgryte changed the title add @stdlib/iter/cartesian-power add iter/cartesian-power Feb 22, 2024
@kgryte
Copy link
Member

kgryte commented Feb 22, 2024

@TheNourhan Would you mind checking the box in the OP indicating that you've read the project contributing guidelines? Thanks!

Copy link
Member

@kgryte kgryte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this @TheNourhan. Looks like this feature addition is missing tests and benchmarks. We won't be able to review until those are added. Thanks!

@kgryte
Copy link
Member

kgryte commented Feb 22, 2024

Also, please ensure that you have run make init and have installed EditorConfig. Currently, your contribution includes a number of lint errors and uses spaces rather than tabs in JavaScript files.

@kgryte kgryte added Utilities Issue or pull request concerning general utilities. Needs Changes Pull request which needs changes before being merged. labels Feb 23, 2024
@TheNourhan
Copy link
Contributor Author

Can you tell me the errors in any file, please?

*/

function iterCartesianPower(x, n) {
var iter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be tab indentation. Make sure all JS files use tab indentation.

Comment on lines 55 to 58
var FLG = false;
var i = 0;
var j = [];
var idx = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have triggered lint errors. Please make sure you have run make init before attempting to commit code.

var idx = [];

// Validate input arguments
if (!Array.isArray(x) && !isTypedArray(x) && !isIterable(x)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look through the codebase and match our spacing conventions. Additionally, you should not be checking for iterables, as you are not handling iterables in the implementation. Lastly, check for a collection, rather than using isArray and isTypedArray.


// Validate input arguments
if (!Array.isArray(x) && !isTypedArray(x) && !isIterable(x)) {
throw new TypeError('invalid argument. First argument must be an array-like object.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include the value in the error message, similar to L65.

if (!Array.isArray(x) && !isTypedArray(x) && !isIterable(x)) {
throw new TypeError('invalid argument. First argument must be an array-like object.');
}
if (!isNumber(n) || isnan(n)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is not necessary given L67.

@kgryte
Copy link
Member

kgryte commented Feb 23, 2024

This PR is still missing tests and benchmarks.

@TheNourhan
Copy link
Contributor Author

TheNourhan commented Feb 23, 2024

I used npm init, the Editorkonfig format and added Testes & Benchmarks, and updated the files you mentioned.
The branch that I pulled doesn't show me errors.

Thanks for your feedback.


# iterCartesianPower

> Create an iterator which generates the Cartesian power of an input array-like object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> Create an iterator which generates the Cartesian power of an input array-like object.
> Create an iterator which returns the Cartesian power.


#### iterCartesianPower( x, n )

Returns an iterator which generates the Cartesian power of an input array-like object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Returns an iterator which generates the Cartesian power of an input array-like object.
Returns an iterator which returns the Cartesian power.

var n = 2;
var iterator = iterCartesianPower( x, n );

for (const combination of iterator) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything should be written in ES5. See also https://github.com/stdlib-js/stdlib/blob/develop/FAQ.md#es2015-and-beyond.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can perform manual iteration. See other iterator packages for examples.

Comment on lines 48 to 50
var x = ['a', 'b', 'c'];
var n = 2;
var iterator = iterCartesianPower( x, n );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var x = ['a', 'b', 'c'];
var n = 2;
var iterator = iterCartesianPower( x, n );
var x = [ 'a', 'b', 'c' ];
var iterator = iterCartesianPower( x, 2 );

Comment on lines 66 to 71
## Notes

- The function expects the first argument x to be an array-like object.
- The second argument n must be a non-negative integer.
- The returned iterator will generate all possible combinations of n elements from the input array x.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Notes
- The function expects the first argument x to be an array-like object.
- The second argument n must be a non-negative integer.
- The returned iterator will generate all possible combinations of n elements from the input array x.

We don't typically explain edge cases. For the last note, this is implied by the concept of the Cartesian power.

<section class="examples">

## Examples

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Do not include spurious newlines unless specified to do so by linting.


```

```javascript
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't split up examples like this. This does not match the conventions in this project.

var n = 2;
var iterator = iterCartesianPower(x, n);

for (const combination of iterator) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES5 here and elsewhere.

Comment on lines 171 to 182
<section class="related">

* * *

## See Also

- <span class="package-name">[`@stdlib/array/from-iterator`][@stdlib/array/from-iterator]</span><span class="delimiter">: </span><span class="description">create (or fill) an array from an iterator.</span>
- <span class="package-name">[`@stdlib/iter/datespace`][@stdlib/iter/datespace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced dates over a specified interval.</span>
- <span class="package-name">[`@stdlib/iter/incrspace`][@stdlib/iter/incrspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced numbers according to a specified increment.</span>
- <span class="package-name">[`@stdlib/iter/logspace`][@stdlib/iter/logspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced numbers on a log scale.</span>
- <span class="package-name">[`@stdlib/iter/step`][@stdlib/iter/step]</span><span class="delimiter">: </span><span class="description">create an iterator which returns a sequence of numbers according to a specified increment.</span>
- <span class="package-name">[`@stdlib/iter/unitspace`][@stdlib/iter/unitspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns numbers incremented by one.</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<section class="related">
* * *
## See Also
- <span class="package-name">[`@stdlib/array/from-iterator`][@stdlib/array/from-iterator]</span><span class="delimiter">: </span><span class="description">create (or fill) an array from an iterator.</span>
- <span class="package-name">[`@stdlib/iter/datespace`][@stdlib/iter/datespace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced dates over a specified interval.</span>
- <span class="package-name">[`@stdlib/iter/incrspace`][@stdlib/iter/incrspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced numbers according to a specified increment.</span>
- <span class="package-name">[`@stdlib/iter/logspace`][@stdlib/iter/logspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns evenly spaced numbers on a log scale.</span>
- <span class="package-name">[`@stdlib/iter/step`][@stdlib/iter/step]</span><span class="delimiter">: </span><span class="description">create an iterator which returns a sequence of numbers according to a specified increment.</span>
- <span class="package-name">[`@stdlib/iter/unitspace`][@stdlib/iter/unitspace]</span><span class="delimiter">: </span><span class="description">create an iterator which returns numbers incremented by one.</span>
<section class="related">

Comment on lines 194 to 209
<!-- <related-links> -->

[@stdlib/array/from-iterator]: https://www.npmjs.com/package/@stdlib/array-from-iterator

[@stdlib/iter/datespace]: https://github.com/stdlib-js/iter/tree/main/datespace

[@stdlib/iter/incrspace]: https://github.com/stdlib-js/iter/tree/main/incrspace

[@stdlib/iter/logspace]: https://github.com/stdlib-js/iter/tree/main/logspace

[@stdlib/iter/step]: https://github.com/stdlib-js/iter/tree/main/step

[@stdlib/iter/unitspace]: https://github.com/stdlib-js/iter/tree/main/unitspace

<!-- </related-links> -->

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<!-- <related-links> -->
[@stdlib/array/from-iterator]: https://www.npmjs.com/package/@stdlib/array-from-iterator
[@stdlib/iter/datespace]: https://github.com/stdlib-js/iter/tree/main/datespace
[@stdlib/iter/incrspace]: https://github.com/stdlib-js/iter/tree/main/incrspace
[@stdlib/iter/logspace]: https://github.com/stdlib-js/iter/tree/main/logspace
[@stdlib/iter/step]: https://github.com/stdlib-js/iter/tree/main/step
[@stdlib/iter/unitspace]: https://github.com/stdlib-js/iter/tree/main/unitspace
<!-- </related-links> -->


// MODULES //

const bench = require( '@stdlib/bench' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 38 to 47
v = iterator.next();
if ( v.done ) {
b.fail( 'should iterate over all elements' );
}
}
b.toc();
if ( v.done ) {
b.pass( 'benchmark finished' );
} else {
b.fail( 'should have finished iteration' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is not correct. You actually need to ensure that v.done does not return true. The point is to test per iteration performance, not how long it can generate all combinations. If folks want to generate all combos, they should just use @stdlib/array/cartesian-power. Instead, we want to know how long it takes a single iteration.


Parameters
----------
x : ArrayLike<T> | Iterable<T>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res.push( x[ idx[ k ] ] );
}
// Update indices
for ( var k = n - 1; k >= 0; k-- ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We explicitly hoist declared variables. See other packages for examples.

Comment on lines 59 to 64
"linspace",
"linear",
"sequence",
"monotonic",
"arange",
"range",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"linspace",
"linear",
"sequence",
"monotonic",
"arange",
"range",
"cartesian",
"combination",
"permutation",

* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please match the spacing and style conventions of other packages in the project.

tape( 'the function returns an iterator which generates all possible combinations of length `n` containing elements from the input array', function test( t ) {
var expected = [ [ 'a', 'a' ], [ 'a', 'b' ], [ 'a', 'c' ], [ 'b', 'a' ], [ 'b', 'b' ], [ 'b', 'c' ], [ 'c', 'a' ], [ 'c', 'b' ], [ 'c', 'c' ] ];
var actual = [];
for ( var v of iterCartesianPower( [ 'a', 'b', 'c' ], 2) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES5.

@kgryte
Copy link
Member

kgryte commented Feb 24, 2024

@TheNourhan In general, I suggest trying to make your contribution look as closely to other packages as possible. We author everything in ES5 and we enforce various lint conventions, which are not currently adhered to.

@kgryte kgryte changed the title add iter/cartesian-power feat: add iter/cartesian-power Feb 24, 2024
@TheNourhan
Copy link
Contributor Author

I made all the changes you mentioned except for the benchmark file and lint errors I will work on them after I fix the installation errors in my project because the make command does not work well in my env.
Thanks for your feedback.

@TheNourhan
Copy link
Contributor Author

I've made all the changes you mentioned

@kgryte
Copy link
Member

kgryte commented Feb 25, 2024

@TheNourhan Great! Thanks for the update. We'll try and review within the next day or so.

@kgryte kgryte added the Needs Review A pull request which needs code review. label Feb 25, 2024
@TheNourhan
Copy link
Contributor Author

I'm going to close this PR and open a new one, I reinstalled the project and fixed all the errors

@kgryte
Copy link
Member

kgryte commented Mar 16, 2024

@TheNourhan Sounds good. Feel free to do so.

@kgryte
Copy link
Member

kgryte commented Jun 11, 2024

@TheNourhan Is this PR obsolete? Based on your prior comments, you were planning on submitting a new PR.

@TheNourhan
Copy link
Contributor Author

@kgryte I've done it here #2534

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Issue or pull request for adding a new feature. Needs Changes Pull request which needs changes before being merged. Needs Review A pull request which needs code review. Utilities Issue or pull request concerning general utilities.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RFC]: add @stdlib/iter/cartesian-power
4 participants