8
\$\begingroup\$

I've written a small program that calculates Arithmetic and Geometric Partial Sums. I'd like feedback on anything possible, since I intend on writing a cheatsheet that encapsulates all PreCalculus equations.

partial_sum.py

"""
This is a program that calculates arithmetic and geometric
partial sums
"""
from fractions import Fraction
def find_an(parsed_series):
 """
 Finds an in the passed parsed arithmetic series
 :param parsed_series: The series to be analyzed
 """
 for i, _ in enumerate(parsed_series):
 if parsed_series[i] == ".":
 return int(parsed_series[i + 1])
 return None
def arithmetic_partial_sum(series):
 """
 Returns the partial sum of an arithmetic series
 Formula:
 S = n( (a1 + an) / 2 )
 Find an:
 an = a1 + (n - 1)d
 Find n:
 n = 1 + ( (an - a1) / d )
 :param series: Arithmetic series to solve
 """
 series = series.split("+")
 a1 = int(series[0])
 d = int(series[1]) - a1
 an = find_an(series)
 n = 1 + ((an - a1) / d)
 S = n * ((a1 + an) / 2)
 return S
def geometric_partial_sum(series):
 """
 Returns the partial sum of the geometric series
 :param series: Geometric series to solve
 Formula:
 S = (a1 * (1 - (r ** n))) / (1 - r)
 """
 series = series.split("+")
 a1 = int(series[0])
 r = int(series[1]) / a1
 n = len(series)
 S = (a1 * (1 - (r ** n))) / (1 - r)
 return str(Fraction(S).limit_denominator())
if __name__ == '__main__':
 A_SERIES = "3+7+11+15+.+99"
 G_SERIES = f"3+1+{1/3}+{1/9}+{1/27}+{1/81}"
 print(arithmetic_partial_sum(A_SERIES))
 print(geometric_partial_sum(G_SERIES))
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Aug 8, 2019 at 5:21
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

find_an() looks like an internal function, used by arithmetic_partial_sum(). If it is not for external use, it should be named with a leading underscore, to suggest it is private.


arithmetic_partial_sum() appears to handle only integer values, yet it return a floating-point value (1275.0 in the built-in example). It should return an integer, since it is adding up integers. Use the Python3.x integer-division operator: //.

 n = 1 + (an - a1) // d
 S = n * (a1 + an) // 2

Or, not assume the terms are integer, and use float(...) instead.


geometric_partial_sum() fails if the first 2 values are not int values:

>>> geometric_partial_sum(f"1+{1/3}+{1/9}+{1/27}+{1/81}")
Traceback (most recent call last):
 File "<pyshell#1>", line 1, in <module>
 geometric_partial_sum(f"1+{1/3}+{1/9}+{1/27}+{1/81}")
 File "...\partial_sum.py", line 63, in geometric_partial_sum
 r = int(series[1]) / a1
ValueError: invalid literal for int() with base 10: '0.3333333333333333'

You should convert the terms to floating-point values, not integers:

 a1 = float(series[0])
 r = float(series[1]) / a1

find_an() assumes \$a_n\$ is immediately after the '.' term, so will fail with:

arithmetic_partial_sum("3+7+11+15+.+95+99")
arithmetic_partial_sum("3+7+11+15+19")

Why not just retrieve the last term?

def find_an(parsed_series):
 return int(parsed_series[-1])

Now the following all succeed and return the correct values

arithmetic_partial_sum("3+7+11+15+.+95+99")
arithmetic_partial_sum("3+7+11+15+...+95+99")
arithmetic_partial_sum("3+7+11+15+19")

The """docstrings""" for arithmetic_partial_sum() and geometric_partial_sum() appear unhelpful. For example:

>>> help(arithmetic_partial_sum)
Help on function arithmetic_partial_sum in module __main__:
arithmetic_partial_sum(series)
 Returns the partial sum of an arithmetic series
 Formula:
 S = n( (a1 + an) / 2 )
 Find an:
 an = a1 + (n - 1)d
 Find n:
 n = 1 + ( (an - a1) / d )
 :param series: Arithmetic series to solve

The function is not returning an or n. Even the formula is not particularly helpful. """docstrings""" should tell a user how to use the function. For example (adding Python 3.6 type hints as well):

def arithmetic_partial_sum(series:str) -> int:
 """
 Returns the sum of an arithmetic series
 Example:
 s = arithmetic_partial_sum("1+3+5+.+99") # returns 2500
 :param series: A string representing the arithmetic series to solve
 """

Now type help(arithmetic_partial_sum):

>>> help(arithmetic_partial_sum)
Help on function arithmetic_partial_sum in module __main__:
arithmetic_partial_sum(series: str) -> int
 Returns the sum of an arithmetic series
 Example:
 s = arithmetic_partial_sum("1+3+5+.+99") # returns 2500
 :param series: A string representing the arithmetic series to solve

The user is told the function takes a string and returns an integer. The format of the string should be clear from the example.

answered Aug 8, 2019 at 22:25
\$\endgroup\$
0
4
\$\begingroup\$

One thing to also include is the fact that it also doesn't support series in which each term alternates between positive and negative as the series = series.split("+")

For example in an arithmetic series like 5+3+1-1-3 with a common difference of -2, the way the series = series.split("+") is set up, will make it detect 1-1-3 as a single term.

And in geometric terms, for example: 9-3+1-(1/3)+(1/9), it will again fail to detect the - and mistake 9-3 and 1-(1/3) as complete terms.

A viable solution is to separate every term whether negative or not by a +. Using the two examples above:

  • Arithmetic: "5+3+1+-1+-3"
  • Geometric: f"9+-3+1+-{1/3}+{1/9}"
AJNeufeld
35.2k5 gold badges41 silver badges103 bronze badges
answered Feb 27, 2020 at 18:14
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.