import inspect

import numpy as np


def evaluatePolicy(T, N, agent, g, l, demandDist):
    res = []
    for _ in range(N):
        s = 0
        for t in range(T):
            prod = int(np.round(agent.decisionRule()))
            demand = demandDist()
            reward = g * min(prod, demand) - l * max(0, prod - demand)
            s += reward
            agent.receiveReward(reward)
        res.append(s)
    return np.mean(res)


def find_agent_classes(module):
    """Return (AgentK, AgentU) classes defined in `module`.

    Accepts either the canonical `AgentK`/`AgentU` names (used by the
    instructor's Baseline/Correction files) or the `<yourname>_K`/`<yourname>_U`
    naming convention students are asked to use for their submissions.
    """
    agentK = getattr(module, "AgentK", None)
    agentU = getattr(module, "AgentU", None)
    if agentK is None or agentU is None:
        for name, obj in inspect.getmembers(module, inspect.isclass):
            if obj.__module__ != module.__name__:
                continue
            if agentK is None and name.endswith("_K"):
                agentK = obj
            if agentU is None and name.endswith("_U"):
                agentU = obj
    return agentK, agentU
