Instruction:
How would you implement a function in Python 3 that
plots the reliability curves against a 1 - diagonal figure.

Response:
def reliability_diagram(rel_objs, obj_labels, colors, markers, filename, figsize=(8, 8), xlabel="Forecast Probability",
                        ylabel="Observed Relative Frequency", ticks=np.arange(0, 1.05, 0.05), dpi=300, inset_size=1.5,
                        title="Reliability Diagram", legend_params=None, bootstrap_sets=None, ci=(2.5, 97.5)):
    """
    Plot reliability curves against a 1:1 diagonal to determine if probability forecasts are consistent with their
    observed relative frequency.

    Args:
        rel_objs (list): List of DistributedReliability objects.
        obj_labels (list): List of labels describing the forecast model associated with each curve.
        colors (list): List of colors for each line
        markers (list): List of line markers
        filename (str): Where to save the figure.
        figsize (tuple): (Width, height) of the figure in inches.
        xlabel (str): X-axis label
        ylabel (str): Y-axis label
        ticks (array): Tick value labels for the x and y axes.
        dpi (int): resolution of the saved figure in dots per inch.
        inset_size (float): Size of inset
        title (str): Title of figure
        legend_params (dict): Keyword arguments for the plot legend.
        bootstrap_sets (list): A list of arrays of bootstrapped DistributedROC objects. If not None,
            confidence regions will be plotted.
        ci (tuple): tuple of bootstrap confidence interval percentiles
    """
    if legend_params is None:
        legend_params = dict(loc=4, fontsize=10, framealpha=1, frameon=True)
    fig, ax = plt.subplots(figsize=figsize)
    plt.plot(ticks, ticks, "k--")
    inset_hist = inset_axes(ax, width=inset_size, height=inset_size, loc=2)
    if bootstrap_sets is not None:
        for b, b_set in enumerate(bootstrap_sets):
            brel_curves = np.dstack([b_rel.reliability_curve().values for b_rel in b_set])
            bin_range = np.percentile(brel_curves[:,0], ci, axis=1)
            rel_range = np.percentile(brel_curves[:, 3], ci, axis=1)
            bin_poly = np.concatenate((bin_range[1], bin_range[0, ::-1]))
            rel_poly = np.concatenate((rel_range[1], rel_range[0, ::-1]))
            bin_poly[np.isnan(bin_poly)] = 0
            rel_poly[np.isnan(rel_poly)] = 0
            plt.fill(bin_poly, rel_poly, alpha=0.5, color=colors[b])
    for r, rel_obj in enumerate(rel_objs):
        rel_curve = rel_obj.reliability_curve()
        ax.plot(rel_curve["Bin_Start"], rel_curve["Positive_Relative_Freq"], color=colors[r], marker=markers[r],
                 label=obj_labels[r])
        inset_hist.semilogy(rel_curve["Bin_Start"], rel_curve["Total_Relative_Freq"], color=colors[r],
                            marker=markers[r])
        inset_hist.set_xlabel("Forecast Probability")
        inset_hist.set_ylabel("Forecast Relative Frequency")
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_xticks(ticks)
    ax.set_yticks(ticks)
    ax.legend(**legend_params)
    ax.set_title(title)
    plt.savefig(filename, dpi=dpi, bbox_inches="tight")
    plt.close()


Instruction:
Can you implement a function in Python 3 that
plots the attributes diagram of the DistributedReliability objects.

Response:
def attributes_diagram(rel_objs, obj_labels, colors, markers, filename, figsize=(8, 8), xlabel="Forecast Probability",
                       ylabel="Observed Relative Frequency", ticks=np.arange(0, 1.05, 0.05), dpi=300,
                       title="Attributes Diagram", legend_params=None, inset_params=None,
                       inset_position=(0.12, 0.72, 0.25, 0.25), bootstrap_sets=None, ci=(2.5, 97.5)):
    """
    Plot reliability curves against a 1:1 diagonal to determine if probability forecasts are consistent with their
    observed relative frequency. Also adds gray areas to show where the climatological probabilities lie and what
    areas result in a positive Brier Skill Score.

    Args:
        rel_objs (list): List of DistributedReliability objects.
        obj_labels (list): List of labels describing the forecast model associated with each curve.
        colors (list): List of colors for each line
        markers (list): List of line markers
        filename (str): Where to save the figure.
        figsize (tuple): (Width, height) of the figure in inches.
        xlabel (str): X-axis label
        ylabel (str): Y-axis label
        ticks (array): Tick value labels for the x and y axes.
        dpi (int): resolution of the saved figure in dots per inch.
        title (str): Title of figure
        legend_params (dict): Keyword arguments for the plot legend.
        inset_params (dict): Keyword arguments for the inset axis.
        inset_position (tuple): Position of the inset axis in normalized axes coordinates (left, bottom, width, height)
        bootstrap_sets (list): A list of arrays of bootstrapped DistributedROC objects. If not None,
            confidence regions will be plotted.
        ci (tuple): tuple of bootstrap confidence interval percentiles
    """
    if legend_params is None:
        legend_params = dict(loc=4, fontsize=10, framealpha=1, frameon=True)
    if inset_params is None:
        inset_params = dict(width="25%", height="25%", loc=2, axes_kwargs=dict(axisbg='white'))
    fig, ax = plt.subplots(figsize=figsize)
    plt.plot(ticks, ticks, "k--")
    inset_hist = inset_axes(ax, **inset_params)
    ip = InsetPosition(ax, inset_position)
    inset_hist.set_axes_locator(ip)
    climo = rel_objs[0].climatology()
    no_skill = 0.5 * ticks + 0.5 * climo
    skill_x = [climo, climo, 1, 1, climo, climo, 0, 0, climo]
    skill_y = [climo, 1, 1, no_skill[-1], climo, 0, 0, no_skill[0], climo]
    f = ax.fill(skill_x, skill_y, "0.8")
    f[0].set_zorder(1)
    ax.plot(ticks, np.ones(ticks.shape) * climo, "k--")
    if bootstrap_sets is not None:
        for b, b_set in enumerate(bootstrap_sets):
            brel_curves = np.vstack([b_rel.reliability_curve()["Positive_Relative_Freq"].values for b_rel in b_set])
            rel_range = np.nanpercentile(brel_curves, ci, axis=0)
            fb = ax.fill_between(b_rel.thresholds[:-1], rel_range[1], rel_range[0], alpha=0.5, color=colors[b])
            fb.set_zorder(2)
    for r, rel_obj in enumerate(rel_objs):
        rel_curve = rel_obj.reliability_curve()
        ax.plot(rel_curve["Bin_Start"], rel_curve["Positive_Relative_Freq"], color=colors[r],
                marker=markers[r], label=obj_labels[r])
        inset_hist.semilogy(rel_curve["Bin_Start"] * 100, rel_obj.frequencies["Total_Freq"][:-1], color=colors[r],
                            marker=markers[r])
    inset_hist.set_xlabel("Forecast Probability")
    inset_hist.set_ylabel("Frequency")
    ax.annotate("No Skill", (0.6, no_skill[12]), rotation=22.5)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_xticks(ticks)
    ax.set_xticklabels((ticks * 100).astype(int))
    ax.set_yticks(ticks)
    ax.set_yticklabels((ticks * 100).astype(int))
    ax.legend(**legend_params)
    ax.set_title(title)
    plt.savefig(filename, dpi=dpi, bbox_inches="tight")
    plt.close()


Instruction:
Given the following Python 3 function, write the documentation
def get_string(self, prompt, default_str=None) -> str:
        accept_event = threading.Event()
        value_ref = [None]

        def perform():
            def accepted(text):
                value_ref[0] = text
                accept_event.set()

            def rejected():
                accept_event.set()

            self.__message_column.remove_all()
            pose_get_string_message_box(self.ui, self.__message_column, prompt, str(default_str), accepted, rejected)
            #self.__message_column.add(self.__make_cancel_row())

        with self.__lock:
            self.__q.append(perform)
            self.document_controller.add_task("ui_" + str(id(self)), self.__handle_output_and_q)
        accept_event.wait()
        def update_message_column():
            self.__message_column.remove_all()
            self.__message_column.add(self.__make_cancel_row())
        self.document_controller.add_task("ui_" + str(id(self)), update_message_column)
        if value_ref[0] is None:
            raise Exception("Cancel")
        return value_ref[0]

Response: Return a string value that the user enters. Raises exception for cancel.


Instruction:
Can you generate the documentation for the following Python 3 function
def __accept_reject(self, prompt, accepted_text, rejected_text, display_rejected):
        accept_event = threading.Event()
        result_ref = [False]

        def perform():
            def accepted():
                result_ref[0] = True
                accept_event.set()

            def rejected():
                result_ref[0] = False
                accept_event.set()

            self.__message_column.remove_all()
            pose_confirmation_message_box(self.ui, self.__message_column, prompt, accepted, rejected, accepted_text, rejected_text, display_rejected)
            #self.__message_column.add(self.__make_cancel_row())

        with self.__lock:
            self.__q.append(perform)
            self.document_controller.add_task("ui_" + str(id(self)), self.__handle_output_and_q)
        accept_event.wait()
        def update_message_column():
            self.__message_column.remove_all()
            self.__message_column.add(self.__make_cancel_row())
        self.document_controller.add_task("ui_" + str(id(self)), update_message_column)
        return result_ref[0]

Response: Return a boolean value for accept or reject.


Instruction:
Make a summary of the following Python 3 code
def compute_weight(self, r, ytr=None, mask=None):
        ytr = self._ytr if ytr is None else ytr
        mask = self._mask if mask is None else mask
        return compute_weight(r, ytr, mask)

Response: Compute the weight of a record using OLS of r


Instruction:
Can you generate the documentation for the following Python 3 function
def isfinite(self):
        "Test whether the predicted values are finite"
        if self._multiple_outputs:
            if self.hy_test is not None:
                r = [(hy.isfinite() and (hyt is None or hyt.isfinite()))
                     for hy, hyt in zip(self.hy, self.hy_test)]
            else:
                r = [hy.isfinite() for hy in self.hy]
            return np.all(r)
        return self.hy.isfinite() and (self.hy_test is None or
                                       self.hy_test.isfinite())

Response: Test whether the predicted values are finite


Instruction:
Write a Python 3 script for
parsing an arbitrary python code to get the value of a named argument in a function call.

Response:
def value_of_named_argument_in_function(argument_name, function_name, search_str,
                                        resolve_varname=False):
    """ Parse an arbitrary block of python code to get the value of a named argument
        from inside a function call
    """
    try:
        search_str = unicode(search_str)
    except NameError:
        pass
    readline = StringIO(search_str).readline
    try:
        token_generator = tokenize.generate_tokens(readline)
        tokens = [SimplifiedToken(toknum, tokval) for toknum, tokval, _, _, _ in token_generator]
    except tokenize.TokenError as e:
        raise ValueError('search_str is not parse-able python code: ' + str(e))
    in_function = False
    is_var = False
    for i in range(len(tokens)):
        if (
            not in_function and
            tokens[i].typenum == tokenize.NAME and tokens[i].value == function_name and
            tokens[i+1].typenum == tokenize.OP and tokens[i+1].value == '('
        ):
            in_function = True
            continue
        elif (
            in_function and
            tokens[i].typenum == tokenize.NAME and tokens[i].value == argument_name and
            tokens[i+1].typenum == tokenize.OP and tokens[i+1].value == '='
        ):
            # value is set to another variable which we are going to attempt to resolve
            if resolve_varname and tokens[i+2].typenum == 1:
                is_var = True
                argument_name = tokens[i+2].value
                break

            # again, for a very specific usecase -- get the whole value and concatenate it
            # this will match something like _version.__version__
            j = 3
            while True:
                if tokens[i+j].value in (',', ')') or tokens[i+j].typenum == 58:
                    break
                j += 1

            return ''.join([t.value for t in tokens[i+2:i+j]]).strip()

    # this is very dumb logic, and only works if the function argument is set to a variable
    # which is set to a string value
    if is_var:
        for i in range(len(tokens)):
            if (
                tokens[i].typenum == tokenize.NAME and tokens[i].value == argument_name and
                tokens[i+1].typenum == tokenize.OP and tokens[i+1].value == '='
            ):
                return tokens[i+2].value.strip()

    return None


Instruction:
Can you generate the documentation for the following Python 3 function
def regex_in_file(regex, filepath, return_match=False):
    file_content = get_file_content(filepath)
    re_method = funcy.re_find if return_match else funcy.re_test
    return re_method(regex, file_content)

Response: Search for a regex in a file


Instruction:
How would you code a function in Python 3 to
search for a regex in a file contained within a package directory.

Response:
def regex_in_package_file(regex, filename, package_name, return_match=False):
    """ Search for a regex in a file contained within the package directory

    If return_match is True, return the found object instead of a boolean
    """
    filepath = package_file_path(filename, package_name)
    return regex_in_file(regex, filepath, return_match=return_match)


Instruction:
Create a Python 3 function to
test to see if a string is a URL or not

Response:
def string_is_url(test_str):
    """ Test to see if a string is a URL or not, defined in this case as a string for which
    urlparse returns a scheme component

    >>> string_is_url('somestring')
    False
    >>> string_is_url('https://some.domain.org/path')
    True
    """
    parsed = urlparse.urlparse(test_str)
    return parsed.scheme is not None and parsed.scheme != ''


Instruction:
Implement a function in Python 3 to
begin a transaction state for the given item.

Response:
def item_transaction(self, item) -> Transaction:
        """Begin transaction state for item.

        A transaction state is exists to prevent writing out to disk, mainly for performance reasons.
        All changes to the object are delayed until the transaction state exits.

        This method is thread safe.
        """
        items = self.__build_transaction_items(item)
        transaction = Transaction(self, item, items)
        self.__transactions.append(transaction)
        return transaction


Instruction:
Can you create a Python 3 function that
inserts a new data item into the document model.

Response:
def insert_data_item(self, before_index, data_item, auto_display: bool = True) -> None:
        """Insert a new data item into document model.

        This method is NOT threadsafe.
        """
        assert data_item is not None
        assert data_item not in self.data_items
        assert before_index <= len(self.data_items) and before_index >= 0
        assert data_item.uuid not in self.__uuid_to_data_item
        # update the session
        data_item.session_id = self.session_id
        # insert in internal list
        self.__insert_data_item(before_index, data_item, do_write=True)
        # automatically add a display
        if auto_display:
            display_item = DisplayItem.DisplayItem(data_item=data_item)
            self.append_display_item(display_item)


Instruction:
Make a summary of the following Python 3 code
def remove_data_item(self, data_item: DataItem.DataItem, *, safe: bool=False) -> typing.Optional[typing.Sequence]:
        # remove data item from any computations
        return self.__cascade_delete(data_item, safe=safe)

Response: Remove a data item from the document model.


Instruction:
Here you have a function in Python 3, explain what it does
def __cascade_delete_inner(self, master_item, safe: bool=False) -> typing.Optional[typing.Sequence]:
        # print(f"cascade {master_item}")
        # this horrible little hack ensures that computation changed messages are delayed until the end of the cascade
        # delete; otherwise there are cases where dependencies can be reestablished during the changed messages while
        # this method is partially finished. ugh. see test_computation_deletes_when_source_cycle_deletes.
        if self.__computation_changed_delay_list is None:
            computation_changed_delay_list = list()
            self.__computation_changed_delay_list = computation_changed_delay_list
        else:
            computation_changed_delay_list = None
        undelete_log = list()
        try:
            items = list()
            dependencies = list()
            self.__build_cascade(master_item, items, dependencies)
            cascaded = True
            while cascaded:
                cascaded = False
                # adjust computation bookkeeping to remove deleted items, then delete unused computations
                items_set = set(items)
                for computation in copy.copy(self.computations):
                    output_deleted = master_item in computation._outputs
                    computation._inputs -= items_set
                    computation._outputs -= items_set
                    if computation not in items and computation != self.__current_computation:
                        # computations are auto deleted if all inputs are deleted or any output is deleted
                        if output_deleted or all(input in items for input in computation._inputs):
                            self.__build_cascade(computation, items, dependencies)
                            cascaded = True
            # print(list(reversed(items)))
            # print(list(reversed(dependencies)))
            for source, target in reversed(dependencies):
                self.__remove_dependency(source, target)
            # now delete the actual items
            for item in reversed(items):
                for computation in self.computations:
                    new_entries = computation.list_item_removed(item)
                    undelete_log.extend(new_entries)
                container = item.container
                if isinstance(item, DataItem.DataItem):
                    name = "data_items"
                elif isinstance(item, DisplayItem.DisplayItem):
                    name = "display_items"
                elif isinstance(item, Graphics.Graphic):
                    name = "graphics"
                elif isinstance(item, DataStructure.DataStructure):
                    name = "data_structures"
                elif isinstance(item, Symbolic.Computation):
                    name = "computations"
                elif isinstance(item, Connection.Connection):
                    name = "connections"
                elif isinstance(item, DisplayItem.DisplayDataChannel):
                    name = "display_data_channels"
                else:
                    name = None
                    assert False, "Unable to cascade delete type " + str(type(item))
                assert name
                # print(container, name, item)
                if container is self and name == "data_items":
                    # call the version of __remove_data_item that doesn't cascade again
                    index = getattr(container, name).index(item)
                    item_dict = item.write_to_dict()
                    # NOTE: __remove_data_item will notify_remove_item
                    undelete_log.extend(self.__remove_data_item(item, safe=safe))
                    undelete_log.append({"type": name, "index": index, "properties": item_dict})
                elif container is self and name == "display_items":
                    # call the version of __remove_data_item that doesn't cascade again
                    index = getattr(container, name).index(item)
                    item_dict = item.write_to_dict()
                    # NOTE: __remove_display_item will notify_remove_item
                    undelete_log.extend(self.__remove_display_item(item, safe=safe))
                    undelete_log.append({"type": name, "index": index, "properties": item_dict})
                elif container:
                    container_ref = str(container.uuid)
                    index = getattr(container, name).index(item)
                    item_dict = item.write_to_dict()
                    container_properties = container.save_properties() if hasattr(container, "save_properties") else dict()
                    undelete_log.append({"type": name, "container": container_ref, "index": index, "properties": item_dict, "container_properties": container_properties})
                    container.remove_item(name, item)
                    # handle top level 'remove item' notifications for data structures, computations, and display items here
                    # since they're not handled elsewhere.
                    if container == self and name in ("data_structures", "computations"):
                        self.notify_remove_item(name, item, index)
        except Exception as e:
            import sys, traceback
            traceback.print_exc()
            traceback.format_exception(*sys.exc_info())
        finally:
            # check whether this call of __cascade_delete is the top level one that will finish the computation
            # changed messages.
            if computation_changed_delay_list is not None:
                self.__finish_computation_changed()
        return undelete_log

Response: Cascade delete an item.


Instruction:
Can you create a Python 3 function that
returns the list of data items that directly depends on data in this item.

Response:
def get_dependent_items(self, item) -> typing.List:
        """Return the list of data items containing data that directly depends on data in this item."""
        with self.__dependency_tree_lock:
            return copy.copy(self.__dependency_tree_source_to_target_map.get(weakref.ref(item), list()))


Instruction:
Here you have a function in Python 3, explain what it does
def __get_deep_dependent_item_set(self, item, item_set) -> None:
        if not item in item_set:
            item_set.add(item)
            with self.__dependency_tree_lock:
                for dependent in self.get_dependent_items(item):
                    self.__get_deep_dependent_item_set(dependent, item_set)

Response: Recursively returns the list of data items containing data that directly depends on this item.


Instruction:
Create a Python 3 function for
returning the list of data items containing data that directly depends on data in this item.

Response:
def get_dependent_data_items(self, data_item: DataItem.DataItem) -> typing.List[DataItem.DataItem]:
        """Return the list of data items containing data that directly depends on data in this item."""
        with self.__dependency_tree_lock:
            return [data_item for data_item in self.__dependency_tree_source_to_target_map.get(weakref.ref(data_item), list()) if isinstance(data_item, DataItem.DataItem)]


Instruction:
How would you explain what the following Python 3 function does
def transaction_context(self):
        class DocumentModelTransaction:
            def __init__(self, document_model):
                self.__document_model = document_model

            def __enter__(self):
                self.__document_model.persistent_object_context.enter_write_delay(self.__document_model)
                return self

            def __exit__(self, type, value, traceback):
                self.__document_model.persistent_object_context.exit_write_delay(self.__document_model)
                self.__document_model.persistent_object_context.rewrite_item(self.__document_model)

        return DocumentModelTransaction(self)

Response: Return a context object for a document - wide transaction.


Instruction:
Implement a Python 3 function for
returning a context manager to put the data item in a live state.

Response:
def data_item_live(self, data_item):
        """ Return a context manager to put the data item in a 'live state'. """
        class LiveContextManager:
            def __init__(self, manager, object):
                self.__manager = manager
                self.__object = object
            def __enter__(self):
                self.__manager.begin_data_item_live(self.__object)
                return self
            def __exit__(self, type, value, traceback):
                self.__manager.end_data_item_live(self.__object)
        return LiveContextManager(self, data_item)


Instruction:
Here you have a function in Python 3, explain what it does
def begin_data_item_live(self, data_item):
        with self.__live_data_items_lock:
            old_live_count = self.__live_data_items.get(data_item.uuid, 0)
            self.__live_data_items[data_item.uuid] = old_live_count + 1
        if old_live_count == 0:
            data_item._enter_live_state()
            for dependent_data_item in self.get_dependent_data_items(data_item):
                self.begin_data_item_live(dependent_data_item)

Response: Begins a live state for the data item.


Instruction:
Given the following Python 3 function, write the documentation
def end_data_item_live(self, data_item):
        with self.__live_data_items_lock:
            live_count = self.__live_data_items.get(data_item.uuid, 0) - 1
            assert live_count >= 0
            self.__live_data_items[data_item.uuid] = live_count
        if live_count == 0:
            data_item._exit_live_state()
            for dependent_data_item in self.get_dependent_data_items(data_item):
                self.end_data_item_live(dependent_data_item)

Response: Ends a live state for the data item.


Instruction:
Given the following Python 3 function, write the documentation
def __construct_data_item_reference(self, hardware_source: HardwareSource.HardwareSource, data_channel: HardwareSource.DataChannel):
        session_id = self.session_id
        key = self.make_data_item_reference_key(hardware_source.hardware_source_id, data_channel.channel_id)
        data_item_reference = self.get_data_item_reference(key)
        with data_item_reference.mutex:
            data_item = data_item_reference.data_item
            # if we still don't have a data item, create it.
            if data_item is None:
                data_item = DataItem.DataItem()
                data_item.ensure_data_source()
                data_item.title = "%s (%s)" % (hardware_source.display_name, data_channel.name) if data_channel.name else hardware_source.display_name
                data_item.category = "temporary"
                data_item_reference.data_item = data_item

                def append_data_item():
                    self.append_data_item(data_item)
                    self._update_data_item_reference(key, data_item)

                self.__call_soon(append_data_item)

            def update_session():
                # update the session, but only if necessary (this is an optimization to prevent unnecessary display updates)
                if data_item.session_id != session_id:
                    data_item.session_id = session_id
                session_metadata = ApplicationData.get_session_metadata_dict()
                if data_item.session_metadata != session_metadata:
                    data_item.session_metadata = session_metadata
                if data_channel.processor:
                    src_data_channel = hardware_source.data_channels[data_channel.src_channel_index]
                    src_data_item_reference = self.get_data_item_reference(self.make_data_item_reference_key(hardware_source.hardware_source_id, src_data_channel.channel_id))
                    data_channel.processor.connect_data_item_reference(src_data_item_reference)

            self.__call_soon(update_session)

            return data_item_reference

Response: Construct a data item reference and assign a data item to it.


Instruction:
Create a Python 3 function to
create a new data item with computation specified by processing_id inputs and region_list_map.

Response:
def __make_computation(self, processing_id: str, inputs: typing.List[typing.Tuple[DisplayItem.DisplayItem, typing.Optional[Graphics.Graphic]]], region_list_map: typing.Mapping[str, typing.List[Graphics.Graphic]]=None, parameters: typing.Mapping[str, typing.Any]=None) -> DataItem.DataItem:
        """Create a new data item with computation specified by processing_id, inputs, and region_list_map.

        The region_list_map associates a list of graphics corresponding to the required regions with a computation source (key).
        """
        region_list_map = region_list_map or dict()

        parameters = parameters or dict()

        processing_descriptions = self._processing_descriptions
        processing_description = processing_descriptions[processing_id]

        # first process the sources in the description. match them to the inputs (which are data item/crop graphic tuples)
        src_dicts = processing_description.get("sources", list())
        assert len(inputs) == len(src_dicts)
        src_names = list()
        src_texts = list()
        src_labels = list()
        regions = list()
        region_map = dict()
        for i, (src_dict, input) in enumerate(zip(src_dicts, inputs)):

            display_item = input[0]
            data_item = display_item.data_items[0] if display_item and len(display_item.data_items) > 0 else None

            if not data_item:
                return None

            # each source can have a list of requirements, check through them
            requirements = src_dict.get("requirements", list())
            for requirement in requirements:
                requirement_type = requirement["type"]
                if requirement_type == "dimensionality":
                    min_dimension = requirement.get("min")
                    max_dimension = requirement.get("max")
                    dimensionality = len(data_item.dimensional_shape)
                    if min_dimension is not None and dimensionality < min_dimension:
                        return None
                    if max_dimension is not None and dimensionality > max_dimension:
                        return None
                if requirement_type == "is_sequence":
                    if not data_item.is_sequence:
                        return None

            src_name = src_dict["name"]
            src_label = src_dict["label"]
            use_display_data = src_dict.get("use_display_data", True)
            xdata_property = "display_xdata" if use_display_data else "xdata"
            if src_dict.get("croppable"):
                xdata_property = "cropped_" + xdata_property
            elif src_dict.get("use_filtered_data", False):
                xdata_property = "filtered_" + xdata_property
            src_text = "{}.{}".format(src_name, xdata_property)
            src_names.append(src_name)
            src_texts.append(src_text)
            src_labels.append(src_label)

            # each source can have a list of regions to be matched to arguments or created on the source
            region_dict_list = src_dict.get("regions", list())
            src_region_list = region_list_map.get(src_name, list())
            assert len(region_dict_list) == len(src_region_list)
            for region_dict, region in zip(region_dict_list, src_region_list):
                region_params = region_dict.get("params", dict())
                region_type = region_dict["type"]
                region_name = region_dict["name"]
                region_label = region_params.get("label")
                if region_type == "point":
                    if region:
                        assert isinstance(region, Graphics.PointGraphic)
                        point_region = region
                    else:
                        point_region = Graphics.PointGraphic()
                        for k, v in region_params.items():
                            setattr(point_region, k, v)
                        if display_item:
                            display_item.add_graphic(point_region)
                    regions.append((region_name, point_region, region_label))
                    region_map[region_name] = point_region
                elif region_type == "line":
                    if region:
                        assert isinstance(region, Graphics.LineProfileGraphic)
                        line_region = region
                    else:
                        line_region = Graphics.LineProfileGraphic()
                        line_region.start = 0.25, 0.25
                        line_region.end = 0.75, 0.75
                        for k, v in region_params.items():
                            setattr(line_region, k, v)
                        if display_item:
                            display_item.add_graphic(line_region)
                    regions.append((region_name, line_region, region_params.get("label")))
                    region_map[region_name] = line_region
                elif region_type == "rectangle":
                    if region:
                        assert isinstance(region, Graphics.RectangleGraphic)
                        rect_region = region
                    else:
                        rect_region = Graphics.RectangleGraphic()
                        rect_region.center = 0.5, 0.5
                        rect_region.size = 0.5, 0.5
                        for k, v in region_params.items():
                            setattr(rect_region, k, v)
                        if display_item:
                            display_item.add_graphic(rect_region)
                    regions.append((region_name, rect_region, region_params.get("label")))
                    region_map[region_name] = rect_region
                elif region_type == "ellipse":
                    if region:
                        assert isinstance(region, Graphics.EllipseGraphic)
                        ellipse_region = region
                    else:
                        ellipse_region = Graphics.RectangleGraphic()
                        ellipse_region.center = 0.5, 0.5
                        ellipse_region.size = 0.5, 0.5
                        for k, v in region_params.items():
                            setattr(ellipse_region, k, v)
                        if display_item:
                            display_item.add_graphic(ellipse_region)
                    regions.append((region_name, ellipse_region, region_params.get("label")))
                    region_map[region_name] = ellipse_region
                elif region_type == "spot":
                    if region:
                        assert isinstance(region, Graphics.SpotGraphic)
                        spot_region = region
                    else:
                        spot_region = Graphics.SpotGraphic()
                        spot_region.center = 0.25, 0.75
                        spot_region.size = 0.1, 0.1
                        for k, v in region_params.items():
                            setattr(spot_region, k, v)
                        if display_item:
                            display_item.add_graphic(spot_region)
                    regions.append((region_name, spot_region, region_params.get("label")))
                    region_map[region_name] = spot_region
                elif region_type == "interval":
                    if region:
                        assert isinstance(region, Graphics.IntervalGraphic)
                        interval_region = region
                    else:
                        interval_region = Graphics.IntervalGraphic()
                        for k, v in region_params.items():
                            setattr(interval_region, k, v)
                        if display_item:
                            display_item.add_graphic(interval_region)
                    regions.append((region_name, interval_region, region_params.get("label")))
                    region_map[region_name] = interval_region
                elif region_type == "channel":
                    if region:
                        assert isinstance(region, Graphics.ChannelGraphic)
                        channel_region = region
                    else:
                        channel_region = Graphics.ChannelGraphic()
                        for k, v in region_params.items():
                            setattr(channel_region, k, v)
                        if display_item:
                            display_item.add_graphic(channel_region)
                    regions.append((region_name, channel_region, region_params.get("label")))
                    region_map[region_name] = channel_region

        # now extract the script (full script) or expression (implied imports and return statement)
        script = processing_description.get("script")
        if not script:
            expression = processing_description.get("expression")
            if expression:
                script = Symbolic.xdata_expression(expression)
        assert script

        # construct the computation
        script = script.format(**dict(zip(src_names, src_texts)))
        computation = self.create_computation(script)
        computation.label = processing_description["title"]
        computation.processing_id = processing_id
        # process the data item inputs
        for src_dict, src_name, src_label, input in zip(src_dicts, src_names, src_labels, inputs):
            in_display_item = input[0]
            secondary_specifier = None
            if src_dict.get("croppable", False):
                secondary_specifier = self.get_object_specifier(input[1])
            display_data_channel = in_display_item.display_data_channel
            computation.create_object(src_name, self.get_object_specifier(display_data_channel), label=src_label, secondary_specifier=secondary_specifier)
        # process the regions
        for region_name, region, region_label in regions:
            computation.create_object(region_name, self.get_object_specifier(region), label=region_label)
        # next process the parameters
        for param_dict in processing_description.get("parameters", list()):
            parameter_value = parameters.get(param_dict["name"], param_dict["value"])
            computation.create_variable(param_dict["name"], param_dict["type"], parameter_value, value_default=param_dict.get("value_default"),
                                        value_min=param_dict.get("value_min"), value_max=param_dict.get("value_max"),
                                        control_type=param_dict.get("control_type"), label=param_dict["label"])

        data_item0 = inputs[0][0].data_items[0]
        new_data_item = DataItem.new_data_item()
        prefix = "{} of ".format(processing_description["title"])
        new_data_item.title = prefix + data_item0.title
        new_data_item.category = data_item0.category

        self.append_data_item(new_data_item)

        new_display_item = self.get_display_item_for_data_item(new_data_item)

        # next come the output regions that get created on the target itself
        new_regions = dict()
        for out_region_dict in processing_description.get("out_regions", list()):
            region_type = out_region_dict["type"]
            region_name = out_region_dict["name"]
            region_params = out_region_dict.get("params", dict())
            if region_type == "interval":
                interval_region = Graphics.IntervalGraphic()
                for k, v in region_params.items():
                    setattr(interval_region, k, v)
                new_display_item.add_graphic(interval_region)
                new_regions[region_name] = interval_region

        # now come the connections between the source and target
        for connection_dict in processing_description.get("connections", list()):
            connection_type = connection_dict["type"]
            connection_src = connection_dict["src"]
            connection_src_prop = connection_dict.get("src_prop")
            connection_dst = connection_dict["dst"]
            connection_dst_prop = connection_dict.get("dst_prop")
            if connection_type == "property":
                if connection_src == "display_data_channel":
                    # TODO: how to refer to the data_items? hardcode to data_item0 for now.
                    display_item0 = self.get_display_item_for_data_item(data_item0)
                    display_data_channel0 = display_item0.display_data_channel if display_item0 else None
                    connection = Connection.PropertyConnection(display_data_channel0, connection_src_prop, new_regions[connection_dst], connection_dst_prop, parent=new_data_item)
                    self.append_connection(connection)
            elif connection_type == "interval_list":
                connection = Connection.IntervalListConnection(new_display_item, region_map[connection_dst], parent=new_data_item)
                self.append_connection(connection)

        # save setting the computation until last to work around threaded clone/merge operation bug.
        # the bug is that setting the computation triggers the recompute to occur on a thread.
        # the recompute clones the data item and runs the operation. meanwhile this thread
        # updates the connection. now the recompute finishes and merges back the data item
        # which was cloned before the connection was established, effectively reversing the
        # update that matched the graphic interval to the slice interval on the display.
        # the result is that the slice interval on the display would get set to the default
        # value of the graphic interval. so don't actually update the computation until after
        # everything is configured. permanent solution would be to improve the clone/merge to
        # only update data that had been changed. alternative implementation would only track
        # changes to the data item and then apply them again to the original during merge.
        self.set_data_item_computation(new_data_item, computation)

        return new_data_item


Instruction:
Can you tell what is the following Python 3 function doing
def interpolate_colors(array: numpy.ndarray, x: int) -> numpy.ndarray:
    out_array = []
    for i in range(x):
        if i % (x / (len(array) - 1)) == 0:
            index = i / (x / (len(array) - 1))
            out_array.append(array[int(index)])
        else:
            start_marker = array[math.floor(i / (x / (len(array) - 1)))]
            stop_marker = array[math.ceil(i / (x / (len(array) - 1)))]
            interp_amount = i % (x / (len(array) - 1)) / (x / (len(array) - 1))
            interp_color = numpy.rint(start_marker + ((stop_marker - start_marker) * interp_amount))
            out_array.append(interp_color)
    out_array[-1] = array[-1]
    return numpy.array(out_array).astype(numpy.uint8)

Response: Interpolates the colors in a color map.


Instruction:
Can you implement a function in Python 3 that
stars any gist by providing gistID or gistname or any unique Gistid

Response:
def star(self, **args):
		'''
		star any gist by providing gistID or gistname(for authenticated user)
		'''
		if 'name' in args:
			self.gist_name = args['name']
			self.gist_id = self.getMyID(self.gist_name)
		elif 'id' in args:
			self.gist_id = args['id']
		else:
			raise Exception('Either provide authenticated user\'s Unambigious Gistname or any unique Gistid to be starred')

		r = requests.put(
			'%s'%BASE_URL+'/gists/%s/star' % self.gist_id,
			headers=self.gist.header
			)
		if (r.status_code == 204):
			response = {
				'id': self.gist_id
			}
			return response

		raise Exception('Gist can\'t be starred')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fork(self, **args):
		'''
		fork any gist by providing gistID or gistname(for authenticated user)
		'''
		if 'name' in args:
			self.gist_name = args['name']
			self.gist_id = self.getMyID(self.gist_name)
		elif 'id' in args:
			self.gist_id = args['id']
		else:
			raise Exception('Either provide authenticated user\'s Unambigious Gistname or any unique Gistid to be forked')

		r = requests.post(
			'%s'%BASE_URL+'/gists/%s/forks' % self.gist_id,
			headers=self.gist.header
			)
		if (r.status_code == 201):
			response = {
				'id': self.gist_id,
				'description': r.json()['description'],
				'public': r.json()['public'],
				'comments': r.json()['comments']
			}
			return response

		raise Exception('Gist can\'t be forked')

Response: fork any gist by providing gistID or gistname(for authenticated user)


Instruction:
Make a summary of the following Python 3 code
def checkifstar(self, **args):
		'''
		Check a gist if starred by providing gistID or gistname(for authenticated user)
		'''

		if 'name' in args:
			self.gist_name = args['name']
			self.gist_id = self.getMyID(self.gist_name)
		elif 'id' in args:
			self.gist_id = args['id']
		else:
			raise Exception('Either provide authenticated user\'s Unambigious Gistname or any unique Gistid to be checked for star')

		r = requests.get(
			'%s'%BASE_URL+'/gists/%s/star' % self.gist_id,
			headers=self.gist.header
			)
		if (r.status_code == 204):
			response = {
				'starred': 'True',
				'id': self.gist_id
				}
		else:
			response = {
				'starred': 'False'
			}

		return response

Response: This method checks if a gist is starred by providing gistID or gistname or any unique Gistid to be checked for starred


Instruction:
Make a summary of the following Python 3 code
def salvar(self, destino=None, prefix='tmp', suffix='-sat.log'):
        if destino:
            if os.path.exists(destino):
                raise IOError((errno.EEXIST, 'File exists', destino,))
            destino = os.path.abspath(destino)
            fd = os.open(destino, os.O_EXCL|os.O_CREAT|os.O_WRONLY)
        else:
            fd, destino = tempfile.mkstemp(prefix=prefix, suffix=suffix)

        os.write(fd, self.conteudo())
        os.fsync(fd)
        os.close(fd)

        return os.path.abspath(destino)

Response: Salva o arquivo de log decodificado.


Instruction:
Explain what the following Python 3 code does
def analisar(retorno):
        resposta = analisar_retorno(forcar_unicode(retorno),
                funcao='ExtrairLogs',
                classe_resposta=RespostaExtrairLogs,
                campos=RespostaSAT.CAMPOS + (
                        ('arquivoLog', unicode),
                    ),
                campos_alternativos=[
                        # se a extração dos logs falhar espera-se o padrão de
                        # campos no retorno...
                        RespostaSAT.CAMPOS,
                    ]
            )
        if resposta.EEEEE not in ('15000',):
            raise ExcecaoRespostaSAT(resposta)
        return resposta

Response: Analisar uma : class : RespostaExtrairLogs a partir do retorno.


Instruction:
Explain what the following Python 3 code does
def load_data_old(self):
        units = ""
        if len(self.file_objects) == 1 and self.file_objects[0] is not None:
            data = self.file_objects[0].variables[self.variable][self.forecast_hours]
            if hasattr(self.file_objects[0].variables[self.variable], "units"):
                units = self.file_objects[0].variables[self.variable].units
        elif len(self.file_objects) > 1:
            grid_shape = [len(self.file_objects), 1, 1]
            for file_object in self.file_objects:
                if file_object is not None:
                    if self.variable in file_object.variables.keys():
                        grid_shape = file_object.variables[self.variable].shape
                    elif self.variable.ljust(6, "_") in file_object.variables.keys():
                        grid_shape = file_object.variables[self.variable.ljust(6, "_")].shape

                    else:
                        print("{0} not found".format(self.variable))
                        raise KeyError
                    break
            data = np.zeros((len(self.file_objects), grid_shape[1], grid_shape[2]))
            for f, file_object in enumerate(self.file_objects):
                if file_object is not None:
                    if self.variable in file_object.variables.keys():
                        var_name = self.variable
                    elif self.variable.ljust(6, "_") in file_object.variables.keys():
                        var_name = self.variable.ljust(6, "_")
                    else:
                        print("{0} not found".format(self.variable))
                        raise KeyError
                    data[f] = file_object.variables[var_name][0]
                    if units == "" and hasattr(file_object.variables[var_name], "units"):
                        units = file_object.variables[var_name].units
        else:
            data = None
        return data, units

Response:
Loads time series of 2D data grids from each opened file. The code
        handles loading a full time series from one file or individual time steps
        from multiple files.


Instruction:
Write a Python 3 function that can
load data from netCDF file objects or list of netCDF file objects. Handles special variable name formats.

Response:
def load_data(self):
        """
        Load data from netCDF file objects or list of netCDF file objects. Handles special variable name formats.

        Returns:
            Array of data loaded from files in (time, y, x) dimensions, Units
        """
        units = ""
        if self.file_objects[0] is None:
            raise IOError()
        var_name, z_index = self.format_var_name(self.variable, list(self.file_objects[0].variables.keys()))
        ntimes = 0
        if 'time' in self.file_objects[0].variables[var_name].dimensions:
            ntimes = len(self.file_objects[0].dimensions['time'])

        if ntimes > 1:
            if z_index is None:
                data = self.file_objects[0].variables[var_name][self.forecast_hours].astype(np.float32)
            else:
                data = self.file_objects[0].variables[var_name][self.forecast_hours, z_index].astype(np.float32)
        else:
            y_dim, x_dim = self.file_objects[0].variables[var_name].shape[-2:]
            data = np.zeros((len(self.valid_dates), y_dim, x_dim), dtype=np.float32)
            for f, file_object in enumerate(self.file_objects):
                if file_object is not None:
                    if z_index is None:
                        data[f] = file_object.variables[var_name][0]
                    else:
                        data[f] = file_object.variables[var_name][0, z_index]
        if hasattr(self.file_objects[0].variables[var_name], "units"):
            units = self.file_objects[0].variables[var_name].units
        return data, units


Instruction:
Can you generate the documentation for the following Python 3 function
def format_var_name(variable, var_list):
        z_index = None
        if variable in var_list:
            var_name = variable
        elif variable.ljust(6, "_") in var_list:
            var_name = variable.ljust(6, "_")
        elif any([variable in v_sub.split("_") for v_sub in var_list]):
            var_name = var_list[[variable in v_sub.split("_") for v_sub in var_list].index(True)]
            z_index = var_name.split("_").index(variable)
        else:
            raise KeyError("{0} not found in {1}".format(variable, var_list))
        return var_name, z_index

Response: Returns the variable name and z - level of the variable in file containing relevant data and index of variable z - level if multiple variables in same array in same file.


Instruction:
Can you implement a function in Python 3 that
loads data from flat data files containing total track information and information about each timestep.

Response:
def load_data(self, mode="train", format="csv"):
        """
        Load data from flat data files containing total track information and information about each timestep.
        The two sets are combined using merge operations on the Track IDs. Additional member information is gathered
        from the appropriate member file.
        Args:
            mode: "train" or "forecast"
            format:  file format being used. Default is "csv"
        """
        if mode in self.data.keys():
            run_dates = pd.DatetimeIndex(start=self.start_dates[mode],
                                        end=self.end_dates[mode],freq="1D")
            run_date_str = [d.strftime("%Y%m%d-%H%M") for d in run_dates.date]
            print(run_date_str)
            all_total_track_files = sorted(glob(getattr(self, mode + "_data_path") +
                                                "*total_" + self.ensemble_name + "*." + format))
            all_step_track_files = sorted(glob(getattr(self, mode + "_data_path") +
                                               "*step_" + self.ensemble_name + "*." + format))
            total_track_files = []
            for track_file in all_total_track_files:
                file_date = track_file.split("_")[-1][:-4]
                if file_date in run_date_str:
                    total_track_files.append(track_file)
            step_track_files = []
            for step_file in all_step_track_files:
                file_date = step_file.split("_")[-1][:-4]
                if file_date in run_date_str:
                    step_track_files.append(step_file)

            self.data[mode]["total"] = pd.concat(map(pd.read_csv, total_track_files),
                                                 ignore_index=True)
            self.data[mode]["total"] = self.data[mode]["total"].fillna(value=0)
            self.data[mode]["total"] = self.data[mode]["total"].replace([np.inf, -np.inf], 0)
            self.data[mode]["step"] = pd.concat(map(pd.read_csv, step_track_files),
                                                ignore_index=True)
            self.data[mode]["step"] = self.data[mode]["step"].fillna(value=0)
            self.data[mode]["step"] = self.data[mode]["step"].replace([np.inf, -np.inf], 0)
            if mode == "forecast":
                self.data[mode]["step"] = self.data[mode]["step"].drop_duplicates("Step_ID")
            self.data[mode]["member"] = pd.read_csv(self.member_files[mode])
            self.data[mode]["combo"] = pd.merge(self.data[mode]["step"],
                                                self.data[mode]["total"],
                                                on=["Track_ID", "Ensemble_Name", "Ensemble_Member", "Run_Date"])
            self.data[mode]["combo"] = pd.merge(self.data[mode]["combo"],
                                                self.data[mode]["member"],
                                                on="Ensemble_Member")
            self.data[mode]["total_group"] = pd.merge(self.data[mode]["total"],
                                                      self.data[mode]["member"],
                                                      on="Ensemble_Member")


Instruction:
Write a Python 3 script to
calculate a multivariate normal distribution from the training data for each group of ensemble members and saves it to a pickle file.

Response:
def calc_copulas(self,
                     output_file,
                     model_names=("start-time", "translation-x", "translation-y"),
                     label_columns=("Start_Time_Error", "Translation_Error_X", "Translation_Error_Y")):
        """
        Calculate a copula multivariate normal distribution from the training data for each group of ensemble members.
        Distributions are written to a pickle file for later use.
        Args:
            output_file: Pickle file
            model_names: Names of the tracking models
            label_columns: Names of the data columns used for labeling
        Returns:
        """
        if len(self.data['train']) == 0:
            self.load_data()
        groups = self.data["train"]["member"][self.group_col].unique()
        copulas = {}
        label_columns = list(label_columns)
        for group in groups:
            print(group)
            group_data = self.data["train"]["total_group"].loc[
                self.data["train"]["total_group"][self.group_col] == group]
            group_data = group_data.dropna()
            group_data.reset_index(drop=True, inplace=True)
            copulas[group] = {}
            copulas[group]["mean"] = group_data[label_columns].mean(axis=0).values
            copulas[group]["cov"] = np.cov(group_data[label_columns].values.T)
            copulas[group]["model_names"] = list(model_names)
            del group_data
        pickle.dump(copulas, open(output_file, "w"), pickle.HIGHEST_PROTOCOL)


Instruction:
Write a Python 3 function that can
fit the condition models to predict whether or not hail will occur.

Response:
def fit_condition_models(self, model_names,
                             model_objs,
                             input_columns,
                             output_column="Matched",
                             output_threshold=0.0):
        """
        Fit machine learning models to predict whether or not hail will occur.
        Args:
            model_names: List of strings with the names for the particular machine learning models
            model_objs: scikit-learn style machine learning model objects.
            input_columns: list of the names of the columns used as input for the machine learning model
            output_column: name of the column used for labeling whether or not the event occurs
            output_threshold: splitting threshold to determine if event has occurred. Default 0.0
        """
        print("Fitting condition models")
        groups = self.data["train"]["member"][self.group_col].unique()

        weights = None

        for group in groups:
            print(group)
            group_data = self.data["train"]["combo"].loc[self.data["train"]["combo"][self.group_col] == group]
            if self.sector:

                lon_obj = data.loc[:,'Centroid_Lon']
                lat_obj = data.loc[:,'Centroid_Lat']

                left_lon,right_lon = self.grid_dict["sw_lon"],self.grid_dict["ne_lon"]
                lower_lat,upper_lat = self.grid_dict["sw_lat"],self.grid_dict["ne_lat"]

                weights = np.where((left_lon<=lon_obj)&(right_lon>=lon_obj) &\
                    (lower_lat<=lat_obj)&(upper_lat>=lat_obj),1,0.3)

            output_data = np.where(group_data[output_column] > output_threshold, 1, 0)
            print("Ones: ", np.count_nonzero(output_data > 0), "Zeros: ", np.count_nonzero(output_data == 0))
            self.condition_models[group] = {}
            for m, model_name in enumerate(model_names):
                print(model_name)
                self.condition_models[group][model_name] = deepcopy(model_objs[m])
                try:
                    self.condition_models[group][model_name].fit(group_data[input_columns],
                                output_data,sample_weight=weights)
                except:
                    self.condition_models[group][model_name].fit(group_data[input_columns], output_data)

                if hasattr(self.condition_models[group][model_name], "best_estimator_"):
                    print(self.condition_models[group][model_name].best_estimator_)
                    print(self.condition_models[group][model_name].best_score_)


Instruction:
Implement a function in Python 3 to
fit models to predict hail or no - hail and use cross - validation to determine the probability of a skill score.

Response:
def fit_condition_threshold_models(self, model_names, model_objs, input_columns, output_column="Matched",
                                       output_threshold=0.5, num_folds=5, threshold_score="ets"):
        """
        Fit models to predict hail/no-hail and use cross-validation to determine the probaility threshold that
        maximizes a skill score.

        Args:
            model_names: List of machine learning model names
            model_objs: List of Scikit-learn ML models
            input_columns: List of input variables in the training data
            output_column: Column used for prediction
            output_threshold: Values exceeding this threshold are considered positive events; below are nulls
            num_folds: Number of folds in the cross-validation procedure
            threshold_score: Score available in ContingencyTable used for determining the best probability threshold
        Returns:
            None
        """
        print("Fitting condition models")
        groups = self.data["train"]["member"][self.group_col].unique()

        weights=None

        for group in groups:
            print(group)
            group_data = self.data["train"]["combo"].iloc[
                np.where(self.data["train"]["combo"][self.group_col] == group)[0]]

            if self.sector:
                lon_obj = group_data.loc[:,'Centroid_Lon']
                lat_obj = group_data.loc[:,'Centroid_Lat']

                conus_lat_lon_points = zip(lon_obj.values.ravel(),lat_obj.values.ravel())
                center_lon, center_lat = self.proj_dict["lon_0"],self.proj_dict["lat_0"]

                distances = np.array([np.sqrt((x-center_lon)**2+\
                        (y-center_lat)**2) for (x, y) in conus_lat_lon_points])

                min_dist, max_minus_min = min(distances),max(distances)-min(distances)

                distance_0_1 = [1.0-((d - min_dist)/(max_minus_min)) for d in distances]
                weights = np.array(distance_0_1)

            output_data = np.where(group_data.loc[:, output_column] > output_threshold, 1, 0)
            ones = np.count_nonzero(output_data > 0)
            print("Ones: ", ones, "Zeros: ", np.count_nonzero(output_data == 0))
            self.condition_models[group] = {}
            num_elements = group_data[input_columns].shape[0]

            for m, model_name in enumerate(model_names):
                print(model_name)
                roc = DistributedROC(thresholds=np.arange(0, 1.1, 0.01))
                self.condition_models[group][model_name] = deepcopy(model_objs[m])

                try:
                    kf = KFold(n_splits=num_folds)
                    for train_index, test_index in kf.split(group_data[input_columns].values):
                        if np.count_nonzero(output_data[train_index]) > 0:
                            try:
                                self.condition_models[group][model_name].fit(
                                        group_data.iloc[train_index][input_columns],
                                        output_data[train_index],sample_weight=weights[train_index])
                            except:
                                self.condition_models[group][model_name].fit(
                                        group_data.iloc[train_index][input_columns],
                                        output_data[train_index])

                            cv_preds = self.condition_models[group][model_name].predict_proba(
                                group_data.iloc[test_index][input_columns])[:,1]

                            roc.update(cv_preds, output_data[test_index])

                        else:
                            continue

                except TypeError:
                    kf = KFold(num_elements,n_folds=num_folds)
                    for train_index, test_index in kf:

                        if np.count_nonzero(output_data[train_index]) > 0:
                            try:
                                self.condition_models[group][model_name].fit(
                                        group_data.iloc[train_index][input_columns],
                                        output_data[train_index],sample_weight=weights[train_index])
                            except:
                                self.condition_models[group][model_name].fit(
                                        group_data.iloc[train_index][input_columns],
                                        output_data[train_index])
                            cv_preds = self.condition_models[group][model_name].predict_proba(
                                group_data.iloc[test_index][input_columns])[:, 1]

                            roc.update(cv_preds, output_data[test_index])

                        else:
                            continue

                self.condition_models[group][
                    model_name + "_condition_threshold"], _ = roc.max_threshold_score(threshold_score)
                print(model_name + " condition threshold: {0:0.3f}".format(
                self.condition_models[group][model_name + "_condition_threshold"]))
                self.condition_models[group][model_name].fit(group_data[input_columns], output_data)


Instruction:
Can you implement a function in Python 3 that
predicts the probability of each condition model in the data.

Response:
def predict_condition_models(self, model_names,
                                 input_columns,
                                 metadata_cols,
                                 data_mode="forecast",
                                 ):
        """
        Apply condition modelsto forecast data.
        Args:
            model_names: List of names associated with each condition model used for prediction
            input_columns: List of columns in data used as input into the model
            metadata_cols: Columns from input data that should be included in the data frame with the predictions.
            data_mode: Which data subset to pull from for the predictions, "forecast" by default
        Returns:
            A dictionary of data frames containing probabilities of the event and specified metadata
        """
        groups = self.condition_models.keys()
        predictions = pd.DataFrame(self.data[data_mode]["combo"][metadata_cols])
        for group in groups:
            print(group)
            print(self.condition_models[group])
            g_idxs = self.data[data_mode]["combo"][self.group_col] == group
            group_count = np.count_nonzero(g_idxs)
            if group_count > 0:
                for m, model_name in enumerate(model_names):
                    mn = model_name.replace(" ", "-")
                    predictions.loc[g_idxs, mn + "_conditionprob"] = self.condition_models[group][
                                                                         model_name].predict_proba(
                        self.data[data_mode]["combo"].loc[g_idxs, input_columns])[:, 1]
                    predictions.loc[g_idxs,
                                    mn + "_conditionthresh"] = np.where(predictions.loc[g_idxs, mn + "_conditionprob"]
                                                                        >= self.condition_models[group][
                                                                            model_name + "_condition_threshold"], 1, 0)

        return predictions


Instruction:
Create a Python 3 function for
fitting multitask machine learning models to predict the parameters of a size distribution of a specific class.

Response:
def fit_size_distribution_models(self, model_names, model_objs, input_columns,
                                     output_columns=None, calibrate=False):
        """
        Fits multitask machine learning models to predict the parameters of a size distribution
        Args:
            model_names: List of machine learning model names
            model_objs: scikit-learn style machine learning model objects
            input_columns: Training data columns used as input for ML model
            output_columns: Training data columns used for prediction
            calibrate: Whether or not to fit a log-linear regression to predictions from ML model
        """
        if output_columns is None:
            output_columns = ["Shape", "Location", "Scale"]
        groups = np.unique(self.data["train"]["member"][self.group_col])

        weights=None

        for group in groups:
            group_data = self.data["train"]["combo"].loc[self.data["train"]["combo"][self.group_col] == group]
            group_data = group_data.dropna()
            group_data = group_data[group_data[output_columns[-1]] > 0]
            if self.sector:

                lon_obj = group_data.loc[:,'Centroid_Lon']
                lat_obj = group_data.loc[:,'Centroid_Lat']

                conus_lat_lon_points = zip(lon_obj.values.ravel(),lat_obj.values.ravel())
                center_lon, center_lat = self.proj_dict["lon_0"],self.proj_dict["lat_0"]

                distances = np.array([np.sqrt((x-center_lon)**2+\
                        (y-center_lat)**2) for (x, y) in conus_lat_lon_points])

                min_dist, max_minus_min = min(distances),max(distances)-min(distances)

                distance_0_1 = [1.0-((d - min_dist)/(max_minus_min)) for d in distances]
                weights = np.array(distance_0_1)

            self.size_distribution_models[group] = {"multi": {}, "lognorm": {}}
            if calibrate:
                self.size_distribution_models[group]["calshape"] = {}
                self.size_distribution_models[group]["calscale"] = {}
            log_labels = np.log(group_data[output_columns].values)
            log_means = log_labels.mean(axis=0)
            log_sds = log_labels.std(axis=0)
            self.size_distribution_models[group]['lognorm']['mean'] = log_means
            self.size_distribution_models[group]['lognorm']['sd'] = log_sds
            for m, model_name in enumerate(model_names):
                print(group, model_name)
                self.size_distribution_models[group]["multi"][model_name] = deepcopy(model_objs[m])
                try:
                    self.size_distribution_models[group]["multi"][model_name].fit(group_data[input_columns],
                                                                              (log_labels - log_means) / log_sds,
                                                                        sample_weight=weights)
                except:
                    self.size_distribution_models[group]["multi"][model_name].fit(group_data[input_columns],
                                                                              (log_labels - log_means) / log_sds)
                if calibrate:
                    training_predictions = self.size_distribution_models[
                        group]["multi"][model_name].predict(group_data[input_columns])
                    self.size_distribution_models[group]["calshape"][model_name] = LinearRegression()
                    self.size_distribution_models[group]["calshape"][model_name].fit(training_predictions[:, 0:1],
                                                                                (log_labels[:, 0] - log_means[0]) /
                                                                                log_sds[
                                                                                0],
                                                                                sample_weight=weights)
                    self.size_distribution_models[group]["calscale"][model_name] = LinearRegression()
                    self.size_distribution_models[group]["calscale"][model_name].fit(training_predictions[:, 1:],
                                                                                (log_labels[:, 1] - log_means[1]) /
                                                                                log_sds[
                                                                                1],
                                                                            sample_weight=weights)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fit_size_distribution_component_models(self, model_names, model_objs, input_columns, output_columns):
        groups = np.unique(self.data["train"]["member"][self.group_col])

        weights=None

        for group in groups:
            print(group)
            group_data = self.data["train"]["combo"].loc[self.data["train"]["combo"][self.group_col] == group]
            group_data = group_data.dropna()
            group_data = group_data.loc[group_data[output_columns[-1]] > 0]

            if self.sector:

                lon_obj = group_data.loc[:,'Centroid_Lon']
                lat_obj = group_data.loc[:,'Centroid_Lat']

                conus_lat_lon_points = zip(lon_obj.values.ravel(),lat_obj.values.ravel())
                center_lon, center_lat = self.proj_dict["lon_0"],self.proj_dict["lat_0"]

                distances = np.array([np.sqrt((x-center_lon)**2+\
                        (y-center_lat)**2) for (x, y) in conus_lat_lon_points])

                min_dist, max_minus_min = min(distances),max(distances)-min(distances)

                distance_0_1 = [1.0-((d - min_dist)/(max_minus_min)) for d in distances]
                weights = np.array(distance_0_1)

            self.size_distribution_models[group] = {"lognorm": {}}
            self.size_distribution_models[group]["lognorm"]["pca"] = PCA(n_components=len(output_columns))
            log_labels = np.log(group_data[output_columns].values)
            log_labels[:, np.where(output_columns == "Shape")[0]] *= -1
            log_means = log_labels.mean(axis=0)
            log_sds = log_labels.std(axis=0)
            log_norm_labels = (log_labels - log_means) / log_sds
            out_pc_labels = self.size_distribution_models[group]["lognorm"]["pca"].fit_transform(log_norm_labels)
            self.size_distribution_models[group]['lognorm']['mean'] = log_means
            self.size_distribution_models[group]['lognorm']['sd'] = log_sds
            for comp in range(len(output_columns)):
                self.size_distribution_models[group]["pc_{0:d}".format(comp)] = dict()
                for m, model_name in enumerate(model_names):
                    print(model_name, comp)
                    self.size_distribution_models[group][
                        "pc_{0:d}".format(comp)][model_name] = deepcopy(model_objs[m])
                    try:
                        self.size_distribution_models[group][
                            "pc_{0:d}".format(comp)][model_name].fit(group_data[input_columns],
                                                                 out_pc_labels[:, comp],
                                                            sample_weight=weights)
                    except:
                        self.size_distribution_models[group][
                            "pc_{0:d}".format(comp)][model_name].fit(group_data[input_columns],
                                                                 out_pc_labels[:, comp])
        return

Response: This function calculates the 2 principal components of the hail size distribution between the shape and scale parameters.


Instruction:
Can you write a function in Python 3 where it
makes predictions using fitted size distribution models.

Response:
def predict_size_distribution_models(self, model_names, input_columns, metadata_cols,
                                         data_mode="forecast", location=6, calibrate=False):
        """
        Make predictions using fitted size distribution models.
        Args:
            model_names: Name of the models for predictions
            input_columns: Data columns used for input into ML models
            metadata_cols: Columns from input data that should be included in the data frame with the predictions.
            data_mode: Set of data used as input for prediction models
            location: Value of fixed location parameter
            calibrate: Whether or not to apply calibration model
        Returns:
            Predictions in dictionary of data frames grouped by group type
        """
        groups = self.size_distribution_models.keys()
        predictions = {}
        for group in groups:
            group_data = self.data[data_mode]["combo"].loc[self.data[data_mode]["combo"][self.group_col] == group]
            predictions[group] = group_data[metadata_cols]
            if group_data.shape[0] > 0:
                log_mean = self.size_distribution_models[group]["lognorm"]["mean"]
                log_sd = self.size_distribution_models[group]["lognorm"]["sd"]
                for m, model_name in enumerate(model_names):
                    multi_predictions = self.size_distribution_models[group]["multi"][model_name].predict(
                        group_data[input_columns])
                    if calibrate:
                        multi_predictions[:, 0] = self.size_distribution_models[group]["calshape"][model_name].predict(
                            multi_predictions[:, 0:1])
                        multi_predictions[:, 1] = self.size_distribution_models[group]["calscale"][model_name].predict(
                            multi_predictions[:, 1:])
                    multi_predictions = np.exp(multi_predictions * log_sd + log_mean)
                    if multi_predictions.shape[1] == 2:
                        multi_predictions_temp = np.zeros((multi_predictions.shape[0], 3))
                        multi_predictions_temp[:, 0] = multi_predictions[:, 0]
                        multi_predictions_temp[:, 1] = location
                        multi_predictions_temp[:, 2] = multi_predictions[:, 1]
                        multi_predictions = multi_predictions_temp
                    for p, pred_col in enumerate(["shape", "location", "scale"]):
                        predictions[group][model_name].loc[:, model_name.replace(" ", "-") + "_" + pred_col] = \
                            multi_predictions[:, p]
        return predictions


Instruction:
Write a Python 3 function for
making predictions using fitted size distribution models.

Response:
def predict_size_distribution_component_models(self, model_names, input_columns, output_columns, metadata_cols,
                                                   data_mode="forecast", location=6):
        """
        Make predictions using fitted size distribution models.
        Args:
            model_names: Name of the models for predictions
            input_columns: Data columns used for input into ML models
            output_columns: Names of output columns
            metadata_cols: Columns from input data that should be included in the data frame with the predictions.
            data_mode: Set of data used as input for prediction models
            location: Value of fixed location parameter
        Returns:
            Predictions in dictionary of data frames grouped by group type
        """
        groups = self.size_distribution_models.keys()
        predictions = pd.DataFrame(self.data[data_mode]["combo"][metadata_cols])
        for group in groups:
            group_idxs = self.data[data_mode]["combo"][self.group_col] == group
            group_count = np.count_nonzero(group_idxs)
            print(self.size_distribution_models[group])
            if group_count > 0:
                log_mean = self.size_distribution_models[group]["lognorm"]["mean"]
                log_sd = self.size_distribution_models[group]["lognorm"]["sd"]
                for m, model_name in enumerate(model_names):
                    raw_preds = np.zeros((group_count, len(output_columns)))
                    for c in range(len(output_columns)):
                        raw_preds[:, c] = self.size_distribution_models[group][
                            "pc_{0:d}".format(c)][model_name].predict(self.data[data_mode]["combo"].loc[group_idxs,
                                                                                input_columns])
                    log_norm_preds = self.size_distribution_models[group]["lognorm"]["pca"].inverse_transform(raw_preds)
                    log_norm_preds[:, 0] *= -1
                    multi_predictions = np.exp(log_norm_preds * log_sd + log_mean)
                    if multi_predictions.shape[1] == 2:
                        multi_predictions_temp = np.zeros((multi_predictions.shape[0], 3))
                        multi_predictions_temp[:, 0] = multi_predictions[:, 0]
                        multi_predictions_temp[:, 1] = location
                        multi_predictions_temp[:, 2] = multi_predictions[:, 1]
                        multi_predictions = multi_predictions_temp
                    for p, pred_col in enumerate(["shape", "location", "scale"]):
                        predictions.loc[group_idxs, model_name.replace(" ", "-") + "_" + pred_col] = \
                            multi_predictions[:, p]
        return predictions


Instruction:
How would you code a function in Python 3 to
fit size models to produce discrete pdfs of forecast hail sizes.

Response:
def fit_size_models(self, model_names,
                        model_objs,
                        input_columns,
                        output_column="Hail_Size",
                        output_start=5,
                        output_step=5,
                        output_stop=100):
        """
        Fit size models to produce discrete pdfs of forecast hail sizes.
        Args:
            model_names: List of model names
            model_objs: List of model objects
            input_columns: List of input variables
            output_column: Output variable name
            output_start: Hail size bin start
            output_step: hail size bin step
            output_stop: hail size bin stop
        """
        print("Fitting size models")
        groups = self.data["train"]["member"][self.group_col].unique()
        output_start = int(output_start)
        output_step = int(output_step)
        output_stop = int(output_stop)
        for group in groups:
            group_data = self.data["train"]["combo"].loc[self.data["train"]["combo"][self.group_col] == group]
            group_data.dropna(inplace=True)
            group_data = group_data[group_data[output_column] >= output_start]
            output_data = group_data[output_column].values.astype(int)
            output_data[output_data > output_stop] = output_stop
            discrete_data = ((output_data - output_start) // output_step) * output_step + output_start
            self.size_models[group] = {}
            self.size_models[group]["outputvalues"] = np.arange(output_start, output_stop + output_step, output_step,
                                                                dtype=int)
            for m, model_name in enumerate(model_names):
                print("{0} {1}".format(group, model_name))
                self.size_models[group][model_name] = deepcopy(model_objs[m])
                self.size_models[group][model_name].fit(group_data[input_columns], discrete_data)


Instruction:
Can you create a Python 3 function that
predicts the size models for the given model_names.

Response:
def predict_size_models(self, model_names,
                            input_columns,
                            metadata_cols,
                            data_mode="forecast"):
        """
        Apply size models to forecast data.
        Args:
            model_names:
            input_columns:
            metadata_cols:
            data_mode:
        """
        groups = self.size_models.keys()
        predictions = {}
        for group in groups:
            group_data = self.data[data_mode]["combo"].loc[self.data[data_mode]["combo"][self.group_col] == group]
            if group_data.shape[0] > 0:
                predictions[group] = {}
                output_values = self.size_models[group]["outputvalues"].astype(int)
                for m, model_name in enumerate(model_names):
                    print("{0} {1}".format(group, model_name))
                    pred_col_names = [model_name.replace(" ", "-") + "_{0:02d}".format(p) for p in output_values]
                    predictions[group][model_name] = group_data[metadata_cols]
                    pred_vals = self.size_models[group][model_name].predict_proba(group_data[input_columns])
                    pred_classes = self.size_models[group][model_name].classes_
                    pred_pdf = np.zeros((pred_vals.shape[0], output_values.size))
                    for pcv, pc in enumerate(pred_classes):
                        idx = np.where(output_values == pc)[0][0]
                        pred_pdf[:, idx] = pred_vals[:, pcv]
                    for pcn, pred_col_name in enumerate(pred_col_names):
                        predictions[group][model_name].loc[:, pred_col_name] = pred_pdf[:, pcn]
        return predictions


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fit_track_models(self,
                         model_names,
                         model_objs,
                         input_columns,
                         output_columns,
                         output_ranges,
                         ):
        """
        Fit machine learning models to predict track error offsets.
            model_names:
            model_objs:
            input_columns:
            output_columns:
            output_ranges:
        """
        print("Fitting track models")
        groups = self.data["train"]["member"][self.group_col].unique()
        for group in groups:
            group_data = self.data["train"]["combo"].loc[self.data["train"]["combo"][self.group_col] == group]
            group_data = group_data.dropna()
            group_data = group_data.loc[group_data["Duration_Step"] == 1]
            for model_type, model_dict in self.track_models.items():
                model_dict[group] = {}
                output_data = group_data[output_columns[model_type]].values.astype(int)
                output_data[output_data < output_ranges[model_type][0]] = output_ranges[model_type][0]
                output_data[output_data > output_ranges[model_type][1]] = output_ranges[model_type][1]
                discrete_data = (output_data - output_ranges[model_type][0]) // output_ranges[model_type][2] * \
                                output_ranges[model_type][2] + output_ranges[model_type][0]
                model_dict[group]["outputvalues"] = np.arange(output_ranges[model_type][0],
                                                              output_ranges[model_type][1] +
                                                              output_ranges[model_type][2],
                                                              output_ranges[model_type][2])
                for m, model_name in enumerate(model_names):
                    print("{0} {1} {2}".format(group, model_type, model_name))
                    model_dict[group][model_name] = deepcopy(model_objs[m])
                    model_dict[group][model_name].fit(group_data[input_columns], discrete_data)

Response: Fit track models to predict track error offsets.


Instruction:
Can you create a Python 3 function that
saves the machine learning models to pickle files.

Response:
def save_models(self, model_path):
        """
        Save machine learning models to pickle files.
        """
        for group, condition_model_set in self.condition_models.items():
            for model_name, model_obj in condition_model_set.items():
                out_filename = model_path + \
                               "{0}_{1}_condition.pkl".format(group,
                                                              model_name.replace(" ", "-"))
                with open(out_filename, "wb") as pickle_file:
                    pickle.dump(model_obj,
                                pickle_file,
                                pickle.HIGHEST_PROTOCOL)
        for group, size_model_set in self.size_models.items():
            for model_name, model_obj in size_model_set.items():
                out_filename = model_path + \
                               "{0}_{1}_size.pkl".format(group,
                                                         model_name.replace(" ", "-"))
                with open(out_filename, "wb") as pickle_file:
                    pickle.dump(model_obj,
                                pickle_file,
                                pickle.HIGHEST_PROTOCOL)
        for group, dist_model_set in self.size_distribution_models.items():
            for model_type, model_objs in dist_model_set.items():
                for model_name, model_obj in model_objs.items():
                    out_filename = model_path + \
                                   "{0}_{1}_{2}_sizedist.pkl".format(group,
                                                                     model_name.replace(" ", "-"),
                                                                     model_type)
                    with open(out_filename, "wb") as pickle_file:
                        pickle.dump(model_obj,
                                    pickle_file,
                                    pickle.HIGHEST_PROTOCOL)
        for model_type, track_type_models in self.track_models.items():
            for group, track_model_set in track_type_models.items():
                for model_name, model_obj in track_model_set.items():
                    out_filename = model_path + \
                                   "{0}_{1}_{2}_track.pkl".format(group,
                                                                  model_name.replace(" ", "-"),
                                                                  model_type)
                    with open(out_filename, "wb") as pickle_file:
                        pickle.dump(model_obj,
                                    pickle_file,
                                    pickle.HIGHEST_PROTOCOL)

        return


Instruction:
Given the following Python 3 function, write the documentation
def load_models(self, model_path):
        condition_model_files = sorted(glob(model_path + "*_condition.pkl"))
        if len(condition_model_files) > 0:
            for condition_model_file in condition_model_files:
                model_comps = condition_model_file.split("/")[-1][:-4].split("_")
                if model_comps[0] not in self.condition_models.keys():
                    self.condition_models[model_comps[0]] = {}
                model_name = model_comps[1].replace("-", " ")
                with open(condition_model_file, "rb") as cmf:
                    if "condition_threshold" in condition_model_file:
                        self.condition_models[model_comps[0]][model_name + "_condition_threshold"] = pickle.load(cmf)
                    else:
                        self.condition_models[model_comps[0]][model_name] = pickle.load(cmf)

        size_model_files = sorted(glob(model_path + "*_size.pkl"))
        if len(size_model_files) > 0:
            for size_model_file in size_model_files:
                model_comps = size_model_file.split("/")[-1][:-4].split("_")
                if model_comps[0] not in self.size_models.keys():
                    self.size_models[model_comps[0]] = {}
                model_name = model_comps[1].replace("-", " ")
                with open(size_model_file, "rb") as smf:
                    self.size_models[model_comps[0]][model_name] = pickle.load(smf)

        size_dist_model_files = sorted(glob(model_path + "*_sizedist.pkl"))
        if len(size_dist_model_files) > 0:
            for dist_model_file in size_dist_model_files:
                model_comps = dist_model_file.split("/")[-1][:-4].split("_")
                if model_comps[0] not in self.size_distribution_models.keys():
                    self.size_distribution_models[model_comps[0]] = {}
                if "_".join(model_comps[2:-1]) not in self.size_distribution_models[model_comps[0]].keys():
                    self.size_distribution_models[model_comps[0]]["_".join(model_comps[2:-1])] = {}
                model_name = model_comps[1].replace("-", " ")
                with open(dist_model_file, "rb") as dmf:
                    self.size_distribution_models[model_comps[0]]["_".join(model_comps[2:-1])][
                        model_name] = pickle.load(dmf)

        track_model_files = sorted(glob(model_path + "*_track.pkl"))
        if len(track_model_files) > 0:
            for track_model_file in track_model_files:
                model_comps = track_model_file.split("/")[-1][:-4].split("_")
                group = model_comps[0]
                model_name = model_comps[1].replace("-", " ")
                model_type = model_comps[2]
                if model_type not in self.track_models.keys():
                    self.track_models[model_type] = {}
                if group not in self.track_models[model_type].keys():
                    self.track_models[model_type][group] = {}
                with open(track_model_file, "rb") as tmf:
                    self.track_models[model_type][group][model_name] = pickle.load(tmf)

Response: Load models from pickle files.


Instruction:
Make a summary of the following Python 3 code
def output_forecasts_json(self, forecasts,
                              condition_model_names,
                              size_model_names,
                              dist_model_names,
                              track_model_names,
                              json_data_path,
                              out_path):
        """
        Output forecast values to geoJSON file format.
        :param forecasts:
        :param condition_model_names:
        :param size_model_names:
        :param track_model_names:
        :param json_data_path:
        :param out_path:
        :return:
        """
        total_tracks = self.data["forecast"]["total"]
        for r in np.arange(total_tracks.shape[0]):
            track_id = total_tracks.loc[r, "Track_ID"]
            print(track_id)
            track_num = track_id.split("_")[-1]
            ensemble_name = total_tracks.loc[r, "Ensemble_Name"]
            member = total_tracks.loc[r, "Ensemble_Member"]
            group = self.data["forecast"]["member"].loc[self.data["forecast"]["member"]["Ensemble_Member"] == member,
                                                        self.group_col].values[0]
            run_date = track_id.split("_")[-4][:8]
            step_forecasts = {}
            for ml_model in condition_model_names:
                step_forecasts["condition_" + ml_model.replace(" ", "-")] = forecasts["condition"][group].loc[
                    forecasts["condition"][group]["Track_ID"] == track_id, ml_model]
            for ml_model in size_model_names:
                step_forecasts["size_" + ml_model.replace(" ", "-")] = forecasts["size"][group][ml_model].loc[
                    forecasts["size"][group][ml_model]["Track_ID"] == track_id]
            for ml_model in dist_model_names:
                step_forecasts["dist_" + ml_model.replace(" ", "-")] = forecasts["dist"][group][ml_model].loc[
                    forecasts["dist"][group][ml_model]["Track_ID"] == track_id]
            for model_type in forecasts["track"].keys():
                for ml_model in track_model_names:
                    mframe = forecasts["track"][model_type][group][ml_model]
                    step_forecasts[model_type + "_" + ml_model.replace(" ", "-")] = mframe.loc[
                        mframe["Track_ID"] == track_id]
            json_file_name = "{0}_{1}_{2}_model_track_{3}.json".format(ensemble_name,
                                                                       run_date,
                                                                       member,
                                                                       track_num)
            full_json_path = json_data_path + "/".join([run_date, member]) + "/" + json_file_name
            with open(full_json_path) as json_file_obj:
                try:
                    track_obj = json.load(json_file_obj)
                except FileNotFoundError:
                    print(full_json_path + " not found")
                    continue
            for f, feature in enumerate(track_obj['features']):
                del feature['properties']['attributes']
                for model_name, fdata in step_forecasts.items():
                    ml_model_name = model_name.split("_")[1]
                    if "condition" in model_name:
                        feature['properties'][model_name] = fdata.values[f]
                    else:
                        predcols = []
                        for col in fdata.columns:
                            if ml_model_name in col:
                                predcols.append(col)
                        feature['properties'][model_name] = fdata.loc[:, predcols].values[f].tolist()
            full_path = []
            for part in [run_date, member]:
                full_path.append(part)
                if not os.access(out_path + "/".join(full_path), os.R_OK):
                    try:
                        os.mkdir(out_path + "/".join(full_path))
                    except OSError:
                        print("directory already created")
            out_json_filename = out_path + "/".join(full_path) + "/" + json_file_name
            with open(out_json_filename, "w") as out_json_obj:
                json.dump(track_obj, out_json_obj, indent=1, sort_keys=True)
        return

Response: Output forecasts to geoJSON file format.


Instruction:
Can you implement a function in Python 3 that
outputs hail forecasts to csv files by ensemble member and ensemble name.

Response:
def output_forecasts_csv(self, forecasts, mode, csv_path, run_date_format="%Y%m%d-%H%M"):
        """
        Output hail forecast values to csv files by run date and ensemble member.

        Args:
            forecasts:
            mode:
            csv_path:
        Returns:
        """
        merged_forecasts = pd.merge(forecasts["condition"],
                                    forecasts["dist"],
                                    on=["Step_ID","Track_ID","Ensemble_Member","Forecast_Hour"])
        all_members = self.data[mode]["combo"]["Ensemble_Member"]
        members = np.unique(all_members)
        all_run_dates = pd.DatetimeIndex(self.data[mode]["combo"]["Run_Date"])
        run_dates = pd.DatetimeIndex(np.unique(all_run_dates))
        print(run_dates)
        for member in members:
            for run_date in run_dates:
                mem_run_index = (all_run_dates == run_date) & (all_members == member)
                member_forecast = merged_forecasts.loc[mem_run_index]
                member_forecast.to_csv(join(csv_path, "hail_forecasts_{0}_{1}_{2}.csv".format(self.ensemble_name,
                                                                                member,
                                                                                run_date.strftime
																							  (run_date_format))))
        return


Instruction:
How would you explain what the following Python 3 function does
def ativar_sat(self, tipo_certificado, cnpj, codigo_uf):
        return self.invocar__AtivarSAT(
                self.gerar_numero_sessao(), tipo_certificado,
                self._codigo_ativacao, cnpj, codigo_uf)

Response: AtivarSAT para ER SAT para o estabelecimento de unidade federativa.