# Ryan Martin
# macid: abcd123
# student number: #######
# November 23, 2011
#
#
# This is a solution for Major Assignment 5 (Lab 11) on Monday.

class particle1D:

    def __init__(self, m, r0, v0, a0):
        self.m = float(m)
        self.r = float(r0)
        self.v = float(v0)
        self.a = float(a0)

    def getM(self):
        return self.m

    def getR(self):
        return self.r
    
    def getV(self):
        return self.v
    
    def getA(self):
        return self.a

    def update(self, delta_t):
        self.r = self.r + self.v * delta_t + 0.5 * self.a * delta_t**2
        self.v = self.v + self.a * delta_t

    def applySpringForce(self, k):
        self.a = -1.0 * k * self.r / self.m

def runSpringSim(p, cycles, delta_t, k):
    result = [p.getR()]

    for i in range(cycles):
        p.applySpringForce(k)
        p.update(delta_t)

        result.append(p.getR())

    return result

'''
Design Question

runSpringSim outputs a list of positions after each cycle.
Since each cycle is essentially advancing time by the 
time interval delta_t, the list of values is actually
the position curve of the particle at intervals of delta_t
from time 0 to time cycles*delta_t.

We could use the list of position values, together with
delta_t, as input for a plotting function, letting us
easily graph the position of the particle over time.
(For those interested, Python does not by default have
a plotting library. matplotlib is one of the more
widely used external plotting libraries).

'''
##Note: This format is used by our automated marking system.
##You will see that, for inputs, the class/function/method name is
##given with the corresponding inputs to that class/function/method
##listed right after it. The expected outputs are the state
##variables of the object after calling the function/method.
'''
Testing Report
MON = {'test1': 
       {'inputs': ['particle1D', [1, 0, 2, 0], 'update', [0.1]],
       'outputs': [testingClass(1, 0.2, 2, 0)]},
	'test2': 
       {'inputs': ['particle1D', [2.5, -1.5, -1.5, 2], 'update', [0.2]],
       'outputs': [testingClass(2.5, -1.76, -1.1, 2.0)]},
       'test3':
       {'inputs': ['particle1D', [2, 1, 1, 2], 'applySpringForce', [1]],
       'outputs': [testingClass(2, 1, 1, -0.5)]},
       'test4':
       {'inputs': ['runSpringSim', [('particle1D', [1, 2, 0, 0]), 10, 0.1, 5]],
       'outputs': [[2.0, 1.95, 1.8012499999999998, 1.5587187499999997, 1.2321882812499998, 0.8358851367187496, 0.3878801567382809, -0.0907189555786136, -0.5767470979244997, -1.046088588932808, -1.4748591877696835]]}}
'''