Instruction:
Write a Python 3 script for
returning the maximum possible number of plates in a module given a set of sed plates.

Response:
def n_sed_plates_max(sed_inputs=sed_dict):
    """Return the maximum possible number of plate settlers in a module given
    plate spacing, thickness, angle, and unsupported length of plate settler.
    Parameters
    ----------
    S_plate : float
        Edge to edge distance between plate settlers
    thickness_plate : float
        Thickness of PVC sheet used to make plate settlers
    L_sed_plate_cantilevered : float
        Maximum length of sed plate sticking out past module pipes without any
        additional support. The goal is to prevent floppy modules that don't
        maintain constant distances between the plates
    angle_plate : float
        Angle of plate settlers
    Returns
    -------
    int
        Maximum number of plates
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    B_plate = sed_inputs['plate_settlers']['S'] + sed_inputs['plate_settlers']['thickness']
    return math.floor((sed_inputs['plate_settlers']['L_cantilevered'].magnitude / B_plate.magnitude
                      * np.tan(sed_inputs['plate_settlers']['angle'].to(u.rad).magnitude)) + 1)


Instruction:
Can you write a function in Python 3 where it
returns the minimum inner width of each diffuser in the sedimentation tank.

Response:
def w_diffuser_inner_min(sed_inputs=sed_dict):
    """Return the minimum inner width of each diffuser in the sedimentation tank.
    Parameters
    ----------
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations. Can be found in sed.yaml
    Returns
    -------
    float
        Minimum inner width of each diffuser in the sedimentation tank
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    return ((sed_inputs['tank']['vel_up'].to(u.inch/u.s).magnitude /
             sed_inputs['manifold']['diffuser']['vel_max'].to(u.inch/u.s).magnitude)
             * sed_inputs['tank']['W'])


Instruction:
Write a Python 3 script for
returning the inner width of each diffuser in the sedimentation tank.

Response:
def w_diffuser_inner(sed_inputs=sed_dict):
    """Return the inner width of each diffuser in the sedimentation tank.
    Parameters
    ----------
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Inner width of each diffuser in the sedimentation tank
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    return ut.ceil_nearest(w_diffuser_inner_min(sed_inputs).magnitude,
                           (np.arange(1/16,1/4,1/16)*u.inch).magnitude)


Instruction:
How would you explain what the following Python 3 function does
def w_diffuser_outer(sed_inputs=sed_dict):
    return (w_diffuser_inner_min(sed_inputs['tank']['W']) +
            (2 * sed_inputs['manifold']['diffuser']['thickness_wall'])).to(u.m).magnitude

Response: Return the outer width of each diffuser in the sedimentation tank.


Instruction:
Given the following Python 3 function, write the documentation
def L_diffuser_outer(sed_inputs=sed_dict):
    return ((sed_inputs['manifold']['diffuser']['A'] /
           (2 * sed_inputs['manifold']['diffuser']['thickness_wall']))
           - w_diffuser_inner(sed_inputs).to(u.inch)).to(u.m).magnitude

Response: Return the outer length of each diffuser in the sedimentation tank.


Instruction:
How would you code a function in Python 3 to
return the inner length of each diffuser in the sedimentation tank.

Response:
def L_diffuser_inner(sed_inputs=sed_dict):
    """Return the inner length of each diffuser in the sedimentation tank.
    Parameters
    ----------
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Inner length of each diffuser in the sedimentation tank
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    return L_diffuser_outer(sed_inputs['tank']['W']) -
            (2 * (sed_inputs['manifold']['diffuser']['thickness_wall']).to(u.m)).magnitude)


Instruction:
Explain what the following Python 3 code does
def q_diffuser(sed_inputs=sed_dict):
    return (sed_inputs['tank']['vel_up'].to(u.m/u.s) *
             sed_inputs['tank']['W'].to(u.m) *
             L_diffuser_outer(sed_inputs)).magnitude

Response: Return the flow through each diffuser in the sedimentation tank.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def vel_sed_diffuser(sed_inputs=sed_dict):
    return (q_diffuser(sed_inputs).magnitude
            / (w_diffuser_inner(w_tank) * L_diffuser_inner(w_tank)).magnitude)

Response: Return the velocity through each diffuser in the sedimentation tank.


Instruction:
How would you explain what the following Python 3 function does
def q_tank(sed_inputs=sed_dict):
    return (sed_inputs['tank']['L'] * sed_inputs['tank']['vel_up'].to(u.m/u.s) *
            sed_inputs['tank']['W'].to(u.m)).magnitude

Response: Return the maximum flow through one sedimentation tank.


Instruction:
How would you implement a function in Python 3 that
returns the maximum velocity through the manifold.

Response:
def vel_inlet_man_max(sed_inputs=sed_dict):
    """Return the maximum velocity through the manifold.
    Parameters
    ----------
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Maximum velocity through the manifold.
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    vel_manifold_max = (sed_inputs['diffuser']['vel_max'].to(u.m/u.s).magnitude *
        sqrt(2*((1-(sed_inputs['manifold']['ratio_Q_man_orifice'])**2)) /
        (((sed_inputs['manifold']['ratio_Q_man_orifice'])**2)+1)))
    return vel_manifold_max


Instruction:
Implement a Python 3 function for
returning the number of tanks required for a given flow rate.

Response:
def n_tanks(Q_plant, sed_inputs=sed_dict):
    """Return the number of sedimentation tanks required for a given flow rate.
    Parameters
    ----------
    Q_plant : float
        Total plant flow rate
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    int
        Number of sedimentation tanks required for a given flow rate.
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    q = q_tank(sed_inputs).magnitude
    return (int(np.ceil(Q_plant / q)))


Instruction:
Create a Python 3 function to
return the length of the inlet and exit channels for the sedimentation tank.

Response:
def L_channel(Q_plant, sed_inputs=sed_dict):
    """Return the length of the inlet and exit channels for the sedimentation tank.
    Parameters
    ----------
    Q_plant : float
        Total plant flow rate
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Length of the inlet and exit channels for the sedimentation tank.
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    n_tanks = n_tanks(Q_plant, sed_inputs)
    return ((n_tanks * sed_inputs['tank']['W']) + sed_inputs['thickness_wall'] +
            ((n_tanks-1) * sed_inputs['thickness_wall']))


Instruction:
Implement a function in Python 3 to
return the inner diameter of the exit manifold by guessing an initial diameter of the exit manifold.

Response:
def ID_exit_man(Q_plant, temp, sed_inputs=sed_dict):
    """Return the inner diameter of the exit manifold by guessing an initial
    diameter then iterating through pipe flow calculations until the answer
    converges within 1%% error
    Parameters
    ----------
    Q_plant : float
        Total plant flow rate
    temp : float
        Design temperature
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Inner diameter of the exit manifold
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    #Inputs do not need to be checked here because they are checked by
    #functions this function calls.
    nu = pc.viscosity_dynamic(temp)
    hl = sed_input['manifold']['exit_man']['hl_orifice'].to(u.m)
    L = sed_ipnut['manifold']['tank']['L']
    N_orifices = sed_inputs['manifold']['exit_man']['N_orifices']
    K_minor = con.K_MINOR_PIPE_EXIT
    pipe_rough = mat.PIPE_ROUGH_PVC.to(u.m)

    D = max(diam_pipemajor(Q_plant, hl, L, nu, pipe_rough).magnitude,
                   diam_pipeminor(Q_plant, hl, K_minor).magnitude)
    err = 1.00
    while err > 0.01:
            D_prev = D
            f = pc.fric(Q_plant, D_prev, nu, pipe_rough)
            D = ((8*Q_plant**2 / pc.GRAVITY.magnitude * np.pi**2 * hl) *
                    (((f*L/D_prev + K_minor) * (1/3 * 1/) *
                    (1/3 + 1/(2 * N_orifices) + 1/(6 * N_orifices**2)))
                    / (1 - sed_inputs['manifold']['ratio_Q_orifice']**2)))**0.25
            err = abs(D_prev - D) / ((D + D_prev) / 2)
    return D


Instruction:
Create a Python 3 function for
returning the diameter of the orifices in the exit manifold for the sedimentation tank.

Response:
def D_exit_man_orifice(Q_plant, drill_bits, sed_inputs=sed_dict):
    """Return the diameter of the orifices in the exit manifold for the sedimentation tank.
    Parameters
    ----------
    Q_plant : float
        Total plant flow rate
    drill_bits : list
        List of possible drill bit sizes
    sed_inputs : dict
        A dictionary of all of the constant inputs needed for sedimentation tank
        calculations can be found in sed.yaml
    Returns
    -------
    float
        Diameter of the orifices in the exit manifold for the sedimentation tank.
    Examples
    --------
    >>> from aide_design.play import*
    >>>
    """
    Q_orifice = Q_plant/sed_input['exit_man']['N_orifices']
    D_orifice = np.sqrt(Q_orifice**4)/(np.pi * con.RATIO_VC_ORIFICE * np.sqrt(2 * pc.GRAVITY.magnitude * sed_input['exit_man']['hl_orifice'].magnitude))
    return ut.ceil_nearest(D_orifice, drill_bits)


Instruction:
Can you generate the documentation for the following Python 3 function
def L_sed_plate(sed_inputs=sed_dict):
    L_sed_plate = ((sed_input['plate_settlers']['S'] * ((sed_input['tank']['vel_up']/sed_input['plate_settlers']['vel_capture'])-1)
                  + sed_input['plate_settlers']['thickness'] * (sed_input['tank']['vel_up']/sed_input['plate_settlers']['vel_capture']))
                 / (np.sin(sed_input['plate_settlers']['angle']) * np.cos(sed_input['plate_settlers']['angle']))
                 ).to(u.m)
    return L_sed_plate

Response: Return the length of a single plate in the plate settler module based on the desired capture velocity.


Instruction:
Can you generate the documentation for the following Python 3 function
def OD(ND):
    index = (np.abs(np.array(pipedb['NDinch']) - (ND))).argmin()
    return pipedb.iloc[index, 1]

Response: Return a pipe s outer diameter according to its nominal diameter.


Instruction:
Implement a Python 3 function for
returning the inner diameter for schedule 40 pipes.

Response:
def ID_sch40(ND):
    """Return the inner diameter for schedule 40 pipes.

    The wall thickness for these pipes is in the pipedb.

    Take the values of the array, subtract the ND, take the absolute
    value, find the index of the minimium value.
    """
    myindex = (np.abs(np.array(pipedb['NDinch']) - (ND))).argmin()
    return (pipedb.iloc[myindex, 1] - 2*(pipedb.iloc[myindex, 5]))


Instruction:
Here you have a function in Python 3, explain what it does
def ND_all_available():
    ND_all_available = []
    for i in range(len(pipedb['NDinch'])):
        if pipedb.iloc[i, 4] == 1:
            ND_all_available.append((pipedb['NDinch'][i]))
    return ND_all_available * u.inch

Response: Return an array of nominal diameters.


Instruction:
Can you generate the documentation for the following Python 3 function
def ID_SDR_all_available(SDR):
    ID = []
    ND = ND_all_available()
    for i in range(len(ND)):
        ID.append(ID_SDR(ND[i], SDR).magnitude)
    return ID * u.inch

Response: Return an array of inner diameters with a given SDR.


Instruction:
Can you tell what is the following Python 3 function doing
def ND_SDR_available(ID, SDR):
    for i in range(len(np.array(ID_SDR_all_available(SDR)))):
        if np.array(ID_SDR_all_available(SDR))[i] >= (ID.to(u.inch)).magnitude:
            return ND_all_available()[i]

Response: Return an available ND given an ID and a schedule.


Instruction:
Can you generate the documentation for the following Python 3 function
def flow_pipeline(diameters, lengths, k_minors, target_headloss,
                  nu=con.WATER_NU, pipe_rough=mats.PVC_PIPE_ROUGH):
    """
    This function takes a single pipeline with multiple sections, each potentially with different diameters,
    lengths and minor loss coefficients and determines the flow rate for a given headloss.

    :param diameters: list of diameters, where the i_th diameter corresponds to the i_th pipe section
    :type diameters: numpy.ndarray
    :param lengths: list of diameters, where the i_th diameter corresponds to the i_th pipe section
    :type lengths: numpy.ndarray
    :param k_minors: list of diameters, where the i_th diameter corresponds to the i_th pipe section
    :type k_minors: numpy.ndarray
    :param target_headloss: a single headloss describing the total headloss through the system
    :type target_headloss: float
    :param nu: The fluid dynamic viscosity of the fluid. Defaults to water at room temperature (1 * 10**-6 * m**2/s)
    :type nu: float
    :param pipe_rough:  The pipe roughness. Defaults to PVC roughness.
    :type pipe_rough: float

    :return: the total flow through the system
    :rtype: float
    """

    # Ensure all the arguments except total headloss are the same length
    #TODO

    # Total number of pipe lengths
    n = diameters.size

    # Start with a flow rate guess based on the flow through a single pipe section
    flow = pc.flow_pipe(diameters[0], target_headloss, lengths[0], nu, pipe_rough, k_minors[0])
    err = 1.0

    # Add all the pipe length headlosses together to test the error
    while abs(err) > 0.01 :
        headloss = sum([pc.headloss(flow, diameters[i], lengths[i], nu, pipe_rough,
                                    k_minors[i]).to(u.m).magnitude for i in range(n)])
        # Test the error. This is always less than one.
        err = (target_headloss - headloss) / (target_headloss + headloss)
        # Adjust the total flow in the direction of the error. If there is more headloss than target headloss,
        # The flow should be reduced, and vice-versa.
        flow = flow + err * flow

    return flow

Response: This function takes a single pipeline with multiple sections each potentially with different diameters lengths and minor loss coefficients and determines the flow rate for a given headloss.


Instruction:
Can you create a Python 3 function that
returns the width of a Stout weir at elevation z. More info LFOM + sutro + weir + research >

Response:
def stout_w_per_flow(self, z):
        """Return the width of a Stout weir at elevation z. More info
        here. <https://confluence.cornell.edu/display/AGUACLARA/
        LFOM+sutro+weir+research>
        """
        w_per_flow = 2 / ((2 * pc.gravity * z) ** (1 / 2) *
                          con.VC_ORIFICE_RATIO * np.pi * self.hl)
        return w_per_flow.to_base_units()


Instruction:
Can you generate the documentation for the following Python 3 function
def nom_diam_pipe(self):
        ID = pc.diam_circle(self.area_pipe_min)
        return pipe.ND_SDR_available(ID, self.sdr)

Response: The nominal diameter of the LFOM pipe


Instruction:
Create a Python 3 function to
estimate the area of the top orifice for the given set of orifices.

Response:
def area_top_orifice(self):
        """Estimate the orifice area corresponding to the top row of orifices.
        Another solution method is to use integration to solve this problem.
        Here we use the width of the stout weir in the center of the top row
        to estimate the area of the top orifice
        """
        # Calculate the center of the top row:
        z = self.hl - 0.5 * self.b_rows
        # Multiply the stout weir width by the height of one row.
        return self.stout_w_per_flow(z) * self.q * self.b_rows


Instruction:
Can you generate the documentation for the following Python 3 function
def flow_ramp(self):
        return np.linspace(1 / self.n_rows, 1, self.n_rows)*self.q

Response: An equally spaced array representing flow at each row.


Instruction:
Can you write a function in Python 3 where it
calculates the height of the center of each row of orifices.

Response:
def height_orifices(self):
        """Calculates the height of the center of each row of orifices.
        The bottom of the bottom row orifices is at the zero elevation
        point of the LFOM so that the flow goes to zero when the water height
        is at zero.
        """

        return (np.linspace(0, self.n_rows-1, self.n_rows))*self.b_rows + 0.5 * self.orifice_diameter


Instruction:
Given the following Python 3 function, write the documentation
def flow_actual(self, Row_Index_Submerged, N_LFOM_Orifices):

        flow = 0
        for i in range(Row_Index_Submerged + 1):
            flow = flow + (N_LFOM_Orifices[i] * (
               pc.flow_orifice_vert(self.orifice_diameter,
                                    self.b_rows*(Row_Index_Submerged + 1)
                                    - self.height_orifices[i],
                                    con.VC_ORIFICE_RATIO)))
        return flow

Response: Calculates the flow for a given number of submerged rows of orifices.


Instruction:
Explain what the following Python 3 code does
def n_orifices_per_row(self):
        # H is distance from the bottom of the next row of orifices to the
        # center of the current row of orifices
        H = self.b_rows - 0.5*self.orifice_diameter
        flow_per_orifice = pc.flow_orifice_vert(self.orifice_diameter, H, con.VC_ORIFICE_RATIO)
        n = np.zeros(self.n_rows)
        for i in range(self.n_rows):
            # calculate the ideal number of orifices at the current row without
            # constraining to an integer
            flow_needed = self.flow_ramp[i] - self.flow_actual(i, n)
            n_orifices_real = (flow_needed / flow_per_orifice).to(u.dimensionless)
            # constrain number of orifices to be less than the max per row and
            # greater or equal to 0
            n[i] = min((max(0, round(n_orifices_real))), self.n_orifices_per_row_max)
        return n

Response: Calculate number of orifices at each level given an orifice magnitude.


Instruction:
Here you have a function in Python 3, explain what it does
def error_per_row(self):
        FLOW_lfom_error = np.zeros(self.n_rows)
        for i in range(self.n_rows):
            actual_flow = self.flow_actual(i, self.n_orifices_per_row)
            FLOW_lfom_error[i] = (((actual_flow - self.flow_ramp[i]) / self.flow_ramp[i]).to(u.dimensionless)).magnitude
        return FLOW_lfom_error

Response:
This function calculates the error of the design based on the predicted flow rate
        and the actual flow rate through the LFOM.


Instruction:
Can you create a Python 3 function that
returns array of possible drill diameters in imperial.

Response:
def get_drill_bits_d_imperial():
    """Return array of possible drill diameters in imperial."""
    step_32nd = np.arange(0.03125, 0.25, 0.03125)
    step_8th = np.arange(0.25, 1.0, 0.125)
    step_4th = np.arange(1.0, 2.0, 0.25)
    maximum = [2.0]

    return np.concatenate((step_32nd,
                           step_8th,
                           step_4th,
                           maximum)) * u.inch


Instruction:
Write a Python 3 function that can
return array of possible drill diameters in metric.

Response:
def get_drill_bits_d_metric():
    """Return array of possible drill diameters in metric."""
    return np.concatenate((np.arange(1.0, 10.0, 0.1),
                           np.arange(10.0, 18.0, 0.5),
                           np.arange(18.0, 36.0, 1.0),
                           np.arange(40.0, 55.0, 5.0))) * u.mm


Instruction:
Explain what the following Python 3 code does
def C_stock(self):
        return self._C_sys * (self._Q_sys / self._Q_stock).to(u.dimensionless)

Response: Return the required concentration of material in the stock given the system concentration and flow rate.


Instruction:
Can you implement a function in Python 3 that
returns the amount of time at which the materal will be depleted.

Response:
def T_stock(self, V_stock):
        """Return the amount of time at which the stock of materal will be
        depleted.

        :param V_stock: Volume of the stock of material
        :type V_stock: float

        :return: Time at which the stock will be depleted
        :rtype: float
        """
        return Stock.T_stock(self, V_stock, self._Q_stock).to(u.hr)


Instruction:
How would you implement a function in Python 3 that
returns the volume of super ( more concentrated ) stock that must be diluted for the desired stock volume and required concentration.

Response:
def V_super_stock(self, V_stock, C_super_stock):
        """Return the volume of super (more concentrated) stock that must be
        diluted for the desired stock volume and required stock concentration.

        :param V_stock: Volume of the stock of material
        :type V_stock: float
        :param C_super_stock: Concentration of the super stock
        :type C_super_stock: float

        :return: Volume of super stock to dilute
        :rtype: float
        """
        return Stock.V_super_stock(self, V_stock, self.C_stock(), C_super_stock)


Instruction:
Write a Python 3 function for
returning the required flow rate given a reactor s desired system flow rate system concentration and stock concentration and stock concentration.

Response:
def Q_stock(self):
        """Return the required flow rate from the stock of material given
        a reactor's desired system flow rate, system concentration, and stock
        concentration.

        :return: Flow rate from the stock of material
        :rtype: float
        """
        return self._Q_sys * (self._C_sys / self._C_stock).to(u.dimensionless)


Instruction:
Given the following Python 3 function, write the documentation
def rpm(self, vol_per_rev):
        return Stock.rpm(self, vol_per_rev, self.Q_stock()).to(u.rev/u.min)

Response:
Return the pump speed required for the reactor s stock of material
        given the volume of fluid output per revolution by the stock s pump.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def T_stock(self, V_stock):
        return Stock.T_stock(self, V_stock, self.Q_stock()).to(u.hr)

Response: Return the amount of time at which the materal will be depleted.


Instruction:
How would you explain what the following Python 3 function does
def V_super_stock(self, V_stock, C_super_stock):
        return Stock.V_super_stock(self, V_stock, self._C_stock, C_super_stock)

Response:
Returns the volume of super ( more concentrated ) stock that must be
        diluted for the desired volume and stock concentration.


Instruction:
Given the following Python 3 function, write the documentation
def vel_grad_avg(self):
        return ((u.standard_gravity * self.HL) /
               (pc.viscosity_kinematic(self.temp) * self.Gt)).to(u.s ** -1)

Response:
Calculate the average velocity gradient of water flowing
        through the flocculator.


Instruction:
How would you implement a function in Python 3 that
calculates the minimum flocculator channel width given the minimum H_e and S ratio between expansion height H and baffle spacing S.

Response:
def W_min_HS_ratio(self):
        """Calculate the minimum flocculator channel width, given the minimum
        ratio between expansion height (H) and baffle spacing (S).
        :returns: Minimum channel width given H_e/S
        :rtype: float * centimeter
        """
        return ((self.HS_RATIO_MIN * self.Q / self.downstream_H) *
               (self.BAFFLE_K /
                (2 * self.downstream_H * pc.viscosity_kinematic(self.temp) * self.vel_grad_avg ** 2)) ** (1/3)
               ).to(u.cm)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def channel_n(self):
        min_hydraulic_W =\
            np.amax(np.array([1, (self.max_W/self.W_min_HS_ratio).to(u.dimensionless)])) * self.W_min_HS_ratio
        return 2*np.ceil(((self.vol / (min_hydraulic_W * self.downstream_H) +
                           self.ent_tank_L) / (2 * self.max_L)).to(u.dimensionless))

Response: Calculates the minimum number of channels based on the maximum possible channel width and the maximum length of the channels.


Instruction:
Here you have a function in Python 3, explain what it does
def channel_L(self):
        channel_L = ((self.vol / (self.channel_W * self.downstream_H) + self.ent_tank_L) / self.channel_n).to(u.m)
        return channel_L

Response: The channel length of the flocculator.


Instruction:
Implement a function in Python 3 to
return the maximum distance between expansions for the largest allowable H / S ratio.

Response:
def expansion_max_H(self):
        """"Return the maximum distance between expansions for the largest
        allowable H/S ratio.
        :returns: Maximum expansion distance
        :rtype: float * meter
        Examples
        --------
        exp_dist_max(20*u.L/u.s, 40*u.cm, 37000, 25*u.degC, 2*u.m)
        0.375 meter
        """
        return (((self.BAFFLE_K / (2 * pc.viscosity_kinematic(self.temp) * (self.vel_grad_avg ** 2))) *
                (self.Q * self.RATIO_MAX_HS / self.channel_W) ** 3) ** (1/4)).to(u.m)


Instruction:
Can you implement a function in Python 3 that
returns the spacing between baffles.

Response:
def baffle_S(self):
        """Return the spacing between baffles.
        :returns: Spacing between baffles
        :rtype: int
        """
        return ((self.BAFFLE_K /
                ((2 * self.expansion_H * (self.vel_grad_avg ** 2) *
                 pc.viscosity_kinematic(self.temp))).to_base_units()) ** (1/3) *
               self.Q / self.channel_W).to(u.cm)


Instruction:
Here you have a function in Python 3, explain what it does
def drain_K(self):
        drain_K = minorloss.PIPE_ENTRANCE_K_MINOR + minorloss.PIPE_ENTRANCE_K_MINOR + minorloss.PIPE_EXIT_K_MINOR
        return drain_K

Response: Return the minor loss coefficient of the drain pipe.


Instruction:
How would you explain what the following Python 3 function does
def drain_D(self):
        tank_A = 2 * self.channel_L * self.channel_W
        drain_D = (np.sqrt(8 * tank_A / (np.pi * self.drain_t) * np.sqrt(
           self.downstream_H * self.drain_K / (2 * u.standard_gravity)))).to_base_units()
        return drain_D

Response: Returns depth of drain pipe.


Instruction:
Write a Python 3 script for
returning the diameter of the drain pipe.

Response:
def drain_ND(self):
        """Returns the diameter of the drain pipe.
        Each drain pipe will drain two channels because channels are connected by
        a port at the far end and the first channel can't have a drain because
        of the entrance tank. Need to review the design to see if this is a good
        assumption.
        D_{Pipe} = \sqrt{ \frac{8 A_{Tank}}{\pi t_{Drain}} \sqrt{ \frac{h_0 \sum K}{2g} } }
        :returns: list of designed values
        :rtype: float * centimeter
        """
        drain_ND = pipes.ND_SDR_available(self.drain_D, self.SDR)
        return drain_ND


Instruction:
How would you implement a function in Python 3 that
returns the designed values.

Response:
def design(self):
        """Returns the designed values.
        :returns: list of designed values (G, t, channel_W, obstacle_n)
        :rtype: int
        """
        floc_dict = {'channel_n': self.channel_n,
                     'channel_L': self.channel_L,
                     'channel_W': self.channel_W,
                     'baffle_S': self.baffle_S,
                     'obstacle_n': self.obstacle_n,
                     'G': self.vel_grad_avg,
                     't': self.retention_time,
                     'expansion_max_H': self.expansion_max_H,
                     'drain_ND': self.drain_ND}
        return floc_dict


Instruction:
Implement a function in Python 3 to
draw the Onshape flocculator model based off of this object.

Response:
def draw(self):
        """Draw the Onshape flocculator model based off of this object."""
        from onshapepy import Part
        CAD = Part(
            'https://cad.onshape.com/documents/b4cfd328713460beeb3125ac/w/3928b5c91bb0a0be7858d99e/e/6f2eeada21e494cebb49515f'
        )
        CAD.params = {
            'channel_L': self.channel_L,
            'channel_W': self.channel_W,
            'channel_H': self.downstream_H,
            'channel_pairs': self.channel_n/2,
            'baffle_S': self.baffle_S,
        }


Instruction:
Make a summary of the following Python 3 code
def viscosity_kinematic_alum(conc_alum, temp):
    nu = (1 + (4.255 * 10**-6) * conc_alum**2.289) * pc.viscosity_kinematic(temp).magnitude
    return nu

Response: Return the dynamic viscosity of water at a given temperature.


Instruction:
Explain what the following Python 3 code does
def viscosity_kinematic_pacl(conc_pacl, temp):
    nu = (1 + (2.383 * 10**-5) * conc_pacl**1.893) * pc.viscosity_kinematic(temp).magnitude
    return nu

Response: Return the dynamic viscosity of water at a given temperature.


Instruction:
Can you implement a function in Python 3 that
returns the dynamic viscosity of water at a given temperature.

Response:
def viscosity_kinematic_chem(conc_chem, temp, en_chem):
     """Return the dynamic viscosity of water at a given temperature.

    If given units, the function will automatically convert to Kelvin.
    If not given units, the function will assume Kelvin.
    """
     if en_chem == 0:
         nu = viscosity_kinematic_alum(conc_chem, temp).magnitude
     if en_chem == 1:
         nu =  viscosity_kinematic_pacl(conc_chem, temp).magnitude
     if en_chem not in [0,1]:
         nu =  pc.viscosity_kinematic(temp).magnitude
     return nu


Instruction:
Can you tell what is the following Python 3 function doing
def max_linear_flow(Diam, HeadlossCDC, Ratio_Error, KMinor):
    flow = (pc.area_circle(Diam)).magnitude * np.sqrt((2 * Ratio_Error * HeadlossCDC * pc.gravity)/ KMinor)
    return flow.magnitude

Response: Return the maximum flow that can be put through a tube of a given diameter with a linear head loss.


Instruction:
Write a Python 3 function that can
calculate the length of each tube given the corresponding flow rate and coagulant.

Response:
def _length_cdc_tube_array(FlowPlant, ConcDoseMax, ConcStock,
                           DiamTubeAvail, HeadlossCDC, temp, en_chem, KMinor):
    """Calculate the length of each diameter tube given the corresponding flow rate
    and coagulant. Choose the tube that is shorter than the maximum length tube."""

    Flow = _flow_cdc_tube(FlowPlant, ConcDoseMax, ConcStock, DiamTubeAvail, HeadlossCDC,Ratio_Error, KMinor).magnitude

    return _len_tube(Flow, DiamTubeAvail, HeadlossCDC, ConcStock, temp, en_chem, KMinor).magnitude


Instruction:
Write a Python 3 function that can
return the length of the tubing in the specified order.

Response:
def len_cdc_tube(FlowPlant, ConcDoseMax, ConcStock,
                 DiamTubeAvail, HeadlossCDC, LenCDCTubeMax, temp,
                 en_chem, KMinor):
   """The length of tubing may be longer than the max specified if the stock
   concentration is too high to give a viable solution with the specified
   length of tubing."""
   index = i_cdc(FlowPlant, ConcDoseMax, ConcStock,
                DiamTubeAvail, HeadlossCDC, LenCDCTubeMax, temp,
                en_chem, KMinor)
   len_cdc_tube = (_length_cdc_tube_array(FlowPlant, ConcDoseMax, ConcStock,
                                        DiamTubeAvail, HeadlossCDC, temp, en_chem,
                                        KMinor))[index].magnitude

   return len_cdc_tube


Instruction:
Write a Python 3 script for
returning the density of the aluminum in the nanocluster.

Response:
def dens_alum_nanocluster(coag):
    """Return the density of the aluminum in the nanocluster.

    This is useful for determining the volume of nanoclusters
    given a concentration of aluminum.
    """
    density = (coag.PrecipDensity * MOLEC_WEIGHT_ALUMINUM
               * coag.PrecipAluminumMPM / coag.PrecipMolecWeight)
    return density


Instruction:
Create a Python 3 function to
return the density of the PACl solution.

Response:
def dens_pacl_solution(ConcAluminum, temp):
    """Return the density of the PACl solution.

    From Stock Tank Mixing report Fall 2013:
    https://confluence.cornell.edu/download/attachments/137953883/20131213_Research_Report.pdf
    """
    return ((0.492 * ConcAluminum * PACl.MolecWeight
             / (PACl.AluminumMPM * MOLEC_WEIGHT_ALUMINUM)
             ) + pc.density_water(temp).magnitude
            )


Instruction:
Here you have a function in Python 3, explain what it does
def particle_number_concentration(ConcMat, material):
    return ConcMat.to(material.Density.units) / ((material.Density * np.pi * material.Diameter**3) / 6)

Response: Return the number of particles in the suspension.


Instruction:
Here you have a function in Python 3, explain what it does
def sep_dist_clay(ConcClay, material):
    return ((material.Density/ConcClay)*((np.pi
                            * material.Diameter ** 3)/6))**(1/3)

Response: Return the separation distance between clay particles.


Instruction:
How would you implement a function in Python 3 that
returns the number of nanoclusters in a given Aluminum.

Response:
def num_nanoclusters(ConcAluminum, coag):
    """Return the number of Aluminum nanoclusters."""
    return (ConcAluminum / (dens_alum_nanocluster(coag).magnitude
                            * np.pi * coag.Diameter**3))


Instruction:
Can you generate the documentation for the following Python 3 function
def frac_vol_floc_initial(ConcAluminum, ConcClay, coag, material):
    return ((conc_precipitate(ConcAluminum, coag).magnitude/coag.PrecipDensity)
            + (ConcClay / material.Density))

Response: Return the volume fraction of flocs initially present in a single particle system.


Instruction:
How would you code a function in Python 3 to
calculate the number of doubling collisions required to produce a single doubling .

Response:
def num_coll_reqd(DIM_FRACTAL, material, DiamTarget):
    """Return the number of doubling collisions required.

    Calculates the number of doubling collisions required to produce
    a floc of diameter DiamTarget.
    """
    return DIM_FRACTAL * np.log2(DiamTarget/material.Diameter)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def sep_dist_floc(ConcAluminum, ConcClay, coag, material,
                  DIM_FRACTAL, DiamTarget):
    """Return separation distance as a function of floc size."""
    return (material.Diameter
            * (np.pi/(6
                      * frac_vol_floc_initial(ConcAluminum, ConcClay,
                                              coag, material)
                      ))**(1/3)
            * (DiamTarget / material.Diameter)**(DIM_FRACTAL / 3)
            )

Response: Return separation distance as a function of floc size.


Instruction:
Can you implement a function in Python 3 that
returns the floc volume fraction.

Response:
def frac_vol_floc(ConcAluminum, ConcClay, coag, DIM_FRACTAL,
                  material, DiamTarget):
    """Return the floc volume fraction."""
    return (frac_vol_floc_initial(ConcAluminum, ConcClay, coag, material)
            * (DiamTarget / material.Diameter)**(3-DIM_FRACTAL)
            )


Instruction:
Here you have a function in Python 3, explain what it does
def dens_floc_init(ConcAluminum, ConcClay, coag, material):
    return (conc_floc(ConcAluminum, ConcClay, coag).magnitude
            / frac_vol_floc_initial(ConcAluminum, ConcClay, coag, material)
            )

Response: Return the density of the initial floc.


Instruction:
How would you explain what the following Python 3 function does
def ratio_area_clay_total(ConcClay, material, DiamTube, RatioHeightDiameter):
    return (1
            / (1
               + (2 * material.Diameter
                  / (3 * DiamTube * ratio_clay_sphere(RatioHeightDiameter)
                     * (ConcClay / material.Density)
                     )
                  )
               )
            )

Response: Calculates the total surface area of clay in suspension with the given concentration and material.


Instruction:
Can you create a Python 3 function that
calculates the coverage of a coagulant with the given clay.

Response:
def gamma_coag(ConcClay, ConcAluminum, coag, material,
               DiamTube, RatioHeightDiameter):
    """Return the coverage of clay with nanoglobs.

    This function accounts for loss to the tube flocculator walls
    and a poisson distribution on the clay given random hits by the
    nanoglobs. The poisson distribution results in the coverage only
    gradually approaching full coverage as coagulant dose increases.

    :param ConcClay: Concentration of clay in suspension
    :type ConcClay: float
    :param ConcAluminum: Concentration of aluminum in solution
    :type ConcAluminum: float
    :param coag: Type of coagulant in solution, e.g. floc_model.PACl
    :type coag: floc_model.Material
    :param material: Type of clay in suspension, e.g. floc_model.Clay
    :type material: floc_model.Material
    :param DiamTube: Diameter of flocculator tube (assumes tube flocculator for calculation of reactor surface area)
    :type DiamTube: float
    :param RatioHeightDiameter: Dimensionless ratio of clay height to clay diameter
    :type RatioHeightDiameter: float

    :return: Fraction of the clay surface area that is coated with coagulant precipitates
    :rtype: float
    """
    return (1 - np.exp((
                       (-frac_vol_floc_initial(ConcAluminum, 0*u.kg/u.m**3, coag, material)
                         * material.Diameter)
                        / (frac_vol_floc_initial(0*u.kg/u.m**3, ConcClay, coag, material)
                           * coag.Diameter))
                       * (1 / np.pi)
                       * (ratio_area_clay_total(ConcClay, material,
                                                DiamTube, RatioHeightDiameter)
                          / ratio_clay_sphere(RatioHeightDiameter))
                       ))


Instruction:
Implement a function in Python 3 to
return the fraction of the coagulant that is coated with humic acid.

Response:
def gamma_humic_acid_to_coag(ConcAl, ConcNatOrgMat, NatOrgMat, coag):
    """Return the fraction of the coagulant that is coated with humic acid.

    :param ConcAl: Concentration of alumninum in solution
    :type ConcAl: float
    :param ConcNatOrgMat: Concentration of natural organic matter in solution
    :type ConcNatOrgMat: float
    :param NatOrgMat: type of natural organic matter, e.g. floc_model.HumicAcid
    :type NatOrgMat: floc_model.Material
    :param coag: Type of coagulant in solution, e.g. floc_model.PACl
    :type coag: floc_model.Material

    :return: fraction of the coagulant that is coated with humic acid
    :rtype: float
    """
    return min(((ConcNatOrgMat / conc_precipitate(ConcAl, coag).magnitude)
                * (coag.Density / NatOrgMat.Density)
                * (coag.Diameter / (4 * NatOrgMat.Diameter))
                ),
               1)


Instruction:
How would you explain what the following Python 3 function does
def pacl_term(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat,
               coag, material, RatioHeightDiameter):
    """Return the fraction of the surface area that is covered with coagulant
    that is not covered with humic acid.

    :param DiamTube: Diameter of the dosing tube
    :type Diamtube: float
    :param ConcClay: Concentration of clay in solution
    :type ConcClay: float
    :param ConcAl: Concentration of alumninum in solution
    :type ConcAl: float
    :param ConcNatOrgMat: Concentration of natural organic matter in solution
    :type ConcNatOrgMat: float
    :param NatOrgMat: type of natural organic matter, e.g. floc_model.HumicAcid
    :type NatOrgMat: floc_model.Material
    :param coag: Type of coagulant in solution, e.g. floc_model.PACl
    :type coag: floc_model.Material
    :param material: Type of clay in suspension, e.g. floc_model.Clay
    :type material: floc_model.Material
    :param RatioHeightDiameter: Dimensionless ratio of clay height to clay diameter
    :type RatioHeightDiameter: float

    :return: fraction of the surface area that is covered with coagulant that is not covered with humic acid
    :rtype: float
    """
    return (gamma_coag(ConcClay, ConcAl, coag, material, DiamTube,
                       RatioHeightDiameter)
            * (1 - gamma_humic_acid_to_coag(ConcAl, ConcNatOrgMat,
                                            NatOrgMat, coag))
            )

Response: Returns the fraction of the coagulant that is not covered with humic acid.


Instruction:
Implement a Python 3 function for
calculating floc density as a function of size.

Response:
def dens_floc(ConcAl, ConcClay, DIM_FRACTAL, DiamTarget, coag, material, Temp):
    """Calculate floc density as a function of size."""
    WaterDensity = pc.density_water(Temp).magnitude
    return ((dens_floc_init(ConcAl, ConcClay, coag, material).magnitude
             - WaterDensity
             )
            * (material.Diameter / DiamTarget)**(3 - DIM_FRACTAL)
            + WaterDensity
            )


Instruction:
Explain what the following Python 3 code does
def vel_term_floc(ConcAl, ConcClay, coag, material, DIM_FRACTAL,
                  DiamTarget, Temp):
    """Calculate floc terminal velocity."""
    WaterDensity = pc.density_water(Temp).magnitude
    return (((pc.gravity.magnitude * material.Diameter**2)
             / (18 * PHI_FLOC * pc.viscosity_kinematic(Temp).magnitude)
             )
            * ((dens_floc_init(ConcAl, ConcClay, coag, material).magnitude
                - WaterDensity
                )
               / WaterDensity
               )
            * (DiamTarget / material.Diameter) ** (DIM_FRACTAL - 1)
            )

Response: Calculate floc terminal velocity.


Instruction:
Here you have a function in Python 3, explain what it does
def diam_floc_vel_term(ConcAl, ConcClay, coag, material,
                       DIM_FRACTAL, VelTerm, Temp):
    """Calculate floc diamter as a function of terminal velocity."""
    WaterDensity = pc.density_water(Temp).magnitude
    return (material.Diameter * (((18 * VelTerm * PHI_FLOC
                          * pc.viscosity_kinematic(Temp).magnitude
                          )
                         / (pc.gravity.magnitude * material.Diameter**2)
                         )
                         * (WaterDensity
                            / (dens_floc_init(ConcAl, ConcClay, coag,
                                              material).magnitude
                               - WaterDensity
                               )
                            )
                        ) ** (1 / (DIM_FRACTAL - 1))
            )

Response: Calculate floc diamter as a function of terminal velocity.


Instruction:
Here you have a function in Python 3, explain what it does
def time_col_laminar(EnergyDis, Temp, ConcAl, ConcClay, coag, material,
                     DiamTarget, DiamTube, DIM_FRACTAL, RatioHeightDiameter):
    """Calculate single collision time for laminar flow mediated collisions.

    Calculated as a function of floc size.
    """
    return (((1/6) * ((6/np.pi)**(1/3))
             * frac_vol_floc_initial(ConcAl, ConcClay, coag, material) ** (-2/3)
             * (pc.viscosity_kinematic(Temp).magnitude / EnergyDis) ** (1 / 2)
             * (DiamTarget / material.Diameter) ** (2*DIM_FRACTAL/3 - 2)
             )  # End of the numerator
            / (gamma_coag(ConcClay, ConcAl, coag, material, DiamTube,
                          RatioHeightDiameter)
               )  # End of the denominator
            )

Response: Calculate single collision time for laminar flow mediated collisions.


Instruction:
Can you create a Python 3 function that
calculates single collision time for turbulent flow mediated collisions.

Response:
def time_col_turbulent(EnergyDis, ConcAl, ConcClay, coag, material,
                       DiamTarget, DIM_FRACTAL):
    """Calculate single collision time for turbulent flow mediated collisions.

    Calculated as a function of floc size.
    """
    return((1/6) * (6/np.pi)**(1/9) * EnergyDis**(-1/3) * DiamTarget**(2/3)
           * frac_vol_floc_initial(ConcAl, ConcClay, coag, material)**(-8/9)
           * (DiamTarget / material.Diameter)**((8*(DIM_FRACTAL-3)) / 9)
           )


Instruction:
Write a Python 3 function that can
return the total diam of the Kolmogorov.

Response:
def diam_kolmogorov(EnergyDis, Temp, ConcAl, ConcClay, coag, material,
                    DIM_FRACTAL):
    """Return the size of the floc with separation distances equal to
    the Kolmogorov length and the inner viscous length scale.
    """
    return (material.Diameter
            * ((eta_kolmogorov(EnergyDis, Temp).magnitude / material.Diameter)
               * ((6 * frac_vol_floc_initial(ConcAl, ConcClay, coag, material))
                  / np.pi
                  )**(1/3)
               )**(3 / DIM_FRACTAL)
            )


Instruction:
Create a Python 3 function to
return the Dean Number.

Response:
def dean_number(PlantFlow, IDTube, RadiusCoil, Temp):
    """Return the Dean Number.

    The Dean Number is a dimensionless parameter that is the unfortunate
    combination of Reynolds and tube curvature. It would have been better
    to keep the Reynolds number and define a simple dimensionless geometric
    parameter.
    """
    return (reynolds_rapid_mix(PlantFlow, IDTube, Temp)
            * (IDTube / (2 * RadiusCoil))**(1/2)
            )


Instruction:
Create a Python 3 function for
returning the coil of a given coil.

Response:
def g_coil(FlowPlant, IDTube, RadiusCoil, Temp):
    """We need a reference for this.

    Karen's thesis likely has this equation and the reference.
    """
    return (g_straight(FlowPlant, IDTube).magnitude
            * (1 + 0.033 *
                np.log10(dean_number(FlowPlant, IDTube, RadiusCoil, Temp)
                        ) ** 4
               ) ** (1/2)
            )


Instruction:
Can you write a function in Python 3 where it
calculates the G Residence Time for a coiled tube flocculator.

Response:
def g_time_res(FlowPlant, IDTube, RadiusCoil, LengthTube, Temp):
    """G Residence Time calculated for a coiled tube flocculator."""
    return (g_coil(FlowPlant, IDTube, RadiusCoil, Temp).magnitude
            * time_res_tube(IDTube, LengthTube, FlowPlant).magnitude
            )


Instruction:
How would you explain what the following Python 3 function does
def define_Precip(self, diameter, density, molecweight, alumMPM):
        self.PrecipDiameter = diameter
        self.PrecipDensity = density
        self.PrecipMolecWeight = molecweight
        self.PrecipAluminumMPM = alumMPM

Response: Define a precipitate for the chemical.


Instruction:
Can you tell what is the following Python 3 function doing
def ent_tank_a(self):
        # first guess planview area
        a_new = 1 * u.m**2
        a_ratio = 2  # set to >1+tolerance to start while loop
        tolerance = 0.01
        a_floc_pv = (
            self.floc.vol /
            (self.floc.downstream_H + (self.floc.HL / 2))
        )
        while a_ratio > (1 + tolerance):
            a_et_pv = a_new
            a_etf_pv = a_et_pv + a_floc_pv
            w_tot = a_etf_pv / self.floc.max_L
            w_chan = w_tot / self.floc.channel_n

            a_new = self.floc.max_L * w_chan
            a_ratio = a_new / a_et_pv
        return a_new

Response: Calculate the planview area of the entrance tank given the volume of the flocculator.


Instruction:
Can you generate the documentation for the following Python 3 function
def area_lfom_orifices_top(FLOW,HL_LFOM):
    return ((FLOW*width_stout(HL_LFOM*u.m,HL_LFOM*u.m-0.5*dist_center_lfom_rows(FLOW,HL_LFOM)).magnitude *
        dist_center_lfom_rows(FLOW,HL_LFOM).magnitude))

Response: Estimate the area of the top row of orifices.


Instruction:
Given the following Python 3 function, write the documentation
def n_lfom_orifices_per_row_max(FLOW,HL_LFOM,drill_bits):
    return math.floor(math.pi * (pipe.ID_SDR(
        nom_diam_lfom_pipe(FLOW, HL_LFOM), design.lfom.SDR_LFOM).magnitude)
                      / (orifice_diameter(FLOW, HL_LFOM, drill_bits).magnitude +
                         aguaclara.design.lfom.ORIFICE_S.magnitude))

Response: A bound on the number of orifices allowed in each row.


Instruction:
How would you explain what the following Python 3 function does
def height_lfom_orifices(FLOW,HL_LFOM,drill_bits):
    return (np.arange((orifice_diameter(FLOW,HL_LFOM,drill_bits)*0.5),
                      HL_LFOM,
                      (dist_center_lfom_rows(FLOW,HL_LFOM))))

Response: Calculates the height of the center of each row of orifices.


Instruction:
Write a Python 3 script to
calculate the flow for a given number of submerged rows of orifices HL_LFOM and drill_bits.

Response:
def flow_lfom_actual(FLOW,HL_LFOM,drill_bits,Row_Index_Submerged,N_LFOM_Orifices):
    """Calculates the flow for a given number of submerged rows of orifices
    harray is the distance from the water level to the center of the orifices
    when the water is at the max level
    """
    D_LFOM_Orifices=orifice_diameter(FLOW, HL_LFOM, drill_bits).magnitude
    row_height=dist_center_lfom_rows(FLOW, HL_LFOM).magnitude
    harray = (np.linspace(row_height, HL_LFOM, n_lfom_rows(FLOW, HL_LFOM))) - 0.5 * D_LFOM_Orifices
    FLOW_new = 0
    for i in range(Row_Index_Submerged+1):
        FLOW_new = FLOW_new + (N_LFOM_Orifices[i] * (
            pc.flow_orifice_vert(D_LFOM_Orifices, harray[Row_Index_Submerged-i],
                                 con.VC_ORIFICE_RATIO).magnitude))
    return FLOW_new


Instruction:
Explain what the following Python 3 code does
def round_sf(number, digits):
    units = None
    try:
        num = number.magnitude
        units = number.units
    except AttributeError:
        num = number

    try:
        if (units != None):
            rounded_num = round(num, digits - int(floor(log10(abs(num)))) - 1) * units
        else:
            rounded_num = round(num, digits - int(floor(log10(abs(num)))) - 1)
        return rounded_num
    except ValueError:  # Prevents an error with log10(0)
        if (units != None):
            return 0 * units
        else:
            return 0

Response: Returns inputted value rounded to number of significant figures desired.


Instruction:
Can you generate the documentation for the following Python 3 function
def stepceil_with_units(param, step, unit):
    counter = 0 * unit
    while counter < param.to(unit):
        counter += step * unit
    return counter

Response:
This function returns the smallest multiple of step greater than param greater than or
    equal to unit.


Instruction:
Can you write a function in Python 3 where it
wraps a function to handle list inputs.

Response:
def list_handler(HandlerResult="nparray"):
    """Wraps a function to handle list inputs."""
    def decorate(func):
        def wrapper(*args, **kwargs):
            """Run through the wrapped function once for each array element.

            :param HandlerResult: output type. Defaults to numpy arrays.
            """
            sequences = []
            enumsUnitCheck = enumerate(args)
            argsList = list(args)
            #This for loop identifies pint unit objects and strips them
            #of their units.
            for num, arg in enumsUnitCheck:
                if type(arg) == type(1 * u.m):
                    argsList[num] = arg.to_base_units().magnitude
            enumsUnitless = enumerate(argsList)
            #This for loop identifies arguments that are sequences and
            #adds their index location to the list 'sequences'.
            for num, arg in enumsUnitless:
                if isinstance(arg, (list, tuple, np.ndarray)):
                    sequences.append(num)
            #If there are no sequences to iterate through, simply return
            #the function.
            if len(sequences) == 0:
                result = func(*args, **kwargs)
            else:
                #iterant keeps track of how many times we've iterated and
                #limiter stops the loop once we've iterated as many times
                #as there are list elements. Without this check, a few
                #erroneous runs will occur, appending the last couple values
                #to the end of the list multiple times.
                #
                #We only care about the length of sequences[0] because this
                #function is recursive, and sequences[0] is always the relevant
                #sequences for any given run.
                limiter = len(argsList[sequences[0]])
                iterant = 0
                result = []
                for num in sequences:
                    for arg in argsList[num]:
                        if iterant >= limiter:
                            break
                        #We can safely replace the entire list argument
                        #with a single element from it because of the looping
                        #we're doing. We redefine the object, but that
                        #definition remains within this namespace and does
                        #not penetrate further up the function.
                        argsList[num] = arg
                        #Here we dive down the rabbit hole. This ends up
                        #creating a multi-dimensional array shaped by the
                        #sizes and shapes of the lists passed.
                        result.append(wrapper(*argsList,
                                              HandlerResult=HandlerResult, **kwargs))
                        iterant += 1
                #HandlerResult allows the user to specify what type to
                #return the generated sequence as. It defaults to numpy
                #arrays because functions tend to handle them better, but if
                #the user does not wish to import numpy the base Python options
                #are available to them.
                if HandlerResult == "nparray":
                    result = np.array(result)
                elif HandlerResult == "tuple":
                    result = tuple(result)
                elif HandlerResult == "list":
                    result == list(result)
            return result
        return wrapper
    return decorate


Instruction:
Write a Python 3 function that can
check whether passed parameter values fall within approved ranges.

Response:
def check_range(*args):
    """
    Check whether passed paramters fall within approved ranges.

    Does not return anything, but will raise an error if a parameter falls
    outside of its defined range.

    Input should be passed as an array of sequences, with each sequence
    having three elements:
        [0] is the value being checked,
        [1] is the range parameter(s) within which the value should fall, and
        [2] is the name of the parameter, for better error messages.
    If [2] is not supplied, "Input" will be appended as a generic name.

    Range requests that this function understands are listed in the
    knownChecks sequence.
    """
    knownChecks = ('>0', '>=0', '0-1', '<0', '<=0', 'int', 'boolean')
    for arg in args:
        #Converts arg to a mutable list
        arg = [*arg]
        if len(arg) == 1:
            #arg[1] details what range the parameter should fall within; if
            #len(arg) is 1 that means a validity was not specified and the
            #parameter should not have been passed in its current form
            raise TypeError("No range-validity parameter provided.")
        elif len(arg) == 2:
            #Appending 'Input" to the end allows us to give more descriptive
            #error messages that do not fail if no description was supplied.
            arg.append("Input")
        #This ensures that all whitespace is removed before checking if the
        #request is understood
        arg[1] = "".join(arg[1].lower().split())
        #This block checks that each range request is understood.
        #If the request is a compound one, it must be separated into individual
        #requests for validity comprehension
        for i in arg[1].split(","):
            if i not in knownChecks:
                raise RuntimeError("Unknown parameter validation "
                                       "request: {0}.".format(i))
        if not isinstance(arg[0], (list, tuple, np.ndarray)):
            arg[0] = [arg[0]]
        for i in arg[0]:
            if '>0' in arg[1] and i <= 0:
                raise ValueError("{1} is {0} but must be greater than "
                                 "0.".format(i, arg[2]))
            if '>=0' in arg[1] and i <0:
                raise ValueError("{1} is {0} but must be 0 or "
                                 "greater.".format(i, arg[2]))
            if '0-1' in arg[1] and not 0 <= i <= 1:
                raise ValueError("{1} is {0} but must be between 0 and "
                                 "1.".format(i, arg[2]))
            if '<0' in arg[1] and i >= 0:
                raise ValueError("{1} is {0} but must be less than "
                                 "0.".format(i, arg[2]))
            if '<=0' in arg[1] and i >0:
                raise ValueError("{1} is {0} but must be 0 or "
                                 "less.".format(i, arg[2]))
            if 'int' in arg[1] and int(i) != i:
                raise TypeError("{1} is {0} but must be a numeric "
                                "integer.".format(i, arg[2]))
            if 'boolean' in arg[1] and type(i) != bool:
                raise TypeError("{1} is {0} but must be a "
                                "boolean.".format(i, arg[2]))


Instruction:
Make a summary of the following Python 3 code
def main():
    parser = argparse.ArgumentParser(
        description='Performs clustering from the command-line. Calls JVM start/stop automatically.')
    parser.add_argument("-j", metavar="classpath", dest="classpath", help="additional classpath, jars/directories")
    parser.add_argument("-X", metavar="heap", dest="heap", help="max heap size for jvm, e.g., 512m")
    parser.add_argument("-t", metavar="train", dest="train", required=True, help="training set file")
    parser.add_argument("-T", metavar="test", dest="test", help="test set file")
    parser.add_argument("-d", metavar="outmodel", dest="outmodel", help="model output file name")
    parser.add_argument("-l", metavar="inmodel", dest="inmodel", help="model input file name")
    parser.add_argument("-p", metavar="attributes", dest="attributes", help="attribute range")
    parser.add_argument("-x", metavar="num folds", dest="numfolds", help="number of folds")
    parser.add_argument("-s", metavar="seed", dest="seed", help="seed value for randomization")
    parser.add_argument("-c", metavar="class index", dest="classindex", help="1-based class attribute index")
    parser.add_argument("-g", metavar="graph", dest="graph", help="graph output file (if supported)")
    parser.add_argument("clusterer", help="clusterer classname, e.g., weka.clusterers.SimpleKMeans")
    parser.add_argument("option", nargs=argparse.REMAINDER, help="additional clusterer options")
    parsed = parser.parse_args()
    jars = []
    if parsed.classpath is not None:
        jars = parsed.classpath.split(os.pathsep)
    params = []
    if parsed.train is not None:
        params.extend(["-t", parsed.train])
    if parsed.test is not None:
        params.extend(["-T", parsed.test])
    if parsed.outmodel is not None:
        params.extend(["-d", parsed.outmodel])
    if parsed.inmodel is not None:
        params.extend(["-l", parsed.inmodel])
    if parsed.attributes is not None:
        params.extend(["-p", parsed.attributes])
    if parsed.numfolds is not None:
        params.extend(["-x", parsed.numfolds])
    if parsed.seed is not None:
        params.extend(["-s", parsed.seed])
    if parsed.classindex is not None:
        params.extend(["-c", parsed.classindex])
    if parsed.graph is not None:
        params.extend(["-g", parsed.graph])

    jvm.start(jars, max_heap_size=parsed.heap, packages=True)

    logger.debug("Commandline: " + join_options(sys.argv[1:]))

    try:
        clusterer = Clusterer(classname=parsed.clusterer)
        if len(parsed.option) > 0:
            clusterer.options = parsed.option
        print(ClusterEvaluation.evaluate_clusterer(clusterer, params))
    except Exception as e:
        print(e)
    finally:
        jvm.stop()

Response: Main function for the clusterer command line tool.


Instruction:
Given the following Python 3 function, write the documentation
def update_clusterer(self, inst):
        if self.is_updateable:
            javabridge.call(self.jobject, "updateClusterer", "(Lweka/core/Instance;)V", inst.jobject)
        else:
            logger.critical(classes.get_classname(self.jobject) + " is not updateable!")

Response: Updates the clusterer with the instance.


Instruction:
Write a Python 3 script to
signal the clusterer that updating with new data has finished.

Response:
def update_finished(self):
        """
        Signals the clusterer that updating with new data has finished.
        """
        if self.is_updateable:
            javabridge.call(self.jobject, "updateFinished", "()V")
        else:
            logger.critical(classes.get_classname(self.jobject) + " is not updateable!")


Instruction:
How would you explain what the following Python 3 function does
def distribution_for_instance(self, inst):
        pred = self.__distribution(inst.jobject)
        return javabridge.get_env().get_double_array_elements(pred)

Response: Peforms a prediction returning the cluster distribution for the given Instance.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def cluster_assignments(self):
        array = javabridge.call(self.jobject, "getClusterAssignments", "()[D")
        if array is None:
            return None
        else:
            return javabridge.get_env().get_double_array_elements(array)

Response: Returns an array of cluster assignments corresponding to the most recent set of instances clustered.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def classes_to_clusters(self):
        array = javabridge.call(self.jobject, "getClassesToClusters", "()[I")
        if array is None:
            return None
        else:
            return javabridge.get_env().get_int_array_elements(array)

Response: Returns the array of minimum error class to cluster mappings.


Instruction:
Can you tell what is the following Python 3 function doing
def crossvalidate_model(cls, clusterer, data, num_folds, rnd):
        return javabridge.static_call(
            "Lweka/clusterers/ClusterEvaluation;", "crossValidateModel",
            "(Lweka/clusterers/DensityBasedClusterer;Lweka/core/Instances;ILjava/util/Random;)D",
            clusterer.jobject, data.jobject, num_folds, rnd.jobject)

Response: Cross - validates the clusterer and returns the loglikelihood.


Instruction:
How would you explain what the following Python 3 function does
def deepcopy(obj):
    if isinstance(obj, JavaObject):
        wrapped = True
        jobject = obj.jobject
    else:
        wrapped = False
        jobject = obj
    try:
        serialized = javabridge.make_instance("weka/core/SerializedObject", "(Ljava/lang/Object;)V", jobject)
        jcopy = javabridge.call(serialized, "getObject", "()Ljava/lang/Object;")
        if wrapped:
            jcopy = obj.__class__(jobject=jcopy)
        return jcopy
    except JavaException as e:
        print("Failed to create copy of " + classes.get_classname(obj) + ": " + str(e))
        return None

Response: Creates a deep copy of the object.


Instruction:
Can you write a function in Python 3 where it
reads the serialized objects from disk.

Response:
def read_all(filename):
    """
    Reads the serialized objects from disk. Caller must wrap objects in appropriate Python wrapper classes.

    :param filename: the file with the serialized objects
    :type filename: str
    :return: the list of JB_OBjects
    :rtype: list
    """
    array = javabridge.static_call(
        "Lweka/core/SerializationHelper;", "readAll",
        "(Ljava/lang/String;)[Ljava/lang/Object;",
        filename)
    if array is None:
        return None
    else:
        return javabridge.get_env().get_object_array_elements(array)


Instruction:
How would you explain what the following Python 3 function does
def write(filename, jobject):
    if isinstance(jobject, JavaObject):
        jobject = jobject.jobject
    javabridge.static_call(
        "Lweka/core/SerializationHelper;", "write",
        "(Ljava/lang/String;Ljava/lang/Object;)V",
        filename, jobject)

Response: Writes the object to disk.


Instruction:
Explain what the following Python 3 code does
def decrease_frequency(self, frequency=None):
        if frequency is None:
            javabridge.call(self.jobject, "decreaseFrequency", "()V")
        else:
            javabridge.call(self.jobject, "decreaseFrequency", "(I)V", frequency)

Response: Decreases the frequency of the current object.


Instruction:
Implement a function in Python 3 to
increase the frequency. :param frequency: the frequency to increase by, 1 if None :type frequency: int

Response:
def increase_frequency(self, frequency=None):
        """
        Increases the frequency.

        :param frequency: the frequency to increase by, 1 if None
        :type frequency: int
        """
        if frequency is None:
            javabridge.call(self.jobject, "increaseFrequency", "()V")
        else:
            javabridge.call(self.jobject, "increaseFrequency", "(I)V", frequency)


Instruction:
How would you explain what the following Python 3 function does
def consequence(self):
        items = javabridge.get_collection_wrapper(
            javabridge.call(self.jobject, "getConsequence", "()Ljava/util/Collection;"))
        result = []
        for item in items:
            result.append(Item(item))
        return result

Response:
Get the the consequence.

        :return: the consequence, list of Item objects
        :rtype: list


Instruction:
Can you write a function in Python 3 where it
checks whether association rules can be generated.

Response:
def can_produce_rules(self):
        """
        Checks whether association rules can be generated.

        :return: whether scheme implements AssociationRulesProducer interface and
        association rules can be generated
        :rtype: bool
        """
        if not self.check_type(self.jobject, "weka.associations.AssociationRulesProducer"):
            return False
        return javabridge.call(self.jobject, "canProduceRules", "()Z")


Instruction:
Write a Python 3 script to
return the association rules that were generated. Only if implements AssociationRulesProducer.

Response:
def association_rules(self):
        """
        Returns association rules that were generated. Only if implements AssociationRulesProducer.

        :return: the association rules that were generated
        :rtype: AssociationRules
        """
        if not self.check_type(self.jobject, "weka.associations.AssociationRulesProducer"):
            return None
        return AssociationRules(
            javabridge.call(self.jobject, "getAssociationRules", "()Lweka/associations/AssociationRules;"))


Instruction:
Implement a Python 3 function for
returning the rule metric names of the association rules. Only if implements AssociationRulesProducer.

Response:
def rule_metric_names(self):
        """
        Returns the rule metric names of the association rules. Only if implements AssociationRulesProducer.

        :return: the metric names
        :rtype: list
        """
        if not self.check_type(self.jobject, "weka.associations.AssociationRulesProducer"):
            return None
        return string_array_to_list(
            javabridge.call(self.jobject, "getRuleMetricNames", "()[Ljava/lang/String;"))


Instruction:
How would you code a function in Python 3 to
return a Loader that can load the specified file.

Response:
def loader_for_file(filename):
    """
    Returns a Loader that can load the specified file, based on the file extension. None if failed to determine.

    :param filename: the filename to get the loader for
    :type filename: str
    :return: the assoicated loader instance or None if none found
    :rtype: Loader
    """
    loader = javabridge.static_call(
        "weka/core/converters/ConverterUtils", "getLoaderForFile",
        "(Ljava/lang/String;)Lweka/core/converters/AbstractFileLoader;", filename)
    if loader is None:
        return None
    else:
        return Loader(jobject=loader)


Instruction:
Explain what the following Python 3 code does
def saver_for_file(filename):
    saver = javabridge.static_call(
        "weka/core/converters/ConverterUtils", "getSaverForFile",
        "(Ljava/lang/String;)Lweka/core/converters/AbstractFileSaver;", filename)
    if saver is None:
        return None
    else:
        return Saver(jobject=saver)

Response: Returns a Saver that can load the specified file.


Instruction:
Implement a function in Python 3 to
save the data to the file specified by filename. Returns whether successfully saved.

Response:
def save_any_file(data, filename):
    """
    Determines a Saver based on the the file extension. Returns whether successfully saved.

    :param filename: the name of the file to save
    :type filename: str
    :param data: the data to save
    :type data: Instances
    :return: whether successfully saved
    :rtype: bool
    """
    saver = saver_for_file(filename)
    if saver is None:
        return False
    else:
        saver.save_file(data, filename)
        return True


Instruction:
Here you have a function in Python 3, explain what it does
def ndarray_to_instances(array, relation, att_template="Att-#", att_list=None):
    if len(numpy.shape(array)) != 2:
        raise Exception("Number of array dimensions must be 2!")
    rows, cols = numpy.shape(array)

    # header
    atts = []
    if att_list is not None:
        if len(att_list) != cols:
            raise Exception(
                "Number columns and provided attribute names differ: " + str(cols) + " != " + len(att_list))
        for name in att_list:
            att = Attribute.create_numeric(name)
            atts.append(att)
    else:
        for i in range(cols):
            name = att_template.replace("#", str(i+1)).replace("!", str(i)).replace("@", relation)
            att = Attribute.create_numeric(name)
            atts.append(att)
    result = Instances.create_instances(relation, atts, rows)

    # data
    for i in range(rows):
        inst = Instance.create_instance(array[i])
        result.add_instance(inst)

    return result

Response: Converts the numpy array into an Instances object and returns it.


Instruction:
How would you code a function in Python 3 to
load the specified file and returns the Instances object.

Response:
def load_file(self, dfile, incremental=False):
        """
        Loads the specified file and returns the Instances object.
        In case of incremental loading, only the structure.

        :param dfile: the file to load
        :type dfile: str
        :param incremental: whether to load the dataset incrementally
        :type incremental: bool
        :return: the full dataset or the header (if incremental)
        :rtype: Instances
        :raises Exception: if the file does not exist
        """
        self.enforce_type(self.jobject, "weka.core.converters.FileSourcedConverter")
        self.incremental = incremental
        if not javabridge.is_instance_of(dfile, "Ljava/io/File;"):
            dfile = javabridge.make_instance(
                "Ljava/io/File;", "(Ljava/lang/String;)V", javabridge.get_env().new_string_utf(str(dfile)))
        javabridge.call(self.jobject, "reset", "()V")
        # check whether file exists, otherwise previously set file gets loaded again
        sfile = javabridge.to_string(dfile)
        if not os.path.exists(sfile):
            raise Exception("Dataset file does not exist: " + str(sfile))
        javabridge.call(self.jobject, "setFile", "(Ljava/io/File;)V", dfile)
        if incremental:
            self.structure = Instances(javabridge.call(self.jobject, "getStructure", "()Lweka/core/Instances;"))
            return self.structure
        else:
            return Instances(javabridge.call(self.jobject, "getDataSet", "()Lweka/core/Instances;"))


Instruction:
Create a Python 3 function to
load the specified URL and returns the Instances object.

Response:
def load_url(self, url, incremental=False):
        """
        Loads the specified URL and returns the Instances object.
        In case of incremental loading, only the structure.

        :param url: the URL to load the data from
        :type url: str
        :param incremental: whether to load the dataset incrementally
        :type incremental: bool
        :return: the full dataset or the header (if incremental)
        :rtype: Instances
        """
        self.enforce_type(self.jobject, "weka.core.converters.URLSourcedLoader")
        self.incremental = incremental
        javabridge.call(self.jobject, "reset", "()V")
        javabridge.call(self.jobject, "setURL", "(Ljava/lang/String;)V", str(url))
        if incremental:
            self.structure = Instances(javabridge.call(self.jobject, "getStructure", "()Lweka/core/Instances;"))
            return self.structure
        else:
            return Instances(javabridge.call(self.jobject, "getDataSet", "()Lweka/core/Instances;"))


Instruction:
Write a Python 3 script for
loading the Instances object from the specified directory and returns the Instances object.

Response:
def load(self):
        """
        Loads the text files from the specified directory and returns the Instances object.
        In case of incremental loading, only the structure.

        :return: the full dataset or the header (if incremental)
        :rtype: Instances
        """
        javabridge.call(self.jobject, "reset", "()V")
        return Instances(javabridge.call(self.jobject, "getDataSet", "()Lweka/core/Instances;"))


Instruction:
How would you code a function in Python 3 to
save the Instances object in the specified file.

Response:
def save_file(self, data, dfile):
        """
        Saves the Instances object in the specified file.

        :param data: the data to save
        :type data: Instances
        :param dfile: the file to save the data to
        :type dfile: str
        """
        self.enforce_type(self.jobject, "weka.core.converters.FileSourcedConverter")
        if not javabridge.is_instance_of(dfile, "Ljava/io/File;"):
            dfile = javabridge.make_instance(
                "Ljava/io/File;", "(Ljava/lang/String;)V", javabridge.get_env().new_string_utf(str(dfile)))
        javabridge.call(self.jobject, "setFile", "(Ljava/io/File;)V", dfile)
        javabridge.call(self.jobject, "setInstances", "(Lweka/core/Instances;)V", data.jobject)
        javabridge.call(self.jobject, "writeBatch", "()V")


Instruction:
Make a summary of the following Python 3 code
def string_array_to_list(a):
    result = []
    length = javabridge.get_env().get_array_length(a)
    wrapped = javabridge.get_env().get_object_array_elements(a)
    for i in range(length):
        result.append(javabridge.get_env().get_string(wrapped[i]))
    return result

Response: Converts the Java string array into Python unicode string list.


Instruction:
Can you generate the documentation for the following Python 3 function
def string_list_to_array(l):
    result = javabridge.get_env().make_object_array(len(l), javabridge.get_env().find_class("java/lang/String"))
    for i in range(len(l)):
        javabridge.get_env().set_object_array_element(result, i, javabridge.get_env().new_string_utf(l[i]))
    return result

Response: Turns a Python unicode string list into a Java String array.


Instruction:
Can you write a function in Python 3 where it
converts the Java matrix of doubles into a Numpy array.

Response:
def double_matrix_to_ndarray(m):
    """
    Turns the Java matrix (2-dim array) of doubles into a numpy 2-dim array.

    :param m: the double matrix
    :type: JB_Object
    :return: Numpy array
    :rtype: numpy.darray
    """
    rows = javabridge.get_env().get_object_array_elements(m)
    num_rows = len(rows)
    num_cols = javabridge.get_env().get_array_length(rows[0])
    result = numpy.zeros(num_rows * num_cols).reshape((num_rows, num_cols))
    i = 0
    for row in rows:
        elements = javabridge.get_env().get_double_array_elements(row)
        n = 0
        for element in elements:
            result[i][n] = element
            n += 1
        i += 1
    return result


Instruction:
Write a Python 3 function for
converting the java. util. Enumeration into a list.

Response:
def enumeration_to_list(enm):
    """
    Turns the java.util.Enumeration into a list.

    :param enm: the enumeration to convert
    :type enm: JB_Object
    :return: the list
    :rtype: list
    """
    result = []
    while javabridge.call(enm, "hasMoreElements", "()Z"):
        result.append(javabridge.call(enm, "nextElement", "()Ljava/lang/Object;"))
    return result


Instruction:
Implement a Python 3 function for
running attribute selection from the command-line. Calls JVM start/stop automatically. Use -h to see all options.

Response:
def main():
    """
    Runs attribute selection from the command-line. Calls JVM start/stop automatically.
    Use -h to see all options.
    """
    parser = argparse.ArgumentParser(
        description='Performs attribute selection from the command-line. Calls JVM start/stop automatically.')
    parser.add_argument("-j", metavar="classpath", dest="classpath", help="additional classpath, jars/directories")
    parser.add_argument("-X", metavar="heap", dest="heap", help="max heap size for jvm, e.g., 512m")
    parser.add_argument("-i", metavar="input", dest="input", required=True, help="input file")
    parser.add_argument("-c", metavar="class index", dest="classindex", help="1-based class attribute index")
    parser.add_argument("-s", metavar="search", dest="search", help="search method, classname and options")
    parser.add_argument("-x", metavar="num folds", dest="numfolds", help="number of folds")
    parser.add_argument("-n", metavar="seed", dest="seed", help="the seed value for randomization")
    parser.add_argument("evaluator", help="evaluator classname, e.g., weka.attributeSelection.CfsSubsetEval")
    parser.add_argument("option", nargs=argparse.REMAINDER, help="additional evaluator options")
    parsed = parser.parse_args()
    jars = []
    if parsed.classpath is not None:
        jars = parsed.classpath.split(os.pathsep)
    params = []
    if parsed.input is not None:
        params.extend(["-i", parsed.input])
    if parsed.classindex is not None:
        params.extend(["-c", parsed.classindex])
    if parsed.search is not None:
        params.extend(["-s", parsed.search])
    if parsed.numfolds is not None:
        params.extend(["-x", parsed.numfolds])
    if parsed.seed is not None:
        params.extend(["-n", parsed.seed])

    jvm.start(jars, max_heap_size=parsed.heap, packages=True)

    logger.debug("Commandline: " + join_options(sys.argv[1:]))

    try:
        evaluation = ASEvaluation(classname=parsed.evaluator)
        if len(parsed.option) > 0:
            evaluation.options = parsed.option
        print(AttributeSelection.attribute_selection(evaluation, params))
    except Exception as e:
        print(e)
    finally:
        jvm.stop()


Instruction:
How would you explain what the following Python 3 function does
def search(self, evaluation, data):
        array = javabridge.call(
            self.jobject, "search", "(Lweka/attributeSelection/ASEvaluation;Lweka/core/Instances;)[I",
            evaluation.jobject, data.jobject)
        if array is None:
            return None
        else:
            javabridge.get_env().get_int_array_elements(array)

Response: Performs the search and returns the indices of the selected attributes.


Instruction:
Explain what the following Python 3 code does
def post_process(self, indices):
        array = javabridge.call(self.jobject, "postProcess", "([I)[I", indices)
        if array is None:
            return None
        else:
            return javabridge.get_env().get_int_array_elements(array)

Response: Post - processes the evaluator with the selected attribute indices.


Instruction:
Can you write a function in Python 3 where it
returns the selected attributes from the last run.

Response:
def selected_attributes(self):
        """
        Returns the selected attributes from the last run.

        :return: the Numpy array of 0-based indices
        :rtype: ndarray
        """
        array = javabridge.call(self.jobject, "selectedAttributes", "()[I")
        if array is None:
            return None
        else:
            return javabridge.get_env().get_int_array_elements(array)


Instruction:
Explain what the following Python 3 code does
def ranked_attributes(self):
        matrix = javabridge.call(self.jobject, "rankedAttributes", "()[[D")
        if matrix is None:
            return None
        else:
            return typeconv.double_matrix_to_ndarray(matrix)

Response: Returns the matrix of ranked attributes from the last run.


Instruction:
Implement a Python 3 function for
reducing the dimensionality of the provided Instances or Instance object.

Response:
def reduce_dimensionality(self, data):
        """
        Reduces the dimensionality of the provided Instance or Instances object.

        :param data: the data to process
        :type data: Instances
        :return: the reduced dataset
        :rtype: Instances
        """
        if type(data) is Instance:
            return Instance(
                javabridge.call(
                    self.jobject, "reduceDimensionality",
                    "(Lweka/core/Instance;)Lweka/core/Instance;", data.jobject))
        else:
            return Instances(
                javabridge.call(
                    self.jobject, "reduceDimensionality",
                    "(Lweka/core/Instances;)Lweka/core/Instances;", data.jobject))


Instruction:
Can you create a Python 3 function that
generates the threshold curve data from the evaluation object s predictions and the class - label.

Response:
def generate_thresholdcurve_data(evaluation, class_index):
    """
    Generates the threshold curve data from the evaluation object's predictions.

    :param evaluation: the evaluation to obtain the predictions from
    :type evaluation: Evaluation
    :param class_index: the 0-based index of the class-label to create the plot for
    :type class_index: int
    :return: the generated threshold curve data
    :rtype: Instances
    """
    jtc = JavaObject.new_instance("weka.classifiers.evaluation.ThresholdCurve")
    pred = javabridge.call(evaluation.jobject, "predictions", "()Ljava/util/ArrayList;")
    result = Instances(
        javabridge.call(jtc, "getCurve", "(Ljava/util/ArrayList;I)Lweka/core/Instances;", pred, class_index))
    return result


Instruction:
Can you implement a function in Python 3 that
retrieves x and y columns from the data generated by the weka. classifiers. evaluator. ThresholdCurve class.

Response:
def get_thresholdcurve_data(data, xname, yname):
    """
    Retrieves x and y columns from  of the data generated by the weka.classifiers.evaluation.ThresholdCurve
    class.

    :param data: the threshold curve data
    :type data: Instances
    :param xname: the name of the X column
    :type xname: str
    :param yname: the name of the Y column
    :type yname: str
    :return: tuple of x and y arrays
    :rtype: tuple
    """
    xi = data.attribute_by_name(xname).index
    yi = data.attribute_by_name(yname).index
    x = []
    y = []
    for i in range(data.num_instances):
        inst = data.get_instance(i)
        x.append(inst.get_value(xi))
        y.append(inst.get_value(yi))
    return x, y


Instruction:
Implement a function in Python 3 to
plot the ROC curve for the given class_index.

Response:
def plot_roc(evaluation, class_index=None, title=None, key_loc="lower right", outfile=None, wait=True):
    """
    Plots the ROC (receiver operator characteristics) curve for the given predictions.

    TODO: click events http://matplotlib.org/examples/event_handling/data_browser.html

    :param evaluation: the evaluation to obtain the predictions from
    :type evaluation: Evaluation
    :param class_index: the list of 0-based indices of the class-labels to create the plot for
    :type class_index: list
    :param title: an optional title
    :type title: str
    :param key_loc: the position string for the key
    :type key_loc: str
    :param outfile: the output file, ignored if None
    :type outfile: str
    :param wait: whether to wait for the user to close the plot
    :type wait: bool
    """
    if not plot.matplotlib_available:
        logger.error("Matplotlib is not installed, plotting unavailable!")
        return
    if class_index is None:
        class_index = [0]
    ax = None
    for cindex in class_index:
        data = generate_thresholdcurve_data(evaluation, cindex)
        head = evaluation.header
        area = get_auc(data)
        x, y = get_thresholdcurve_data(data, "False Positive Rate", "True Positive Rate")
        if ax is None:
            fig, ax = plt.subplots()
            ax.set_xlabel("False Positive Rate")
            ax.set_ylabel("True Positive Rate")
            if title is None:
                title = "ROC"
            ax.set_title(title)
            ax.grid(True)
            fig.canvas.set_window_title(title)
            plt.xlim([-0.05, 1.05])
            plt.ylim([-0.05, 1.05])
        plot_label = head.class_attribute.value(cindex) + " (AUC: %0.4f)" % area
        ax.plot(x, y, label=plot_label)
        ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c="0.3")
    plt.draw()
    plt.legend(loc=key_loc, shadow=True)
    if outfile is not None:
        plt.savefig(outfile)
    if wait:
        plt.show()


Instruction:
Write a Python 3 script for
plotting a learning curve.

Response:
def plot_learning_curve(classifiers, train, test=None, increments=100, metric="percent_correct",
                        title="Learning curve", label_template="[#] @ $", key_loc="lower right",
                        outfile=None, wait=True):
    """
    Plots a learning curve.

    :param classifiers: list of Classifier template objects
    :type classifiers: list of Classifier
    :param train: dataset to use for the building the classifier, used for evaluating it test set None
    :type train: Instances
    :param test: optional dataset (or list of datasets) to use for the testing the built classifiers
    :type test: list or Instances
    :param increments: the increments (>= 1: # of instances, <1: percentage of dataset)
    :type increments: float
    :param metric: the name of the numeric metric to plot (Evaluation.<metric>)
    :type metric: str
    :param title: the title for the plot
    :type title: str
    :param label_template: the template for the label in the plot
                           (#: 1-based index of classifier, @: full classname, !: simple classname,
                           $: options, *: 1-based index of test set)
    :type label_template: str
    :param key_loc: the location string for the key
    :type key_loc: str
    :param outfile: the output file, ignored if None
    :type outfile: str
    :param wait: whether to wait for the user to close the plot
    :type wait: bool
    """

    if not plot.matplotlib_available:
        logger.error("Matplotlib is not installed, plotting unavailable!")
        return
    if not train.has_class():
        logger.error("Training set has no class attribute set!")
        return

    if increments >= 1:
        inc = increments
    else:
        inc = round(train.num_instances * increments)

    if test is None:
        tst = [train]
    elif isinstance(test, list):
        tst = test
    elif isinstance(test, Instances):
        tst = [test]
    else:
        logger.error("Expected list or Instances object, instead: " + type(test))
        return
    for t in tst:
        if train.equal_headers(t) is not None:
            logger.error("Training and test set are not compatible: " + train.equal_headers(t))
            return

    steps = []
    cls = []
    evls = {}
    for classifier in classifiers:
        cl = Classifier.make_copy(classifier)
        cls.append(cl)
        evls[cl] = {}
        for t in tst:
            evls[cl][t] = []

    for i in range(train.num_instances):
        if (i > 0) and (i % inc == 0):
            steps.append(i+1)
        for cl in cls:
            # train
            if cl.is_updateable:
                if i == 0:
                    tr = Instances.copy_instances(train, 0, 1)
                    cl.build_classifier(tr)
                else:
                    cl.update_classifier(train.get_instance(i))
            else:
                if (i > 0) and (i % inc == 0):
                    tr = Instances.copy_instances(train, 0, i + 1)
                    cl.build_classifier(tr)
            # evaluate
            if (i > 0) and (i % inc == 0):
                for t in tst:
                    evl = Evaluation(t)
                    evl.test_model(cl, t)
                    evls[cl][t].append(getattr(evl, metric))

    fig, ax = plt.subplots()
    ax.set_xlabel("# of instances")
    ax.set_ylabel(metric)
    ax.set_title(title)
    fig.canvas.set_window_title(title)
    ax.grid(True)
    i = 0
    for cl in cls:
        evlpertest = evls[cl]
        i += 1
        n = 0
        for t in tst:
            evl = evlpertest[t]
            n += 1
            plot_label = label_template.\
                replace("#", str(i)).\
                replace("*", str(n)).\
                replace("@", cl.classname).\
                replace("!", cl.classname[cl.classname.rfind(".") + 1:]).\
                replace("$", join_options(cl.config))
            ax.plot(steps, evl, label=plot_label)
    plt.draw()
    plt.legend(loc=key_loc, shadow=True)
    if outfile is not None:
        plt.savefig(outfile)
    if wait:
        plt.show()


Instruction:
Given the following Python 3 function, write the documentation
def all_packages():
    establish_cache()
    result = []
    pkgs = javabridge.get_collection_wrapper(
        javabridge.static_call(
            "weka/core/WekaPackageManager", "getAllPackages", "()Ljava/util/List;"))
    for pkge in pkgs:
        result.append(Package(pkge))
    return result

Response: Returns a list of all packages.


Instruction:
Write a Python 3 function for
installing a package from a repository or archive.

Response:
def install_package(pkge, version="Latest"):
    """
    The list of packages to install.

    :param pkge: the name of the repository package, a URL (http/https) or a zip file
    :type pkge: str
    :param version: in case of the repository packages, the version
    :type version: str
    :return: whether successfully installed
    :rtype: bool
    """
    establish_cache()
    if pkge.startswith("http://") or pkge.startswith("https://"):
        url = javabridge.make_instance(
            "java/net/URL", "(Ljava/lang/String;)V", javabridge.get_env().new_string_utf(pkge))
        return not javabridge.static_call(
            "weka/core/WekaPackageManager", "installPackageFromURL",
            "(Ljava/net/URL;[Ljava/io/PrintStream;)Ljava/lang/String;", url, []) is None
    elif pkge.lower().endswith(".zip"):
        return not javabridge.static_call(
            "weka/core/WekaPackageManager", "installPackageFromArchive",
            "(Ljava/lang/String;[Ljava/io/PrintStream;)Ljava/lang/String;", pkge, []) is None
    else:
        return javabridge.static_call(
            "weka/core/WekaPackageManager", "installPackageFromRepository",
            "(Ljava/lang/String;Ljava/lang/String;[Ljava/io/PrintStream;)Z", pkge, version, [])


Instruction:
Can you generate a brief explanation for the following Python 3 code
def is_installed(name):
    pkgs = installed_packages()
    for pkge in pkgs:
        if pkge.name == name:
            return True
    return False

Response: Checks whether a package with the given name is already installed.


Instruction:
Write a Python 3 script to
return the dependencies of the package.

Response:
def dependencies(self):
        """
        Returns the dependencies of the package.

        :return: the list of Dependency objects
        :rtype: list of Dependency
        """
        result = []
        dependencies = javabridge.get_collection_wrapper(
            javabridge.call(self.jobject, "getDependencies", "()Ljava/util/List;"))
        for dependency in dependencies:
            result.append(Dependency(dependency))
        return result


Instruction:
How would you explain what the following Python 3 function does
def check_constraint(self, pkge=None, constr=None):
        if not pkge is None:
            return javabridge.call(
                self.jobject, "checkConstraint", "(Lweka/core/packageManagement/Package;)Z", pkge.jobject)
        if not constr is None:
            return javabridge.call(
                self.jobject, "checkConstraint", "(Lweka/core/packageManagement/PackageConstraint;)Z", pkge.jobject)
        raise Exception("Either package or package constraing must be provided!")

Response:
Checks the constraints.

        :param pkge: the package to check
        :type pkge: Package
        :param constr: the package constraint to check
        :type constr: PackageConstraint


Instruction:
Write a Python 3 function for
setting the custom properties file to use.

Response:
def custom_properties(self, props):
        """
        Sets the custom properties file to use.

        :param props: the props file
        :type props: str
        """
        fprops = javabridge.make_instance("java/io/File", "(Ljava/lang/String;)V", props)
        javabridge.call(self.jobject, "setCustomPropsFile", "(Ljava/io/File;)V", fprops)


Instruction:
Create a Python 3 function to
retrieve the Instances from the specified query.

Response:
def retrieve_instances(self, query=None):
        """
        Executes either the supplied query or the one set via options (or the 'query' property).

        :param query: query to execute if not the currently set one
        :type query: str
        :return: the generated dataq
        :rtype: Instances
        """
        if query is None:
            data = javabridge.call(self.jobject, "retrieveInstances", "()Lweka/core/Instances;")
        else:
            data = javabridge.call(self.jobject, "retrieveInstances", "(Ljava/lang/String;)Lweka/core/Instances;")
        return Instances(data)


Instruction:
Create a Python 3 function to
return the owner of these capabilities if any.

Response:
def owner(self):
        """
        Returns the owner of these capabilities, if any.

        :return: the owner, can be None
        :rtype: JavaObject
        """
        obj = javabridge.call(self.jobject, "getOwner", "()Lweka/core/CapabilitiesHandler;")
        if obj is None:
            return None
        else:
            return JavaObject(jobject=obj)


Instruction:
Can you implement a function in Python 3 that
returns all the dependencies.

Response:
def dependencies(self):
        """
        Returns all the dependencies.

        :return: the dependency list
        :rtype: list
        """
        result = []
        iterator = javabridge.iterate_java(javabridge.call(self.jobject, "dependencies", "()Ljava/util/Iterator;"))
        for c in iterator:
            result.append(Capability(c))
        return result


Instruction:
Can you generate a brief explanation for the following Python 3 code
def for_instances(cls, data, multi=None):
        if multi is None:
            return Capabilities(javabridge.static_call(
                "weka/core/Capabilities", "forInstances",
                "(Lweka/core/Instances;)Lweka/core/Capabilities;", data.jobject))
        else:
            return Capabilities(javabridge.static_call(
                "weka/core/Capabilities", "forInstances",
                "(Lweka/core/Instances;Z)Lweka/core/Capabilities;", data.jobject, multi))

Response: Returns a Capabilities object specific for the given data.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def scatter_plot(data, index_x, index_y, percent=100.0, seed=1, size=50, title=None, outfile=None, wait=True):
    if not plot.matplotlib_available:
        logger.error("Matplotlib is not installed, plotting unavailable!")
        return

    # create subsample
    data = plot.create_subsample(data, percent=percent, seed=seed)

    # collect data
    x = []
    y = []
    if data.class_index == -1:
        c = None
    else:
        c = []
    for i in range(data.num_instances):
        inst = data.get_instance(i)
        x.append(inst.get_value(index_x))
        y.append(inst.get_value(index_y))
        if c is not None:
            c.append(inst.get_value(inst.class_index))

    # plot data
    fig, ax = plt.subplots()
    if c is None:
        ax.scatter(x, y, s=size, alpha=0.5)
    else:
        ax.scatter(x, y, c=c, s=size, alpha=0.5)
    ax.set_xlabel(data.attribute(index_x).name)
    ax.set_ylabel(data.attribute(index_y).name)
    if title is None:
        title = "Attribute scatter plot"
        if percent != 100:
            title += " (%0.1f%%)" % percent
    ax.set_title(title)
    ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c="0.3")
    ax.grid(True)
    fig.canvas.set_window_title(data.relationname)
    plt.draw()
    if outfile is not None:
        plt.savefig(outfile)
    if wait:
        plt.show()

Response: Plots two attributes against each other.