For the below query, show that both summation and product are instances of a more general function, called accumulate, with the following signature:
def accumulate(combiner, start, n, term): """Return the result of combining the first n terms in a sequence.""" "*** YOUR CODE HERE ***"
Accumulate takes as arguments the same arguments term and n as summation and product, together with a combiner function (of two arguments) that specifies how the current term is to be combined with the accumulation of the preceding terms and a start value that specifies what base value to use to start the accumulation. Implement accumulate and show how summation and product can both be defined as simple calls to accumulate:
def summation_using_accumulate(n, term): """An implementation of summation using accumulate. >>> summation_using_accumulate(4, square) 30 """ "*** YOUR CODE HERE ***" def product_using_accumulate(n, term): """An implementation of product using accumulate. >>> product_using_accumulate(4, square) 576 """ "*** YOUR CODE HERE ***"
Below is the solution:
from operator import mul, add
def accumulate(combiner, start, n, f):
"""Return the result of combining the first n terms in a sequence."""
total = start #Result of summation gets stored here
i = 1 #Initial value of sequence
while i <= n:
total = combiner(total, f(i))
i = i + 1
return total
def summation_using_accumulate(n, f):
"""An implementation of summation using accumulate.
>>> summation_using_accumulate(4, square)
30
"""
return accumulate(add, 0, n, f)
def product_using_accumulate(n, f):
"""An implementation of product using accumulate.
>>> product_using_accumulate(4, square)
576
"""
return accumulate(mul, 1, n, f)
def square(x):
return mul(x, x)
print("product_using_accumulate: ",product_using_accumulate(4, square))
print("summation_using_accumulate: ",summation_using_accumulate(4, square))
print(accumulate(add, 0, 4, square))
print(accumulate(mul, 1, 4, square))
I have tested this code and looks good to me.
My questions:
Does the solution look incorrect in any aspect?
Any feedback on naming conventions?
Any feedback on coding style?
2 Answers 2
Here is the implementation I think you were being led towards:
##from functools import reduce # if Python 3.x
from operator import add, mul
def accumulate(combiner, start, n, f):
"""Return the result of combining the first n terms in a sequence."""
## return reduce(combiner, (f(i+1) for i in range(n)), start) # <- built-in version
total = start
for i in range(n):
total = combiner(total, f(i+1))
return total
def summation_using_accumulate(n, f):
"""An implementation of summation using accumulate.
>>> summation_using_accumulate(4, square)
30
"""
return accumulate(add, 0, n, f)
def product_using_accumulate(n, f):
"""An implementation of product using accumulate.
>>> product_using_accumulate(4, square)
576
"""
return accumulate(mul, 1, n, f)
def square(x):
return mul(x, x)
That's how you can
show how summation and product can both be defined as simple calls to accumulate
i.e. simply by doing it, which gives the results required:
>>> product_using_accumulate(4, square)
576
>>> summation_using_accumulate(4, square)
30
Also, note the use of for
and range
, which is easier and much less error-prone that manually incrementing values in a while
loop.
So the answers to your specific questions:
- No;
accumulate
,product_using_accumulate
andsummation_using_accumulate
were all wrong, but you've fixed that now; - No; not now that you've removed
Currentterm
(which should have beencurrent_term
- per the style guide, variable names arelowercase_with_underscores
); and - Yes; you need more spaces, e.g.
return accumulate(add,0,n,f)
should bereturn accumulate(add, 0, n, f)
.
-
1\$\begingroup\$ I think
for i in range(1, n + 1)
would be better: less risk of accidentally writingi
in the loop body instead ofi + 1
. \$\endgroup\$Gareth Rees– Gareth Rees2014年07月11日 13:36:55 +00:00Commented Jul 11, 2014 at 13:36 -
1\$\begingroup\$ @GarethRees that would make sense in a longer loop, for example where
i
is used more than once, but in such a short one I think it's a moot point. \$\endgroup\$jonrsharpe– jonrsharpe2014年07月11日 13:39:25 +00:00Commented Jul 11, 2014 at 13:39 -
\$\begingroup\$ @jonrsharpe In my solution, what exactly is reduce technique? calling accumulate() in thos two functions product_using_accumulate() and summation_using_accumulate()? \$\endgroup\$overexchange– overexchange2014年07月11日 14:31:50 +00:00Commented Jul 11, 2014 at 14:31
-
\$\begingroup\$ @overexchange what?
reduce
is a built-in Python function that does exactly what youraccumulate
function is supposed to do, but with slightly different parameters. \$\endgroup\$jonrsharpe– jonrsharpe2014年07月11日 14:34:16 +00:00Commented Jul 11, 2014 at 14:34 -
\$\begingroup\$ @jonrsharpe what is the advantage of learning/writing such crytic syntax?
reduce(combiner, (f(i+1) for i in range(n)), start)
?total = combiner(total, f(i+1))
looks more readable \$\endgroup\$overexchange– overexchange2014年07月11日 14:40:08 +00:00Commented Jul 11, 2014 at 14:40
If a homework problem starts with the words "Show that", I would expect the answer to contain a proof (or at least an argument), not just an implementation.
You've misunderstood the problem statement. It says that
start
"specifies what value to use to start the accumulation", but in your implementation,start
is the index of the first item in the sequence to contribute to the accumulation. Both of the test cases havestart=1
andf(1)=1
so they are incapable of detecting your mistake.Your implementations of
summation_using_accumulate
andproduct_using_accumulate
do not actually useaccumulate
!
-
\$\begingroup\$ for your point,
Your implementations of summation_using_accumulate and product_using_accumulate do not actually use accumulate!
please help me understand, where was this point told in the question? \$\endgroup\$overexchange– overexchange2014年07月11日 12:40:53 +00:00Commented Jul 11, 2014 at 12:40 -
\$\begingroup\$ for your second point, i edited my query, do u think it make sense now? and i tested with different start values \$\endgroup\$overexchange– overexchange2014年07月11日 12:42:23 +00:00Commented Jul 11, 2014 at 12:42
-
\$\begingroup\$ @overexchange the
start
argument toaccumulate
for adding should be0
. \$\endgroup\$jonrsharpe– jonrsharpe2014年07月11日 12:47:25 +00:00Commented Jul 11, 2014 at 12:47 -
\$\begingroup\$ @jonrsharpe but question says:
a start value that specifies what base value to use to start the accumulation.
from this what i understand is, what is the start value of the sequence whose last term in sequence is n. did i mis-understand? so in one example i gave argument as 1 and another example i gave argument as 3 \$\endgroup\$overexchange– overexchange2014年07月11日 12:50:54 +00:00Commented Jul 11, 2014 at 12:50 -
\$\begingroup\$ @overexchange yes, you misunderstood - that's the value to start the accumulation, not to start the sequence. It should be
total = start
nottotal = f(start)
. The sequence always starts atf(1)
. \$\endgroup\$jonrsharpe– jonrsharpe2014年07月11日 12:55:18 +00:00Commented Jul 11, 2014 at 12:55
..._using_accumulate
functions actually useaccumulate
! Your calls at the end should be inside those functions. \$\endgroup\$neither of your ..._using_accumulate functions actually use accumulate!
, i still did not understand, where is this point asked in the query? Please help me!! \$\endgroup\$accumulate
. And in terms of "feedback on Coding style" - see the style guide. \$\endgroup\$..._using_accumulate
?! The purpose is not just to minimise the code (Python hassum
andreduce
built right in, so why bother with any of this?), it's to understand the processes involved. \$\endgroup\$