# Sequence and Series Calculator

The Sequences & Series involved are Arithmetic and Geometric. stores and allows you to calculate using these given formulas and import fractions into micropython

Support for micropython! Micropython, however, only has a subset of functions of pythons, and it's standard library is very limited, so i had to reinvent the wheel on some things.

I'd like advice on efficiency, math, optimization, compactness, design, and general information about improving my program (it was designed for micropython).

Arithmetic:

1. An = a1 + (n-1)d

2. Sn = n/2 x (2a1 + (n-1)d) OR Sn = n/2(a + L)

Geometric:

1. An = a1(r)^(n-1)

2. Sn = (a(1-(r)^n)/(1-r)

3. S_infinity = a/(1-r)

Both:

1. ability to find the first nth to exceed a value
from math import sqrt, log

def take_inputs(*args):
"""
takes a list of variable names, and sets it up so that that input is carried out, and
a list is returned with the numerical values, to be used for unpacking into their variables

Ex:
take_inputs('a', 'b', 'c')
a = 4
b = 2
c = 3
- [4, 2, 3] -

"""
values = []
for prompt in args:
values.append(eval(str(input(prompt + " = "))))
return values

def check_for_L():
"""
checks if an 'x' was inputted at L.

if 'x', then return None (L wasn't inputted)
if any other value, then return the float form of that value
Ex:
check_for_L()
Enter x if L not present!
Enter L: 5
- 5.0 -

"""
L = input("Enter x if L not present!\nEnter L: ")
if L == 'x':
return None
return float(L)

class Arithmetic:

def a_nth(self):
print("An = a1 + (n-1)d")
a1, n, d = take_inputs('a1', 'n', 'd')
print(round(a1 + (n - 1) * d, 5))

def sum(self):
print("Sn = n/2(2a1+(n-1)d)", "Sn = n/2(a1+L)", sep="\n")
L = check_for_L()
if not L:
a1, n, d = take_inputs('a1', 'n', 'd')
print(round((n/2) * (2 * a1 + (n - 1) * d), 5))

else:
a1, n = take_inputs('a1', 'n')
print(round((n/2) * (a1 + L), 5))

def exceed_nth(self):
print("a+(n-1)d > Value")
a1, d, value = take_inputs('a1', 'd', 'value')
n = round(( (value - a1) / d ) + 1, 5)
print("n to exceed = " + str(n))

def exceed_sum_to_nth(self):
print("n/2(2a1+(n-1)d)>Value", "n/2(a1+L)>Value", sep="\n")
L = check_for_L()
if L:
a1, value = take_inputs('a1', 'value')
n = round((2 * value) / (a1 + L), 5)
print("n to exceed = " + str(n))

else:
a1, d, value = take_inputs('a1', 'd', 'value')
n = round((-2*a1 + d + sqrt(4*(a1**2) - 4*a1*d + d**2 + 8*d*value))/(2*d), 5)
print("n to exceed = " + str(n))

class Geometric:

def a_nth(self):
print("An = ar^(n-1)")
a1, r, n = take_inputs('a1', 'r', 'n')
print(round(a1 * r ** (n - 1), 5))

def sum(self):
print("Sn = a(1-r^n)/(1-r)")
a1, r, n = take_inputs('a1', 'r', 'n')
print( round((a1 * (1 - r**n) )/(1 - r), 5))

def sum_to_infinity(self):
print("S(inf) = a/(1-r)")
a1, r = take_inputs('a1', 'r')
print(round(a1/(1-r), 5))

def exceed_nth(self):
print("ar^(n-1) > Value")
a1, r, value = take_inputs('a1', 'r', 'value')
n = round(log( r*(value/a1) ) / log(r), 5)
print("n to exceed = " + str(n))

def exceed_sum_to_nth(self):
print("a(1-r^n)/(1-r)>Value")
a1, r, value = take_inputs('a1', 'r', 'value')
n = round(log( (a1 + r*value - value) / a1) / log(r), 5)
print("n to exceed = " + str(n))

class BIOS:

choices_prompt = "a for arithmetic\nb for geometric\n>> "

def __init__(self):
"""
responsible for handling basic input and output, for the terminal, and options/choices.
"""
self.running = True
self.arithmetic = Arithmetic()
self.geometric = Geometric()

self.choices = {'a': self.arithmetic_sequences, 'b': self.geometric_sequences}
self.arithmetic_choices        = {'a': self.arithmetic.a_nth, 'b': self.arithmetic.sum, 'c': self.arithmetic_exceed}
self.geometric_choices         = {'a': self.geometric.a_nth, 'b': self.geometric.sum, 'c': self.geometric.sum_to_infinity, 'd': self.geometric_exceed}
self.arithmetic_exceed_choices = {'a': self.arithmetic.exceed_nth, 'b': self.arithmetic.exceed_sum_to_nth}
self.geometric_exceed_choices = {'a': self.geometric.exceed_nth, 'b': self.geometric.exceed_sum_to_nth}

@staticmethod
"""
a list of prompts is given as arguments,

Ex:
menu('a for apple', 'b for bye', 'c for cat')
a for apple
b for bye
c for cat
>> a
- a -
"""
return input("\n".join(list(args) + [">> "]))

def stop_decorator(func):
"""
Decorator for stopping certain functions, after they're done by asking with a prompt
"""
def wrapper(self):
func(self)
command = input("Enter nothing to stop: ")
if command == '':
self.running = False
return wrapper

@stop_decorator
def arithmetic_sequences(self):
sub_choice = self.menu("Arithmetic:", "a for a_nth term", "b for sum", "c for min_term_exceed")
self.arithmetic_choices.get(sub_choice, lambda: None)()

@stop_decorator
def geometric_sequences(self):
sub_choice = self.menu("Geometric:", "a for a_nth term", "b for sum", "c for sum to infinity", "d for min terms exceed")
self.geometric_choices.get(sub_choice, lambda: None)()

def arithmetic_exceed(self):
sub_choice = self.menu("Exceed Arithmetic:", "a for nth", "b for sum_to_nth")
self.arithmetic_exceed_choices.get(sub_choice, lambda: None)()

def geometric_exceed(self):
sub_choice = self.menu("Exceed Geometric:", "a for nth", "b for sum_to_nth")
self.geometric_exceed_choices.get(sub_choice, lambda: None)()

def main(self):
"""
runs the program indefinitely as long as the user wants.
"""
while self.running:
self.choices.get(input(self.choices_prompt), lambda: None)()
print()

program = BIOS()
program.main()
$$$$
`
• yes, so that i can input values like 3/2, which is a fraction, and possibly pi, in the near future. I am aware this is a vulnerability/security issue, but this is just a math program lol for a calculator nonetheless. I'm pretty much gonna be the only one using it. – Eren Yaegar Sep 13 '20 at 22:41