#!/usr/bin/env python3
"""Optional learner exercise. This intentionally fails until integrate is implemented.
Implement Euler/Heun without calling the supplied reference. Python 3.10+.
The public checks are practice, not independent grading or code review.
"""
import math

def integrate(point, time, dt, method, velocity):
    """Return a NEW two-coordinate point, leaving the input unchanged.
    Euler: query velocity once at (point,time).
    Heun: query there, predict the Euler endpoint, query at that endpoint/time+dt,
    then use the average velocity. Do not make extra velocity calls.
    Reject unknown methods, nonfinite times/steps, dt <= 0, time < 0 or time+dt > 1.
    """
    raise NotImplementedError('Implement the numerical step before running these checks')

def check():
    for method,expected_calls in [('euler',1),('heun',2)]:
        calls=[]
        def constant(point,time):
            calls.append((list(point),time));return [2.,-1.]
        point=[1.,3.]
        result=integrate(point,0,.25,method,constant)
        assert result==[1.5,2.75] and point==[1.,3.] and result is not point
        assert len(calls)==expected_calls
    assert integrate([1.,0.],0,1,'euler',lambda x,t:x)==[2.,0.]
    assert integrate([1.,0.],0,1,'heun',lambda x,t:x)==[2.5,0.]
    # Time-dependent velocity catches using the wrong time in the second query.
    assert integrate([0.,0.],0,1,'heun',lambda x,t:[t,t])==[.5,.5]
    for time,dt,method in [(0,0,'euler'),(-1,.1,'euler'),(.8,.3,'heun'),(0,.1,'unknown'),(float('nan'),.1,'euler')]:
        try:
            integrate([0.,0.],time,dt,method,lambda x,t:x)
        except ValueError:
            pass
        else:
            raise AssertionError('Reject invalid controls with ValueError')
    print('Public sampler checks passed. Add your own counterexamples; independent review remains pending.')

if __name__=='__main__':
    check()
