Instruction:
Write a Python 3 function for
sending an email to the user who has the entry in the offer assignment model.

Response:
def send_offer_assignment_email(self, user_email, offer_assignment_id, subject, email_body, site_code=None):
    """ Sends the offer assignment email.
    Args:
        self: Ignore.
        user_email (str): Recipient's email address.
        offer_assignment_id (str): Key of the entry in the offer_assignment model.
        subject (str): Email subject.
        email_body (str): The body of the email.
        site_code (str): Identifier of the site sending the email.
    """
    config = get_sailthru_configuration(site_code)
    response = _send_offer_assignment_notification_email(config, user_email, subject, email_body, site_code, self)
    if response and response.is_ok():
        send_id = response.get_body().get('send_id')  # pylint: disable=no-member
        if _update_assignment_email_status(offer_assignment_id, send_id, 'success'):
            logger.info('[Offer Assignment] Offer assignment notification sent with message --- {message}'.format(
                message=email_body))
        else:
            logger.exception(
                '[Offer Assignment] An error occurred while updating email status data for '
                'offer {token_offer} and email {token_email} via the ecommerce API.'.format(
                    token_offer=offer_assignment_id,
                    token_email=user_email,
                )
            )


Instruction:
How would you code a function in Python 3 to
send an email to the user s offer assignment notification emails.

Response:
def _send_offer_assignment_notification_email(config, user_email, subject, email_body, site_code, task):
    """Handles sending offer assignment notification emails and retrying failed emails when appropriate."""
    try:
        sailthru_client = get_sailthru_client(site_code)
    except SailthruError:
        logger.exception(
            '[Offer Assignment] A client error occurred while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(message=email_body)
        )
        return None
    email_vars = {
        'subject': subject,
        'email_body': email_body,
    }
    try:
        response = sailthru_client.send(
            template=config['templates']['assignment_email'],
            email=user_email,
            _vars=email_vars
        )
    except SailthruClientError:
        logger.exception(
            '[Offer Assignment] A client error occurred while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(message=email_body)
        )
        return None

    if not response.is_ok():
        error = response.get_error()
        logger.error(
            '[Offer Assignment] A {token_error_code} - {token_error_message} error occurred'
            ' while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(
                message=email_body,
                token_error_code=error.get_error_code(),
                token_error_message=error.get_message()
            )
        )
        if can_retry_sailthru_request(error):
            logger.info(
                '[Offer Assignment] An attempt will be made to resend the offer assignment notification.'
                ' Message: {message}'.format(message=email_body)
            )
            schedule_retry(task, config)
        else:
            logger.warning(
                '[Offer Assignment] No further attempts will be made to send the offer assignment notification.'
                ' Failed Message: {message}'.format(message=email_body)
            )

    return response


Instruction:
Here you have a function in Python 3, explain what it does
def _update_assignment_email_status(offer_assignment_id, send_id, status, site_code=None):
    api = get_ecommerce_client(url_postfix='assignment-email/', site_code=site_code)
    post_data = {
        'offer_assignment_id': offer_assignment_id,
        'send_id': send_id,
        'status': status,
    }
    try:
        api_response = api.status().post(post_data)
    except RequestException:
        logger.exception(
            '[Offer Assignment] An error occurred while updating offer assignment email status for '
            'offer id {token_offer} and message id {token_send_id} via the Ecommerce API.'.format(
                token_offer=offer_assignment_id,
                token_send_id=send_id
            )
        )
        return False
    return True if api_response.get('status') == 'updated' else False

Response: Update the status of an offer assignment email model.


Instruction:
Write a Python 3 function for
sending the email after an offer is assigned to the current site.

Response:
def send_offer_update_email(self, user_email, subject, email_body, site_code=None):
    """ Sends the offer emails after assignment, either for revoking or reminding.
    Args:
        self: Ignore.
        user_email (str): Recipient's email address.
        subject (str): Email subject.
        email_body (str): The body of the email.
        site_code (str): Identifier of the site sending the email.
    """
    config = get_sailthru_configuration(site_code)
    _send_offer_assignment_notification_email(config, user_email, subject, email_body, site_code, self)


Instruction:
Here you have a function in Python 3, explain what it does
def get_logger_config(log_dir='/var/tmp',
                      logging_env='no_env',
                      edx_filename='edx.log',
                      dev_env=False,
                      debug=False,
                      local_loglevel='INFO',
                      service_variant='ecomworker'):

    """
    Returns a dictionary containing logging configuration.

    If dev_env is True, logging will not be done via local rsyslogd.
    Instead, application logs will be dropped into log_dir. 'edx_filename'
    is ignored unless dev_env is True.
    """
    # Revert to INFO if an invalid string is passed in
    if local_loglevel not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
        local_loglevel = 'INFO'

    hostname = platform.node().split('.')[0]
    syslog_format = (
        '[service_variant={service_variant}]'
        '[%(name)s][env:{logging_env}] %(levelname)s '
        '[{hostname}  %(process)d] [%(filename)s:%(lineno)d] '
        '- %(message)s'
    ).format(
        service_variant=service_variant,
        logging_env=logging_env, hostname=hostname
    )

    if debug:
        handlers = ['console']
    else:
        handlers = ['local']

    logger_config = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s %(levelname)s %(process)d '
                          '[%(name)s] %(filename)s:%(lineno)d - %(message)s',
            },
            'syslog_format': {'format': syslog_format},
            'raw': {'format': '%(message)s'},
        },
        'handlers': {
            'console': {
                'level': 'DEBUG' if debug else 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'standard',
                'stream': sys.stdout,
            },
        },
        'loggers': {
            'requests': {
                'handlers': handlers,
                'level': 'WARNING',
                'propagate': True
            },
            '': {
                'handlers': handlers,
                'level': 'DEBUG',
                'propagate': False
            },
        }
    }

    if dev_env:
        edx_file_loc = os.path.join(log_dir, edx_filename)
        logger_config['handlers'].update({
            'local': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': local_loglevel,
                'formatter': 'standard',
                'filename': edx_file_loc,
                'maxBytes': 1024 * 1024 * 2,
                'backupCount': 5,
            },
        })
    else:
        logger_config['handlers'].update({
            'local': {
                'level': local_loglevel,
                'class': 'logging.handlers.SysLogHandler',
                # Use a different address for Mac OS X
                'address': '/var/run/syslog' if sys.platform == 'darwin' else '/dev/log',
                'formatter': 'syslog_format',
                'facility': SysLogHandler.LOG_LOCAL0,
            },
        })

    return logger_config

Response: Returns a dictionary containing logging configuration.


Instruction:
Here you have a function in Python 3, explain what it does
def _retry_order(self, exception, max_fulfillment_retries, order_number):
    retries = self.request.retries
    if retries == max_fulfillment_retries:
        logger.exception('Fulfillment of order [%s] failed. Giving up.', order_number)
    else:
        logger.warning('Fulfillment of order [%s] failed. Retrying.', order_number)

    countdown = 2 ** retries
    raise self.retry(exc=exception, countdown=countdown, max_retries=max_fulfillment_retries)

Response:
Retry the order with exponential backoff until the fulfillment
    succeeds or the retry limit is reached.


Instruction:
How would you implement a function in Python 3 that
fulfills an order. Arguments: order_number (str): Order number indicating which order to fulfill. Returns: None

Response:
def fulfill_order(self, order_number, site_code=None, email_opt_in=False):
    """Fulfills an order.

    Arguments:
        order_number (str): Order number indicating which order to fulfill.

    Returns:
        None
    """
    max_fulfillment_retries = get_configuration('MAX_FULFILLMENT_RETRIES', site_code=site_code)
    api = get_ecommerce_client(site_code=site_code)
    try:
        logger.info('Requesting fulfillment of order [%s].', order_number)
        api.orders(order_number).fulfill.put(email_opt_in=email_opt_in)
    except exceptions.HttpClientError as exc:
        status_code = exc.response.status_code  # pylint: disable=no-member
        if status_code == 406:
            # The order is not fulfillable. Therefore, it must be complete.
            logger.info('Order [%s] has already been fulfilled. Ignoring.', order_number)
            raise Ignore()
        else:
            # Unknown client error. Let's retry to resolve it.
            logger.warning(
                'Fulfillment of order [%s] failed because of HttpClientError. Retrying',
                order_number,
                exc_info=True
            )
            _retry_order(self, exc, max_fulfillment_retries, order_number)

    except (exceptions.HttpServerError, exceptions.Timeout, SSLError) as exc:
        # Fulfillment failed, retry
        _retry_order(self, exc, max_fulfillment_retries, order_number)


Instruction:
Write a Python 3 script to
return a Sailthru client for the specified site.

Response:
def get_sailthru_client(site_code):
    """
    Returns a Sailthru client for the specified site.

    Args:
        site_code (str): Site for which the client should be configured.

    Returns:
        SailthruClient

    Raises:
        SailthruNotEnabled: If Sailthru is not enabled for the specified site.
        ConfigurationError: If either the Sailthru API key or secret are not set for the site.
    """
    # Get configuration
    config = get_sailthru_configuration(site_code)

    # Return if Sailthru integration disabled
    if not config.get('SAILTHRU_ENABLE'):
        msg = 'Sailthru is not enabled for site {}'.format(site_code)
        log.debug(msg)
        raise SailthruNotEnabled(msg)

    # Make sure key and secret configured
    key = config.get('SAILTHRU_KEY')
    secret = config.get('SAILTHRU_SECRET')

    if not (key and secret):
        msg = 'Both key and secret are required for site {}'.format(site_code)
        log.error(msg)
        raise ConfigurationError(msg)

    return SailthruClient(key, secret)


Instruction:
Given the following Python 3 function, write the documentation
def get(self, key):
        lock.acquire()
        try:
            if key not in self:
                return None

            current_time = time.time()
            if self[key].expire > current_time:
                return self[key].value

            # expired key, clean out all expired keys
            deletes = []
            for k, val in self.items():
                if val.expire <= current_time:
                    deletes.append(k)
            for k in deletes:
                del self[k]

            return None
        finally:
            lock.release()

Response: Get an object from the cache with the given key.


Instruction:
Explain what the following Python 3 code does
def set(self, key, value, duration):
        lock.acquire()
        try:
            self[key] = CacheObject(value, duration)
        finally:
            lock.release()

Response: Save an object in the cache


Instruction:
Can you implement a function in Python 3 that
gets a value from the configuration module.

Response:
def get_configuration(variable, site_code=None):
    """
    Get a value from configuration.

    Retrieves the value corresponding to the given variable from the configuration module
    currently in use by the app.  Specify a site_code value to check for a site-specific override.

    Arguments:
        variable (str): The name of a variable from the configuration module.

    Keyword Arguments:
        site_code (str): The SITE_OVERRIDES key to inspect for site-specific values

    Returns:
        The value corresponding to the variable, or None if the variable is not found.
    """
    name = os.environ.get(CONFIGURATION_MODULE)

    # __import__ performs a full import, but only returns the top-level
    # package, not the targeted module. sys.modules is a dictionary
    # mapping module names to loaded modules.
    __import__(name)
    module = sys.modules[name]

    # Locate the setting in the specified module, then attempt to apply a site-specific override
    setting_value = getattr(module, variable, None)
    site_overrides = getattr(module, 'SITE_OVERRIDES', None)
    if site_overrides and site_code is not None:
        site_specific_overrides = site_overrides.get(site_code)
        if site_specific_overrides:
            override_value = site_specific_overrides.get(variable)
            if override_value:
                setting_value = override_value

    if setting_value is None:
        raise RuntimeError('Worker is improperly configured: {} is unset in {}.'.format(variable, module))
    return setting_value


Instruction:
Can you generate the documentation for the following Python 3 function
def get_ecommerce_client(url_postfix='', site_code=None):
    ecommerce_api_root = get_configuration('ECOMMERCE_API_ROOT', site_code=site_code)
    signing_key = get_configuration('JWT_SECRET_KEY', site_code=site_code)
    issuer = get_configuration('JWT_ISSUER', site_code=site_code)
    service_username = get_configuration('ECOMMERCE_SERVICE_USERNAME', site_code=site_code)
    return EdxRestApiClient(
        ecommerce_api_root + url_postfix, signing_key=signing_key, issuer=issuer, username=service_username)

Response: Get client for fetching data from ecommerce API.


Instruction:
Make a summary of the following Python 3 code
def get_overrides_filename(variable):
    filename = os.environ.get(variable)

    if filename is None:
        msg = 'Please set the {} environment variable.'.format(variable)
        raise EnvironmentError(msg)

    return filename

Response: Get the name of the file containing configuration overrides from the provided environment variable.


Instruction:
Write a Python 3 script to
get the output files layout for the specified output category

Response:
def get_output_files_layout(output_category):
    """
    Parameters
    ----------
    output_category: str
        inputs: epw, idf
        table: summary table
        other: other
    """
    # check  category
    if output_category not in ("inputs", "table", "other"):
        raise RuntimeError(f"unknown {output_category}")

    # get version dict
    layouts = _layouts_matrix[OS_NAME][output_category]

    # get version
    return get_value_by_version(layouts)


Instruction:
How would you implement a function in Python 3 that
finds the value depending in current eplus version.

Response:
def get_value_by_version(d):
    """
    Finds the value depending in current eplus version.

    Parameters
    ----------
    d: dict
        {(0, 0): value, (x, x): value, ...}
        for current version (cv), current value is the value of version v such as v <= cv < v+1
    """
    from oplus import CONF  # touchy import

    cv = CONF.eplus_version[:2]
    for v, value in sorted(d.items(), reverse=True):
        if cv >= v:
            return value


Instruction:
Write a Python 3 script to
switch the DataFrame to datetime instants.

Response:
def switch_to_datetime_instants(df, start_year, eplus_frequency):
    """
    works inplace
    """
    # timestep -> monthly
    if eplus_frequency in (TIMESTEP, DAILY, HOURLY, MONTHLY):
        # prepare year switch
        if eplus_frequency in (TIMESTEP, HOURLY, DAILY):
            # print((df[["month", "day"]] - df[["month", "day"]].shift()) == pd.Series([-12, -31]))
            year_counter = (
                    (df[["month", "day"]] - df[["month", "day"]].shift()) ==
                    pd.Series(dict(month=12, day=-31))
            ).all(axis=1).cumsum()
        else:
            year_counter = ((df["month"] - df["month"].shift()) == -12).cumsum()

        # add year columns
        df["year"] = year_counter + start_year

        # create index
        columns = {
            TIMESTEP: ("year", "month", "day", "hour", "minute"),
            HOURLY: ("year", "month", "day", "hour"),
            DAILY: ("year", "month", "day"),
            MONTHLY: ("year", "month")
        }[eplus_frequency]
        if eplus_frequency == MONTHLY:
            df.index = df.apply(  # apply transforms ints to floats, we need to re-cast
                lambda x: dt.datetime(*(tuple(int(x[k]) for k in columns) + (1,))),
                axis=1
            )
        else:
            df.index = df.apply(lambda x: dt.datetime(*(int(x[k]) for k in columns)), axis=1)

        # drop old columns
        df.drop(columns=list(columns), inplace=True)

        # force frequency
        if eplus_frequency == TIMESTEP:
            # find freq
            ts = df.index[1] - df.index[0]
            # force
            forced_df = df.asfreq(ts)
        else:
            forced_df = df.asfreq({
                HOURLY: "H",
                DAILY: "D",
                MONTHLY: "MS"
            }[eplus_frequency])

        # if timestep, hourly or daily, check did not change (only those can suffer from leap year problems)
        if eplus_frequency in (TIMESTEP, HOURLY, DAILY):
            try:
                assert_index_equal(df.index, forced_df.index)
            except AssertionError:
                raise ValueError(
                    f"Couldn't convert to datetime instants (frequency: {eplus_frequency}). Probable cause : "
                    f"given start year ({start_year}) is incorrect and data can't match because of leap year issues."
                ) from None

        return forced_df

    # annual
    if eplus_frequency == ANNUAL:
        # check first year
        if df["year"].iloc[0] != start_year:
            raise ValueError(
                f"Given start year ({start_year}) differs from annual output data first year ({df['year'].iloc[0]}),"
                f"can't switch to datetime instants.")
        df.index = df["year"].map(lambda x: dt.datetime(x, 1, 1))
        del df["year"]

        # force freq
        df = df.asfreq("YS")

        return df

    # run period
    if eplus_frequency == RUN_PERIOD:
        return df

    raise AssertionError("should not be here")


Instruction:
Implement a function in Python 3 to
return the most recent eplus available version of the oplus package.

Response:
def eplus_version(self):
        """
        if _eplus_version is defined => _eplus_version
        else most recent eplus available version
        """
        # check energy plus is installed
        if len(self.eplus_available_versions) == 0:
            raise RuntimeError("Energy plus is not install, can't use oplus package.")

        # see if version is defined
        if self._eplus_version is not None:
            return self._eplus_version

        # return most recent version
        return sorted(self.eplus_available_versions.keys(), reverse=True)[0]


Instruction:
Can you implement a function in Python 3 that
checks that the data is hourly datetime instants and if so sanitize the date and time variables.

Response:
def _check_and_sanitize_datetime_instants(df):
    """
    Parameters
    ----------
    df

    Returns
    -------
    sanitized df
    """
    # leave if not relevant
    if df is None or len(df) == 0:
        return df

    # check datetime index
    if not isinstance(df.index, pd.DatetimeIndex):
        raise ValueError("df index must be a datetime index.")

    # force frequency if needed
    if df.index.freq != "H":
        forced_df = df.asfreq("H")
        # check no change
        try:
            assert_index_equal(df.index, forced_df.index)
        except AssertionError:
            raise ValueError(
                f"Couldn't convert to hourly datetime instants. Probable cause : "
                f"given start instant ({df.index[0]}) is incorrect and data can't match because of leap year issues."
            ) from None
        # replace old variable
        df = forced_df

    # check first minute is 0
    if df.index[0].minute != 0:
        raise ValueError("Minutes must be 0.")

    return df


Instruction:
Write a Python 3 function that can
return start and end of the calendar for the current weather set.

Response:
def get_bounds(self):
        """
        Returns
        -------
        (start, end)

        Datetime instants of beginning and end of data. If no data, will be: (None, None).
        """
        start, end = None, None
        if len(self._weather_series) == 0:
            return start, end

        for i in (0, -1):
            # create or find instant
            if self.has_tuple_instants:
                row = self._weather_series.iloc[i, :]
                instant = dt.datetime(row["year"], row["month"], row["day"], row["hour"], row["minute"])
            else:
                instant = self._weather_series.index[i].to_pydatetime()

            # store
            if i == 0:
                start = instant
            else:
                end = instant

        return start, end


Instruction:
Write a Python 3 function for
returning a WeatherData instance from an epw file.

Response:
def from_epw(cls, buffer_or_path):
        """
        Parameters
        ----------
        buffer_or_path: buffer or path containing epw format.

        Returns
        -------
        WeatherData instance.
        """
        from .epw_parse import parse_epw
        _, buffer = to_buffer(buffer_or_path)
        with buffer as f:
            return parse_epw(f)


Instruction:
Make a summary of the following Python 3 code
def to_epw(self, buffer_or_path=None):
        # copy and change hours convention [0, 23] -> [1, 24]
        df = self._weather_series.copy()
        df["hour"] += 1
        epw_content = self._headers_to_epw() + df.to_csv(header=False, index=False, line_terminator="\n")
        return multi_mode_write(
            lambda buffer: buffer.write(epw_content),
            lambda: epw_content,
            buffer_or_path=buffer_or_path
        )

Response: Returns a string containing the epw info of the current state of the entry.


Instruction:
Given the following Python 3 function, write the documentation
def parse_idf(file_like):
    tables_data = {}
    head_comment = ""
    record_data = None
    make_new_record = True

    copyright_list = get_multi_line_copyright_message().split("\n")

    for i, raw_line in enumerate(file_like):
        # manage if copyright
        try:
            copyright_line = copyright_list[i]
            if raw_line.strip() == copyright_line:
                # skip copyright line
                continue
        except IndexError:
            pass

        # GET LINE CONTENT AND COMMENT
        split_line = raw_line.split("!")

        # no "!" in the raw_line
        if len(split_line) == 1:
            # this is an empty line
            if len(split_line[0].strip()) == 0:
                content, comment = None, None
            # this is a record line with no comments
            else:
                content, comment = split_line[0].strip(), None
        # there is at least one "!" in the raw_line
        else:
            # this is a comment line
            if len(split_line[0].strip()) == 0:
                content, comment = None, "!".join(split_line[1:])
            # this is a record line with a comment
            else:
                content, comment = split_line[0].strip(), "!".join(split_line[1:])

        # SKIP CURRENT LINE IF VOID
        if (content, comment) == (None, None):
            continue

        # NO CONTENT
        if not content:
            if record_data is None:  # we only manage head idf comment
                head_comment += comment.strip() + "\n"
            continue

        # CONTENT
        # check if record end and prepare
        record_end = content[-1] == ";"
        content = content[:-1]  # we tear comma or semi-colon
        content_l = [text.strip() for text in content.split(",")]

        # record creation if needed
        if make_new_record:
            # get table ref
            table_ref = table_name_to_ref(content_l[0].strip())

            # skip if special table
            if table_ref.lower() in (
                    "lead input",
                    "end lead input",
                    "simulation data",
                    "end simulation data"
            ):
                continue

            # declare table if necessary
            if table_ref not in tables_data:
                tables_data[table_ref] = []

            # create and store record
            record_data = dict()
            tables_data[table_ref].append(record_data)

            # prepare in case fields on the same line
            content_l = content_l[1:]
            make_new_record = False

        # fields
        for value_s in content_l:
            field_index = len(record_data)
            record_data[field_index] = value_s

        # signal that new record must be created
        if record_end:
            make_new_record = True

    # add comment key
    tables_data["_comment"] = head_comment
    return tables_data

Response: Parse the idf file and return a dictionary of the idf and the record data.


Instruction:
Write a Python 3 script to
run EPlus on the given path.

Response:
def run_eplus(epm_or_idf_path, weather_data_or_epw_path, simulation_dir_path, stdout=None, stderr=None, beat_freq=None):
    """
    Parameters
    ----------
    epm_or_idf_path:
    weather_data_or_epw_path
    simulation_dir_path
    stdout: default sys.stdout
    stderr: default sys.stderr
    beat_freq: if not none, stdout will be used at least every beat_freq (in seconds)
    """
    # work with absolute paths
    simulation_dir_path = os.path.abspath(simulation_dir_path)

    # check dir path
    if not os.path.isdir(simulation_dir_path):
        raise NotADirectoryError("Simulation directory does not exist: '%s'." % simulation_dir_path)

    # epm
    if not isinstance(epm_or_idf_path, Epm):
        # we don't copy file directly because we want to manage it's external files
        # could be optimized (use _copy_without_read_only)
        epm = Epm.from_idf(epm_or_idf_path)
    else:
        epm = epm_or_idf_path

    # create idf
    simulation_idf_path = os.path.join(simulation_dir_path, CONF.default_model_name + ".idf")
    epm.to_idf(simulation_idf_path)

    # weather data
    simulation_epw_path = os.path.join(simulation_dir_path, CONF.default_model_name + ".epw")
    if isinstance(weather_data_or_epw_path, WeatherData):
        weather_data_or_epw_path.to_epw(simulation_epw_path)
    else:
        # no need to load: we copy directly
        _copy_without_read_only(weather_data_or_epw_path, simulation_epw_path)

    # copy epw if needed (depends on os/eplus version)
    temp_epw_path = get_simulated_epw_path()
    if temp_epw_path is not None:
        _copy_without_read_only(simulation_epw_path, temp_epw_path)

    # prepare command
    eplus_relative_cmd = get_simulation_base_command()
    eplus_cmd = os.path.join(CONF.eplus_base_dir_path, eplus_relative_cmd)

    # idf
    idf_command_style = get_simulation_input_command_style("idf")
    if idf_command_style == SIMULATION_INPUT_COMMAND_STYLES.simu_dir:
        idf_file_cmd = os.path.join(simulation_dir_path, CONF.default_model_name)
    elif idf_command_style == SIMULATION_INPUT_COMMAND_STYLES.file_path:
        idf_file_cmd = simulation_idf_path
    else:
        raise AssertionError("should not be here")

    # epw
    epw_command_style = get_simulation_input_command_style("epw")
    if epw_command_style == SIMULATION_INPUT_COMMAND_STYLES.simu_dir:
        epw_file_cmd = os.path.join(simulation_dir_path, CONF.default_model_name)
    elif epw_command_style == SIMULATION_INPUT_COMMAND_STYLES.file_path:
        epw_file_cmd = simulation_epw_path
    else:
        raise AssertionError("should not be here")

    # command list
    simulation_command_style = get_simulation_command_style()
    if simulation_command_style == SIMULATION_COMMAND_STYLES.args:
        cmd_l = [eplus_cmd, idf_file_cmd, epw_file_cmd]
    elif simulation_command_style == SIMULATION_COMMAND_STYLES.kwargs:
        cmd_l = [eplus_cmd, "-w", epw_file_cmd, "-r", idf_file_cmd]
    else:
        raise RuntimeError("should not be here")

    # launch calculation
    run_subprocess(
        cmd_l,
        cwd=simulation_dir_path,
        stdout=stdout,
        stderr=stderr,
        beat_freq=beat_freq
    )

    # if needed, we delete temp weather data (only on Windows, see above)
    if (temp_epw_path is not None) and os.path.isfile(temp_epw_path):
        os.remove(os.path.join(temp_epw_path))


Instruction:
Can you write a function in Python 3 where it
creates a new simulation object for the given epm or path.

Response:
def simulate(
            cls,
            epm_or_path,
            weather_data_or_path,
            base_dir_path,
            simulation_name=None,
            stdout=None,
            stderr=None,
            beat_freq=None
    ):
        """
        Parameters
        ----------
        epm_or_path
        weather_data_or_path
        base_dir_path: simulation dir path
        simulation_name: str, default None
            if provided, simulation will be done in {base_dir_path}/{simulation_name}
            else, simulation will be done in {base_dir_path}
        stdout: stream, default logger.info
            stream where EnergyPlus standard output is redirected
        stderr: stream, default logger.error
            stream where EnergyPlus standard error is redirected
        beat_freq: float, default None
            if provided, subprocess in which EnergyPlus is run will write at given frequency in standard output. May
            be used to monitor subprocess state.

        Returns
        -------
        Simulation instance
        """
        # manage simulation dir path
        if not os.path.isdir(base_dir_path):
            raise NotADirectoryError("Base dir path not found: '%s'" % base_dir_path)
        simulation_dir_path = base_dir_path if simulation_name is None else os.path.join(base_dir_path, simulation_name)

        # make directory if does not exist
        if not os.path.exists(simulation_dir_path):
            os.mkdir(simulation_dir_path)

        # run simulation
        stdout = LoggerStreamWriter(logger_name=__name__, level=logging.INFO) if stdout is None else stdout
        stderr = LoggerStreamWriter(logger_name=__name__, level=logging.ERROR) if stderr is None else stderr
        run_eplus(
            epm_or_path,
            weather_data_or_path,
            simulation_dir_path,
            stdout=stdout,
            stderr=stderr,
            beat_freq=beat_freq
        )

        # return simulation object
        return cls(
            base_dir_path,
            simulation_name=simulation_name
        )


Instruction:
Can you tell what is the following Python 3 function doing
def _file_refs(self):
        if self._prepared_file_refs is None:
            self._prepared_file_refs = {
                FILE_REFS.idf: FileInfo(
                    constructor=lambda path: self._epm_cls.from_idf(path, idd_or_buffer_or_path=self._idd),
                    get_path=lambda: get_input_file_path(self.dir_path, FILE_REFS.idf)
                ),
                FILE_REFS.epw: FileInfo(
                    constructor=lambda path: self._weather_data_cls.from_epw(path),
                    get_path=lambda: get_input_file_path(self.dir_path, FILE_REFS.epw)
                ),
                FILE_REFS.eio: FileInfo(
                    constructor=lambda path: self._eio_cls(path),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.eio)
                ),
                FILE_REFS.eso: FileInfo(
                    constructor=lambda path: self._standard_output_cls(path),
                    get_path=lambda: get_output_file_path(
                        self.dir_path,
                        FILE_REFS.eso
                    )
                ),
                FILE_REFS.mtr: FileInfo(
                    constructor=lambda path: self._standard_output_cls(path),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mtr)
                ),
                FILE_REFS.mtd: FileInfo(
                    constructor=lambda path: self._mtd_cls(path),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mtd)
                ),
                FILE_REFS.mdd: FileInfo(
                    constructor=lambda path: open(path).read(),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mdd)

                ),
                FILE_REFS.err: FileInfo(
                    constructor=lambda path: self._err_cls(path),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.err)
                ),
                FILE_REFS.summary_table: FileInfo(
                    constructor=lambda path: self._summary_table_cls(path),
                    get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.summary_table)
                )
            }
        return self._prepared_file_refs

Response: Defines the file references that are used by the file system.


Instruction:
Here you have a function in Python 3, explain what it does
def exists(self, file_ref):
        if file_ref not in FILE_REFS:
            raise ValueError("Unknown file_ref: '%s'. Available: '%s'." % (file_ref, list(sorted(FILE_REFS._fields))))
        return os.path.isfile(self._path(file_ref))

Response: Returns True if the file with the given file_ref exists in the local cache.


Instruction:
Can you tell what is the following Python 3 function doing
def get_file_path(self, file_ref):
        if not self.exists(file_ref):
            raise FileNotFoundError("File '%s' not found in simulation '%s'." % (file_ref, self._path(file_ref)))
        return self._path(file_ref)

Response: Returns the path of the file in the simulation.


Instruction:
Given the following Python 3 function, write the documentation
def default_external_files_dir_name(model_name):
    name, ext = os.path.splitext(model_name)
    return name + CONF.external_files_suffix

Response: Returns the default external files directory name for a given model name.


Instruction:
Can you write a function in Python 3 where it
populates the internal state of the object with the data from the JSON data.

Response:
def _dev_populate_from_json_data(self, json_data):
        """
        !! Must only be called once, when empty !!
        """

        # workflow
        # --------
        # (methods belonging to create/update/delete framework:
        #     epm._dev_populate_from_json_data, table.batch_add, record.update, queryset.delete, record.delete)
        # 1. add inert
        #     * data is checked
        #     * old links are unregistered
        #     * record is stored in table (=> pk uniqueness is checked)
        # 2. activate: hooks, links, external files

        # manage comment if any
        comment = json_data.pop("_comment", None)
        if comment is not None:
            self._comment = comment

        # populate external files
        external_files_data = json_data.pop("_external_files", dict())
        self._dev_external_files_manager.populate_from_json_data(external_files_data)

        # manage records
        added_records = []
        for table_ref, json_data_records in json_data.items():
            # find table
            table = getattr(self, table_ref)

            # create record (inert)
            records = table._dev_add_inert(json_data_records)

            # add records (inert)
            added_records.extend(records)

        # activate hooks
        for r in added_records:
            r._dev_activate_hooks()

        # activate links and external files
        for r in added_records:
            r._dev_activate_links()
            r._dev_activate_external_files()


Instruction:
Explain what the following Python 3 code does
def get_external_files(self):
        external_files = []
        for table in self._tables.values():
            for r in table:
                external_files.extend([ef for ef in r.get_external_files()])
        return external_files

Response: Returns a list of all external files in the database.


Instruction:
Explain what the following Python 3 code does
def set_defaults(self):
        for table in self._tables.values():
            for r in table:
                r.set_defaults()

Response: Set the default values of all tables and entries in this EPM.


Instruction:
Explain what the following Python 3 code does
def from_json_data(cls, json_data, check_required=True, idd_or_buffer_or_path=None):
        epm = cls(
            idd_or_buffer_or_path=idd_or_buffer_or_path,
            check_required=check_required
        )

        epm._dev_populate_from_json_data(json_data)
        return epm

Response: Create an Epm instance from a dictionary of serialized data.


Instruction:
Write a Python 3 script for
creating an Epm instance from an IDF file.

Response:
def from_idf(cls, buffer_or_path, check_required=True, idd_or_buffer_or_path=None):
        """
        Parameters
        ----------
        buffer_or_path: idf buffer or path
        check_required: boolean, default True
            If True, will raise an exception if a required field is missing. If False, not not perform any checks.
        idd_or_buffer_or_path: (expert) to load using a custom idd

        Returns
        -------
        An Epm instance.
        """
        # todo: add geometry only (or equivalent)
        return cls._create_from_buffer_or_path(
            parse_idf,
            buffer_or_path,
            idd_or_buffer_or_path=idd_or_buffer_or_path,
            check_required=check_required
        )


Instruction:
Can you generate the documentation for the following Python 3 function
def from_json(cls, buffer_or_path, check_required=True, idd_or_buffer_or_path=None):
        return cls._create_from_buffer_or_path(
            json.load,
            buffer_or_path,
            idd_or_buffer_or_path=idd_or_buffer_or_path,
            check_required=check_required
        )

Response: Create an Epm instance from a json buffer or path.


Instruction:
Given the following Python 3 function, write the documentation
def to_json_data(self):
        # create data
        d = collections.OrderedDict((t.get_ref(), t.to_json_data()) for t in self._tables.values())
        d["_comment"] = self._comment
        d.move_to_end("_comment", last=False)
        d["_external_files"] = self._dev_external_files_manager
        return d

Response: Returns a dictionary of serialized data.


Instruction:
Write a Python 3 function for
returning a json string of the current object.

Response:
def to_json(self, buffer_or_path=None, indent=2):
        """
        Parameters
        ----------
        buffer_or_path: buffer or path, default None
            output to write into. If None, will return a json string.
        indent: int, default 2
            Defines the indentation of the json

        Returns
        -------
        None, or a json string (if buffer_or_path is None).
        """
        # return json
        return json_data_to_json(
            self.to_json_data(),
            buffer_or_path=buffer_or_path,
            indent=indent
        )


Instruction:
Write a Python 3 script for
returning a idf string of the current state of the object.

Response:
def to_idf(self, buffer_or_path=None, dump_external_files=True):
        """
        Parameters
        ----------
        buffer_or_path: buffer or path, default None
            output to write into. If None, will return a json string.
        dump_external_files: boolean, default True
            if True, external files will be dumped in external files directory

        Returns
        -------
        None, or an idf string (if buffer_or_path is None).
        """
        # prepare comment
        comment = get_multi_line_copyright_message()
        if self._comment != "":
            comment += textwrap.indent(self._comment, "! ", lambda line: True)
        comment += "\n\n"

        # prepare external files dir path if file path
        if isinstance(buffer_or_path, str):
            dir_path, file_name = os.path.split(buffer_or_path)
            model_name, _ = os.path.splitext(file_name)
        else:
            model_name, dir_path = None, os.path.curdir

        # dump files if asked
        if dump_external_files:
            self.dump_external_files(
                target_dir_path=os.path.join(dir_path, get_external_files_dir_name(model_name=model_name))
            )

        # prepare body
        formatted_records = []
        for table_ref, table in self._tables.items():  # self._tables is already sorted
            formatted_records.extend([r.to_idf(model_name=model_name) for r in sorted(table)])
        body = "\n\n".join(formatted_records)

        # return
        content = comment + body
        return multi_mode_write(
            lambda f: f.write(content),
            lambda: content,
            buffer_or_path
        )


Instruction:
Here you have a function in Python 3, explain what it does
def select(self, filter_by=None):
        iterator = self._records if filter_by is None else filter(filter_by, self._records)
        return Queryset(self._table, iterator)

Response: Returns a new Queryset containing only the records that match the filter_by.


Instruction:
Can you generate the documentation for the following Python 3 function
def one(self, filter_by=None):
        # filter if needed
        qs = self if filter_by is None else self.select(filter_by=filter_by)

        # check one and only one
        if len(qs) == 0:
            raise RecordDoesNotExistError("Queryset set contains no value.")
        if len(qs) > 1:
            raise MultipleRecordsReturnedError("Queryset contains more than one value.")

        # return record
        return qs[0]

Response: Returns a single record from the queryset.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_simulated_epw_path():
    from oplus import CONF  # touchy imports

    if OS_NAME == "windows":
        return os.path.join(CONF.eplus_base_dir_path, "WeatherData", "%s.epw" % CONF.default_model_name)

Response: Returns the path to the epw file that should be used for simulation.


Instruction:
Given the following Python 3 function, write the documentation
def prepare_extensible(self):
        # see if extensible and store cycle len
        for k in self._tags:
            if "extensible" in k:
                cycle_len = int(k.split(":")[1])
                break
        else:
            # not extensible
            return

        # find cycle start and prepare patterns
        cycle_start = None
        cycle_patterns = []
        for i, field_descriptor in enumerate(self._field_descriptors):
            # quit if finished
            if (cycle_start is not None) and (i >= (cycle_start + cycle_len)):
                break

            # set cycle start if not set yet
            if (cycle_start is None) and ("begin-extensible" in field_descriptor.tags):
                cycle_start = i

            # leave if cycle start not reached yet
            if cycle_start is None:
                continue

            # store pattern
            cycle_patterns.append(field_descriptor.ref.replace("1", r"(\d+)"))
        else:
            raise RuntimeError("cycle start not found")

        # detach unnecessary field descriptors
        self._field_descriptors = self._field_descriptors[:cycle_start + cycle_len]

        # store cycle info
        self.extensible_info = (cycle_start, cycle_len, tuple(cycle_patterns))

        # set field descriptor cycle_start index (for error messages while serialization)
        for i, fd in enumerate(self._field_descriptors[cycle_start:]):
            fd.set_extensible_info(cycle_start, cycle_len, cycle_patterns[i])

Response: This function is called when all the fields in the archive are marked as extensible.


Instruction:
Write a Python 3 function for
getting the reduced index of the base field that has been applied to the extensible entry

Response:
def get_field_reduced_index(self, index):
        """
        reduced index: modulo of extensible has been applied
        """
        # return index if not extensible
        if self.extensible_info is None:
            return index

        # manage extensible
        cycle_start, cycle_len, _ = self.extensible_info

        # base field
        if index < cycle_start:
            return index

        # extensible field
        return cycle_start + ((index - cycle_start) % cycle_len)


Instruction:
Can you tell what is the following Python 3 function doing
def get_extended_name(self, index):
        field_descriptor = self.get_field_descriptor(index)
        if self.extensible_info is None:
            return field_descriptor.name
        cycle_start, cycle_len, _ = self.extensible_info
        cycle_num = (index - cycle_start) // cycle_len
        return None if field_descriptor.name is None else field_descriptor.name.replace("1", str(cycle_num))

Response: Gets the extended name of the entry at the given index.


Instruction:
How would you explain what the following Python 3 function does
def deserialize(self, value, index):
        # -- serialize if not raw type
        # transform to string if external file
        if isinstance(value, ExternalFile):
            value = value.pointer

        # transform to string if record
        if isinstance(value, Record):
            try:
                value = value[0]
            except IndexError:
                raise ValueError("can't set given record because it does not have a name field")

        # -- prepare if string
        if isinstance(value, str):
            # change multiple spaces to mono spaces
            value = re.sub(spaces_and_newlines_pattern, lambda x: " ", value.strip())

            # see if still not empty
            if value == "":
                return None

            # make ASCII compatible
            value = unidecode.unidecode(value)

            # make lower case if not retaincase
            if "retaincase" not in self.tags:
                value = value.lower()

            # check not too big
            if len(value) >= 100:
                raise FieldValidationError(
                    f"Field has more than 100 characters which is the limit. "
                    f"{self.get_error_location_message(value, index=index)}"
                )

        # transform to external file if relevant
        if self.is_file_name:
            value = ExternalFile.deserialize(value)

        # -- deserialize

        # numeric types
        if self.detailed_type in ("integer", "real"):
            # manage none
            if value is None:
                return None

            # special values: auto-calculate, auto-size, use-weather-file
            if value in ("autocalculate", "autosize", "useweatherfile"):
                return value

            if self.detailed_type == "integer":
                try:
                    return int(value)
                except:
                    raise FieldValidationError(
                        f"Couldn't parse to integer. {self.get_error_location_message(value, index=index)}"
                    )

            try:
                return float(value)
            except:
                raise FieldValidationError(
                    f"Couldn't parse to float. {self.get_error_location_message(value, index=index)}"
                )

        # simple string types
        if self.detailed_type in ("alpha", "choice", "node", "external-list"):
            # manage none
            if value is None:
                return None

            # ensure it was str
            if not isinstance_str(value):
                raise FieldValidationError(
                    f"Value must be a string. {self.get_error_location_message(value, index=index)}"
                )
            return value

        # manage hooks (eplus reference)
        if self.detailed_type == "reference":
            # manage None
            if value is None:
                return NONE_RECORD_HOOK

            # reference class name appears in v9.0.1
            references = self.tags.get("reference", [])
            # table_name, index, value, references, class_references
            return RecordHook(references, index, value)

        # manage links (eplus object-list)
        if self.detailed_type == "object-list":
            # manage None
            if value is None:
                return NONE_LINK

            return Link(self.tags["object-list"], value, index)

        raise RuntimeError("should not be here")

Response: Deserialize a value into a value that can be used to store the error message in the database.


Instruction:
How would you implement a function in Python 3 that
returns the detailed type of the resource.

Response:
def detailed_type(self):
        """
        Uses EPlus double approach of type ('type' tag, and/or 'key', 'object-list', 'external-list', 'reference' tags)
        to determine detailed type.

        Returns
        -------
        "integer", "real", "alpha", "choice", "reference", "object-list", "external-list", "node"
        """
        if self._detailed_type is None:
            if ("reference" in self.tags) or ("reference-class-name" in self.tags):
                self._detailed_type = "reference"
            elif "type" in self.tags:
                self._detailed_type = self.tags["type"][0].lower()  # idd is not very rigorous on case
            elif "key" in self.tags:
                self._detailed_type = "choice"
            elif "object-list" in self.tags:
                self._detailed_type = "object-list"
            elif "external-list" in self.tags:
                self._detailed_type = "external-list"
            elif self.basic_type == "A":
                self._detailed_type = "alpha"
            elif self.basic_type == "N":
                self._detailed_type = "real"
            else:
                raise ValueError("Can't find detailed type.")
        return self._detailed_type


Instruction:
Given the following Python 3 function, write the documentation
def short_refs(self):
        naive_short_refs_d = dict()  # naive_short_ref: {refs, ...}
        for ef in self._external_files:
            if ef.naive_short_ref not in naive_short_refs_d:
                naive_short_refs_d[ef.naive_short_ref] = set()
            naive_short_refs_d[ef.naive_short_ref].add(ef.ref)

        short_refs = dict()
        for naive_short_ref, refs in naive_short_refs_d.items():
            if len(refs) == 1:
                short_refs[refs.pop()] = naive_short_ref
                continue
            base, ext = os.path.splitext(naive_short_ref)
            for i, ref in enumerate(sorted(refs)):
                short_refs[ref] = f"{base}-{i}.{ext}"

        return short_refs

Response: Returns a dictionary of all the short_refs of the external files that are not in the registry.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_value(self, column_name_or_i, filter_column_name_or_i, filter_criterion):
        # find column indexes
        column_i = self._get_column_index(column_name_or_i)
        filter_column_i = self._get_column_index(filter_column_name_or_i)

        filter_fct = {
            float: lambda x: float(x) == filter_criterion,
            int: lambda x: int(x) == filter_criterion,
            str: lambda x: x.lower() == filter_criterion.lower()
        }[type(filter_criterion)]

        for row_i, row in enumerate(self._data):
            if filter_fct(row[filter_column_i]):
                break
        else:
            raise ValueError("Filter did not return any values.")

        return self._data[row_i][column_i]

Response: Returns the value of the specified column matching the given filter criterion.


Instruction:
Make a summary of the following Python 3 code
def _update_value_inert(self, index, value):
        # get field descriptor
        field_descriptor = self._table._dev_descriptor.get_field_descriptor(index)

        # prepare value
        value = field_descriptor.deserialize(value, index)

        # unregister previous link if relevant
        if isinstance(value, Link):
            # de-activate current link if any
            current_link = self._data.get(index)
            if current_link is not None:
                current_link.unregister()

        # unregister previous hook if relevant
        if isinstance(value, RecordHook):
            current_record_hook = self._data.get(index)
            if current_record_hook is not None:
                current_record_hook.unregister()

        # unregister previous external file if relevant
        if isinstance(value, ExternalFile):
            current_external_file = self._data.get(index)
            if current_external_file is not None:
                current_external_file._dev_unregister()

        # if None remove and leave
        if value in (None, NONE_RECORD_HOOK, NONE_LINK, NONE_EXTERNAL_FILE):
            # we don't check required, because this method is called by _update_inert which does the job
            self._dev_set_none_without_unregistering(index, check_not_required=False)
            return

        # if relevant, store current pk to signal table
        old_hook = None
        if index == 0 and not self._table._dev_auto_pk:
            old_hook = self._data.get(0)  # we use get, because record may not have a pk yet if it is being created

        # set value
        self._data[index] = value

        # signal pk update if relevant
        if old_hook is not None:
            self._table._dev_record_pk_was_updated(old_hook.target_value)

Response: Update the value of the relevant record entry in the internal list.


Instruction:
Given the following Python 3 function, write the documentation
def get_serialized_value(self, ref_or_index, model_name=None):
        index = (
            self._table._dev_descriptor.get_field_index(ref_or_index) if isinstance(ref_or_index, str)
            else ref_or_index
        )

        # get value
        value = self._data.get(index)

        # serialize
        value = value.serialize() if isinstance(value, (Link, RecordHook)) else value

        # manage file names
        if isinstance(value, ExternalFile):
            value = os.path.join(get_external_files_dir_name(model_name=model_name), value.naive_short_ref)

        return value

Response: Get the serialized value of the current entry.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_external_files(self):
        return [v for v in self._data.values() if isinstance(v, ExternalFile)]

Response: Returns ------- list of ExternalFiles instances contained by record.


Instruction:
Can you generate the documentation for the following Python 3 function
def update(self, data=None, **or_data):

        # workflow
        # --------
        # (methods belonging to create/update/delete framework:
        #     epm._dev_populate_from_json_data, table.batch_add, record.update, queryset.delete, record.delete)
        # 1. add inert
        #     * data is checked
        #     * old links are unregistered
        #     * record is stored in table (=> pk uniqueness is checked)
        # 2. activate: hooks, links, external files

        data = or_data if data is None else data

        self._update_inert(data)

        self._dev_activate_hooks()
        self._dev_activate_links()
        self._dev_activate_external_files()

Response: Update the record with the given data.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def copy(self, new_name=None):
        # todo: check this really works, !! must not use same link, hook, external_file, ... for different records !!
        # auto pk tables can just be copied
        if self._table._dev_auto_pk:
            return self._table.add(self._data)

        # for ref pk tables, must manage name
        name = str(uuid.uuid4()) if new_name is None else new_name
        new_data = dict((k, name if k == 0 else v) for (k, v) in self._data.items())
        return self._table.add(new_data)

Response: Copy the current record to another record.


Instruction:
Given the following Python 3 function, write the documentation
def set_defaults(self):
        defaults = {}
        for i in range(len(self)):
            if i in self._data:
                continue
            default = self.get_field_descriptor(i).tags.get("default", [None])[0]
            if default is not None:
                defaults[i] = default

        self.update(defaults)

Response: Sets all empty fields for which a default value is defined to default value


Instruction:
Make a summary of the following Python 3 code
def add_fields(self, *args):
        if not self.is_extensible():
            raise TypeError("Can't use add_fields on a non extensible record.")

        # prepare update data
        self_len = len(self)
        data = dict([(self_len + i, args[i]) for i in range(len(args))])

        # update
        self.update(data)

Response: Adds fields to the record.


Instruction:
Write a Python 3 function that can
insert a value into the index of the current record set.

Response:
def insert(self, index, value):
        """
        This method only works for extensible fields. It allows to insert a value, and shifts all other following
        values.

        Parameters
        ----------
        index: position of insertion
        value: value to insert
        """
        # prepare index (will check for extensible)
        index = self._prepare_pop_insert_index(index=index)

        # remove extensible fields
        fields = self.clear_extensible_fields()

        # insert
        fields.insert(index, value)

        # add new list
        self.add_fields(*fields)


Instruction:
Explain what the following Python 3 code does
def clear_extensible_fields(self):
        if not self.is_extensible():
            raise TypeError("Can't use add_fields on a non extensible record.")
        cycle_start, cycle_len, patterns = self.get_extensible_info()
        return [self.get_serialized_value(i) for i in range(cycle_start, len(self))]

Response: Returns a list of cleared fields from the record that are not extensible.


Instruction:
Can you tell what is the following Python 3 function doing
def delete(self):
        # workflow
        # --------
        # (methods belonging to create/update/delete framework:
        #     epm._dev_populate_from_json_data, table.batch_add, record.update, queryset.delete, record.delete)
        # 1. unregister: links, hooks and external files
        # 3. remove from table without unregistering

        # unregister links
        self._unregister_links()

        # unregister hooks
        self._unregister_hooks()

        # unregister external files
        self._unregister_external_files()

        # tell table to remove without unregistering
        self.get_table()._dev_remove_record_without_unregistering(self)

        # make stale
        self._table = None
        self._data = None

Response: Deletes record and removes it from database.


Instruction:
Write a Python 3 script for
returning the field descriptor of the current object.

Response:
def get_field_descriptor(self, ref_or_index):
        """
        Parameters
        ----------
        ref_or_index: str or int
            field lowercase name, or field position

        Returns
        -------
        Field descriptor (info contained in Idd)
        """
        if isinstance(ref_or_index, int):
            index = ref_or_index
        else:
            index = self._table._dev_descriptor.get_field_index(ref_or_index)
        return self._table._dev_descriptor.get_field_descriptor(index)


Instruction:
Implement a Python 3 function for
returning a dictionary of serialized data.

Response:
def to_json_data(self, model_name=None):
        """
        Parameters
        ----------
        model_name: str, default None
            if given, will be used as external file directory base name

        Returns
        -------
        A dictionary of serialized data.
        """
        return collections.OrderedDict([(k, self.get_serialized_value(k, model_name=model_name )) for k in self._data])


Instruction:
How would you implement a function in Python 3 that
returns the string representation of the idd record as an idd record.

Response:
def to_idf(self, model_name=None):
        """
        Parameters
        ----------
         model_name: str, default None
            if given, will be used as external file directory base name

        Returns
        -------
        idf string
        """

        json_data = self.to_json_data(model_name=model_name)

        # record descriptor ref
        s = f"{self._table._dev_descriptor.table_name},\n"

        # fields
        # fields_nb: we don't use len(self) but max(self). We wan't to stop if no more values (even base fields)
        #   because some idd records are defined without extensibles (although they should used them), for example
        #   construction, and eplus does not know what to do...
        fields_nb = max(self._data)+1
        for i in range(fields_nb):
            # value
            tab = " " * TAB_LEN
            raw_value = json_data.get(i, "")
            content = f"{tab}{raw_value}{';' if i == fields_nb-1 else ','}"

            # comment
            spaces_nb = COMMENT_COLUMN_START - len(content)
            if spaces_nb < 0:
                spaces_nb = TAB_LEN

            # comment
            name = self._table._dev_descriptor.get_extended_name(i)
            comment = "" if name is None else " " * spaces_nb + f"! {name}"

            # store
            s += f"{content}{comment}\n"

        return s


Instruction:
Write a Python 3 function that can
check if there are too many examples in the current order.

Response:
def check():
    """
    Tested under EPlus 8.1.0 on Windows (Geoffroy).
    """
    # !! CAN BE VERY LONG
    epw_path = os.path.join(CONF.eplus_base_dir_path, "WeatherData",
                            "USA_VA_Sterling-Washington.Dulles.Intl.AP.724030_TMY3.epw")
    idf_dir_path = os.path.join(CONF.eplus_base_dir_path, "ExampleFiles")
    test_num = 0
    for file_num, file_name in enumerate(os.listdir(idf_dir_path)):
        if file_num < START_FILE_NUM:
            continue
        base, ext = os.path.splitext(file_name)
        if ext == ".idf":
            with tempfile.TemporaryDirectory() as simulation_dir_path:
                s = simulate(os.path.join(idf_dir_path, file_name), epw_path,
                             simulation_dir_path if DEBUG_SIMUL_DIR_PATH is None else
                             DEBUG_SIMUL_DIR_PATH)
                if s.exists("eio"):
                    eio = Eio(s.get_file_path("eio"))  # raise error if problem
                    test_num += 1
        if test_num == MAX_TESTS_NB:
            break


Instruction:
Implement a function in Python 3 to
get the dataframes for the given environment.

Response:
def get_data(self, environment_title_or_num=-1, frequency=None):
        """
        Parameters
        ----------
        environment_title_or_num
        frequency: 'str', default None
            'timestep', 'hourly', 'daily', 'monthly', 'annual', 'run_period'
            If None, will look for the smallest frequency of environment.
        """

        # manage environment num
        if isinstance(environment_title_or_num, int):
            environment_title = tuple(self._raw_environments.keys())[environment_title_or_num]
        else:
            environment_title = environment_title_or_num

        if environment_title not in self._dfs:
            raise ValueError(f"No environment named {environment_title}. Available environments: {tuple(self._dfs)}.")

        # get environment dataframes
        environment_dfs = self._dfs[environment_title]

        # find first non null frequency if not given
        if frequency is None:
            for frequency in FREQUENCIES:
                if environment_dfs[frequency] is not None:
                    break

        # check frequency
        if frequency not in FREQUENCIES:
            raise ValueError(f"Unknown frequency: {frequency}. Available frequencies: {FREQUENCIES}")

        return self._dfs[environment_title][frequency]


Instruction:
Here you have a function in Python 3, explain what it does
def _dev_add_inert(self, records_data):
        added_records = []
        for r_data in records_data:
            # create record
            record = Record(
                self,
                data=r_data
            )

            # store
            # we don't check uniqueness here => will be done while checking hooks
            self._records[record.get_pk()] = record

            # remember record
            added_records.append(record)

        return added_records

Response: Add inerts to the internal list of records.


Instruction:
Explain what the following Python 3 code does
def select(self, filter_by=None):
        records = self._records.values() if filter_by is None else filter(filter_by, self._records.values())
        return Queryset(self, records=records)

Response: Returns a new Queryset containing only the records that match the filter_by.


Instruction:
Write a Python 3 script to
return a single record in the set.

Response:
def one(self, filter_by=None):
        """
        Parameters
        ----------
        filter_by: callable, default None
            Callable must take one argument (a record of table), and return True to keep record, or False to skip it.
            Example : .one(lambda x: x.name == "my_name").
            If None, records are not filtered.

        Returns
        -------
        Record instance if one and only one record is found. Else raises.

        Raises
        ------
        RecordDoesNotExistError if no record is found
        MultipleRecordsReturnedError if multiple records are found
        """
        return Queryset(self, records=self._records.values()).one(filter_by=filter_by)


Instruction:
Create a Python 3 function for
registering a record hook.

Response:
def register_record_hook(self, hook):
        """
        target record must have been set
        """
        for key in hook.keys:
            if key in self._record_hooks:
                field_descriptor = hook.target_record.get_field_descriptor(hook.target_index)
                raise FieldValidationError(
                    f"Reference key already exists, can't create: {key}. "
                    f"{field_descriptor.get_error_location_message(hook.target_value, hook.target_index)}"
                )
            self._record_hooks[key] = hook


Instruction:
How would you explain what the following Python 3 function does
def register_link(self, link):
        keys = tuple((ref, link.initial_hook_value) for ref in link.hook_references)

        # look for a record hook
        for k in keys:
            if k in self._record_hooks:
                # set link target
                link.set_target(target_record=self._record_hooks[k].target_record)
                break
        else:
            # look for a table hook
            for k in keys:
                if k in self._table_hooks:
                    # set link target
                    link.set_target(target_table=self._table_hooks[k])
                    break
            else:
                field_descriptor = link.source_record.get_field_descriptor(link.source_index)
                raise FieldValidationError(
                    f"No object found with any of given references : {keys}. "
                    f"{field_descriptor.get_error_location_message(link.initial_hook_value)}"
                )

        # store by source
        if link.source_record not in self._links_by_source:
            self._links_by_source[link.source_record] = set()
        self._links_by_source[link.source_record].add(link)

        # store by target
        if link.target not in self._links_by_target:
            self._links_by_target[link.target] = set()
        self._links_by_target[link.target].add(link)

Response: Register a link in the database.


Instruction:
Write a Python 3 function for
running a command in a new process and returns its return code.

Response:
def run_subprocess(command, cwd=None, stdout=None, stderr=None, shell=False, beat_freq=None):
    """
    Parameters
    ----------
    command: command
    cwd: current working directory
    stdout: output info stream (must have 'write' method)
    stderr: output error stream (must have 'write' method)
    shell: see subprocess.Popen
    beat_freq: if not none, stdout will be used at least every beat_freq (in seconds)
    """
    sys.encoding = CONF.encoding
    # prepare variables
    stdout = sys.stdout if stdout is None else stdout
    stderr = sys.stderr if stderr is None else stderr

    # run subprocess
    with subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        cwd=cwd,
        shell=shell,
        universal_newlines=True
    ) as sub_p:
        # link output streams
        with redirect_stream(sub_p.stdout, stdout), redirect_stream(sub_p.stderr, stderr):
            while True:
                try:
                    sub_p.wait(timeout=beat_freq)
                    break
                except subprocess.TimeoutExpired:
                    stdout.write("subprocess is still running\n")
                    if hasattr(sys.stdout, "flush"):
                        sys.stdout.flush()
        return sub_p.returncode


Instruction:
Given the following Python 3 function, write the documentation
def get_string_buffer(path_or_content, expected_extension):
    buffer, path = None, None

    # path or content string

    if isinstance(path_or_content, str):
        if path_or_content[-len(expected_extension)-1:] == ".%s" % expected_extension:
            if not os.path.isfile(path_or_content):
                raise FileNotFoundError("No file at given path: '%s'." % path_or_content)
            buffer, path = open(path_or_content, encoding=CONF.encoding), path_or_content
        else:
            buffer = io.StringIO(path_or_content, )

    # text io
    elif isinstance(path_or_content, io.TextIOBase):
        buffer = path_or_content

    # bytes
    elif isinstance(path_or_content, bytes):
        buffer = io.StringIO(path_or_content.decode(encoding=CONF.encoding))
    elif isinstance(path_or_content, io.BufferedIOBase):
        buffer = io.StringIO(path_or_content.read().decode(encoding=CONF.encoding))
    else:
        raise ValueError("path_or_content type could not be identified")

    return buffer, path

Response: Returns a string_buffer object for the given path_or_content.


Instruction:
Given the following Python 3 function, write the documentation
def get_data(self, simulation_step=None, error_category=None):
        if simulation_step is None and error_category is None:
            return self._df.dropna(axis="rows", how="all")

        if simulation_step is not None:
            if simulation_step not in self._simulation_step_list:
                raise RuntimeError("The simulation_step '%s' is not referred in the error file." % simulation_step)

            if error_category is not None:
                if error_category not in self.CATEGORIES:
                    raise RuntimeError("The error_cat '%s' is wrong." % error_category)
                iterables = [simulation_step, error_category]
                columns = pd.MultiIndex.from_product(iterables)
                series = self._df[simulation_step][error_category].dropna(axis="rows", how="all")

                df = pd.DataFrame(index=series.index, columns=columns)
                df[simulation_step] = series
                return df

            return self._df[simulation_step].dropna(axis="rows", how="all")

        if error_category is not None:
            if error_category not in self.CATEGORIES:
                raise RuntimeError("The error_category '%s' is wrong." % error_category)
            df = self._df.copy()
            df.columns = df.columns.swaplevel(0, 1)
            return df[error_category].dropna(axis="rows", how="all")

Response: Returns a dataframe of the data for the specified simulation_step and error_category.


Instruction:
Create a Python 3 function for
creating regex and return.

Response:
def _create_regex(self, line, intent_name):
        """ Create regex and return. If error occurs returns None. """
        try:
            return re.compile(self._create_intent_pattern(line, intent_name),
                              re.IGNORECASE)
        except sre_constants.error as e:
            LOG.warning('Failed to parse the line "{}" '
                        'for {}'.format(line, intent_name))
            return None


Instruction:
Write a Python 3 function for
converting status ( id ) to its string name.

Response:
def str(cls, value):
        '''Convert status (id) to its string name.'''
        for k, v in cls.__dict__.items():
            if k[0] in string.ascii_uppercase and v == value:
                return k.lower().replace('_', ' ')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def remaining_duration(self, time):
        '''Returns the remaining duration for a recording.
        '''
        return max(0, self.end - max(self.start, time))

Response: Returns the remaining duration for a recording.


Instruction:
Create a Python 3 function for
serializing this object as dictionary usable for conversion to JSON.

Response:
def serialize(self):
        '''Serialize this object as dictionary usable for conversion to JSON.

        :return: Dictionary representing this object.
        '''
        return {
            'type': 'event',
            'id': self.uid,
            'attributes': {
                'start': self.start,
                'end': self.end,
                'uid': self.uid,
                'title': self.title,
                'data': self.get_data(),
                'status': Status.str(self.status)
                }
            }


Instruction:
How would you explain what the following Python 3 function does
def http_request(url, post_data=None):
    '''Make an HTTP request to a given URL with optional parameters.
    '''
    logger.debug('Requesting URL: %s' % url)
    buf = bio()
    curl = pycurl.Curl()
    curl.setopt(curl.URL, url.encode('ascii', 'ignore'))

    # Disable HTTPS verification methods if insecure is set
    if config()['server']['insecure']:
        curl.setopt(curl.SSL_VERIFYPEER, 0)
        curl.setopt(curl.SSL_VERIFYHOST, 0)

    if config()['server']['certificate']:
        # Make sure verification methods are turned on
        curl.setopt(curl.SSL_VERIFYPEER, 1)
        curl.setopt(curl.SSL_VERIFYHOST, 2)
        # Import your certificates
        curl.setopt(pycurl.CAINFO, config()['server']['certificate'])

    if post_data:
        curl.setopt(curl.HTTPPOST, post_data)
    curl.setopt(curl.WRITEFUNCTION, buf.write)
    curl.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_DIGEST)
    curl.setopt(pycurl.USERPWD, "%s:%s" % (config()['server']['username'],
                                           config()['server']['password']))
    curl.setopt(curl.HTTPHEADER, ['X-Requested-Auth: Digest'])
    curl.setopt(curl.FAILONERROR, True)
    curl.setopt(curl.FOLLOWLOCATION, True)
    curl.perform()
    curl.close()
    result = buf.getvalue()
    buf.close()
    return result

Response: Make an HTTP request to a given URL with optional parameters.


Instruction:
Can you write a function in Python 3 where it
gets available service endpoints for a given service type from the Opencast ServiceRegistry.

Response:
def get_service(service_type):
    '''Get available service endpoints for a given service type from the
    Opencast ServiceRegistry.
    '''
    endpoint = '/services/available.json?serviceType=' + str(service_type)
    url = '%s%s' % (config()['server']['url'], endpoint)
    response = http_request(url).decode('utf-8')
    services = (json.loads(response).get('services') or {}).get('service', [])
    services = ensurelist(services)
    endpoints = [service['host'] + service['path'] for service in services
                 if service['online'] and service['active']]
    for endpoint in endpoints:
        logger.info(u'Endpoint for %s: %s', service_type, endpoint)
    return endpoints


Instruction:
Can you tell what is the following Python 3 function doing
def unix_ts(dtval):
    '''Convert datetime into a unix timestamp.
    This is the equivalent to Python 3's int(datetime.timestamp()).

    :param dt: datetime to convert
    '''
    epoch = datetime(1970, 1, 1, 0, 0, tzinfo=tzutc())
    delta = (dtval - epoch)
    return delta.days * 24 * 3600 + delta.seconds

Response: Convert a datetime into a unix timestamp.


Instruction:
Make a summary of the following Python 3 code
def try_mkdir(directory):
    '''Try to create a directory. Pass without error if it already exists.
    '''
    try:
        os.mkdir(directory)
    except OSError as err:
        if err.errno != errno.EEXIST:
            raise err

Response: Try to create a directory. Pass without error.


Instruction:
Explain what the following Python 3 code does
def configure_service(service):
    '''Get the location of a given service from Opencast and add it to the
    current configuration.
    '''
    while not config().get('service-' + service) and not terminate():
        try:
            config()['service-' + service] = \
                get_service('org.opencastproject.' + service)
        except pycurl.error as e:
            logger.error('Could not get %s endpoint: %s. Retrying in 5s' %
                         (service, e))
            time.sleep(5.0)

Response: Get the location of a given service from Opencast and add it to the current configuration.


Instruction:
Can you generate the documentation for the following Python 3 function
def register_ca(status='idle'):
    '''Register this capture agent at the Matterhorn admin server so that it
    shows up in the admin interface.

    :param address: Address of the capture agent web ui
    :param status: Current status of the capture agent
    '''
    # If this is a backup CA we don't tell the Matterhorn core that we are
    # here.  We will just run silently in the background:
    if config()['agent']['backup_mode']:
        return
    params = [('address', config()['ui']['url']), ('state', status)]
    name = urlquote(config()['agent']['name'].encode('utf-8'), safe='')
    url = '%s/agents/%s' % (config()['service-capture.admin'][0], name)
    try:
        response = http_request(url, params).decode('utf-8')
        if response:
            logger.info(response)
    except pycurl.error as e:
        logger.warning('Could not set agent state to %s: %s' % (status, e))

Response: Register this capture agent at the Matterhorn admin server so that it shows up in the admin interface.


Instruction:
Can you tell what is the following Python 3 function doing
def recording_state(recording_id, status):
    '''Send the state of the current recording to the Matterhorn core.

    :param recording_id: ID of the current recording
    :param status: Status of the recording
    '''
    # If this is a backup CA we do not update the recording state since the
    # actual CA does that and we want to interfere.  We will just run silently
    # in the background:
    if config()['agent']['backup_mode']:
        return
    params = [('state', status)]
    url = config()['service-capture.admin'][0]
    url += '/recordings/%s' % recording_id
    try:
        result = http_request(url, params)
        logger.info(result)
    except pycurl.error as e:
        logger.warning('Could not set recording state to %s: %s' % (status, e))

Response: Send the state of the current recording to the Matterhorn core.


Instruction:
Can you implement a function in Python 3 that
updates the status of a particular event in the database.

Response:
def update_event_status(event, status):
    '''Update the status of a particular event in the database.
    '''
    dbs = db.get_session()
    dbs.query(db.RecordedEvent).filter(db.RecordedEvent.start == event.start)\
                               .update({'status': status})
    event.status = status
    dbs.commit()


Instruction:
Implement a Python 3 function for
updating the status of a particular service in the database.

Response:
def set_service_status(service, status):
    '''Update the status of a particular service in the database.
    '''
    srv = db.ServiceStates()
    srv.type = service
    srv.status = status

    dbs = db.get_session()
    dbs.merge(srv)
    dbs.commit()
    dbs.close()


Instruction:
How would you implement a function in Python 3 that
updates the status of a particular service in the database.

Response:
def get_service_status(service):
    '''Update the status of a particular service in the database.
    '''
    dbs = db.get_session()
    srvs = dbs.query(db.ServiceStates).filter(db.ServiceStates.type == service)

    if srvs.count():
        return srvs[0].status

    return db.ServiceStatus.STOPPED


Instruction:
Implement a function in Python 3 to
update the current agent state in opencast.

Response:
def update_agent_state():
    '''Update the current agent state in opencast.
    '''
    configure_service('capture.admin')
    status = 'idle'

    # Determine reported agent state with priority list
    if get_service_status(db.Service.SCHEDULE) == db.ServiceStatus.STOPPED:
        status = 'offline'
    elif get_service_status(db.Service.CAPTURE) == db.ServiceStatus.BUSY:
        status = 'capturing'
    elif get_service_status(db.Service.INGEST) == db.ServiceStatus.BUSY:
        status = 'uploading'

    register_ca(status=status)


Instruction:
Implement a function in Python 3 to
find the best match for the configuration file.

Response:
def configuration_file(cfgfile):
    '''Find the best match for the configuration file.
    '''
    if cfgfile is not None:
        return cfgfile
    # If no file is explicitely specified, probe for the configuration file
    # location.
    cfg = './etc/pyca.conf'
    if not os.path.isfile(cfg):
        return '/etc/pyca.conf'
    return cfg


Instruction:
Implement a Python 3 function for
updating the configuration from a file.

Response:
def update_configuration(cfgfile=None):
    '''Update configuration from file.

    :param cfgfile: Configuration file to load.
    '''
    configobj.DEFAULT_INTERPOLATION = 'template'
    cfgfile = configuration_file(cfgfile)
    cfg = configobj.ConfigObj(cfgfile, configspec=cfgspec, encoding='utf-8')
    validator = Validator()
    val = cfg.validate(validator)
    if val is not True:
        raise ValueError('Invalid configuration: %s' % val)
    if len(cfg['capture']['files']) != len(cfg['capture']['flavors']):
        raise ValueError('List of files and flavors do not match')
    globals()['__config'] = cfg
    logger_init()
    if cfg['server'].get('url', '').endswith('/'):
        logger.warning('Base URL ends with /. This is most likely a '
                       'configuration error. The URL should contain nothing '
                       'of the service paths.')
    logger.info('Configuration loaded from %s' % cfgfile)
    check()
    return cfg


Instruction:
Implement a function in Python 3 to
check configuration for sanity.

Response:
def check():
    '''Check configuration for sanity.
    '''
    if config('server')['insecure']:
        logger.warning('HTTPS CHECKS ARE TURNED OFF. A SECURE CONNECTION IS '
                       'NOT GUARANTEED')
    if config('server')['certificate']:
        # Ensure certificate exists and is readable
        open(config('server')['certificate'], 'rb').close()
    if config('agent')['backup_mode']:
        logger.info('Agent runs in backup mode. No data will be sent to '
                    'Opencast')


Instruction:
Given the following Python 3 function, write the documentation
def logger_init():
    '''Initialize logger based on configuration
    '''
    handlers = []
    logconf = config('logging')
    if logconf['syslog']:
        handlers.append(logging.handlers.SysLogHandler(address='/dev/log'))
    if logconf['stderr']:
        handlers.append(logging.StreamHandler(sys.stderr))
    if logconf['file']:
        handlers.append(logging.handlers.WatchedFileHandler(logconf['file']))
    for handler in handlers:
        handler.setFormatter(logging.Formatter(logconf['format']))
        logging.root.addHandler(handler)

    logging.root.setLevel(logconf['level'].upper())
    logger.info('Log level set to %s' % logconf['level'])

Response: Initialize logger based on configuration


Instruction:
Can you generate the documentation for the following Python 3 function
def home():
    '''Serve the status page of the capture agent.
    '''
    # Get IDs of existing preview images
    preview = config()['capture']['preview']
    previewdir = config()['capture']['preview_dir']
    preview = [p.replace('{{previewdir}}', previewdir) for p in preview]
    preview = zip(preview, range(len(preview)))
    preview = [p[1] for p in preview if os.path.isfile(p[0])]

    # Get limits for recording table
    try:
        limit_upcoming = int(request.args.get('limit_upcoming', 5))
        limit_processed = int(request.args.get('limit_processed', 15))
    except ValueError:
        limit_upcoming = 5
        limit_processed = 15

    db = get_session()
    upcoming_events = db.query(UpcomingEvent)\
                        .order_by(UpcomingEvent.start)\
                        .limit(limit_upcoming)
    recorded_events = db.query(RecordedEvent)\
                        .order_by(RecordedEvent.start.desc())\
                        .limit(limit_processed)
    recording = get_service_status(Service.CAPTURE) == ServiceStatus.BUSY
    uploading = get_service_status(Service.INGEST) == ServiceStatus.BUSY
    processed = db.query(RecordedEvent).count()
    upcoming = db.query(UpcomingEvent).count()

    return render_template('home.html', preview=preview, config=config(),
                           recorded_events=recorded_events,
                           upcoming_events=upcoming_events,
                           recording=recording, uploading=uploading,
                           processed=processed, upcoming=upcoming,
                           limit_upcoming=limit_upcoming,
                           limit_processed=limit_processed,
                           dtfmt=dtfmt)

Response: Serve the status page of the capture agent.


Instruction:
Write a Python 3 script to
serve the preview image with the given id

Response:
def serve_image(image_id):
    '''Serve the preview image with the given id
    '''
    try:
        preview_dir = config()['capture']['preview_dir']
        filepath = config()['capture']['preview'][image_id]
        filepath = filepath.replace('{{previewdir}}', preview_dir)
        filepath = os.path.abspath(filepath)
        if os.path.isfile(filepath):
            directory, filename = filepath.rsplit('/', 1)
            return send_from_directory(directory, filename)
    except (IndexError, KeyError):
        pass
    return '', 404


Instruction:
Write a Python 3 script for
intercepting sigterm and terminate all processes.

Response:
def sigterm_handler(signum, frame):
    '''Intercept sigterm and terminate all processes.
    '''
    sigint_handler(signum, frame)
    for process in multiprocessing.active_children():
        process.terminate()
    sys.exit(0)


Instruction:
Explain what the following Python 3 code does
def parse_ical(vcal):
    '''Parse Opencast schedule iCalendar file and return events as dict
    '''
    vcal = vcal.replace('\r\n ', '').replace('\r\n\r\n', '\r\n')
    vevents = vcal.split('\r\nBEGIN:VEVENT\r\n')
    del(vevents[0])
    events = []
    for vevent in vevents:
        event = {}
        for line in vevent.split('\r\n'):
            line = line.split(':', 1)
            key = line[0].lower()
            if len(line) <= 1 or key == 'end':
                continue
            if key.startswith('dt'):
                event[key] = unix_ts(dateutil.parser.parse(line[1]))
                continue
            if not key.startswith('attach'):
                event[key] = line[1]
                continue
            # finally handle attachments
            event['attach'] = event.get('attach', [])
            attachment = {}
            for x in [x.split('=') for x in line[0].split(';')]:
                if x[0].lower() in ['fmttype', 'x-apple-filename']:
                    attachment[x[0].lower()] = x[1]
            attachment['data'] = b64decode(line[1]).decode('utf-8')
            event['attach'].append(attachment)
        events.append(event)
    return events

Response: Parse Opencast schedule iCalendar file and return events as dict


Instruction:
Make a summary of the following Python 3 code
def get_schedule():
    '''Try to load schedule from the Matterhorn core. Returns a valid schedule
    or None on failure.
    '''
    params = {'agentid': config()['agent']['name'].encode('utf8')}
    lookahead = config()['agent']['cal_lookahead'] * 24 * 60 * 60
    if lookahead:
        params['cutoff'] = str((timestamp() + lookahead) * 1000)
    uri = '%s/calendars?%s' % (config()['service-scheduler'][0],
                               urlencode(params))
    try:
        vcal = http_request(uri)
    except pycurl.error as e:
        logger.error('Could not get schedule: %s' % e)
        return

    try:
        cal = parse_ical(vcal.decode('utf-8'))
    except Exception:
        logger.error('Could not parse ical')
        logger.error(traceback.format_exc())
        return
    db = get_session()
    db.query(UpcomingEvent).delete()
    for event in cal:
        # Ignore events that have already ended
        if event['dtend'] <= timestamp():
            continue
        e = UpcomingEvent()
        e.start = event['dtstart']
        e.end = event['dtend']
        e.uid = event.get('uid')
        e.title = event.get('summary')
        e.set_data(event)
        db.add(e)
    db.commit()

Response:
Try to load a schedule from the Matterhorn core. Returns a valid schedule
    or None on failure.


Instruction:
Can you tell what is the following Python 3 function doing
def control_loop():
    '''Main loop, retrieving the schedule.
    '''
    set_service_status(Service.SCHEDULE, ServiceStatus.BUSY)
    notify.notify('READY=1')
    while not terminate():
        notify.notify('WATCHDOG=1')
        # Try getting an updated schedule
        get_schedule()
        session = get_session()
        next_event = session.query(UpcomingEvent)\
                            .filter(UpcomingEvent.end > timestamp())\
                            .order_by(UpcomingEvent.start)\
                            .first()
        if next_event:
            logger.info('Next scheduled recording: %s',
                        datetime.fromtimestamp(next_event.start))
            notify.notify('STATUS=Next scheduled recording: %s' %
                          datetime.fromtimestamp(next_event.start))
        else:
            logger.info('No scheduled recording')
            notify.notify('STATUS=No scheduled recording')
        session.close()

        next_update = timestamp() + config()['agent']['update_frequency']
        while not terminate() and timestamp() < next_update:
            time.sleep(0.1)

    logger.info('Shutting down schedule service')
    set_service_status(Service.SCHEDULE, ServiceStatus.STOPPED)

Response: Main loop for the schedule.


Instruction:
Here you have a function in Python 3, explain what it does
def control_loop():
    '''Main loop, updating the capture agent state.
    '''
    set_service_status(Service.AGENTSTATE, ServiceStatus.BUSY)
    notify.notify('READY=1')
    notify.notify('STATUS=Running')
    while not terminate():
        notify.notify('WATCHDOG=1')
        update_agent_state()

        next_update = timestamp() + config()['agent']['update_frequency']
        while not terminate() and timestamp() < next_update:
            time.sleep(0.1)

    logger.info('Shutting down agentstate service')
    set_service_status(Service.AGENTSTATE, ServiceStatus.STOPPED)

Response: Main loop for the agentstate service.


Instruction:
Write a Python 3 script to
return a jsonapi error object

Response:
def make_error_response(error, status=500):
    ''' Return a response with a jsonapi error object
    '''
    content = {
        'errors': [{
            'status': status,
            'title': error
        }]
    }
    return make_response(jsonify(content), status)


Instruction:
How would you explain what the following Python 3 function does
def make_data_response(data, status=200):
    ''' Return a response with a list of jsonapi data objects
    '''
    content = {'data': ensurelist(data)}
    return make_response(jsonify(content), status)

Response: Return a response with a list of jsonapi data objects


Instruction:
Write a Python 3 script to
serve a json representation of internal agentstate as meta data

Response:
def internal_state():
    '''Serve a json representation of internal agentstate as meta data
    '''
    data = {'services': {
        'capture': ServiceStatus.str(get_service_status(Service.CAPTURE)),
        'ingest': ServiceStatus.str(get_service_status(Service.INGEST)),
        'schedule': ServiceStatus.str(get_service_status(Service.SCHEDULE)),
        'agentstate': ServiceStatus.str(get_service_status(Service.AGENTSTATE))
        }
    }
    return make_response(jsonify({'meta': data}))


Instruction:
How would you implement a function in Python 3 that
serves a JSON representation of events

Response:
def events():
    '''Serve a JSON representation of events
    '''
    db = get_session()
    upcoming_events = db.query(UpcomingEvent)\
                        .order_by(UpcomingEvent.start)
    recorded_events = db.query(RecordedEvent)\
                        .order_by(RecordedEvent.start.desc())

    result = [event.serialize() for event in upcoming_events]
    result += [event.serialize() for event in recorded_events]
    return make_data_response(result)


Instruction:
How would you code a function in Python 3 to
return a specific events JSON

Response:
def event(uid):
    '''Return a specific events JSON
    '''
    db = get_session()
    event = db.query(RecordedEvent).filter(RecordedEvent.uid == uid).first() \
        or db.query(UpcomingEvent).filter(UpcomingEvent.uid == uid).first()

    if event:
        return make_data_response(event.serialize())
    return make_error_response('No event with specified uid', 404)


Instruction:
Can you generate the documentation for the following Python 3 function
def delete_event(uid):
    '''Delete a specific event identified by its uid. Note that only recorded
    events can be deleted. Events in the buffer for upcoming events are
    regularly replaced anyway and a manual removal could have unpredictable
    effects.

    Use ?hard=true parameter to delete the recorded files on disk as well.

    Returns 204 if the action was successful.
    Returns 404 if event does not exist
    '''
    logger.info('deleting event %s via api', uid)
    db = get_session()
    events = db.query(RecordedEvent).filter(RecordedEvent.uid == uid)
    if not events.count():
        return make_error_response('No event with specified uid', 404)
    hard_delete = request.args.get('hard', 'false')
    if hard_delete == 'true':
        logger.info('deleting recorded files at %s', events[0].directory())
        shutil.rmtree(events[0].directory())
    events.delete()
    db.commit()
    return make_response('', 204)

Response: Delete an event identified by the uid.


Instruction:
How would you code a function in Python 3 to
modify an event specified by its uid.

Response:
def modify_event(uid):
    '''Modify an event specified by its uid. The modifications for the event
    are expected as JSON with the content type correctly set in the request.

    Note that this method works for recorded events only. Upcoming events part
    of the scheduler cache cannot be modified.
    '''
    try:
        data = request.get_json()['data'][0]
        if data['type'] != 'event' or data['id'] != uid:
            return make_error_response('Invalid data', 400)
        # Check attributes
        for key in data['attributes'].keys():
            if key not in ('status', 'start', 'end'):
                return make_error_response('Invalid data', 400)
        # Check new status
        new_status = data['attributes'].get('status')
        if new_status:
            new_status = new_status.upper().replace(' ', '_')
            data['attributes']['status'] = int(getattr(Status, new_status))
    except Exception:
        return make_error_response('Invalid data', 400)

    db = get_session()
    event = db.query(RecordedEvent).filter(RecordedEvent.uid == uid).first()
    if not event:
        return make_error_response('No event with specified uid', 404)
    event.start = data['attributes'].get('start', event.start)
    event.end = data['attributes'].get('end', event.end)
    event.status = data['attributes'].get('status', event.status)
    logger.debug('Updating event %s via api', uid)
    db.commit()
    return make_data_response(event.serialize())