[proxy] github.com← back | site home | direct (HTTPS) ↗ | proxy home | ◑ dark◐ light
/ cpython Public

Conversation

Copy link
Member

pablogsal commented Dec 29, 2018

Comparison between math.prod and reduce + operator.mul

❯ ./python ../experiment.py
.....................
math.prod: Mean +- std dev: 79.3 us +- 1.8 us
.....................
reduce+operator.mul: Mean +- std dev: 517 us +- 13 us

https://bugs.python.org/issue35606

Note: This PR is a reference implementation to further discuss the addition of prod to the mathmodule.

pablogsal self-assigned this Dec 29, 2018
pablogsal requested a review from rhettinger December 29, 2018 22:06
pablogsal changed the title bpo-bpo35606: Implement math.prod bpo-35606: Implement math.prod Dec 29, 2018
Copy link
Contributor

Choose a reason for hiding this comment

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

unnecessary line?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed

Copy link
Contributor

eamanu commented Dec 30, 2018

Look.

>>> math.prod([3,2,1], [2,1])
[2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1]

This isn't normal, right?

Copy link
Member Author

pablogsal commented Dec 30, 2018

@eamanu Is the same result you will get if you use a simple reduce algorithm:

>>> from functools import reduce
>>> reduce(lambda x,y: x * y, [3,2,1], [1,2])
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

This raises the question if we should ban certain data types as lists/dicts...etc but that behaviour is totally normal for that input.

Copy link
Contributor

eamanu commented Dec 30, 2018

@pablogsal If we based on sum(), list/tuples/etc should no be accepted

Copy link
Member Author

pablogsal commented Dec 30, 2018

@eamanu Why not? This is perfectly valid and an analogous is in the test suite:

>>> sum([[1,2,3,4]], [1,2,3,3,4])
[1, 2, 3, 3, 4, 1, 2, 3, 4]

We can decide to limit the API to not accept list/tuples/etc but people can get away and subclass them or implement their own containers. I think the text in the doc and docstring is enough.

Copy link
Contributor

eamanu commented Dec 30, 2018

I think the text in the doc and docstring is enough.

Ok, yes, you are right.

A test with the form math.prod([3,2,1], [2,1]) can be added?

Copy link
Contributor

eamanu left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

Choose a reason for hiding this comment

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

Support for these macros was dropped in 3.7, so you can leave them out. We still define the macros to avoid breaking pre-existing third-party code but the macros don't do anything, they are empty.

Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

Copy link
Contributor

Please add an entry to whatsnew/3.8.rst. Otherwise, this all looks good :-)

pablogsal force-pushed the bpo35606 branch 3 times, most recently from a97b7f6 to a9ffb24 Compare February 7, 2019 01:18
Copy link
Contributor

rhettinger commented Feb 7, 2019

Can you please fix-up the CI bot failures. Likely, it wants the trailing whitespace cleaned-up.

rhettinger merged commit bc09851 into python:master Feb 7, 2019
pablogsal deleted the bpo35606 branch February 7, 2019 09:24
Comment on lines +1748 to +1757
self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
values = [bytearray(b'a'), bytearray(b'b')]
self.assertRaises(TypeError, prod, values, bytearray(b''))
self.assertRaises(TypeError, prod, [[1], [2], [3]])
self.assertRaises(TypeError, prod, [{2:3}])
self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
with self.assertRaises(TypeError):
prod([10, 20], [30, 40]) # start is a keyword-only argument
Copy link

s-cork Sep 23, 2021

Choose a reason for hiding this comment

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

@rhettinger / @pablogsal - Skulpt committer here - implementing these tests in our own project.

I was wondering if the intention wasn't quite right with some of these TypeError tests?
Most of them fail because start is a keyword only argument.
Whereas it looks like - for most of them except the final test - the intention is to check multiplication across incompatible types within the prod function.

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 use _PyLong_One.

}
/* Loop over all the items in the iterable until we finish, we overflow
* or we found a non integer element */
while(result == NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

Add a space between while and (.

}
if (PyLong_CheckExact(item)) {
long b = PyLong_AsLongAndOverflow(item, &overflow);
long x = i_result * b;
Copy link
Member

Choose a reason for hiding this comment

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

Signed integer overflow is an undefined behavior.

/* Continue if there is no overflow */
if (overflow == 0
&& x < INT_MAX && x > INT_MIN
&& !(b != 0 && x / i_result != b)) {
Copy link
Member

Choose a reason for hiding this comment

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

Possible division by 0.

double f_result = PyFloat_AS_DOUBLE(result);
Py_DECREF(result);
result = NULL;
while(result == NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

Add a space between while and (.

Copy link
Member Author

@serhiy-storchaka Thanks for the review. This PR is already merged so I can do a separate PR if you wish

Copy link
Member

Please address @s-cork comment. Tests do not work as intended.

Copy link
Member

Ah, I started reviewing after seen @s-cork comment, without noticing that this PR was merged years ago.

Copy link
Member Author

Yeah, most of these things are already fixed, although is possible that some of these still remain. I will do a check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants