import pytest
import mymlscratch
import numpy as np

def test_linear_regression_code_returns_string():
    code = mymlscratch.get_linear_regression_code()
    assert isinstance(code, str)
    assert len(code) > 0
    assert "LinearRegression" in code

def test_logistic_regression_code_returns_string():
    code = mymlscratch.get_logistic_regression_code()
    assert isinstance(code, str)
    assert len(code) > 0
    assert "LogisticRegression" in code

def test_knn_code_returns_string():
    code = mymlscratch.get_knn_code()
    assert isinstance(code, str)
    assert len(code) > 0
    assert "KNearestNeighbors" in code

def test_list_available_algorithms():
    algorithms = mymlscratch.list_available_algorithms()
    assert isinstance(algorithms, list)
    assert len(algorithms) > 0
    assert "linear_regression" in algorithms

def test_linear_regression_code_is_executable():
    code = mymlscratch.get_linear_regression_code()
    # This should not raise an exception
    namespace = {}
    exec(code, namespace)
    assert 'LinearRegression' in namespace
    
def test_linear_regression_functionality():
    code = mymlscratch.get_linear_regression_code()
    
    # Execute code in a namespace
    namespace = {}
    exec(code, namespace)
    
    # Get the LinearRegression class from namespace
    LinearRegression = namespace['LinearRegression']
    
    # Create simple dataset
    X = np.array([[1], [2], [3], [4], [5]])
    y = np.array([2, 4, 6, 8, 10])
    
    # Train model
    model = LinearRegression(learning_rate=0.01, n_iterations=100)
    model.fit(X, y)
    
    # Make predictions
    predictions = model.predict(X)
    
    # Check that predictions are reasonable
    assert predictions.shape == y.shape
    assert np.allclose(predictions, y, atol=1.0)