Instruction:
How would you explain what the following Python 3 function does
def catalog_report(self, catalog, harvest='none', report=None,
                       catalog_id=None, catalog_homepage=None,
                       catalog_org=None):
        """Genera un reporte sobre los datasets de un único catálogo.

        Args:
            catalog (dict, str o unicode): Representación externa (path/URL) o
                interna (dict) de un catálogo.
            harvest (str): Criterio de cosecha ('all', 'none',
                'valid', 'report' o 'good').

        Returns:
            list: Lista de diccionarios, con un elemento por cada dataset
                presente en `catalog`.
        """

        url = catalog if isinstance(catalog, string_types) else None
        catalog = readers.read_catalog(catalog)

        validation = self.validate_catalog(catalog)
        catalog_validation = validation["error"]["catalog"]
        datasets_validations = validation["error"]["dataset"]

        catalog_fields = self._catalog_report_helper(
            catalog, catalog_validation, url, catalog_id, catalog_org
        )

        if "dataset" in catalog and isinstance(catalog["dataset"], list):
            datasets = [d if isinstance(d, dict) else {} for d in
                        catalog["dataset"]]
        else:
            datasets = []

        catalog_report = [
            self._dataset_report(
                dataset, datasets_validations[index], index,
                catalog_fields, harvest, report=report,
                catalog_homepage=catalog_homepage
            )
            for index, dataset in enumerate(datasets)
        ]

        return catalog_report

Response: Genera un reporte sobre los datasets de un único catálogo.


Instruction:
How would you code a function in Python 3 to
generate a list of dicts that represent un archivo un catálogo.

Response:
def generate_harvestable_catalogs(self, catalogs, harvest='all',
                                      report=None, export_path=None):
        """Filtra los catálogos provistos según el criterio determinado en
        `harvest`.

        Args:
            catalogs (str, dict o list): Uno (str o dict) o varios (list de
                strs y/o dicts) catálogos.
            harvest (str): Criterio para determinar qué datasets conservar de
                cada catálogo ('all', 'none', 'valid' o 'report').
            report (list o str): Tabla de reporte generada por
                generate_datasets_report() como lista de diccionarios o archivo
                en formato XLSX o CSV. Sólo se usa cuando `harvest=='report'`.
            export_path (str): Path a un archivo JSON o directorio donde
                exportar los catálogos filtrados. Si termina en ".json" se
                exportará la lista de catálogos a un único archivo. Si es un
                directorio, se guardará en él un JSON por catálogo. Si se
                especifica `export_path`, el método no devolverá nada.

        Returns:
            list of dicts: Lista de catálogos.
        """
        assert isinstance(catalogs, string_types + (dict, list))
        # Si se pasa un único catálogo, genero una lista que lo contenga
        if isinstance(catalogs, string_types + (dict,)):
            catalogs = [catalogs]

        harvestable_catalogs = [readers.read_catalog(c) for c in catalogs]
        catalogs_urls = [catalog if isinstance(catalog, string_types)
                         else None for catalog in catalogs]

        # aplica los criterios de cosecha
        if harvest == 'all':
            pass
        elif harvest == 'none':
            for catalog in harvestable_catalogs:
                catalog["dataset"] = []
        elif harvest == 'valid':
            report = self.generate_datasets_report(catalogs, harvest)
            return self.generate_harvestable_catalogs(
                catalogs=catalogs, harvest='report', report=report,
                export_path=export_path)
        elif harvest == 'report':
            if not report:
                raise ValueError("""
Usted eligio 'report' como criterio de harvest, pero no proveyo un valor para
el argumento 'report'. Por favor, intentelo nuevamente.""")
            datasets_to_harvest = self._extract_datasets_to_harvest(report)
            for idx_cat, catalog in enumerate(harvestable_catalogs):
                catalog_url = catalogs_urls[idx_cat]
                if ("dataset" in catalog and
                        isinstance(catalog["dataset"], list)):
                    catalog["dataset"] = [
                        dataset for dataset in catalog["dataset"]
                        if (catalog_url, dataset.get("title")) in
                        datasets_to_harvest
                    ]
                else:
                    catalog["dataset"] = []
        else:
            raise ValueError("""
{} no es un criterio de harvest reconocido. Pruebe con 'all', 'none', 'valid' o
'report'.""".format(harvest))

        # devuelve los catálogos harvesteables
        if export_path and os.path.isdir(export_path):
            # Creo un JSON por catálogo
            for idx, catalog in enumerate(harvestable_catalogs):
                filename = os.path.join(export_path, "catalog_{}".format(idx))
                writers.write_json(catalog, filename)
        elif export_path:
            # Creo un único JSON con todos los catálogos
            writers.write_json(harvestable_catalogs, export_path)
        else:
            return harvestable_catalogs


Instruction:
Can you create a Python 3 function that
extracts datasets to harvest.

Response:
def _extract_datasets_to_harvest(cls, report):
        """Extrae de un reporte los datos necesarios para reconocer qué
        datasets marcar para cosecha en cualquier generador.

        Args:
            report (str o list): Reporte (lista de dicts) o path a uno.

        Returns:
            list: Lista de tuplas con los títulos de catálogo y dataset de cada
            reporte extraído.
        """
        assert isinstance(report, string_types + (list,))

        # Si `report` es una lista de tuplas con longitud 2, asumimos que es un
        # reporte procesado para extraer los datasets a harvestear. Se devuelve
        # intacta.
        if (isinstance(report, list) and all([isinstance(x, tuple) and
                                              len(x) == 2 for x in report])):
            return report

        table = readers.read_table(report)
        table_keys = table[0].keys()
        expected_keys = ["catalog_metadata_url", "dataset_title",
                         "dataset_accrualPeriodicity"]

        # Verifico la presencia de las claves básicas de un config de harvester
        for key in expected_keys:
            if key not in table_keys:
                raise KeyError("""
El reporte no contiene la clave obligatoria {}. Pruebe con otro archivo.
""".format(key))

        if "harvest" in table_keys:
            # El archivo es un reporte de datasets.
            datasets_to_harvest = [
                (row["catalog_metadata_url"], row["dataset_title"]) for row in
                table if int(row["harvest"])]
        else:
            # El archivo es un config de harvester.
            datasets_to_harvest = [
                (row["catalog_metadata_url"], row["dataset_title"]) for row in
                table]

        return datasets_to_harvest


Instruction:
Explain what the following Python 3 code does
def import_by_path(path: str) -> Callable:

    module_path, _, class_name = path.rpartition('.')
    return getattr(import_module(module_path), class_name)

Response: Imports a class or function given it s absolute path.


Instruction:
Write a Python 3 function for
reading a catalog from the file system.

Response:
def read_catalog(catalog, default_values=None, catalog_format=None):
    """Toma una representación cualquiera de un catálogo, y devuelve su
    representación interna (un diccionario de Python con su metadata.)

    Si recibe una representación _interna_ (un diccionario), lo devuelve
    intacto. Si recibe una representación _externa_ (path/URL a un archivo
    JSON/XLSX), devuelve su represetación interna, es decir, un diccionario.

    Args:
        catalog (dict or str): Representación externa/interna de un catálogo.
            Una representación _externa_ es un path local o una URL remota a un
            archivo con la metadata de un catálogo, en formato JSON o XLSX. La
            representación _interna_ de un catálogo es un diccionario.

    Returns:
        dict: Representación interna de un catálogo para uso en las funciones
        de esta librería.
    """
    unknown_catalog_repr_msg = \
        """No se pudo inferir una representación válida de un catálogo del
        parámetro provisto: {}.""".format(catalog)
    assert isinstance(catalog, string_types + (dict,)
                      ), unknown_catalog_repr_msg

    if isinstance(catalog, dict):
        catalog_dict = catalog

    else:
        # catalog es una URL remota o un path local
        suffix = catalog.split(".")[-1].strip("/")
        if suffix in ('json', 'xlsx'):
            catalog_format = catalog_format or suffix
        if catalog_format == "xlsx":
            try:
                catalog_dict = read_xlsx_catalog(catalog)
            except openpyxl_exceptions + \
                    (ValueError, AssertionError, IOError, BadZipfile) as e:
                raise ce.NonParseableCatalog(catalog, str(e))
        elif catalog_format == "json":
            try:
                catalog_dict = read_json(catalog)
            except(ValueError, TypeError, IOError) as e:
                raise ce.NonParseableCatalog(catalog, str(e))
        elif catalog_format == "ckan":
            catalog_dict = read_ckan_catalog(catalog)
        else:
            catalog_dict = read_suffixless_catalog(catalog)

    # si se pasaron valores default, los aplica al catálogo leído
    if default_values:
        _apply_default_values(catalog_dict, default_values)

    return catalog_dict


Instruction:
Here you have a function in Python 3, explain what it does
def _apply_default_values(catalog, default_values):

    for field, default_value in iteritems(default_values):
        class_metadata = field.split("_")[0]
        field_json_path = field.split("_")[1:]

        # valores default de catálogo
        if class_metadata == "catalog":
            _set_default_value(catalog, field_json_path, default_value)

        # valores default de dataset
        elif class_metadata == "dataset":
            for dataset in catalog["dataset"]:
                _set_default_value(dataset, field_json_path, default_value)

        # valores default de distribución
        elif class_metadata == "distribution":
            for dataset in catalog["dataset"]:
                for distribution in dataset["distribution"]:
                    _set_default_value(
                        distribution, field_json_path, default_value)

        # valores default de field
        elif class_metadata == "field":
            for dataset in catalog["dataset"]:
                for distribution in dataset["distribution"]:

                    # campo "field" en una "distribution" no es obligatorio
                    if distribution.get("field"):
                        for field in distribution["field"]:
                            _set_default_value(
                                field, field_json_path, default_value)

Response: Applies default values to the internal valores of the internal valores of the internal valores of the internal valores of the internal valores of the internal valores.


Instruction:
Make a summary of the following Python 3 code
def _set_default_value(dict_obj, keys, value):
    variable = dict_obj

    if len(keys) == 1:
        if not variable.get(keys[0]):
            variable[keys[0]] = value

    else:
        for idx, field in enumerate(keys):
            if idx < len(keys) - 1:
                variable = variable[field]

        if not variable.get(keys[-1]):
            variable[keys[-1]] = value

Response: Seta valor en diccionario anidado siguiendo lista de keys.


Instruction:
Here you have a function in Python 3, explain what it does
def read_json(json_path_or_url):
    assert isinstance(json_path_or_url, string_types)

    parsed_url = urlparse(json_path_or_url)
    if parsed_url.scheme in ["http", "https"]:
        res = requests.get(json_path_or_url, verify=False)
        json_dict = json.loads(res.content, encoding='utf-8')

    else:
        # Si json_path_or_url parece ser una URL remota, lo advierto.
        path_start = parsed_url.path.split(".")[0]
        if path_start == "www" or path_start.isdigit():
            warnings.warn("""
La dirección del archivo JSON ingresada parece una URL, pero no comienza
con 'http' o 'https' así que será tratada como una dirección local. ¿Tal vez
quiso decir 'http://{}'?""".format(json_path_or_url).encode("utf-8"))

        with io.open(json_path_or_url, encoding='utf-8') as json_file:
            json_dict = json.load(json_file)

    return json_dict

Response: Read a JSON file and return a dict.


Instruction:
Given the following Python 3 function, write the documentation
def read_xlsx_catalog(xlsx_path_or_url, logger=None):
    logger = logger or pydj_logger
    assert isinstance(xlsx_path_or_url, string_types)

    parsed_url = urlparse(xlsx_path_or_url)
    if parsed_url.scheme in ["http", "https"]:
        res = requests.get(xlsx_path_or_url, verify=False)
        tmpfilename = ".tmpfile.xlsx"
        with io.open(tmpfilename, 'wb') as tmpfile:
            tmpfile.write(res.content)
        catalog_dict = read_local_xlsx_catalog(tmpfilename, logger)
        os.remove(tmpfilename)
    else:
        # Si xlsx_path_or_url parece ser una URL remota, lo advierto.
        path_start = parsed_url.path.split(".")[0]
        if path_start == "www" or path_start.isdigit():
            warnings.warn("""
La dirección del archivo JSON ingresada parece una URL, pero no comienza
con 'http' o 'https' así que será tratada como una dirección local. ¿Tal vez
quiso decir 'http://{}'?
            """.format(xlsx_path_or_url).encode("utf8"))

        catalog_dict = read_local_xlsx_catalog(xlsx_path_or_url)

    return catalog_dict

Response: Read a dictionary of all the data in an XLSX file.


Instruction:
How would you explain what the following Python 3 function does
def _make_contact_point(dataset):
    keys = [k for k in ["contactPoint_fn", "contactPoint_hasEmail"]
            if k in dataset]
    if keys:
        dataset["contactPoint"] = {
            key.replace("contactPoint_", ""): dataset.pop(key) for key in keys
        }
    return dataset

Response: En una diccionario a una dataset de los claves necesarias.


Instruction:
Can you write a function in Python 3 where it
gets the index of the dataset that matches the identifier.

Response:
def _get_dataset_index(catalog, dataset_identifier, dataset_title,
                       logger=None):
    """Devuelve el índice de un dataset en el catálogo en función de su
    identificador"""
    logger = logger or pydj_logger
    matching_datasets = []

    for idx, dataset in enumerate(catalog["catalog_dataset"]):
        if dataset["dataset_identifier"] == dataset_identifier:
            if dataset["dataset_title"] == dataset_title:
                matching_datasets.append(idx)
            else:
                logger.warning(
                    ce.DatasetUnexpectedTitle(
                        dataset_identifier,
                        dataset["dataset_title"],
                        dataset_title
                    )
                )

    # Debe haber exactamente un dataset con el identificador provisto.
    no_dsets_msg = "No hay ningun dataset con el identifier {}".format(
        dataset_identifier)
    many_dsets_msg = "Hay mas de un dataset con el identifier {}: {}".format(
        dataset_identifier, matching_datasets)
    if len(matching_datasets) == 0:
        logger.error(no_dsets_msg)
        return None
    elif len(matching_datasets) > 1:
        logger.error(many_dsets_msg)
        return None
    else:
        return matching_datasets[0]


Instruction:
Here you have a function in Python 3, explain what it does
def _get_distribution_indexes(catalog, dataset_identifier, dataset_title,
                              distribution_identifier, distribution_title,
                              logger=None):
    """Devuelve el índice de una distribución en su dataset en función de su
    título, junto con el índice de su dataset padre en el catálogo, en
    función de su identificador"""
    logger = logger or pydj_logger
    dataset_index = _get_dataset_index(
        catalog, dataset_identifier, dataset_title)
    if dataset_index is None:
        return None, None
    else:
        dataset = catalog["catalog_dataset"][dataset_index]

    matching_distributions = []

    for idx, distribution in enumerate(dataset["dataset_distribution"]):
        if distribution["distribution_identifier"] == distribution_identifier:
            if distribution["distribution_title"] == distribution_title:
                matching_distributions.append(idx)
            else:
                logger.warning(
                    ce.DistributionUnexpectedTitle(
                        distribution_identifier,
                        distribution["distribution_title"],
                        distribution_title
                    )
                )

    # Debe haber exactamente una distribución con los identicadores provistos
    if len(matching_distributions) == 0:
        logger.warning(
            ce.DistributionTitleNonExistentError(
                distribution_title, dataset_identifier
            )
        )
        return dataset_index, None
    elif len(matching_distributions) > 1:
        logger.warning(
            ce.DistributionTitleRepetitionError(
                distribution_title, dataset_identifier, matching_distributions)
        )
        return dataset_index, None
    else:
        distribution_index = matching_distributions[0]
        return dataset_index, distribution_index

Response: Get the index of the distribution in the catalog.


Instruction:
Make a summary of the following Python 3 code
def read_local_xlsx_catalog(xlsx_path, logger=None):
    logger = logger or pydj_logger

    wb = pyxl.load_workbook(open(xlsx_path, 'rb'), data_only=True,
                            read_only=True)

    # Toma las hojas del modelo, resistente a mayúsuculas/minúsculas
    ws_catalog = helpers.get_ws_case_insensitive(wb, "catalog")
    ws_dataset = helpers.get_ws_case_insensitive(wb, "dataset")
    ws_distribution = helpers.get_ws_case_insensitive(wb, "distribution")
    ws_theme = helpers.get_ws_case_insensitive(wb, "theme")
    ws_field = helpers.get_ws_case_insensitive(wb, "field")

    catalogs = helpers.sheet_to_table(ws_catalog)
    # Debe haber exactamente un catálogo en la hoja 'Catalog'
    assert (len(catalogs) != 0), "No hay ningun catálogo en la hoja 'Catalog'"
    assert (len(catalogs) < 2), "Hay mas de un catálogo en la hoja 'Catalog'"
    # Genero el catálogo base
    catalog = catalogs[0]

    # Agrego themes y datasets al catálogo
    catalog["catalog_dataset"] = helpers.sheet_to_table(ws_dataset)

    # Me aseguro que los identificadores de dataset se guarden como cadenas
    for dataset in catalog["catalog_dataset"]:
        dataset["dataset_identifier"] = text_type(
            dataset["dataset_identifier"])

    catalog["catalog_themeTaxonomy"] = (
        helpers.sheet_to_table(ws_theme))

    # Agrego lista de distribuciones vacía a cada dataset
    for dataset in catalog["catalog_dataset"]:
        dataset["dataset_distribution"] = []

    # Ubico cada distribución en su dataset
    distributions = helpers.sheet_to_table(ws_distribution)
    for distribution in distributions:
        # Me aseguro que los identificadores se guarden como cadenas
        distribution["dataset_identifier"] = text_type(
            distribution["dataset_identifier"])
        distribution["distribution_identifier"] = text_type(
            distribution["distribution_identifier"])

        dataset_index = _get_dataset_index(
            catalog, distribution["dataset_identifier"],
            distribution["dataset_title"], logger)
        if dataset_index is None:
            logger.error("""La distribucion con ID '{}' y titulo '{}' no se
pudo asignar a un dataset, y no figurara en el data.json de salida.""".format(
                distribution["distribution_identifier"],
                distribution["distribution_title"]))
        else:
            dataset = catalog["catalog_dataset"][dataset_index]
            dataset["dataset_distribution"].append(distribution)

    # Ubico cada campo en su distribución
    fields = helpers.sheet_to_table(ws_field)
    for idx, field in enumerate(fields):
        # Me aseguro que los identificadores se guarden como cadenas
        field["dataset_identifier"] = text_type(field["dataset_identifier"])
        field["distribution_identifier"] = text_type(
            field["distribution_identifier"])

        dataset_index, distribution_index = _get_distribution_indexes(
            catalog, field["dataset_identifier"], field["dataset_title"],
            field["distribution_identifier"], field["distribution_title"],
            logger)

        if dataset_index is None:
            logger.error(
                """No se encontro el dataset '{}' especificado para el campo
                '{}' (fila #{} de la hoja "Field"). Este campo no figurara en
                el data.json de salida.""".format(
                    unidecode(field["dataset_title"]),
                    unidecode(field["field_title"]), idx + 2))

        elif distribution_index is None:
            logger.error(
                """No se encontro la distribucion '{}' especificada para el
                campo'{}' (fila #{} de la hoja "Field"). Este campo no figurara
                en el data.json de salida.""".format(
                    unidecode(field["distribution_title"]),
                    unidecode(field["field_title"]), idx + 2))

        else:
            dataset = catalog["catalog_dataset"][dataset_index]
            distribution = dataset["dataset_distribution"][distribution_index]

            if "distribution_field" in distribution:
                distribution["distribution_field"].append(field)
            else:
                distribution["distribution_field"] = [field]

    # Transformo campos de texto separado por comas en listas
    if "catalog_language" in catalog:
        catalog["catalog_language"] = helpers.string_to_list(
            catalog["catalog_language"], filter_empty=True)

    for dataset in catalog["catalog_dataset"]:
        array_fields = ["dataset_superTheme", "dataset_theme", "dataset_tags",
                        "dataset_keyword", "dataset_language"]
        for field in array_fields:
            if field in dataset:
                dataset[field] = helpers.string_to_list(
                    dataset[field], filter_empty=True)

    # Elimino los prefijos de los campos a nivel catálogo
    _remove_prefixes_and_unprefixed_fields(catalog, 'catalog_')

    # Elimino los prefijos de los campos a nivel tema
    for theme in catalog["themeTaxonomy"]:
        _remove_prefixes_and_unprefixed_fields(theme, 'theme_')

    # Elimino los prefijos de los campos a nivel dataset
    for dataset in catalog["dataset"]:
        _remove_prefixes_and_unprefixed_fields(dataset, 'dataset_')

    # Elimino los campos auxiliares y los prefijos de los campos a nivel
    # distribución
    for dataset in catalog["dataset"]:
        for distribution in dataset["distribution"]:
            _remove_prefixes_and_unprefixed_fields(
                distribution, 'distribution_')

    # Elimino campos auxiliares y los prefijos de los campos a nivel "campo"
    for dataset in catalog["dataset"]:
        for distribution in dataset["distribution"]:
            if "field" in distribution:
                for field in distribution["field"]:
                    _remove_prefixes_and_unprefixed_fields(field, "field_")

    # Agrupo las claves de "publisher" y "contactPoint" en sendos diccionarios
    catalog = _make_publisher(catalog)
    for dataset in catalog["dataset"]:
        dataset = _make_publisher(dataset)
        dataset = _make_contact_point(dataset)

    return catalog

Response: Read a local XLSX catalog and return a dict of diccionario de metadatos de un catálogo.


Instruction:
How would you implement a function in Python 3 that
reads a table from a file.

Response:
def read_table(path):
    """Lee un archivo tabular (CSV o XLSX) a una lista de diccionarios.

    La extensión del archivo debe ser ".csv" o ".xlsx". En función de
    ella se decidirá el método a usar para leerlo.

    Si recibe una lista, comprueba que todos sus diccionarios tengan las
    mismas claves y de ser así, la devuelve intacta. Levanta una Excepción
    en caso contrario.

    Args:
        path(str o list): Como 'str', path a un archivo CSV o XLSX.

    Returns:
        list: Lista de diccionarios con claves idénticas representando el
        archivo original.
    """
    assert isinstance(path, string_types + (list,)), """
{} no es un `path` valido""".format(path)

    # Si `path` es una lista, devolverla intacta si tiene formato tabular.
    # Si no, levantar una excepción.
    if isinstance(path, list):
        if helpers.is_list_of_matching_dicts(path):
            return path
        else:
            raise ValueError("""
La lista ingresada no esta formada por diccionarios con las mismas claves.""")

    # Deduzco el formato de archivo de `path` y redirijo según corresponda.
    suffix = path.split(".")[-1]
    if suffix == "csv":
        return _read_csv_table(path)
    elif suffix == "xlsx":
        return _read_xlsx_table(path)
    else:
        raise ValueError("""
{} no es un sufijo reconocido. Pruebe con .csv o .xlsx""".format(suffix))


Instruction:
Given the following Python 3 function, write the documentation
def _read_csv_table(path):
    with open(path, 'rb') as csvfile:
        reader = csv.DictReader(csvfile)
        table = list(reader)
    return table

Response: Lee un CSV a una lista de diccionarios.


Instruction:
Explain what the following Python 3 code does
def _read_xlsx_table(path):
    workbook = pyxl.load_workbook(path)
    worksheet = workbook.active
    table = helpers.sheet_to_table(worksheet)

    return table

Response: Lee la hoja activa de un archivo XLSX a una lista de diccionarios.


Instruction:
Write a Python 3 function for
ensuring the provided file is a yaml file

Response:
def validate_model_specification_file(file_path: str) -> str:
    """Ensures the provided file is a yaml file"""
    if not os.path.isfile(file_path):
        raise ConfigurationError('If you provide a model specification file, it must be a file. '
                                 f'You provided {file_path}')

    extension = file_path.split('.')[-1]
    if extension not in ['yaml', 'yml']:
        raise ConfigurationError(f'Model specification files must be in a yaml format. You provided {extension}')
    # Attempt to load
    yaml.full_load(file_path)
    return file_path


Instruction:
Write a Python 3 function for
returning a tuple of the value s source and the value at the specified layer.

Response:
def get_value_with_source(self, layer=None):
        """Returns a tuple of the value's source and the value at the specified
        layer. If no layer is specified then the outer layer is used.

        Parameters
        ----------
        layer : str
            Name of the layer to use. If None then the outermost where the value
            exists will be used.

        Raises
        ------
        KeyError
            If the value is not set for the specified layer
        """
        if layer:
            return self._values[layer]

        for layer in reversed(self._layers):
            if layer in self._values:
                return self._values[layer]
        raise KeyError(layer)


Instruction:
Create a Python 3 function for
returning all values and associated metadata for this node as a list.

Response:
def metadata(self):
        """Returns all values and associated metadata for this node as a dict.
        The value which would be selected if the node's value was requested
        is indicated by the `default` flag.
        """
        result = []
        for layer in self._layers:
            if layer in self._values:
                result.append({
                    'layer': layer,
                    'value': self._values[layer][1],
                    'source': self._values[layer][0],
                    'default': layer == self._layers[-1]
                })
        return result


Instruction:
Implement a Python 3 function for
setting a value for a particular layer with optional metadata about source.

Response:
def set_value(self, value, layer=None, source=None):
        """Set a value for a particular layer with optional metadata about source.

        Parameters
        ----------
        value : str
            Data to store in the node.
        layer : str
            Name of the layer to use. If None then the outermost where the value
            exists will be used.
        source : str
            Metadata indicating the source of this value (e.g. a file path)

        Raises
        ------
        TypeError
            If the node is frozen
        KeyError
            If the named layer does not exist
        """
        if self._frozen:
            raise TypeError('Frozen ConfigNode does not support assignment')

        if not layer:
            layer = self._layers[-1]
        self._values[layer] = (source, value)


Instruction:
Make a summary of the following Python 3 code
def drop_layer(self, layer):
        if self._frozen:
            raise TypeError('Frozen ConfigNode does not support modification')
        self.reset_layer(layer)
        self._layers.remove(layer)

Response: Removes the named layer and the value associated with it from the node.


Instruction:
Can you tell what is the following Python 3 function doing
def reset_layer(self, layer):
        if self._frozen:
            raise TypeError('Frozen ConfigNode does not support modification')
        if layer in self._values:
            del self._values[layer]

Response: Removes any value and metadata associated with the named layer.


Instruction:
How would you explain what the following Python 3 function does
def freeze(self):
        self.__dict__['_frozen'] = True
        for child in self._children.values():
            child.freeze()

Response: Causes the ConfigTree to become read only.


Instruction:
How would you explain what the following Python 3 function does
def get_from_layer(self, name, layer=None):
        if name not in self._children:
            if self._frozen:
                raise KeyError(name)
            self._children[name] = ConfigTree(layers=self._layers)
        child = self._children[name]
        if isinstance(child, ConfigNode):
            return child.get_value(layer)
        else:
            return child

Response: Get a configuration value from the named layer.


Instruction:
Write a Python 3 script to
set a value in the named layer with the given source.

Response:
def _set_with_metadata(self, name, value, layer=None, source=None):
        """Set a value in the named layer with the given source.

        Parameters
        ----------
        name : str
            The name of the value
        value
            The value to store
        layer : str, optional
            The name of the layer to store the value in. If none is supplied
            then the value will be stored in the outermost layer.
        source : str, optional
            The source to attribute the value to.

        Raises
        ------
        TypeError
            if the ConfigTree is frozen
        """

        if self._frozen:
            raise TypeError('Frozen ConfigTree does not support assignment')

        if isinstance(value, dict):
            if name not in self._children or not isinstance(self._children[name], ConfigTree):
                self._children[name] = ConfigTree(layers=list(self._layers))
            self._children[name].update(value, layer, source)
        else:
            if name not in self._children or not isinstance(self._children[name], ConfigNode):
                self._children[name] = ConfigNode(list(self._layers))
            child = self._children[name]
            child.set_value(value, layer, source)


Instruction:
Can you tell what is the following Python 3 function doing
def update(self, data: Union[Mapping, str, bytes], layer: str=None, source: str=None):
        if isinstance(data, dict):
            self._read_dict(data, layer, source)
        elif isinstance(data, ConfigTree):
            # TODO: set this to parse the other config tree including layer and source info.  Maybe.
            self._read_dict(data.to_dict(), layer, source)
        elif isinstance(data, str):
            if data.endswith(('.yaml', '.yml')):
                source = source if source else data
                self._load(data, layer, source)
            else:
                try:
                    self._loads(data, layer, source)
                except AttributeError:
                    raise ValueError("The string data should be yaml formated string or path to .yaml/.yml file")
        elif data is None:
            pass
        else:
            raise ValueError(f"Update must be called with dictionary, string, or ConfigTree. "
                             f"You passed in {type(data)}")

Response: Updates the internal state of the object with the given data.


Instruction:
How would you explain what the following Python 3 function does
def _read_dict(self, data_dict, layer=None, source=None):
        for k, v in data_dict.items():
            self._set_with_metadata(k, v, layer, source)

Response: Load a dictionary into the ConfigTree.


Instruction:
Can you tell what is the following Python 3 function doing
def _loads(self, data_string, layer=None, source=None):
        data_dict = yaml.full_load(data_string)
        self._read_dict(data_dict, layer, source)

Response: Loads data from a yaml formatted string.


Instruction:
How would you explain what the following Python 3 function does
def _load(self, f, layer=None, source=None):
        if hasattr(f, 'read'):
            self._loads(f.read(), layer=layer, source=source)
        else:
            with open(f) as f:
                self._loads(f.read(), layer=layer, source=source)

Response: Load data from a yaml formatted file.


Instruction:
Write a Python 3 script to
return value and metadata associated with the named value

Response:
def metadata(self, name):
        """Return value and metadata associated with the named value

        Parameters
        ----------
        name : str
            name to retrieve. If the name contains '.'s it will be retrieved recursively

        Raises
        ------
        KeyError
            if name is not defined in the ConfigTree
        """
        if name in self._children:
            return self._children[name].metadata()
        else:
            head, _, tail = name.partition('.')
            if head in self._children:
                return self._children[head].metadata(key=tail)
            else:
                raise KeyError(name)


Instruction:
Write a Python 3 script to
remove any value and metadata associated with the named layer.

Response:
def reset_layer(self, layer, preserve_keys=()):
        """Removes any value and metadata associated with the named layer.

        Parameters
        ----------
        layer : str
            Name of the layer to reset.
        preserve_keys : list or tuple
            A list of keys to skip while removing data

        Raises
        ------
        TypeError
            If the node is frozen
        KeyError
            If the named layer does not exist
        """
        self._reset_layer(layer, [k.split('.') for k in preserve_keys], prefix=[])


Instruction:
Write a Python 3 function that can
remove the named layer and the value associated with it from the node.

Response:
def drop_layer(self, layer):
        """Removes the named layer and the value associated with it from the node.

        Parameters
        ----------
        layer : str
            Name of the layer to drop.

        Raises
        ------
        TypeError
            If the node is frozen
        KeyError
            If the named layer does not exist
        """
        if self._frozen:
            raise TypeError('Frozen ConfigTree does not support modification')
        for child in self._children.values():
            child.drop_layer(layer)
        self._layers.remove(layer)


Instruction:
How would you implement a function in Python 3 that
lists all keys which are present in the ConfigTree but which have not been accessed.

Response:
def unused_keys(self):
        """Lists all keys which are present in the ConfigTree but which have not been accessed."""
        unused = set()
        for k, c in self._children.items():
            if isinstance(c, ConfigNode):
                if not c.has_been_accessed():
                    unused.add(k)
            else:
                for ck in c.unused_keys():
                    unused.add(k+'.'+ck)
        return unused


Instruction:
Write a Python 3 function that can
create a new Draft4Validator object.

Response:
def create_validator(schema_filename=None, schema_dir=None):
    """Crea el validador necesario para inicializar un objeto DataJson.

    Para poder resolver referencias inter-esquemas, un Validador requiere
    que se especifique un RefResolver (Resolvedor de Referencias) con el
    directorio base (absoluto) y el archivo desde el que se referencia el
    directorio.

    Para poder validar formatos, un Validador requiere que se provea
    explícitamente un FormatChecker. Actualmente se usa el default de la
    librería, jsonschema.FormatChecker().

    Args:
        schema_filename (str): Nombre del archivo que contiene el esquema
            validador "maestro".
        schema_dir (str): Directorio (absoluto) donde se encuentra el
            esquema validador maestro y sus referencias, de tenerlas.

    Returns:
        Draft4Validator: Un validador de JSONSchema Draft #4. El validador
            se crea con un RefResolver que resuelve referencias de
            `schema_filename` dentro de `schema_dir`.
    """
    schema_filename = schema_filename or DEFAULT_CATALOG_SCHEMA_FILENAME
    schema_dir = schema_dir or ABSOLUTE_SCHEMA_DIR
    schema_path = os.path.join(schema_dir, schema_filename)
    schema = readers.read_json(schema_path)

    # Según https://github.com/Julian/jsonschema/issues/98
    # Permite resolver referencias locales a otros esquemas.
    if platform.system() == 'Windows':
        base_uri = "file:///" + schema_path.replace("\\", "/")
    else:
        base_uri = "file://" + schema_path
    resolver = jsonschema.RefResolver(base_uri=base_uri, referrer=schema)

    format_checker = jsonschema.FormatChecker()

    validator = jsonschema.Draft4Validator(
        schema=schema, resolver=resolver, format_checker=format_checker)

    return validator


Instruction:
Can you generate the documentation for the following Python 3 function
def is_valid_catalog(catalog, validator=None):
    catalog = readers.read_catalog(catalog)
    if not validator:
        if hasattr(catalog, "validator"):
            validator = catalog.validator
        else:
            validator = create_validator()

    jsonschema_res = validator.is_valid(catalog)
    custom_errors = iter_custom_errors(catalog)

    return jsonschema_res and len(list(custom_errors)) == 0

Response: Valida que un archivo data. json cumpla con el schema definida.


Instruction:
Here you have a function in Python 3, explain what it does
def validate_catalog(catalog, only_errors=False, fmt="dict",
                     export_path=None, validator=None):
    """Analiza un data.json registrando los errores que encuentra.

    Chequea que el data.json tiene todos los campos obligatorios y que
    tanto los campos obligatorios como los opcionales siguen la estructura
    definida en el schema.

    Args:
        catalog (str o dict): Catálogo (dict, JSON o XLSX) a ser validado.
        only_errors (bool): Si es True sólo se reportan los errores.
        fmt (str): Indica el formato en el que se desea el reporte.
            "dict" es el reporte más verborrágico respetando la
                estructura del data.json.
            "list" devuelve un dict con listas de errores formateados para
                generar tablas.
        export_path (str): Path donde exportar el reporte generado (en
            formato XLSX o CSV). Si se especifica, el método no devolverá
            nada, a pesar de que se pase algún argumento en `fmt`.

    Returns:
        dict: Diccionario resumen de los errores encontrados::

            {
                "status": "OK",  # resultado de la validación global
                "error": {
                    "catalog": {
                        "status": "OK",
                        "errors": []
                        "title": "Título Catalog"},
                    "dataset": [
                        {
                            "status": "OK",
                            "errors": [],
                            "title": "Titulo Dataset 1"
                        },
                        {
                            "status": "ERROR",
                            "errors": [error1_info, error2_info, ...],
                            "title": "Titulo Dataset 2"
                        }
                    ]
                }
            }

        Donde errorN_info es un dict con la información del N-ésimo
        error encontrado, con las siguientes claves: "path", "instance",
        "message", "validator", "validator_value", "error_code".

    """
    catalog = readers.read_catalog(catalog)

    # La respuesta por default se devuelve si no hay errores
    default_response = {
        "status": "OK",
        "error": {
            "catalog": {
                "status": "OK",
                "title": catalog.get("title"),
                "errors": []
            },
            # "dataset" contiene lista de rtas default si el catálogo
            # contiene la clave "dataset" y además su valor es una lista.
            # En caso contrario "dataset" es None.
            "dataset": [
                {
                    "status": "OK",
                    "title": dataset.get("title"),
                    "identifier": dataset.get("identifier"),
                    "list_index": index,
                    "errors": []
                } for index, dataset in enumerate(catalog["dataset"])
            ] if ("dataset" in catalog and
                  isinstance(catalog["dataset"], list)) else None
        }
    }

    # Genero la lista de errores en la instancia a validar
    if not validator:
        if hasattr(catalog, "validator"):
            validator = catalog.validator
        else:
            validator = create_validator()
    jsonschema_errors = list(validator.iter_errors(catalog))
    custom_errors = list(iter_custom_errors(catalog))

    errors = jsonschema_errors + custom_errors

    response = default_response.copy()
    for error in errors:
        response = _update_validation_response(
            error, response)

    # filtra los resultados que están ok, para hacerlo más compacto
    if only_errors:
        response["error"]["dataset"] = [
            dataset for dataset in response["error"]["dataset"] if
            dataset["status"] == "ERROR"]

    # elige el formato del resultado
    if export_path:
        validation_lists = _catalog_validation_to_list(response)

        # config styles para reportes en excel
        alignment = Alignment(
            wrap_text=True,
            shrink_to_fit=True,
            vertical="center"
        )
        column_styles = {
            "catalog": {
                "catalog_status": {"width": 20},
                "catalog_error_location": {"width": 40},
                "catalog_error_message": {"width": 40},
                "catalog_title": {"width": 20},
            },
            "dataset": {
                "dataset_error_location": {"width": 20},
                "dataset_identifier": {"width": 40},
                "dataset_status": {"width": 20},
                "dataset_title": {"width": 40},
                "dataset_list_index": {"width": 20},
                "dataset_error_message": {"width": 40},
            }
        }
        cell_styles = {
            "catalog": [
                {"alignment": Alignment(vertical="center")},
                {"row": 1, "font": Font(bold=True)},
            ],
            "dataset": [
                {"alignment": Alignment(vertical="center")},
                {"row": 1, "font": Font(bold=True)},
            ]
        }

        # crea tablas en un sólo excel o varios CSVs
        writers.write_tables(
            tables=validation_lists, path=export_path,
            column_styles=column_styles, cell_styles=cell_styles
        )

    elif fmt == "dict":
        return response

    elif fmt == "list":
        return _catalog_validation_to_list(response)

    # Comentado porque requiere una extensión pesada nueva para pydatajson
    # elif fmt == "df":
    #     validation_lists = self._catalog_validation_to_list(response)
    #     return {
    #         "catalog": pd.DataFrame(validation_lists["catalog"]),
    #         "dataset": pd.DataFrame(validation_lists["dataset"])
    #     }

    else:
        raise Exception("No se reconoce el formato {}".format(fmt))

Response:
Analiza un data.json registrando los errores que encuentra.

    Chequea que el data.json tiene todos los campos obligatorios y que
    tanto los campos obligatorios como los opcionales siguen la estructura
    definida en el schema.

    Args:
        catalog (str o dict): Catálogo (dict, JSON o XLSX) a ser validado.
        only_errors (bool): Si es True sólo se reportan los errores.
        fmt (str): Indica el formato en el que se desea el reporte.
            "dict" es el reporte más verborrágico respetando la
                estructura del data.json.
            "list" devuelve un dict con listas de errores formateados para
                generar tablas.
        export_path (str): Path donde exportar el reporte generado (en
            formato XLSX o CSV). Si se especifica, el método no devolverá
            nada, a pesar de que se pase algún argumento en `fmt`.

    Returns:
        dict: Diccionario resumen de los errores encontrados::

            {
                "status": "OK",  # resultado de la validación global
                "error": {
                    "catalog": {
                        "status": "OK",
                        "errors": []
                        "title": "Título Catalog"},
                    "dataset": [
                        {
                            "status": "OK",
                            "errors": [],
                            "title": "Titulo Dataset 1"
                        },
                        {
                            "status": "ERROR",
                            "errors": [error1_info, error2_info, ...],
                            "title": "Titulo Dataset 2"
                        }
                    ]
                }
            }

        Donde errorN_info es un dict con la información del N-ésimo
        error encontrado, con las siguientes claves: "path", "instance",
        "message", "validator", "validator_value", "error_code".


Instruction:
Create a Python 3 function for
returning an iterator over the custom error messages that are generated by the jsonschema.

Response:
def iter_custom_errors(catalog):
    """Realiza validaciones sin usar el jsonschema.

    En esta función se agregan bloques de código en python que realizan
    validaciones complicadas o imposibles de especificar usando jsonschema.
    """

    try:
        # chequea que no se repiten los ids de la taxonomía específica
        if "themeTaxonomy" in catalog:
            theme_ids = [theme["id"] for theme in catalog["themeTaxonomy"]]
            dups = _find_dups(theme_ids)
            if len(dups) > 0:
                yield ce.ThemeIdRepeated(dups)

        # chequea que un dataset no use un theme que no exista en la taxonomía
        # TODO: hay que implementarlo

        # chequea que un dataset no use theme con id esté repetido en taxonomía
        # TODO: hay que implementarlo

        # chequea que la extensión de fileName, downloadURL y format sean
        # consistentes
        for dataset_idx, dataset in enumerate(catalog["dataset"]):
            for distribution_idx, distribution in enumerate(
                    dataset["distribution"]):
                for attribute in ['downloadURL', 'fileName']:
                    if not format_matches_extension(distribution, attribute):
                        yield ce.ExtensionError(dataset_idx, distribution_idx,
                                                distribution, attribute)

        # chequea que no haya duplicados en los downloadURL de las
        # distribuciones
        # urls = []
        # for dataset in catalog["dataset"]:
        #     urls += [distribution['downloadURL']
        #              for distribution in dataset['distribution']
        #              if distribution.get('downloadURL')]
        # dups = _find_dups(urls)
        # if len(dups) > 0:
        #     yield ce.DownloadURLRepetitionError(dups)

        # chequea que las URLs de las distribuciones estén operativas
        # hay que revisar
        # for distribution in catalog.distributions:
        #     url = distribution.get("downloadURL")
        #     status_code = requests.head(url).status_code
        #     if status_code != 200:
        #         yield ce.DownloadURLBrokenError(
        #             distribution.get("identifier"), url, status_code)

    except Exception:
        logger.exception("Error de validación.")


Instruction:
Given the following Python 3 function, write the documentation
def format_matches_extension(distribution, attribute):

    if attribute in distribution and "format" in distribution:
        if "/" in distribution['format']:
            possible_format_extensions = mimetypes.guess_all_extensions(
                distribution['format'])
        else:
            possible_format_extensions = ['.' + distribution['format'].lower()]

        file_name = urlparse(distribution[attribute]).path
        extension = os.path.splitext(file_name)[-1].lower()

        if attribute == 'downloadURL' and not extension:
            return True

        # hay extensiones exceptuadas porque enmascaran otros formatos
        if extension.lower().replace(".", "") in EXTENSIONS_EXCEPTIONS:
            return True

        if extension not in possible_format_extensions:
            return False

    return True

Response: Chequea si una extensión podría corresponder a un formato dado.


Instruction:
Make a summary of the following Python 3 code
def push_dataset_to_ckan(catalog, owner_org, dataset_origin_identifier,
                         portal_url, apikey, catalog_id=None,
                         demote_superThemes=True, demote_themes=True,
                         download_strategy=None, generate_new_access_url=None):
    """Escribe la metadata de un dataset en el portal pasado por parámetro.

        Args:
            catalog (DataJson): El catálogo de origen que contiene el dataset.
            owner_org (str): La organización a la cual pertence el dataset.
            dataset_origin_identifier (str): El id del dataset que se va a
                federar.
            portal_url (str): La URL del portal CKAN de destino.
            apikey (str): La apikey de un usuario con los permisos que le
                permitan crear o actualizar el dataset.
            catalog_id (str): El prefijo con el que va a preceder el id del
                dataset en catálogo destino.
            demote_superThemes(bool): Si está en true, los ids de los super
                themes del dataset, se propagan como grupo.
            demote_themes(bool): Si está en true, los labels de los themes
                del dataset, pasan a ser tags. Sino, se pasan como grupo.
            download_strategy(callable): Una función (catálogo, distribución)->
                bool. Sobre las distribuciones que evalúa True, descarga el
                recurso en el downloadURL y lo sube al portal de destino.
                Por default no sube ninguna distribución.
            generate_new_access_url(list): Se pasan los ids de las
                distribuciones cuyo accessURL se regenerar en el portal de
                destino. Para el resto, el portal debe mantiene el valor pasado
                en el DataJson.
        Returns:
            str: El id del dataset en el catálogo de destino.
    """
    dataset = catalog.get_dataset(dataset_origin_identifier)
    ckan_portal = RemoteCKAN(portal_url, apikey=apikey)

    package = map_dataset_to_package(catalog, dataset, owner_org, catalog_id,
                                     demote_superThemes, demote_themes)

    # Get license id
    if dataset.get('license'):
        license_list = ckan_portal.call_action('license_list')
        try:
            ckan_license = next(
                license_item for license_item in license_list if
                license_item['title'] == dataset['license'] or
                license_item['url'] == dataset['license']
            )
            package['license_id'] = ckan_license['id']
        except StopIteration:
            package['license_id'] = 'notspecified'
    else:
        package['license_id'] = 'notspecified'

    try:
        pushed_package = ckan_portal.call_action(
            'package_update', data_dict=package)
    except NotFound:
        pushed_package = ckan_portal.call_action(
            'package_create', data_dict=package)

    with resource_files_download(catalog, dataset.get('distribution', []),
                                 download_strategy) as resource_files:
        resources_update(portal_url, apikey, dataset.get('distribution', []),
                         resource_files, generate_new_access_url, catalog_id)

    ckan_portal.close()
    return pushed_package['id']

Response: Escribe la metadata de un dataset en el CKAN de destino.


Instruction:
Can you tell what is the following Python 3 function doing
def resources_update(portal_url, apikey, distributions,
                     resource_files, generate_new_access_url=None,
                     catalog_id=None):
    """Sube archivos locales a sus distribuciones correspondientes en el portal
     pasado por parámetro.

            Args:
                portal_url (str): La URL del portal CKAN de destino.
                apikey (str): La apikey de un usuario con los permisos que le
                    permitan crear o actualizar el dataset.
                distributions(list): Lista de distribuciones posibles para
                    actualizar.
                resource_files(dict): Diccionario con entradas
                    id_de_distribucion:path_al_recurso a subir
                generate_new_access_url(list): Lista de ids de distribuciones a
                    las cuales se actualizará el accessURL con los valores
                    generados por el portal de destino
                catalog_id(str): prependea el id al id del recurso para
                    encontrarlo antes de subirlo
            Returns:
                list: los ids de los recursos modificados
        """
    ckan_portal = RemoteCKAN(portal_url, apikey=apikey)
    result = []
    generate_new_access_url = generate_new_access_url or []
    for distribution in distributions:
        updated = False
        resource_id = catalog_id + '_' + distribution['identifier']\
            if catalog_id else distribution['identifier']
        fields = {'id': resource_id}
        if distribution['identifier'] in generate_new_access_url:
            fields.update({'accessURL': ''})
            updated = True
        if distribution['identifier'] in resource_files:
            fields.update({'resource_type': 'file.upload',
                           'upload':
                               open(resource_files[distribution['identifier']],
                                    'rb')
                           })
            updated = True
        if updated:
            try:
                pushed = ckan_portal.action.resource_patch(**fields)
                result.append(pushed['id'])
            except CKANAPIError as e:
                logger.exception(
                    "Error subiendo recurso {} a la distribución {}: {}"
                    .format(resource_files[distribution['identifier']],
                            resource_files, str(e)))
    return result

Response: Update the content of a resource in a CKAN portal.


Instruction:
Given the following Python 3 function, write the documentation
def remove_datasets_from_ckan(portal_url, apikey, filter_in=None,
                              filter_out=None, only_time_series=False,
                              organization=None):
    """Borra un dataset en el portal pasado por parámetro.

            Args:
                portal_url (str): La URL del portal CKAN de destino.
                apikey (str): La apikey de un usuario con los permisos que le
                    permitan borrar el dataset.
                filter_in(dict): Diccionario de filtrado positivo, similar al
                    de search.get_datasets.
                filter_out(dict): Diccionario de filtrado negativo, similar al
                    de search.get_datasets.
                only_time_series(bool): Filtrar solo los datasets que tengan
                    recursos con series de tiempo.
                organization(str): Filtrar solo los datasets que pertenezcan a
                    cierta organizacion.
            Returns:
                None
    """
    ckan_portal = RemoteCKAN(portal_url, apikey=apikey)
    identifiers = []
    datajson_filters = filter_in or filter_out or only_time_series
    if datajson_filters:
        identifiers += get_datasets(
            portal_url + '/data.json',
            filter_in=filter_in, filter_out=filter_out,
            only_time_series=only_time_series, meta_field='identifier'
        )
    if organization:
        query = 'organization:"' + organization + '"'
        search_result = ckan_portal.call_action('package_search', data_dict={
            'q': query, 'rows': 500, 'start': 0})
        org_identifiers = [dataset['id']
                           for dataset in search_result['results']]
        start = 500
        while search_result['count'] > start:
            search_result = ckan_portal.call_action(
                'package_search', data_dict={
                    'q': query, 'rows': 500, 'start': start})
            org_identifiers += [dataset['id']
                                for dataset in search_result['results']]
            start += 500

        if datajson_filters:
            identifiers = set(identifiers).intersection(set(org_identifiers))
        else:
            identifiers = org_identifiers

    for identifier in identifiers:
        ckan_portal.call_action('dataset_purge', data_dict={'id': identifier})

Response: Borra un dataset en el portal pasado por parámetro.


Instruction:
Write a Python 3 function that can
harvest a dataset to CKAN.

Response:
def harvest_dataset_to_ckan(catalog, owner_org, dataset_origin_identifier,
                            portal_url, apikey, catalog_id,
                            download_strategy=None):
    """Federa la metadata de un dataset en el portal pasado por parámetro.

        Args:
            catalog (DataJson): El catálogo de origen que contiene el dataset.
            owner_org (str): La organización a la cual pertence el dataset.
            dataset_origin_identifier (str): El id del dataset que se va a
                restaurar.
            portal_url (str): La URL del portal CKAN de destino.
            apikey (str): La apikey de un usuario con los permisos que le
                permitan crear o actualizar el dataset.
            catalog_id(str): El id que prependea al dataset y recursos
            download_strategy(callable): Una función (catálogo, distribución)->
                bool. Sobre las distribuciones que evalúa True, descarga el
                recurso en el downloadURL y lo sube al portal de destino.
                Por default no sube ninguna distribución.
        Returns:
            str: El id del dataset restaurado.
    """

    return push_dataset_to_ckan(catalog, owner_org, dataset_origin_identifier,
                                portal_url, apikey, catalog_id=catalog_id,
                                download_strategy=download_strategy)


Instruction:
Write a Python 3 script for
harvesting a catalog to CKAN.

Response:
def harvest_catalog_to_ckan(catalog, portal_url, apikey, catalog_id,
                            dataset_list=None, owner_org=None,
                            download_strategy=None):
    """Federa los datasets de un catálogo al portal pasado por parámetro.

        Args:
            catalog (DataJson): El catálogo de origen que se federa.
            portal_url (str): La URL del portal CKAN de destino.
            apikey (str): La apikey de un usuario con los permisos que le
                permitan crear o actualizar el dataset.
            catalog_id (str): El prefijo con el que va a preceder el id del
                dataset en catálogo destino.
            dataset_list(list(str)): Los ids de los datasets a federar. Si no
                se pasa una lista, todos los datasests se federan.
            owner_org (str): La organización a la cual pertencen los datasets.
                Si no se pasa, se utiliza el catalog_id.
            download_strategy(callable): Una función (catálogo, distribución)->
                bool. Sobre las distribuciones que evalúa True, descarga el
                recurso en el downloadURL y lo sube al portal de destino.
                Por default no sube ninguna distribución.
        Returns:
            str: El id del dataset en el catálogo de destino.
    """
    # Evitar entrar con valor falsy
    harvested = []
    if dataset_list is None:
        try:
            dataset_list = [ds['identifier'] for ds in catalog.datasets]
        except KeyError:
            logger.exception('Hay datasets sin identificadores')
            return harvested
    owner_org = owner_org or catalog_id
    errors = {}
    for dataset_id in dataset_list:
        try:
            harvested_id = harvest_dataset_to_ckan(catalog, owner_org,
                                                   dataset_id, portal_url,
                                                   apikey, catalog_id,
                                                   download_strategy)
            harvested.append(harvested_id)
        except Exception as e:
            msg = "Error federando catalogo: %s, dataset: %s al portal: %s\n"\
                  % (catalog_id, dataset_id, portal_url)
            msg += str(e)
            logger.error(msg)
            errors[dataset_id] = str(e)

    return harvested, errors


Instruction:
Can you generate a brief explanation for the following Python 3 code
def push_new_themes(catalog, portal_url, apikey):
    ckan_portal = RemoteCKAN(portal_url, apikey=apikey)
    existing_themes = ckan_portal.call_action('group_list')
    new_themes = [theme['id'] for theme in catalog[
        'themeTaxonomy'] if theme['id'] not in existing_themes]
    pushed_names = []
    for new_theme in new_themes:
        name = push_theme_to_ckan(
            catalog, portal_url, apikey, identifier=new_theme)
        pushed_names.append(name)
    return pushed_names

Response: Pushes new themes to CKAN


Instruction:
Can you tell what is the following Python 3 function doing
def get_organization_from_ckan(portal_url, org_id):
    ckan_portal = RemoteCKAN(portal_url)
    return ckan_portal.call_action('organization_show',
                                   data_dict={'id': org_id})

Response: Get organization from CKAN


Instruction:
Here you have a function in Python 3, explain what it does
def push_organization_tree_to_ckan(portal_url, apikey, org_tree, parent=None):
    created = []
    for node in org_tree:
        pushed_org = push_organization_to_ckan(portal_url,
                                               apikey,
                                               node,
                                               parent=parent)
        if pushed_org['success']:
            pushed_org['children'] = push_organization_tree_to_ckan(
                portal_url, apikey, node['children'], parent=node['name'])

        created.append(pushed_org)
    return created

Response: Pushes an organization tree to CKAN


Instruction:
Here you have a function in Python 3, explain what it does
def push_organization_to_ckan(portal_url, apikey, organization, parent=None):
    portal = RemoteCKAN(portal_url, apikey=apikey)
    if parent:
        organization['groups'] = [{'name': parent}]
    try:
        pushed_org = portal.call_action('organization_create',
                                        data_dict=organization)
        pushed_org['success'] = True
    except Exception as e:
        logger.exception('Ocurrió un error creando la organización {}: {}'
                         .format(organization['title'], str(e)))
        pushed_org = {'name': organization, 'success': False}

    return pushed_org

Response: Pushes an organization to CKAN


Instruction:
Implement a function in Python 3 to
remove an organization from CKAN

Response:
def remove_organization_from_ckan(portal_url, apikey, organization_id):
    """Toma un id de organización y la purga del portal de destino.
        Args:
            portal_url (str): La URL del portal CKAN de destino.
            apikey (str): La apikey de un usuario con los permisos que le
                permitan borrar la organización.
            organization_id(str): Id o name de la organización a borrar.
        Returns:
            None.

    """
    portal = RemoteCKAN(portal_url, apikey=apikey)
    try:
        portal.call_action('organization_purge',
                           data_dict={'id': organization_id})

    except Exception as e:
        logger.exception('Ocurrió un error borrando la organización {}: {}'
                         .format(organization_id, str(e)))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def remove_organizations_from_ckan(portal_url, apikey, organization_list):
    for org in organization_list:
        remove_organization_from_ckan(portal_url, apikey, org)

Response: Removes organizations from CKAN


Instruction:
Can you tell what is the following Python 3 function doing
def restore_organization_to_ckan(catalog, owner_org, portal_url, apikey,
                                 dataset_list=None, download_strategy=None,
                                 generate_new_access_url=None):
    """Restaura los datasets de la organización de un catálogo al portal pasado
       por parámetro. Si hay temas presentes en el DataJson que no están en el
       portal de CKAN, los genera.

        Args:
            catalog (DataJson): El catálogo de origen que se restaura.
            portal_url (str): La URL del portal CKAN de destino.
            apikey (str): La apikey de un usuario con los permisos que le
                permitan crear o actualizar el dataset.
            dataset_list(list(str)): Los ids de los datasets a restaurar. Si no
                se pasa una lista, todos los datasests se restauran.
            owner_org (str): La organización a la cual pertencen los datasets.
            download_strategy(callable): Una función (catálogo, distribución)->
                bool. Sobre las distribuciones que evalúa True, descarga el
                recurso en el downloadURL y lo sube al portal de destino.
                Por default no sube ninguna distribución.
            generate_new_access_url(list): Se pasan los ids de las
                    distribuciones cuyo accessURL se regenerar en el portal de
                    destino. Para el resto, el portal debe mantiene el valor
                    pasado en el DataJson.
        Returns:
            list(str): La lista de ids de datasets subidos.
    """
    push_new_themes(catalog, portal_url, apikey)
    restored = []
    if dataset_list is None:
        try:
            dataset_list = [ds['identifier'] for ds in catalog.datasets]
        except KeyError:
            logger.exception('Hay datasets sin identificadores')
            return restored

    for dataset_id in dataset_list:
        try:
            restored_id = restore_dataset_to_ckan(catalog, owner_org,
                                                  dataset_id, portal_url,
                                                  apikey, download_strategy,
                                                  generate_new_access_url)
            restored.append(restored_id)
        except (CKANAPIError, KeyError, AttributeError) as e:
            logger.exception('Ocurrió un error restaurando el dataset {}: {}'
                             .format(dataset_id, str(e)))
    return restored

Response: Restaura los datasets de la organización de un catálogo al portal de CKAN de destino.


Instruction:
Can you tell what is the following Python 3 function doing
def restore_catalog_to_ckan(catalog, origin_portal_url, destination_portal_url,
                            apikey, download_strategy=None,
                            generate_new_access_url=None):
    """Restaura los datasets de un catálogo original al portal pasado
       por parámetro. Si hay temas presentes en el DataJson que no están en
       el portal de CKAN, los genera.

            Args:
                catalog (DataJson): El catálogo de origen que se restaura.
                origin_portal_url (str): La URL del portal CKAN de origen.
                destination_portal_url (str): La URL del portal CKAN de
                    destino.
                apikey (str): La apikey de un usuario con los permisos que le
                    permitan crear o actualizar el dataset.
                download_strategy(callable): Una función
                    (catálogo, distribución)-> bool. Sobre las distribuciones
                    que evalúa True, descarga el recurso en el downloadURL y lo
                    sube al portal de destino. Por default no sube ninguna
                    distribución.
                generate_new_access_url(list): Se pasan los ids de las
                    distribuciones cuyo accessURL se regenerar en el portal de
                    destino. Para el resto, el portal debe mantiene el valor
                    pasado en el DataJson.
            Returns:
                dict: Diccionario con key organización y value la lista de ids
                    de datasets subidos a esa organización
        """
    catalog['homepage'] = catalog.get('homepage') or origin_portal_url
    res = {}
    origin_portal = RemoteCKAN(origin_portal_url)

    try:
        org_list = origin_portal.action.organization_list()

    except CKANAPIError as e:
        logger.exception(
            'Ocurrió un error buscando las organizaciones del portal {}: {}'
            .format(origin_portal_url, str(e)))
        print(e)
        return res

    for org in org_list:
        print("Restaurando organizacion {}".format(org))

        response = origin_portal.action.organization_show(
            id=org, include_datasets=True)
        datasets = [package['id'] for package in response['packages']]
        pushed_datasets = restore_organization_to_ckan(
            catalog, org, destination_portal_url, apikey,
            dataset_list=datasets, download_strategy=download_strategy,
            generate_new_access_url=generate_new_access_url
        )
        res[org] = pushed_datasets

    return res

Response: Restaura los datasets de un catálogo original al portal de CKAN destino.


Instruction:
Can you implement a function in Python 3 that
constructs a simulation from a list of components componentTrees configuration and pluginTrees.

Response:
def initialize_simulation(components: List, input_config: Mapping=None,
                          plugin_config: Mapping=None) -> InteractiveContext:
    """Construct a simulation from a list of components, component
    configuration, and a plugin configuration.

    The simulation context returned by this method still needs to be setup by
    calling its setup method. It is mostly useful for testing and debugging.

    Parameters
    ----------
    components
        A list of initialized simulation components. Corresponds to the
        components block of a model specification.
    input_config
        A nested dictionary with any additional simulation configuration
        information needed. Corresponds to the configuration block of a model
        specification.
    plugin_config
        A dictionary containing a description of any simulation plugins to
        include in the simulation. If you're using this argument, you're either
        deep in the process of simulation development or the maintainers have
        done something wrong. Corresponds to the plugins block of a model
        specification.

    Returns
    -------
        An initialized (but not set up) simulation context.
    """
    config = build_simulation_configuration()
    config.update(input_config)
    plugin_manager = PluginManager(plugin_config)

    return InteractiveContext(config, components, plugin_manager)


Instruction:
Can you write a function in Python 3 where it
constructs a simulation from a list of components and call its setup method.

Response:
def setup_simulation(components: List, input_config: Mapping=None,
                     plugin_config: Mapping=None) -> InteractiveContext:
    """Construct a simulation from a list of components and call its setup
    method.

    Parameters
    ----------
    components
        A list of initialized simulation components. Corresponds to the
        components block of a model specification.
    input_config
        A nested dictionary with any additional simulation configuration
        information needed. Corresponds to the configuration block of a model
        specification.
    plugin_config
        A dictionary containing a description of any simulation plugins to
        include in the simulation. If you're using this argument, you're either
        deep in the process of simulation development or the maintainers have
        done something wrong. Corresponds to the plugins block of a model
        specification.

    Returns
    -------
        A simulation context that is setup and ready to run.
    """
    simulation = initialize_simulation(components, input_config, plugin_config)
    simulation.setup()

    return simulation


Instruction:
Write a Python 3 function for
constructing a simulation from a model specification file.

Response:
def initialize_simulation_from_model_specification(model_specification_file: str) -> InteractiveContext:
    """Construct a simulation from a model specification file.

    The simulation context returned by this method still needs to be setup by
    calling its setup method. It is mostly useful for testing and debugging.

    Parameters
    ----------
    model_specification_file
        The path to a model specification file.

    Returns
    -------
        An initialized (but not set up) simulation context.
    """
    model_specification = build_model_specification(model_specification_file)

    plugin_config = model_specification.plugins
    component_config = model_specification.components
    simulation_config = model_specification.configuration

    plugin_manager = PluginManager(plugin_config)
    component_config_parser = plugin_manager.get_plugin('component_configuration_parser')
    components = component_config_parser.get_components(component_config)

    return InteractiveContext(simulation_config, components, plugin_manager)


Instruction:
Given the following Python 3 function, write the documentation
def setup_simulation_from_model_specification(model_specification_file: str) -> InteractiveContext:
    simulation = initialize_simulation_from_model_specification(model_specification_file)
    simulation.setup()

    return simulation

Response: Construct a simulation from a model specification file and call its setup method.


Instruction:
Explain what the following Python 3 code does
def setup(self):
        super().setup()
        self._start_time = self.clock.time
        self.initialize_simulants()

Response: Setup the simulation and initialize its population.


Instruction:
Can you tell what is the following Python 3 function doing
def initialize_simulants(self):
        super().initialize_simulants()
        self._initial_population = self.population.get_population(True)

Response:
Initialize this simulation s population. Should not be called
        directly.


Instruction:
Here you have a function in Python 3, explain what it does
def reset(self):
        warnings.warn("This reset method is very crude.  It should work for "
                      "many simple simulations, but we make no guarantees. In "
                      "particular, if you have components that manage their "
                      "own state in any way, this might not work.")
        self.population._population = self._initial_population
        self.clock._time = self._start_time

Response: Reset the simulation to its initial state.


Instruction:
Can you generate the documentation for the following Python 3 function
def run(self, with_logging: bool=True) -> int:
        return self.run_until(self.clock.stop_time, with_logging=with_logging)

Response:
Runs the simulation for the time duration specified in the
            configuration.


Instruction:
Implement a Python 3 function for
running the simulation for the given time duration.

Response:
def run_for(self, duration: Timedelta, with_logging: bool=True) -> int:
        """Run the simulation for the given time duration.

        Parameters
        ----------
        duration
            The length of time to run the simulation for. Should be the same
            type as the simulation clock's step size (usually a pandas
            Timedelta).
        with_logging
            Whether or not to log the simulation steps. Only works in an ipython
            environment.

        Returns
        -------
            The number of steps the simulation took.
        """
        return self.run_until(self.clock.time + duration, with_logging=with_logging)


Instruction:
Write a Python 3 function that can
run the simulation until the end time.

Response:
def run_until(self, end_time: Time, with_logging=True) -> int:
        """Run the simulation until the provided end time.

        Parameters
        ----------
        end_time
            The time to run the simulation until. The simulation will run until
            its clock is greater than or equal to the provided end time.
        with_logging
            Whether or not to log the simulation steps. Only works in an ipython
            environment.

        Returns
        -------
            The number of steps the simulation took.
        """
        if not isinstance(end_time, type(self.clock.time)):
            raise ValueError(f"Provided time must be an instance of {type(self.clock.time)}")

        iterations = int(ceil((end_time - self.clock.time)/self.clock.step_size))
        self.take_steps(number_of_steps=iterations, with_logging=with_logging)
        assert self.clock.time - self.clock.step_size < end_time <= self.clock.time
        return iterations


Instruction:
Create a Python 3 function to
advance the simulation one step.

Response:
def step(self, step_size: Timedelta=None):
        """Advance the simulation one step.

        Parameters
        ----------
        step_size
            An optional size of step to take. Must be the same type as the
            simulation clock's step size (usually a pandas.Timedelta).
        """
        old_step_size = self.clock.step_size
        if step_size is not None:
            if not isinstance(step_size, type(self.clock.step_size)):
                raise ValueError(f"Provided time must be an instance of {type(self.clock.step_size)}")
            self.clock._step_size = step_size
        super().step()
        self.clock._step_size = old_step_size


Instruction:
Explain what the following Python 3 code does
def take_steps(self, number_of_steps: int=1, step_size: Timedelta=None, with_logging: bool=True):
        if not isinstance(number_of_steps, int):
            raise ValueError('Number of steps must be an integer.')

        if run_from_ipython() and with_logging:
            for _ in log_progress(range(number_of_steps), name='Step'):
                self.step(step_size)
        else:
            for _ in range(number_of_steps):
                self.step(step_size)

Response: Run the simulation for the given number of steps.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_population(self, untracked: bool=False) -> pd.DataFrame:
        return self.population.get_population(untracked)

Response: Get a copy of the population state table.


Instruction:
Can you tell what is the following Python 3 function doing
def get_listeners(self, event_type: str) -> List[Callable]:
        if event_type not in self.events:
            raise ValueError(f'No event {event_type} in system.')
        return self.events.get_listeners(event_type)

Response: Get all listeners of a particular type of event.


Instruction:
How would you explain what the following Python 3 function does
def get_emitter(self, event_type: str) -> Callable:
        if event_type not in self.events:
            raise ValueError(f'No event {event_type} in system.')
        return self.events.get_emitter(event_type)

Response: Get the callable that emits the given type of events.


Instruction:
Given the following Python 3 function, write the documentation
def get_components(self) -> List:
        return [component for component in self.component_manager._components + self.component_manager._managers]

Response: Get a list of all components in the simulation.


Instruction:
Implement a Python 3 function for
constructing a LookupTable from input data.

Response:
def build_table(self, data, key_columns=('sex',), parameter_columns=(['age', 'age_group_start', 'age_group_end'],
                                                                         ['year', 'year_start', 'year_end']),
                    value_columns=None) -> LookupTable:
        """Construct a LookupTable from input data.

        If data is a ``pandas.DataFrame``, an interpolation function of the specified
        order will be calculated for each permutation of the set of key_columns.
        The columns in parameter_columns will be used as parameters for the interpolation
        functions which will estimate all remaining columns in the table.

        If data is a number, time, list, or tuple, a scalar table will be constructed with
        the values in data as the values in each column of the table, named according to
        value_columns.

        Parameters
        ----------
        data        : The source data which will be used to build the resulting LookupTable.
        key_columns : [str]
                      Columns used to select between interpolation functions. These
                      should be the non-continuous variables in the data. For
                      example 'sex' in data about a population.
        parameter_columns : [str]
                      The columns which contain the parameters to the interpolation functions.
                      These should be the continuous variables. For example 'age'
                      in data about a population.
        value_columns : [str]
                      The data columns that will be in the resulting LookupTable. Columns to be
                      interpolated over if interpolation or the names of the columns in the scalar
                      table.
        Returns
        -------
        LookupTable
        """
        return self._lookup_table_manager.build_table(data, key_columns, parameter_columns, value_columns)


Instruction:
Write a Python 3 function that can
check that the data for any parameters in the sequence is complete.

Response:
def check_data_complete(data, parameter_columns):
    """ For any parameters specified with edges, make sure edges
    don't overlap and don't have any gaps. Assumes that edges are
    specified with ends and starts overlapping (but one exclusive and
    the other inclusive) so can check that end of previous == start
    of current.

    If multiple parameters, make sure all combinations of parameters
    are present in data."""

    param_edges = [p[1:] for p in parameter_columns if isinstance(p, (Tuple, List))]  # strip out call column name

    # check no overlaps/gaps
    for p in param_edges:
        other_params = [p_ed[0] for p_ed in param_edges if p_ed != p]
        if other_params:
            sub_tables = data.groupby(list(other_params))
        else:
            sub_tables = {None: data}.items()

        n_p_total = len(set(data[p[0]]))

        for _, table in sub_tables:

            param_data = table[[p[0], p[1]]].copy().sort_values(by=p[0])
            start, end = param_data[p[0]].reset_index(drop=True), param_data[p[1]].reset_index(drop=True)

            if len(set(start)) < n_p_total:
                raise ValueError(f'You must provide a value for every combination of {parameter_columns}.')

            if len(start) <= 1:
                continue
            for i in range(1, len(start)):
                e = end[i-1]
                s = start[i]
                if e > s or s == start[i-1]:
                    raise ValueError(f'Parameter data must not contain overlaps. Parameter {p} '
                                     f'contains overlapping data.')
                if e < s:
                    raise NotImplementedError(f'Interpolation only supported for parameter columns '
                                              f'with continuous bins. Parameter {p} contains '
                                              f'non-continuous bins.')


Instruction:
Make a summary of the following Python 3 code
def add_sub_directory(self, key, path):
        sub_dir_path = os.path.join(self.results_root, path)
        os.makedirs(sub_dir_path, exist_ok=True)
        self._directories[key] = sub_dir_path
        return sub_dir_path

Response: Adds a sub - directory to the results directory.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def write_output(self, data, file_name, key=None):
        path = os.path.join(self._directories[key], file_name)
        extension = file_name.split('.')[-1]

        if extension == 'yaml':
            with open(path, 'w') as f:
                yaml.dump(data, f)
        elif extension == 'hdf':
            # to_hdf breaks with categorical dtypes.
            categorical_columns = data.dtypes[data.dtypes == 'category'].index
            data.loc[:, categorical_columns] = data.loc[:, categorical_columns].astype('object')
            # Writing to an hdf over and over balloons the file size so write to new file and move it over to avoid
            data.to_hdf(path + "update", 'data')
            if os.path.exists(path):
                os.remove(path)
            os.rename(path + "update", path)
        else:
            raise NotImplementedError(
                f"Only 'yaml' and 'hdf' file types are supported. You requested {extension}")

Response: Writes output data to disk.


Instruction:
How would you explain what the following Python 3 function does
def copy_file(self, src_path, file_name, key=None):
        path = os.path.join(self._directories[key], file_name)
        shutil.copyfile(src_path, path)

Response: Copies a file unmodified to a location inside the ouput directory.


Instruction:
Create a Python 3 function to
load combined SAR format logfile in ASCII format.

Response:
def load_file(self):
        '''
        Loads combined SAR format logfile in ASCII format.
            :return: ``True`` if loading and parsing of file went fine, \
            ``False`` if it failed (at any point)
        '''
        daychunks = self.__split_file()

        if (daychunks):

            maxcount = len(self.__splitpointers)
            for i in range(maxcount):
                start = self.__splitpointers[i]
                end = None
                if (i < (maxcount - 1)):
                    end = self.__splitpointers[i + 1]

                chunk = self.__get_chunk(start, end)

                parser = sarparse.Parser()
                cpu_usage, mem_usage, swp_usage, io_usage = \
                    parser._parse_file(parser._split_file(chunk))

                self.__sarinfos[self.__get_part_date(chunk)] = {
                    "cpu": cpu_usage,
                    "mem": mem_usage,
                    "swap": swp_usage,
                    "io": io_usage
                }
                del(cpu_usage)
                del(mem_usage)
                del(swp_usage)
                del(io_usage)
                del(parser)

            return(True)


Instruction:
Can you write a function in Python 3 where it
gets the next available chunk from the sar combo file.

Response:
def __get_chunk(self, start=0, end=None):
        '''
        Gets chunk from the sar combo file, from start to end
            :param start: where to start a pulled chunk
            :type start: int.
            :param end: where to end a pulled chunk
            :type end: int.
            :return: str.
        '''
        piece = False

        if (self.__filename and os.access(self.__filename, os.R_OK)):

            fhandle = None

            try:
                fhandle = os.open(self.__filename, os.O_RDONLY)
            except OSError:
                print(("Couldn't open file %s" % (self.__filename)))
                fhandle = None

            if (fhandle):

                try:
                    sarmap = mmap.mmap(fhandle, length=0, prot=mmap.PROT_READ)
                except (TypeError, IndexError):
                    os.close(fhandle)
                    traceback.print_exc()
                    #sys.exit(-1)
                    return False

                if (not end):
                    end = sarmap.size()

                try:
                    sarmap.seek(start)
                    piece = sarmap.read(end - start)
                except:
                    traceback.print_exc()

            os.close(fhandle)

        return(piece)


Instruction:
Implement a Python 3 function for
splitting combined SAR output file into separate sections.

Response:
def __split_file(self):
        '''
        Splits combined SAR output file (in ASCII format) in order to
        extract info we need for it, in the format we want.
            :return: ``List``-style of SAR file sections separated by
                the type of info they contain (SAR file sections) without
                parsing what is exactly what at this point
        '''
        # Filename passed checks through __init__
        if (self.__filename and os.access(self.__filename, os.R_OK)):

            fhandle = None

            try:
                fhandle = os.open(self.__filename, os.O_RDONLY)
            except OSError:
                print(("Couldn't open file %s" % (self.__filename)))
                fhandle = None

            if (fhandle):

                try:
                    sarmap = mmap.mmap(fhandle, length=0, prot=mmap.PROT_READ)
                except (TypeError, IndexError):
                    os.close(fhandle)
                    traceback.print_exc()
                    #sys.exit(-1)
                    return False

            sfpos = sarmap.find(PATTERN_MULTISPLIT, 0)

            while (sfpos > -1):

                '''Split by day found'''
                self.__splitpointers.append(sfpos)

                # Iterate for new position
                try:
                    sfpos = sarmap.find(PATTERN_MULTISPLIT, (sfpos + 1))
                except ValueError:
                    print("ValueError on mmap.find()")
                    return True

            if (self.__splitpointers):
                # Not sure if this will work - if empty set
                # goes back as True here
                return True

        return False


Instruction:
Write a Python 3 script for
returning the date of the combo part from the file

Response:
def __get_part_date(self, part=''):
        '''
        Retrieves date of the combo part from the file
            :param part: Part of the combo file (parsed out whole SAR file
                from the combo
            :type part: str.
            :return: string containing date in ISO format (YYY-MM-DD)
        '''
        if (type(part) is not StringType):
            # We can cope with strings only
            return False

        firstline = part.split("\n")[0]

        info = firstline.split()
        datevalue = ''

        try:
            datevalue = info[3]

        except KeyError:
            datevalue = False

        except:
            traceback.print_exc()
            datevalue = False

        return(datevalue)


Instruction:
Write a Python 3 script for
reading the data. json file from CKAN and returns a dict of the data. json.

Response:
def read_ckan_catalog(portal_url):
    """Convierte los metadatos de un portal disponibilizados por la Action API
    v3 de CKAN al estándar data.json.

    Args:
        portal_url (str): URL de un portal de datos CKAN que soporte la API v3.

    Returns:
        dict: Representación interna de un catálogo para uso en las funciones
            de esta librería.
    """
    portal = RemoteCKAN(portal_url)
    try:
        status = portal.call_action(
            'status_show', requests_kwargs={"verify": False})
        packages_list = portal.call_action(
            'package_list', requests_kwargs={"verify": False})
        groups_list = portal.call_action(
            'group_list', requests_kwargs={"verify": False})

        # itera leyendo todos los datasets del portal
        packages = []
        num_packages = len(packages_list)
        for index, pkg in enumerate(packages_list):
            # progreso (necesario cuando son muchos)
            msg = "Leyendo dataset {} de {}".format(index + 1, num_packages)
            logger.info(msg)

            # agrega un nuevo dataset a la lista
            packages.append(portal.call_action(
                'package_show', {'id': pkg},
                requests_kwargs={"verify": False}
            ))

            # tiempo de espera padra evitar baneos
            time.sleep(0.2)

        # itera leyendo todos los temas del portal
        groups = [portal.call_action(
            'group_show', {'id': grp},
            requests_kwargs={"verify": False})
            for grp in groups_list]

        catalog = map_status_to_catalog(status)
        catalog["dataset"] = map_packages_to_datasets(
            packages, portal_url)
        catalog["themeTaxonomy"] = map_groups_to_themes(groups)

    except (CKANAPIError, RequestException) as e:
        logger.exception(
            'Error al procesar el portal %s', portal_url, exc_info=True)
        raise NonParseableCatalog(portal_url, e)

    return catalog


Instruction:
Make a summary of the following Python 3 code
def map_status_to_catalog(status):
    catalog = dict()

    catalog_mapping = {
        "site_title": "title",
        "site_description": "description"
    }

    for status_key, catalog_key in iteritems(catalog_mapping):
        try:
            catalog[catalog_key] = status[status_key]
        except BaseException:
            logger.exception("""
            La clave '%s' no está en el endpoint de status. No se puede
            completar catalog['%s'].""", status_key, catalog_key)

    publisher_mapping = {
        "site_title": "name",
        "error_emails_to": "mbox"
    }

    if any([k in status for k in publisher_mapping.keys()]):
        catalog["publisher"] = dict()
        for status_key, publisher_key in iteritems(publisher_mapping):
            try:
                catalog['publisher'][publisher_key] = status[status_key]
            except BaseException:
                logger.exception("""
                La clave '%s' no está en el endpoint de status. No se puede
                completar catalog['publisher'['%s'].""",
                                 status_key, publisher_key)
    else:
        logger.info("""
        No hay ninguna información sobre catalog['publisher'] en el endpoint
        de 'status'.""")

    catalog['superThemeTaxonomy'] = (
        'http://datos.gob.ar/superThemeTaxonomy.json')

    return catalog

Response:
Convierte el resultado de action. status_show() en metadata a nivel de
    catálogo.