'''
Created on 07-Feb-2021

https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference

@author: bthakur
'''
import random
import inspect
import traceback
from sympy import (symbols, Symbol, latex, pi, 
                   Function,
                   sqrt, sin, cos
                   )
import sympy


from ...helper import BaseHelper
from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate


# _applied_differentiation_manager
# AppliedDifferentiationManager

        
class AppliedDifferentiationManager(BaseManager):
    '''
    Principle of Differential Laws


    Minimum Grade: 4
    Maximum Grade: 10


    Examples
    --------
    ke = AppliedDifferentiationManager()
    ke 
    
    ke.printProblemTypes()
    ke.helpProblemType(0)
    
    ke.getRandomProblem()
    ke.getRandomProblem(problem_type = 0)


    ke.printProblem()
    ke.printAnswer()
    ke.printSolution()


    doc_style: xv_doc
    ''' 

    def __new__(cls, *args, **kwargs):
        instance = super(AppliedDifferentiationManager, cls).__new__(cls, *args, **kwargs)
        for base_class in AppliedDifferentiationManager.__bases__:
            base_class.__init__(instance, *args, **kwargs)
        return instance
    
    def __init__(self, *args, **kwargs):
        self.base_helper = BaseHelper(**kwargs)
        pass

    def _init_problem_types(self, *args, **kwargs):
        self._append_problem_types(
            [
                '_problem_approx_value_of_a_function',
                '_problem_simple_harmonic_motion',
                '_problem_distance_velocity_acceleration',
                '_problem_velocity_acceleration',
                '_problem_distance_velocity',
                '_problem_radioactive_decay',
                '_problem_distance_acceleration',
            ])
        pass

    def _problem_approx_value_of_a_function(self, *args, **kwargs):
        """

        doc_style: xv_doc
        """
        index = kwargs.get("index", None)
        
        app_diff_helper = self.base_helper.get_calculus_helper().get_applied_differentiation_helper()
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        result = app_diff_helper.get_problem_approx_value_of_a_function(**kwargs)
        
        
        prob_s = f"""
        {result['prob_s']}
        
        """
        
        problemTemplate.add_problem(prob_s.strip(), 'text/html')


        soln_s = f"""
        {result['soln_s']}
        """
        
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        {result['answer_s']}
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        
        return problemTemplate
        pass

    def _problem_simple_harmonic_motion(self, *args, **kwargs):
        """
        _problem_simple_harmonic_motion 


        Minimum Grade: 6
        Maximum Grade: 10

    
        Examples
        --------
        from xv.math.algebra import AppliedDifferentiationManager
        ke = AppliedDifferentiationManager()


        ke.getRandomProblem(problem_type = '_problem_simple_harmonic_motion')


        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr,
                           Eq, dsolve, solve)
        x = Function('x')
        t = symbols('t')
        x = x(t)
        
        dx2_dt2 = x.diff(t).diff(t)
        
        k = Symbol("k")
        
        t1, t2 = symbols('t_1 t_2')
        limit_low = 0 # t1
        limit_high = t # t2
        
        eq = Eq(dx2_dt2, -k * x)
        
        eq_integral = eq.integral(t, limit_low, limit_high)
        eq_integral_doit = eq_integral.doit()
        
        eq_integral_doit_integral = eq_integral_doit.integral(t, limit_low, limit_high)
        eq_integral_doit_integral_doit = eq_integral_doit_integral.doit()
        
        
        eq_dsoln = dsolve(eq, x)
        eq_dsoln_subs_0 = eq_dsoln.subs({t: 0})
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        eq_dsoln_subs_subs_1 = eq_dsoln_subs.subs({t: 1})
        C2 = Symbol('C2')
        C2_val = solve(eq_dsoln_subs_subs_1, C2)[0]
        
        eq_dsoln_subs_subs = eq_dsoln_subs.subs({C2: C2_val})
        
        eq_dsoln_subs_subs_simplify = eq_dsoln_subs_subs.simplify()
        
        
        self.eqs = [
            eq,
            eq_integral,
            eq_integral_doit,
            eq_integral_doit_integral,
            eq_integral_doit_integral_doit,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            eq_dsoln_subs_subs_1,
            C2_val,
            eq_dsoln_subs_subs,
            eq_dsoln_subs_subs_simplify,
            ]
        
        labels = {
            x: "displacement",
            t: "time",
            k: "constant",
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(x)}$ and ${latex(t)}$ in a simple harmonic motion
        where:
        {labels_s}
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$

        $\\displaystyle \\implies {latex(eq_integral_doit_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit_integral_doit)}$
        

        <h2>Second Part:</h2>
        $\\displaystyle {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$ \t\t Solving differential equation

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ \t\t Substituting value of ${latex(C1)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs_1)}$ \t\t at ${latex(t)} = 1$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs)}$ \t\t Substituting value of ${latex(C2)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs_simplify)}$ 

        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_integral_doit_integral_doit)}$
        
        $\\displaystyle {latex(eq_dsoln_subs_subs_simplify)}$ 
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass


    def _problem_distance_velocity_acceleration(self, *args, **kwargs):
        """
        _problem_distance_velocity_acceleration 


        Minimum Grade: 6
        Maximum Grade: 10

    
        Examples
        --------
        from xv.math.algebra import AppliedDifferentiationManager
        ke = AppliedDifferentiationManager()


        ke.getRandomProblem(problem_type = '_problem_distance_velocity_acceleration')


        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr,
                           Eq, dsolve, solve)
        s = Function('s')
        v = Function('v')
        t = symbols('t')
        a = symbols('a')
        s = s(t)
        
        dv_dt = s.diff(t).diff(t)
        k = Symbol("k")
        
        t1, t2 = symbols('t_1 t_2')
        limit_low = 0 # t1
        limit_high = t # t2
        
        eq0 = Eq(a, dv_dt)
        
        #prop_rel_N_t = eq0.get_prop_rel(N, t)
        
        eq = eq0
        
        eq_integral = eq.integral(t, limit_low, limit_high)
        eq_integral_doit = eq_integral.doit()
        
        eq_integral_doit_integral = eq_integral_doit.integral(t, limit_low, limit_high)
        eq_integral_doit_integral_doit = eq_integral_doit_integral.doit()
        
        eq_integral_final = eq_integral_doit_integral_doit.subs({
                                        s.diff(t): v
                                        })
        
        eq_dsoln = dsolve(eq, s)
        eq_dsoln_subs_0 = eq_dsoln.subs({t: 0})
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        eq_dsoln_subs_subs_1 = eq_dsoln_subs.subs({t: 1})
        C2 = Symbol('C2')
        C2_val = solve(eq_dsoln_subs_subs_1, C2)[0]
        
        eq_dsoln_subs_subs = eq_dsoln_subs.subs({C2: C2_val})
        
        eq_dsoln_subs_subs_simplify = eq_dsoln_subs_subs.simplify()
        
        
        self.eqs = [
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_integral_doit_integral,
            eq_integral_doit_integral_doit,
            eq_integral_final,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            eq_dsoln_subs_subs_1,
            C2_val,
            eq_dsoln_subs_subs,
            eq_dsoln_subs_subs_simplify,
            ]
        
        labels = {
            a: "acceleration",
            v: "velocity",
            t: "time",
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(a)}$, ${latex(v)}$ and ${latex(t)}$ 
        where:
        {labels_s}
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$

        $\\displaystyle \\implies {latex(eq_integral_doit_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit_integral_doit)}$
        
        $\\displaystyle \\implies {latex(eq_integral_final)}$

        <h2>Second Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$ \t\t Solving differential equation

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ \t\t Substituting value of ${latex(C1)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs_1)}$ \t\t at ${latex(t)} = 1$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs)}$ \t\t Substituting value of ${latex(C2)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs_subs_simplify)}$ 

        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_integral_final)}$
        
        $\\displaystyle {latex(eq_dsoln_subs_subs_simplify)}$ 
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass


    def _problem_velocity_acceleration(self, *args, **kwargs):
        """
        _problem_velocity_acceleration 


        Minimum Grade: 6
        Maximum Grade: 10

    
        Examples
        --------
        from xv.math.algebra import AppliedDifferentiationManager
        ke = AppliedDifferentiationManager()


        ke.getRandomProblem(problem_type = '_problem_velocity_acceleration')


        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr,
                           Eq, dsolve, solve)
        v = Function('v')
        t = symbols('t')
        a = symbols('a')
        v = v(t)
        dv_dt = v.diff(t)
        k = Symbol("k")
        
        t1, t2 = symbols('t_1 t_2')
        limit_low = t1
        limit_high = t2
        
        eq0 = Eq(a, dv_dt)
        
        #prop_rel_N_t = eq0.get_prop_rel(N, t)
        
        eq = eq0
        
        eq_integral = eq.integral(t, limit_low, limit_high)
        eq_integral_doit = eq_integral.doit()
        eq_dsoln = dsolve(eq, v)
        eq_dsoln_subs_0 = eq_dsoln.subs({t: 0})
        
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        
        
        self.eqs = [
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            ]
        
        labels = {
            a: "acceleration",
            v: "velocity",
            t: "time",
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(a)}$, ${latex(v)}$ and ${latex(t)}$ 
        where:
        {labels_s}
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$
        
        <h2>Second Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ 

        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_integral_doit)}$
        
        $\\displaystyle {latex(eq_dsoln_subs)}$ 
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass


    def _problem_distance_velocity(self, *args, **kwargs):
        """
        _problem_distance_velocity 


        Minimum Grade: 6
        Maximum Grade: 10

    
        Examples
        --------
        from xv.math.algebra import AppliedDifferentiationManager
        ke = AppliedDifferentiationManager()


        ke.getRandomProblem(problem_type = '_problem_distance_velocity')


        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr,
                           Eq, dsolve, solve)
        v = symbols('v')
        t = symbols('t')
        s = Function('s')
        s = s(t)
        ds_dt = s.diff(t)
        k = Symbol("k")
        
        t1, t2 = symbols('t_1 t_2')
        limit_low = t1
        limit_high = t2
        
        eq0 = Eq(v, ds_dt)
        
        #prop_rel_N_t = eq0.get_prop_rel(N, t)
        
        eq = eq0
        
        eq_integral = eq.integral(t, limit_low, limit_high)
        eq_integral_doit = eq_integral.doit()
        eq_dsoln = dsolve(eq, s)
        eq_dsoln_subs_0 = eq_dsoln.subs({t: 0})
        
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        
        
        self.eqs = [
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            ]
        
        labels = {
            v: f"velocity",
            t: "time",
            s: "displacement",
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(v)}$, ${latex(s)}$ and ${latex(t)}$ 
        where:
        {labels_s}
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$
        
        <h2>Second Part:</h2>
        $\\displaystyle {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ 

        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_integral_doit)}$
        
        $\\displaystyle {latex(eq_dsoln_subs)}$ 

        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass

    def _problem_radioactive_decay(self, *args, **kwargs):
        """

        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr,
                           Eq, dsolve, solve)
        t = symbols('t')
        N = Function('N')
        N = N(t)
        dN_dt = N.diff(t)
        k = Symbol("\lambda")
        
        t1, t2 = symbols('t_1 t_2')
        limit_low = t1
        limit_high = t2
        
        eq0 = Eq(-dN_dt, k * N)
        
        prop_rel_N_t = eq0.get_prop_rel(N, t)
        
        eq = (eq0 / N).doit()
        
        eq_integral = eq.integral(t, limit_low, limit_high)
        eq_integral_doit = eq_integral.doit()
        eq_dsoln = dsolve(eq, N)
        eq_dsoln_subs_0 = eq_dsoln.subs({t: 0})
        
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        
        
        self.eqs = [
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            ]
        
        labels = {
            N: f"number of radioactive nuclei at point ${latex(t)}$",
            t: "time",
            k: "decay constant",
            -dN_dt: f"rate of decay of nuclei with respect to time"
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(N)}$ and ${latex(t)}$ 
        where:
        {labels_s}
        
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {prop_rel_N_t}$
        
        $\\displaystyle \\implies {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$
        
        <h2>Second Part:</h2>
        $\\displaystyle {prop_rel_N_t}$
        
        $\\displaystyle \\implies {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ 

        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_integral_doit)}$

        $\\displaystyle {latex(eq_dsoln_subs)}$ 

        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass

    pass

    def _problem_distance_acceleration(self, *args, **kwargs):
        """
        _problem_distance_acceleration 


        Minimum Grade: 6
        Maximum Grade: 10

    
        Examples
        --------
        from xv.math.algebra import AppliedDifferentiationManager
        ke = AppliedDifferentiationManager()


        ke.getRandomProblem(problem_type = '_problem_distance_acceleration')


        doc_style: xv_doc
        """
        
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        from sympy import (symbols, Symbol, Function, 
                           UnevaluatedExpr, Derivative,
                           Eq, dsolve, solve)

        v = Function('v')
        s = symbols('s')
        t = symbols('t')
        a = symbols('a')
        v = v(s)
        
        ds_dt = Derivative(s, t)
        dv_ds = Derivative(v, s)
        dv_dt = Derivative(v, t)

        k = Symbol("k")
        
        eq00 = Eq(a, dv_dt)
        eq0 = Eq(a, UnevaluatedExpr(dv_ds) * UnevaluatedExpr(ds_dt)) 
        eq = Eq(a, v * dv_ds) 
        
        
        limit_low = 0 # s1
        limit_high = s # s2
        
        
        eq_integral = eq.integral(s, limit_low, limit_high)
        
        eq_integral_doit = eq_integral.doit()
        
        eq_integral_doit_final = (eq_integral_doit * 2).simplify()
        
        self.eqs = [
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_integral_doit_final,
            ]
        
        eq_dsoln = dsolve(eq, v)
        
        eq_dsoln = eq_dsoln[-1]
        
        eq_dsoln_subs_0 = eq_dsoln.subs({s: 0})
        
        C1 = Symbol('C1')
        C1_val = solve(eq_dsoln_subs_0, C1)[0]

        eq_dsoln_subs = eq_dsoln.subs({C1: C1_val})
        
        eq_dsoln_subs_genform = (eq_dsoln_subs ** 2).simplify()
        
        
        self.eqs = [
            eq00,
            eq0,
            eq,
            eq_integral,
            eq_integral_doit,
            eq_dsoln,
            eq_dsoln_subs_0,
            eq_dsoln_subs,
            eq_dsoln_subs_genform,
            ]
        
        labels = {
            a: "acceleration",
            v: "velocity",
            s: "displacement",
            t: "time",
        }
        labels_s = eq.show_labels(labels)

        
        problem_s = f"""
        <div style="line-height:1.8em;">
        Find relation between ${latex(a)}$, ${latex(v)}$ and ${latex(s)}$ 
        where:
        {labels_s}
        </div>
        """
        
        problemTemplate.add_problem(problem_s.strip(), "text/html",
                                    add_html_line_break = True)
        
        
        soln_s = f"""
        <h2>First Part:</h2>
        $\\displaystyle {latex(eq00)}$
        
        $\\displaystyle \\implies {latex(eq0)}$
        
        $\\displaystyle \\implies {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_integral)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit)}$
        
        $\\displaystyle \\implies {latex(eq_integral_doit_final)}$
        
        <h2>Second Part:</h2>
        $\\displaystyle {latex(eq)}$
        
        $\\displaystyle \\implies {latex(eq_dsoln)}$

        $\\displaystyle \\implies {latex(eq_dsoln_subs_0)}$ \t\t at ${latex(t)} = 0$
        
        $\\displaystyle \\implies {latex(eq_dsoln_subs)}$ 

        $\\displaystyle \\implies {latex(eq_dsoln_subs_genform)}$ 


        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        $\\displaystyle {latex(eq_dsoln_subs_genform)}$ 
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        return problemTemplate
        pass


