Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_data(self, subject_ids=None, visit_ids=None, **kwargs):
        subject_ids = self.convert_subject_ids(subject_ids)
        # Add derived visit IDs to list of visit ids to filter
        all_filesets = []
        all_fields = []
        all_records = []
        # Note we prefer the use of raw REST API calls here for performance
        # reasons over using XnatPy's data structures.
        with self:
            # Get map of internal subject IDs to subject labels in project
            subject_xids_to_labels = {
                s['ID']: s['label'] for s in self._login.get_json(
                    '/data/projects/{}/subjects'.format(self.project_id))[
                        'ResultSet']['Result']}
            # Get list of all sessions within project
            session_xids = [
                s['ID'] for s in self._login.get_json(
                    '/data/projects/{}/experiments'.format(self.project_id))[
                        'ResultSet']['Result']
                if (self.session_filter is None or
                    self.session_filter.match(s['label']))]
            for session_xid in session_xids:
                session_json = self._login.get_json(
                    '/data/projects/{}/experiments/{}'.format(
                        self.project_id, session_xid))['items'][0]
                subject_xid = session_json['data_fields']['subject_ID']
                subject_id = subject_xids_to_labels[subject_xid]
                session_label = session_json['data_fields']['label']
                session_uri = (
                    '/data/archive/projects/{}/subjects/{}/experiments/{}'
                    .format(self.project_id, subject_xid, session_xid))
                # Get field values. We do this first so we can check for the
                # DERIVED_FROM_FIELD to determine the correct session label and
                # study name
                field_values = {}
                try:
                    fields_json = next(
                        c['items'] for c in session_json['children']
                        if c['field'] == 'fields/field')
                except StopIteration:
                    pass
                else:
                    for js in fields_json:
                        try:
                            value = js['data_fields']['field']
                        except KeyError:
                            pass
                        else:
                            field_values[js['data_fields']['name']] = value
                # Extract study name and derived-from session
                if self.DERIVED_FROM_FIELD in field_values:
                    df_sess_label = field_values.pop(self.DERIVED_FROM_FIELD)
                    from_study = session_label[len(df_sess_label) + 1:]
                    session_label = df_sess_label
                else:
                    from_study = None
                # Strip subject ID from session label if required
                if session_label.startswith(subject_id + '_'):
                    visit_id = session_label[len(subject_id) + 1:]
                else:
                    visit_id = session_label
                # Strip project ID from subject ID if required
                if subject_id.startswith(self.project_id + '_'):
                    subject_id = subject_id[len(self.project_id) + 1:]
                # Check subject is summary or not and whether it is to be
                # filtered
                if subject_id == XnatRepo.SUMMARY_NAME:
                    subject_id = None
                elif not (subject_ids is None or subject_id in subject_ids):
                    continue
                # Check visit is summary or not and whether it is to be
                # filtered
                if visit_id == XnatRepo.SUMMARY_NAME:
                    visit_id = None
                elif not (visit_ids is None or visit_id in visit_ids):
                    continue
                # Determine frequency
                if (subject_id, visit_id) == (None, None):
                    frequency = 'per_study'
                elif visit_id is None:
                    frequency = 'per_subject'
                elif subject_id is None:
                    frequency = 'per_visit'
                else:
                    frequency = 'per_session'
                # Append fields
                for name, value in field_values.items():
                    value = value.replace('"', '"')
                    all_fields.append(Field(
                        name=name, value=value, repository=self,
                        frequency=frequency,
                        subject_id=subject_id,
                        visit_id=visit_id,
                        from_study=from_study,
                        **kwargs))
                # Extract part of JSON relating to files
                try:
                    scans_json = next(
                        c['items'] for c in session_json['children']
                        if c['field'] == 'scans/scan')
                except StopIteration:
                    scans_json = []
                for scan_json in scans_json:
                    scan_id = scan_json['data_fields']['ID']
                    scan_type = scan_json['data_fields'].get('type', '')
                    scan_uri = '{}/scans/{}'.format(session_uri, scan_id)
                    try:
                        resources_json = next(
                            c['items'] for c in scan_json['children']
                            if c['field'] == 'file')
                    except StopIteration:
                        resources = {}
                    else:
                        resources = {js['data_fields']['label']:
                                     js['data_fields'].get('format', None)
                                     for js in resources_json}
                    # Remove auto-generated snapshots directory
                    resources.pop('SNAPSHOTS', None)
                    if scan_type == self.PROV_SCAN:
                        # Download provenance JSON files and parse into
                        # records
                        temp_dir = tempfile.mkdtemp()
                        try:
                            with tempfile.TemporaryFile() as temp_zip:
                                self._login.download_stream(
                                    scan_uri + '/files', temp_zip,
                                    format='zip')
                                with ZipFile(temp_zip) as zip_file:
                                    zip_file.extractall(temp_dir)
                            for base_dir, _, fnames in os.walk(temp_dir):
                                for fname in fnames:
                                    if fname.endswith('.json'):
                                        pipeline_name = fname[:-len('.json')]
                                        json_path = op.join(base_dir, fname)
                                        all_records.append(
                                            Record.load(
                                                pipeline_name, frequency,
                                                subject_id, visit_id,
                                                from_study, json_path))
                        finally:
                            shutil.rmtree(temp_dir, ignore_errors=True)
                    else:
                        for resource in resources:
                            all_filesets.append(Fileset(
                                scan_type, id=scan_id, uri=scan_uri,
                                repository=self, frequency=frequency,
                                subject_id=subject_id, visit_id=visit_id,
                                from_study=from_study,
                                resource_name=resource, **kwargs))
                logger.debug("Found node {}:{} on {}:{}".format(
                    subject_id, visit_id, self.server, self.project_id))
        return all_filesets, all_fields, all_records

Response: Find all filesets fields and provenance records within an XNAT project.


Instruction:
Write a Python 3 script for
converting subject ids to strings if they are integers

Response:
def convert_subject_ids(self, subject_ids):
        """
        Convert subject ids to strings if they are integers
        """
        # TODO: need to make this generalisable via a
        #       splitting+mapping function passed to the repository
        if subject_ids is not None:
            subject_ids = set(
                ('{:03d}'.format(s)
                 if isinstance(s, int) else s) for s in subject_ids)
        return subject_ids


Instruction:
Implement a function in Python 3 to
return the XNAT session and cache dir corresponding to the item.

Response:
def get_xsession(self, item):
        """
        Returns the XNAT session and cache dir corresponding to the
        item.
        """
        subj_label, sess_label = self._get_item_labels(item)
        with self:
            xproject = self._login.projects[self.project_id]
            try:
                xsubject = xproject.subjects[subj_label]
            except KeyError:
                xsubject = self._login.classes.SubjectData(
                    label=subj_label, parent=xproject)
            try:
                xsession = xsubject.experiments[sess_label]
            except KeyError:
                xsession = self._login.classes.MrSessionData(
                    label=sess_label, parent=xsubject)
                if item.derived:
                    xsession.fields[
                        self.DERIVED_FROM_FIELD] = self._get_item_labels(
                            item, no_from_study=True)[1]
        return xsession


Instruction:
Here you have a function in Python 3, explain what it does
def _get_item_labels(self, item, no_from_study=False):
        subject_id = self.inv_map_subject_id(item.subject_id)
        visit_id = self.inv_map_visit_id(item.visit_id)
        subj_label, sess_label = self._get_labels(
            item.frequency, subject_id, visit_id)
        if not no_from_study and item.from_study is not None:
            sess_label += '_' + item.from_study
        return (subj_label, sess_label)

Response: Returns the subject and session labels given the frequency and IDs of the items.


Instruction:
How would you implement a function in Python 3 that
returns the labels for the XNAT subject and session given the frequency and provided IDs.

Response:
def _get_labels(self, frequency, subject_id=None, visit_id=None):
        """
        Returns the labels for the XNAT subject and sessions given
        the frequency and provided IDs.
        """
        if frequency == 'per_session':
            subj_label = '{}_{}'.format(self.project_id,
                                        subject_id)
            sess_label = '{}_{}_{}'.format(self.project_id,
                                           subject_id,
                                           visit_id)
        elif frequency == 'per_subject':
            subj_label = '{}_{}'.format(self.project_id,
                                        subject_id)
            sess_label = '{}_{}_{}'.format(self.project_id,
                                           subject_id,
                                           self.SUMMARY_NAME)
        elif frequency == 'per_visit':
            subj_label = '{}_{}'.format(self.project_id,
                                        self.SUMMARY_NAME)
            sess_label = '{}_{}_{}'.format(self.project_id,
                                           self.SUMMARY_NAME,
                                           visit_id)
        elif frequency == 'per_study':
            subj_label = '{}_{}'.format(self.project_id,
                                        self.SUMMARY_NAME)
            sess_label = '{}_{}_{}'.format(self.project_id,
                                           self.SUMMARY_NAME,
                                           self.SUMMARY_NAME)
        else:
            assert False
        return (subj_label, sess_label)


Instruction:
Can you generate the documentation for the following Python 3 function
def turn_on(self, time):
        self._elk.send(cn_encode(self._index, time))

Response: Turn on an output


Instruction:
How would you explain what the following Python 3 function does
def sync(self):
        self.elk.send(cs_encode())
        self.get_descriptions(TextDescriptions.OUTPUT.value)

Response: Retrieve areas from ElkM1


Instruction:
How would you explain what the following Python 3 function does
def detect_version_str(self):
        help_text = run_matlab_cmd("help('{}')".format(self.test_func))
        if not help_text:
            raise ArcanaRequirementNotFoundError(
                "Did not find test function '{}' for {}"
                .format(self.test_func, self))
        return self.parse_help_text(help_text)

Response: Try to detect version of package from command help text.


Instruction:
Make a summary of the following Python 3 code
def target_heating_level(self):
        try:
            if self.side == 'left':
                level = self.device.device_data['leftTargetHeatingLevel']
            elif self.side == 'right':
                level = self.device.device_data['rightTargetHeatingLevel']
            return level
        except TypeError:
            return None

Response: Return target heating level.


Instruction:
Can you generate the documentation for the following Python 3 function
def past_heating_level(self, num):
        if num > 9:
            return 0

        try:
            if self.side == 'left':
                level = self.device.device_data_history[
                    num]['leftHeatingLevel']
            elif self.side == 'right':
                level = self.device.device_data_history[
                    num]['rightHeatingLevel']
            return level
        except TypeError:
            return 0

Response: Return a heating level from the past.


Instruction:
Can you generate the documentation for the following Python 3 function
def now_heating(self):
        try:
            if self.side == 'left':
                heat = self.device.device_data['leftNowHeating']
            elif self.side == 'right':
                heat = self.device.device_data['rightNowHeating']
            return heat
        except TypeError:
            return None

Response: Return current heating state.


Instruction:
Create a Python 3 function to
return seconds of heat time remaining.

Response:
def heating_remaining(self):
        """Return seconds of heat time remaining."""
        try:
            if self.side == 'left':
                timerem = self.device.device_data['leftHeatingDuration']
            elif self.side == 'right':
                timerem = self.device.device_data['rightHeatingDuration']
            return timerem
        except TypeError:
            return None


Instruction:
Implement a function in Python 3 to
return last seen time.

Response:
def last_seen(self):
        """Return mattress last seen time."""
        """
        These values seem to be rarely updated correctly in the API.
        Don't expect accurate results from this property.
        """
        try:
            if self.side == 'left':
                lastseen = self.device.device_data['leftPresenceEnd']
            elif self.side == 'right':
                lastseen = self.device.device_data['rightPresenceEnd']

            date = datetime.fromtimestamp(int(lastseen)) \
                .strftime('%Y-%m-%dT%H:%M:%S')
            return date
        except TypeError:
            return None


Instruction:
Can you write a function in Python 3 where it
returns a dict of all the current heating values.

Response:
def heating_values(self):
        """Return a dict of all the current heating values."""
        heating_dict = {
            'level': self.heating_level,
            'target': self.target_heating_level,
            'active': self.now_heating,
            'remaining': self.heating_remaining,
            'last_seen': self.last_seen,
        }
        return heating_dict


Instruction:
Can you tell what is the following Python 3 function doing
def current_sleep_stage(self):
        try:
            stages = self.intervals[0]['stages']
            num_stages = len(stages)

            if num_stages == 0:
                return None

            # API now always has an awake state last in the dict
            # so always pull the second to last stage while we are
            # in a processing state
            if self.current_session_processing:
                stage = stages[num_stages-2]['stage']
            else:
                stage = stages[num_stages-1]['stage']

            # UNRELIABLE... Removing for now.
            # Check sleep stage against last_seen time to make
            # sure we don't get stuck in a non-awake state.
            #delta_elap = datetime.fromtimestamp(time.time()) \
            #    - datetime.strptime(self.last_seen, '%Y-%m-%dT%H:%M:%S')
            #_LOGGER.debug('User elap: %s', delta_elap.total_seconds())
            #if stage != 'awake' and delta_elap.total_seconds() > 1800:
                # Bed hasn't seen us for 30min so set awake.
            #    stage = 'awake'
        except KeyError:
            stage = None
        return stage

Response: Return sleep stage for in - progress session.


Instruction:
Can you generate the documentation for the following Python 3 function
def current_sleep_breakdown(self):
        try:
            stages = self.intervals[0]['stages']
            breakdown = {'awake': 0, 'light': 0, 'deep': 0, 'rem': 0}
            for stage in stages:
                if stage['stage'] == 'awake':
                    breakdown['awake'] += stage['duration']
                elif stage['stage'] == 'light':
                    breakdown['light'] += stage['duration']
                elif stage['stage'] == 'deep':
                    breakdown['deep'] += stage['duration']
                elif stage['stage'] == 'rem':
                    breakdown['rem'] += stage['duration']
        except KeyError:
            breakdown = None
        return breakdown

Response: Return durations of sleep stages for in - progress session.


Instruction:
Here you have a function in Python 3, explain what it does
def current_bed_temp(self):
        try:
            bedtemps = self.intervals[0]['timeseries']['tempBedC']
            num_temps = len(bedtemps)

            if num_temps == 0:
                return None

            bedtemp = bedtemps[num_temps-1][1]
        except KeyError:
            bedtemp = None
        return bedtemp

Response: Return current bed temperature for in - progress session.


Instruction:
Can you create a Python 3 function that
returns current room temperature for in - progress session.

Response:
def current_room_temp(self):
        """Return current room temperature for in-progress session."""
        try:
            rmtemps = self.intervals[0]['timeseries']['tempRoomC']
            num_temps = len(rmtemps)

            if num_temps == 0:
                return None

            rmtemp = rmtemps[num_temps-1][1]
        except KeyError:
            rmtemp = None
        return rmtemp


Instruction:
Can you generate a brief explanation for the following Python 3 code
def current_resp_rate(self):
        try:
            rates = self.intervals[0]['timeseries']['respiratoryRate']
            num_rates = len(rates)

            if num_rates == 0:
                return None

            rate = rates[num_rates-1][1]
        except KeyError:
            rate = None
        return rate

Response: Return current respiratory rate for in - progress session.


Instruction:
Write a Python 3 script for
returning current heart rate for in - progress session.

Response:
def current_heart_rate(self):
        """Return current heart rate for in-progress session."""
        try:
            rates = self.intervals[0]['timeseries']['heartRate']
            num_rates = len(rates)

            if num_rates == 0:
                return None

            rate = rates[num_rates-1][1]
        except KeyError:
            rate = None
        return rate


Instruction:
Explain what the following Python 3 code does
def current_values(self):
        current_dict = {
            'date': self.current_session_date,
            'score': self.current_sleep_score,
            'stage': self.current_sleep_stage,
            'breakdown': self.current_sleep_breakdown,
            'tnt': self.current_tnt,
            'bed_temp': self.current_bed_temp,
            'room_temp': self.current_room_temp,
            'resp_rate': self.current_resp_rate,
            'heart_rate': self.current_heart_rate,
            'processing': self.current_session_processing,
        }
        return current_dict

Response: Return a dict of all the current parameters.


Instruction:
Can you create a Python 3 function that
returns date and time for start of last session data.

Response:
def last_session_date(self):
        """Return date/time for start of last session data."""
        try:
            date = self.intervals[1]['ts']
        except KeyError:
            return None
        date_f = datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')
        now = time.time()
        offset = datetime.fromtimestamp(now) - datetime.utcfromtimestamp(now)
        return date_f + offset


Instruction:
Implement a Python 3 function for
returning durations of sleep stages for last complete session.

Response:
def last_sleep_breakdown(self):
        """Return durations of sleep stages for last complete session."""
        try:
            stages = self.intervals[1]['stages']
        except KeyError:
            return None

        breakdown = {'awake': 0, 'light': 0, 'deep': 0, 'rem': 0}
        for stage in stages:
            if stage['stage'] == 'awake':
                breakdown['awake'] += stage['duration']
            elif stage['stage'] == 'light':
                breakdown['light'] += stage['duration']
            elif stage['stage'] == 'deep':
                breakdown['deep'] += stage['duration']
            elif stage['stage'] == 'rem':
                breakdown['rem'] += stage['duration']
        return breakdown


Instruction:
Write a Python 3 script to
return avg bed temperature for last session.

Response:
def last_bed_temp(self):
        """Return avg bed temperature for last session."""
        try:
            bedtemps = self.intervals[1]['timeseries']['tempBedC']
        except KeyError:
            return None
        tmp = 0
        num_temps = len(bedtemps)

        if num_temps == 0:
            return None

        for temp in bedtemps:
            tmp += temp[1]
        bedtemp = tmp/num_temps
        return bedtemp


Instruction:
Implement a function in Python 3 to
return avg room temperature for last session.

Response:
def last_room_temp(self):
        """Return avg room temperature for last session."""
        try:
            rmtemps = self.intervals[1]['timeseries']['tempRoomC']
        except KeyError:
            return None
        tmp = 0
        num_temps = len(rmtemps)

        if num_temps == 0:
            return None

        for temp in rmtemps:
            tmp += temp[1]
        rmtemp = tmp/num_temps
        return rmtemp


Instruction:
Write a Python 3 script to
return the average heart rate for last session.

Response:
def last_heart_rate(self):
        """Return avg heart rate for last session."""
        try:
            rates = self.intervals[1]['timeseries']['heartRate']
        except KeyError:
            return None
        tmp = 0
        num_rates = len(rates)

        if num_rates == 0:
            return None

        for rate in rates:
            tmp += rate[1]
        rateavg = tmp/num_rates
        return rateavg


Instruction:
Can you generate a brief explanation for the following Python 3 code
def last_values(self):
        last_dict = {
            'date': self.last_session_date,
            'score': self.last_sleep_score,
            'breakdown': self.last_sleep_breakdown,
            'tnt': self.last_tnt,
            'bed_temp': self.last_bed_temp,
            'room_temp': self.last_room_temp,
            'resp_rate': self.last_resp_rate,
            'heart_rate': self.last_heart_rate,
            'processing': self.last_session_processing,
        }
        return last_dict

Response: Return a dict of all the last parameters.


Instruction:
Can you write a function in Python 3 where it
calculates some heating data stats.

Response:
def heating_stats(self):
        """Calculate some heating data stats."""
        local_5 = []
        local_10 = []

        for i in range(0, 10):
            level = self.past_heating_level(i)
            if level == 0:
                _LOGGER.debug('Cant calculate stats yet...')
                return
            if i < 5:
                local_5.append(level)
            local_10.append(level)

        _LOGGER.debug('%s Heating History: %s', self.side, local_10)

        try:
            # Average of 5min on the history dict.
            fiveminavg = statistics.mean(local_5)
            tenminavg = statistics.mean(local_10)
            _LOGGER.debug('%s Heating 5 min avg: %s', self.side, fiveminavg)
            _LOGGER.debug('%s Heating 10 min avg: %s', self.side, tenminavg)

            # Standard deviation
            fivestdev = statistics.stdev(local_5)
            tenstdev = statistics.stdev(local_10)
            _LOGGER.debug('%s Heating 5 min stdev: %s', self.side, fivestdev)
            _LOGGER.debug('%s Heating 10 min stdev: %s', self.side, tenstdev)

            # Variance
            fivevar = statistics.variance(local_5)
            tenvar = statistics.variance(local_10)
            _LOGGER.debug('%s Heating 5 min variance: %s', self.side, fivevar)
            _LOGGER.debug('%s Heating 10 min variance: %s', self.side, tenvar)
        except:
            _LOGGER.debug('Cant calculate stats yet...')


Instruction:
How would you implement a function in Python 3 that
determines presence based on the heating level and end presence of the resource.

Response:
def dynamic_presence(self):
        """
        Determine presence based on bed heating level and end presence
        time reported by the api.

        Idea originated from Alex Lee Yuk Cheung SmartThings Code.
        """

        # self.heating_stats()

        if not self.presence:
            if self.heating_level > 50:
                # Can likely make this better
                if not self.now_heating:
                    self.presence = True
                elif self.heating_level - self.target_heating_level >= 8:
                    self.presence = True
            elif self.heating_level > 25:
                # Catch rising edge
                if self.past_heating_level(0) - self.past_heating_level(1) >= 2 \
                    and self.past_heating_level(1) - self.past_heating_level(2) >= 2 \
                        and self.past_heating_level(2) - self.past_heating_level(3) >= 2:
                    # Values are increasing so we are likely in bed
                    if not self.now_heating:
                        self.presence = True
                    elif self.heating_level - self.target_heating_level >= 8:
                        self.presence = True

        elif self.presence:
            if self.heating_level <= 15:
                # Failsafe, very slow
                self.presence = False
            elif self.heating_level < 50:
                if self.past_heating_level(0) - self.past_heating_level(1) < 0 \
                    and self.past_heating_level(1) - self.past_heating_level(2) < 0 \
                        and self.past_heating_level(2) - self.past_heating_level(3) < 0:
                    # Values are decreasing so we are likely out of bed
                    self.presence = False

        # Last seen can lag real-time by up to 35min so this is
        # mostly a backup to using the heat values.
        # seen_delta = datetime.fromtimestamp(time.time()) \
        #     - datetime.strptime(self.last_seen, '%Y-%m-%dT%H:%M:%S')
        # _LOGGER.debug('%s Last seen time delta: %s', self.side,
        #               seen_delta.total_seconds())
        # if self.presence and seen_delta.total_seconds() > 2100:
        #     self.presence = False

        _LOGGER.debug('%s Presence Results: %s', self.side, self.presence)


Instruction:
Can you tell what is the following Python 3 function doing
async def set_heating_level(self, level, duration=0):
        url = '{}/devices/{}'.format(API_URL, self.device.deviceid)

        # Catch bad inputs
        level = 10 if level < 10 else level
        level = 100 if level > 100 else level

        if self.side == 'left':
            data = {
                'leftHeatingDuration': duration,
                'leftTargetHeatingLevel': level
            }
        elif self.side == 'right':
            data = {
                'rightHeatingDuration': duration,
                'rightTargetHeatingLevel': level
            }

        set_heat = await self.device.api_put(url, data)
        if set_heat is None:
            _LOGGER.error('Unable to set eight heating level.')
        else:
            # Standard device json is returned after setting
            self.device.handle_device_json(set_heat['device'])

Response: Update heating data json.


Instruction:
Can you generate the documentation for the following Python 3 function
async def update_trend_data(self, startdate, enddate):
        url = '{}/users/{}/trends'.format(API_URL, self.userid)
        params = {
            'tz': self.device.tzone,
            'from': startdate,
            'to': enddate
            }

        trends = await self.device.api_get(url, params)
        if trends is None:
            _LOGGER.error('Unable to fetch eight trend data.')
        else:
            self.trends = trends['days']

Response: Update trends data json for specified time period.


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def update_intervals_data(self):
        url = '{}/users/{}/intervals'.format(API_URL, self.userid)

        intervals = await self.device.api_get(url)
        if intervals is None:
            _LOGGER.error('Unable to fetch eight intervals data.')
        else:
            self.intervals = intervals['intervals']

Response: Update intervals data json for specified time period.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def save(obj=None, m2m_data=None):
    m2m_data = {} if m2m_data is None else m2m_data
    obj.save_base(raw=True)
    for attr, values in m2m_data.items():
        for value in values:
            getattr(obj, attr).add(value)

Response: Saves a deserialized model object.


Instruction:
Explain what the following Python 3 code does
def custom_parser(self, json_text=None):
        app_config = django_apps.get_app_config("django_collect_offline")
        for json_parser in app_config.custom_json_parsers:
            json_text = json_parser(json_text)
        return json_text

Response: Runs json_text thru custom parsers.


Instruction:
Can you create a Python 3 function that
gets channel lazy property

Response:
def channel(self):
        """ channel lazy property """
        # start shell, non-blocking channel
        chan = self.cli.invoke_shell(width=360, height=80)
        chan.setblocking(0)
        # set channel timeout
        chan.settimeout(10)
        # now waiting for shell prompt ('username@')
        result = ""
        count = 0
        while count < 10:
            try:
                recv_part = chan.recv(16384).decode()
                result += recv_part
            except socket.timeout:
                # socket.timeout here means 'no more data'
                pass

            if result.find('%s@' % self.username) != -1:
                return chan
            time.sleep(1)
            count += 1
        # failed to get shell prompt on channel :-(
        raise StitchesConnectionException("Failed to get shell prompt")


Instruction:
Write a Python 3 function that can
disconnect from the internal state of the object.

Response:
def disconnect(self):
        """
        Close the connection
        """
        if hasattr(self, '_lazy_sftp'):
            if self.sftp is not None:
                self.sftp.close()
            delattr(self, '_lazy_sftp')
        if hasattr(self, '_lazy_channel'):
            if self.channel is not None:
                self.channel.close()
            delattr(self, '_lazy_channel')
        if hasattr(self, '_lazy_cli'):
            if self.cli is not None:
                self.cli.close()
            delattr(self, '_lazy_cli')
        if hasattr(self, '_lazy_pbm'):
            if self.pbm is not None:
                self.pbm.close()
            delattr(self, '_lazy_pbm')
        if hasattr(self, '_lazy_rpyc'):
            if self.rpyc is not None:
                self.rpyc.close()
            delattr(self, '_lazy_rpyc')


Instruction:
How would you code a function in Python 3 to
execute a command in the connection and return the stdout and stderr of the command.

Response:
def exec_command(self, command, bufsize=-1, get_pty=False):
        """
        Execute a command in the connection

        @param command: command to execute
        @type command: str

        @param bufsize: buffer size
        @type bufsize: int

        @param get_pty: get pty
        @type get_pty: bool

        @return: the stdin, stdout, and stderr of the executing command
        @rtype: tuple(L{paramiko.ChannelFile}, L{paramiko.ChannelFile},
                      L{paramiko.ChannelFile})

        @raise SSHException: if the server fails to execute the command
        """
        self.last_command = command
        return self.cli.exec_command(command, bufsize, get_pty=get_pty)


Instruction:
How would you implement a function in Python 3 that
executes a command and get its return value

Response:
def recv_exit_status(self, command, timeout=10, get_pty=False):
        """
        Execute a command and get its return value

        @param command: command to execute
        @type command: str

        @param timeout: command execution timeout
        @type timeout: int

        @param get_pty: get pty
        @type get_pty: bool

        @return: the exit code of the process or None in case of timeout
        @rtype: int or None
        """
        status = None
        self.last_command = command
        stdin, stdout, stderr = self.cli.exec_command(command, get_pty=get_pty)
        if stdout and stderr and stdin:
            for _ in range(timeout):
                if stdout.channel.exit_status_ready():
                    status = stdout.channel.recv_exit_status()
                    break
                time.sleep(1)

            self.last_stdout = stdout.read()
            self.last_stderr = stderr.read()

            stdin.close()
            stdout.close()
            stderr.close()
        return status


Instruction:
Make a summary of the following Python 3 code
def set(self, value):
        self._elk.send(cx_encode(self._index, value))

Response: Set the value of the current counter.


Instruction:
Can you generate the documentation for the following Python 3 function
def save(self, path):
        with open(path, 'w') as f:
            try:
                json.dump(self.prov, f, indent=2)
            except TypeError:
                raise ArcanaError(
                    "Could not serialise provenance record dictionary:\n{}"
                    .format(pformat(self.prov)))

Response: Saves the provenance object to a JSON file optionally including checksums for inputs and outputs.


Instruction:
Can you generate the documentation for the following Python 3 function
def load(cls, pipeline_name, frequency, subject_id, visit_id, from_study,
             path):
        """
        Loads a saved provenance object from a JSON file

        Parameters
        ----------
        path : str
            Path to the provenance file
        frequency : str
            The frequency of the record
        subject_id : str | None
            The subject ID of the provenance record
        visit_id : str | None
            The visit ID of the provenance record
        from_study : str
            Name of the study the derivatives were created for

        Returns
        -------
        record : Record
            The loaded provenance record
        """
        with open(path) as f:
            prov = json.load(f)
        return Record(pipeline_name, frequency, subject_id, visit_id,
                      from_study, prov)

Response: Loads a saved provenance object from a JSON file.


Instruction:
Can you tell what is the following Python 3 function doing
def mismatches(self, other, include=None, exclude=None):
        if include is not None:
            include_res = [self._gen_prov_path_regex(p) for p in include]
        if exclude is not None:
            exclude_res = [self._gen_prov_path_regex(p) for p in exclude]
        diff = DeepDiff(self._prov, other._prov, ignore_order=True)
        # Create regular expresssions for the include and exclude paths in
        # the format that deepdiff uses for nested dictionary/lists

        def include_change(change):
            if include is None:
                included = True
            else:
                included = any(rx.match(change) for rx in include_res)
            if included and exclude is not None:
                included = not any(rx.match(change) for rx in exclude_res)
            return included

        filtered_diff = {}
        for change_type, changes in diff.items():
            if isinstance(changes, dict):
                filtered = dict((k, v) for k, v in changes.items()
                                if include_change(k))
            else:
                filtered = [c for c in changes if include_change(c)]
            if filtered:
                filtered_diff[change_type] = filtered
        return filtered_diff

Response: Compares two provenance objects and returns a dictionary of differences between those objects.


Instruction:
Given the following Python 3 function, write the documentation
def translate(cls, substudy_name, pipeline_getter, auto_added=False):
        assert isinstance(substudy_name, basestring)
        assert isinstance(pipeline_getter, basestring)

        def translated_getter(self, **name_maps):
            substudy_spec = self.substudy_spec(substudy_name)
            # Combine mapping of names of sub-study specs with
            return getattr(self.substudy(substudy_name), pipeline_getter)(
                prefix=substudy_name + '_',
                input_map=substudy_spec.name_map,
                output_map=substudy_spec.name_map,
                study=self, name_maps=name_maps)
        # Add reduce method to allow it to be pickled
        translated_getter.auto_added = auto_added
        return translated_getter

Response: Returns a method that returns a new method that calls the pipeline_getter with the given name_maps and returns the new method that returns the new instance of the class with the translated name_maps.


Instruction:
Create a Python 3 function for
returning an iterator over the data specs that are not explicitly provided by the name map.

Response:
def auto_data_specs(self):
        """
        Data specs in the sub-study class that are not explicitly provided
        in the name map
        """
        for spec in self.study_class.data_specs():
            if spec.name not in self._name_map:
                yield spec


Instruction:
Can you generate the documentation for the following Python 3 function
def _make_nodes(self, cwd=None):
        for i, node in NipypeMapNode._make_nodes(self, cwd=cwd):
            # "Cast" NiPype node to a Arcana Node and set Arcana Node
            # parameters
            node.__class__ = self.node_cls
            node._environment = self._environment
            node._versions = self._versions
            node._wall_time = self._wall_time
            node._annotations = self._annotations
            yield i, node

Response: Cast generated nodes to Arcana Nodes


Instruction:
Given the following Python 3 function, write the documentation
def get_query(query_name):
    query_file_match = list(
        filter(lambda i: query_name == i.stem, FLAT_QUERIES))
    if not query_file_match:
        return None
    # TODO: Log warning if more than one match
    query_file = query_file_match[0]
    with open(query_file) as f:
        metadata, query_body = frontmatter.parse(f.read())
    result_mod = query_file.suffix.strip('.')
    query_obj = SimpleNamespace(
        name=query_name,
        metadata=metadata,
        path=query_file,
        result_mod=result_mod,
        body=query_body,
        error=False,
        executed=datetime.utcnow().isoformat())
    return query_obj

Response: Find file matching query_name read and return query object


Instruction:
Write a Python 3 script to
call get_query then submit query to resultset module

Response:
def get_result_set(query_name, **kwargs):
    """ Call get_query, then submit query from file to resultset module
    """
    query = get_query(query_name)
    if not query:
        query = SimpleNamespace()
        query.error = f"No query found matching '{query_name}'"
        return query
    try:
        result_mod = import_module(
            f'nerium.contrib.resultset.{query.result_mod}')
    except ModuleNotFoundError:
        result_mod = import_module('nerium.resultset.sql')
    query.params = {**kwargs}
    query.body = process_template(sql=query.body, **query.params)
    result = result_mod.result(query, **query.params)
    # Dumping and reloading via json here gets us datetime and decimal
    # serialization handling courtesy of `tablib`
    query.result = json.loads(json.dumps(result, default=serialize_objects_handler))
    try:
        if 'error' in query.result[0].keys():
            query.error = query.result[0]['error']
    except IndexError:
        pass
    return query


Instruction:
Can you write a function in Python 3 where it
generates CSV from result set

Response:
def results_to_csv(query_name, **kwargs):
    """ Generate CSV from result data
    """
    query = get_result_set(query_name, **kwargs)
    result = query.result
    columns = list(result[0].keys())
    data = [tuple(row.values()) for row in result]
    frame = tablib.Dataset()
    frame.headers = columns
    for row in data:
        frame.append(row)
    csvs = frame.export('csv')
    return csvs


Instruction:
Write a Python 3 script to
register with app_label. modelname wrapper_cls.

Response:
def register(self, models=None, wrapper_cls=None):
        """Registers with app_label.modelname, wrapper_cls.
        """
        self.loaded = True
        for model in models:
            model = model.lower()
            if model not in self.registry:
                self.registry.update({model: wrapper_cls or self.wrapper_cls})
                if self.register_historical:
                    historical_model = ".historical".join(model.split("."))
                    self.registry.update(
                        {historical_model: wrapper_cls or self.wrapper_cls}
                    )
            else:
                raise AlreadyRegistered(f"Model is already registered. Got {model}.")


Instruction:
Given the following Python 3 function, write the documentation
def register_for_app(
        self, app_label=None, exclude_models=None, exclude_model_classes=None
    ):
        """Registers all models for this app_label.
        """
        models = []
        exclude_models = exclude_models or []
        app_config = django_apps.get_app_config(app_label)
        for model in app_config.get_models():
            if model._meta.label_lower in exclude_models:
                pass
            elif exclude_model_classes and issubclass(model, exclude_model_classes):
                pass
            else:
                models.append(model._meta.label_lower)
        self.register(models)

Response: Registers all models for this app_label.


Instruction:
How would you implement a function in Python 3 that
returns a wrapped model instance.

Response:
def get_wrapped_instance(self, instance=None):
        """Returns a wrapped model instance.
        """
        if instance._meta.label_lower not in self.registry:
            raise ModelNotRegistered(f"{repr(instance)} is not registered with {self}.")
        wrapper_cls = self.registry.get(instance._meta.label_lower) or self.wrapper_cls
        if wrapper_cls:
            return wrapper_cls(instance)
        return instance


Instruction:
How would you explain what the following Python 3 function does
def site_models(self, app_label=None):
        site_models = {}
        app_configs = (
            django_apps.get_app_configs()
            if app_label is None
            else [django_apps.get_app_config(app_label)]
        )
        for app_config in app_configs:
            model_list = [
                model
                for model in app_config.get_models()
                if model._meta.label_lower in self.registry
            ]
            if model_list:
                model_list.sort(key=lambda m: m._meta.verbose_name)
                site_models.update({app_config.name: model_list})
        return site_models

Response: Returns a dictionary of registered models.


Instruction:
How would you explain what the following Python 3 function does
def get_fileset(self, fileset):
        # Don't need to cache fileset as it is already local as long
        # as the path is set
        if fileset._path is None:
            primary_path = self.fileset_path(fileset)
            aux_files = fileset.format.default_aux_file_paths(primary_path)
            if not op.exists(primary_path):
                raise ArcanaMissingDataException(
                    "{} does not exist in {}"
                    .format(fileset, self))
            for aux_name, aux_path in aux_files.items():
                if not op.exists(aux_path):
                    raise ArcanaMissingDataException(
                        "{} is missing '{}' side car in {}"
                        .format(fileset, aux_name, self))
        else:
            primary_path = fileset.path
            aux_files = fileset.aux_files
        return primary_path, aux_files

Response: Get the path of the fileset from the repository.


Instruction:
Write a Python 3 function for
getting the value of the field from the repository

Response:
def get_field(self, field):
        """
        Update the value of the field from the repository
        """
        # Load fields JSON, locking to prevent read/write conflicts
        # Would be better if only checked if locked to allow
        # concurrent reads but not possible with multi-process
        # locks (in my understanding at least).
        fpath = self.fields_json_path(field)
        try:
            with InterProcessLock(fpath + self.LOCK_SUFFIX,
                                  logger=logger), open(fpath, 'r') as f:
                dct = json.load(f)
            val = dct[field.name]
            if field.array:
                val = [field.dtype(v) for v in val]
            else:
                val = field.dtype(val)
        except (KeyError, IOError) as e:
            try:
                # Check to see if the IOError wasn't just because of a
                # missing file
                if e.errno != errno.ENOENT:
                    raise
            except AttributeError:
                pass
            raise ArcanaMissingDataException(
                "{} does not exist in the local repository {}"
                .format(field.name, self))
        return val


Instruction:
Create a Python 3 function for
inserting or updates a fileset in the repository.

Response:
def put_fileset(self, fileset):
        """
        Inserts or updates a fileset in the repository
        """
        target_path = self.fileset_path(fileset)
        if op.isfile(fileset.path):
            shutil.copyfile(fileset.path, target_path)
            # Copy side car files into repository
            for aux_name, aux_path in fileset.format.default_aux_file_paths(
                    target_path).items():
                shutil.copyfile(self.aux_file[aux_name], aux_path)
        elif op.isdir(fileset.path):
            if op.exists(target_path):
                shutil.rmtree(target_path)
            shutil.copytree(fileset.path, target_path)
        else:
            assert False


Instruction:
Create a Python 3 function to
insert or updates a field in the repository

Response:
def put_field(self, field):
        """
        Inserts or updates a field in the repository
        """
        fpath = self.fields_json_path(field)
        # Open fields JSON, locking to prevent other processes
        # reading or writing
        with InterProcessLock(fpath + self.LOCK_SUFFIX, logger=logger):
            try:
                with open(fpath, 'r') as f:
                    dct = json.load(f)
            except IOError as e:
                if e.errno == errno.ENOENT:
                    dct = {}
                else:
                    raise
            if field.array:
                dct[field.name] = list(field.value)
            else:
                dct[field.name] = field.value
            with open(fpath, 'w') as f:
                json.dump(dct, f, indent=2)


Instruction:
Explain what the following Python 3 code does
def find_data(self, subject_ids=None, visit_ids=None, **kwargs):
        all_filesets = []
        all_fields = []
        all_records = []
        for session_path, dirs, files in os.walk(self.root_dir):
            relpath = op.relpath(session_path, self.root_dir)
            path_parts = relpath.split(op.sep) if relpath != '.' else []
            ids = self._extract_ids_from_path(path_parts, dirs, files)
            if ids is None:
                continue
            subj_id, visit_id, from_study = ids
            # Check for summaries and filtered IDs
            if subj_id == self.SUMMARY_NAME:
                subj_id = None
            elif subject_ids is not None and subj_id not in subject_ids:
                continue
            if visit_id == self.SUMMARY_NAME:
                visit_id = None
            elif visit_ids is not None and visit_id not in visit_ids:
                continue
            # Map IDs into ID space of study
            subj_id = self.map_subject_id(subj_id)
            visit_id = self.map_visit_id(visit_id)
            # Determine frequency of session|summary
            if (subj_id, visit_id) == (None, None):
                frequency = 'per_study'
            elif subj_id is None:
                frequency = 'per_visit'
            elif visit_id is None:
                frequency = 'per_subject'
            else:
                frequency = 'per_session'
            filtered_files = self._filter_files(files, session_path)
            for fname in filtered_files:
                basename = split_extension(fname)[0]
                all_filesets.append(
                    Fileset.from_path(
                        op.join(session_path, fname),
                        frequency=frequency,
                        subject_id=subj_id, visit_id=visit_id,
                        repository=self,
                        from_study=from_study,
                        potential_aux_files=[
                            f for f in filtered_files
                            if (split_extension(f)[0] == basename and
                                f != fname)],
                        **kwargs))
            for fname in self._filter_dirs(dirs, session_path):
                all_filesets.append(
                    Fileset.from_path(
                        op.join(session_path, fname),
                        frequency=frequency,
                        subject_id=subj_id, visit_id=visit_id,
                        repository=self,
                        from_study=from_study,
                        **kwargs))
            if self.FIELDS_FNAME in files:
                with open(op.join(session_path,
                                  self.FIELDS_FNAME), 'r') as f:
                    dct = json.load(f)
                all_fields.extend(
                    Field(name=k, value=v, frequency=frequency,
                          subject_id=subj_id, visit_id=visit_id,
                          repository=self, from_study=from_study,
                          **kwargs)
                    for k, v in list(dct.items()))
            if self.PROV_DIR in dirs:
                if from_study is None:
                    raise ArcanaRepositoryError(
                        "Found provenance directory in session directory (i.e."
                        " not in study-specific sub-directory)")
                base_prov_dir = op.join(session_path, self.PROV_DIR)
                for fname in os.listdir(base_prov_dir):
                    all_records.append(Record.load(
                        split_extension(fname)[0],
                        frequency, subj_id, visit_id, from_study,
                        op.join(base_prov_dir, fname)))
        return all_filesets, all_fields, all_records

Response: Find all data within a repository and return a list of all the filesets fields and provenance records.


Instruction:
Implement a Python 3 function for
trying to guess the depth of a directory repository.

Response:
def guess_depth(self, root_dir):
        """
        Try to guess the depth of a directory repository (i.e. whether it has
        sub-folders for multiple subjects or visits, depending on where files
        and/or derived label files are found in the hierarchy of
        sub-directories under the root dir.

        Parameters
        ----------
        root_dir : str
            Path to the root directory of the repository
        """
        deepest = -1
        for path, dirs, files in os.walk(root_dir):
            depth = self.path_depth(path)
            filtered_files = self._filter_files(files, path)
            if filtered_files:
                logger.info("Guessing depth of directory repository at '{}' is"
                            " {} due to unfiltered files ('{}') in '{}'"
                            .format(root_dir, depth,
                                    "', '".join(filtered_files), path))
                return depth
            if self.PROV_DIR in dirs:
                depth_to_return = max(depth - 1, 0)
                logger.info("Guessing depth of directory repository at '{}' is"
                            "{} due to \"Derived label file\" in '{}'"
                            .format(root_dir, depth_to_return, path))
                return depth_to_return
            if depth >= self.MAX_DEPTH:
                logger.info("Guessing depth of directory repository at '{}' is"
                            " {} as '{}' is already at maximum depth"
                            .format(root_dir, self.MAX_DEPTH, path))
                return self.MAX_DEPTH
            try:
                for fpath in chain(filtered_files,
                                   self._filter_dirs(dirs, path)):
                    Fileset.from_path(fpath)
            except ArcanaError:
                pass
            else:
                if depth > deepest:
                    deepest = depth
        if deepest == -1:
            raise ArcanaRepositoryError(
                "Could not guess depth of '{}' repository as did not find "
                "a valid session directory within sub-directories."
                .format(root_dir))
        return deepest


Instruction:
How would you code a function in Python 3 to
get the data source from the database.

Response:
def get_data_source(query):
    """ Get data source connection metadata based on config. Prefer, in order:
        - Query file frontmatter
        - `db.yaml` file in query subdirectory
        - DATABASE_URL in environment

    To allow for possible non-SQL sources to be contributed, we only
    return a config value here, and leave connecting to concrete
    resultset module, as required values and connection method might change.
    (This is also why we return a dict, despite having a single value in the
    SQL case.)
    """
    # *** GET CONNECTION PARAMS: ***
    # from frontmatter
    try:
        return query.metadata['data_source']
    except KeyError:
        try:
            return dict(url=query.metadata['database_url'])
        except KeyError:
            pass

    # from file in directory if present
    db_file = query.path.parent / 'db.yaml'
    if db_file.is_file():
        with open(db_file, 'r') as dbf:
            db_meta = yaml.safe_load(dbf.read())
            try:
                return db_meta['data_source']
            except KeyError:
                try:
                    return dict(url=db_meta['database_url'])
                except KeyError:
                    pass

    # Use env['DATABASE_URL']/sqlite if nothing else is configured
    return dict(
        url=os.getenv('DATABASE_URL', 'sqlite:///'))


Instruction:
Implement a Python 3 function for
returning a particular fileset|field in the collection corresponding to the given subject and visit ids.

Response:
def item(self, subject_id=None, visit_id=None):
        """
        Returns a particular fileset|field in the collection corresponding to
        the given subject and visit_ids. subject_id and visit_id must be
        provided for relevant frequencies. Note that subject_id/visit_id can
        also be provided for non-relevant frequencies, they will just be
        ignored.

        Parameter
        ---------
        subject_id : str
            The subject id of the item to return
        visit_id : str
            The visit id of the item to return
        """

        if self.frequency == 'per_session':
            if subject_id is None or visit_id is None:
                raise ArcanaError(
                    "The 'subject_id' ({}) and 'visit_id' ({}) must be "
                    "provided to get an item from {}".format(
                        subject_id, visit_id, self))
            try:
                subj_dct = self._collection[subject_id]
            except KeyError:
                raise ArcanaIndexError(
                    subject_id,
                    "{} not a subject ID in '{}' collection ({})"
                    .format(subject_id, self.name,
                            ', '.join(self._collection.keys())))
            try:
                fileset = subj_dct[visit_id]
            except KeyError:
                raise ArcanaIndexError(
                    visit_id,
                    "{} not a visit ID in subject {} of '{}' "
                    "collection ({})"
                    .format(visit_id, subject_id, self.name,
                            ', '.join(subj_dct.keys())))
        elif self.frequency == 'per_subject':
            if subject_id is None:
                raise ArcanaError(
                    "The 'subject_id' arg must be provided to get "
                    "the match from {}"
                    .format(self))
            try:
                fileset = self._collection[subject_id]
            except KeyError:
                raise ArcanaIndexError(
                    subject_id,
                    "{} not a subject ID in '{}' collection ({})"
                    .format(subject_id, self.name,
                            ', '.join(self._collection.keys())))
        elif self.frequency == 'per_visit':
            if visit_id is None:
                raise ArcanaError(
                    "The 'visit_id' arg must be provided to get "
                    "the match from {}"
                    .format(self))
            try:
                fileset = self._collection[visit_id]
            except KeyError:
                raise ArcanaIndexError(
                    visit_id,
                    "{} not a visit ID in '{}' collection ({})"
                    .format(visit_id, self.name,
                            ', '.join(self._collection.keys())))
        elif self.frequency == 'per_study':
            try:
                fileset = self._collection[0]
            except IndexError:
                raise ArcanaIndexError(
                    "'{}' Collection is empty so doesn't have a "
                    "per_study node".format(self.name))
        return fileset


Instruction:
Given the following Python 3 function, write the documentation
def bind(self, study, **kwargs):  # @UnusedVariable
        if self.frequency == 'per_subject':
            tree_subject_ids = list(study.tree.subject_ids)
            subject_ids = list(self._collection.keys())
            if tree_subject_ids != subject_ids:
                raise ArcanaUsageError(
                    "Subject IDs in collection provided to '{}' ('{}') "
                    "do not match Study tree ('{}')".format(
                        self.name, "', '".join(subject_ids),
                        "', '".join(tree_subject_ids)))
        elif self.frequency == 'per_visit':
            tree_visit_ids = list(study.tree.visit_ids)
            visit_ids = list(self._collection.keys())
            if tree_visit_ids != visit_ids:
                raise ArcanaUsageError(
                    "Subject IDs in collection provided to '{}' ('{}') "
                    "do not match Study tree ('{}')".format(
                        self.name, "', '".join(visit_ids),
                        "', '".join(tree_visit_ids)))
        elif self.frequency == 'per_session':
            for subject in study.tree.subjects:
                if subject.id not in self._collection:
                    raise ArcanaUsageError(
                        "Study subject ID '{}' was not found in colleciton "
                        "provided to '{}' (found '{}')".format(
                            subject.id, self.name,
                            "', '".join(self._collection.keys())))
                for session in subject.sessions:
                    if session.visit_id not in self._collection[subject.id]:
                        raise ArcanaUsageError(
                            "Study visit ID '{}' for subject '{}' was not "
                            "found in colleciton provided to '{}' (found '{}')"
                            .format(subject.id, self.name,
                                    "', '".join(
                                        self._collection[subject.id].keys())))

Response: Bind the study to the source and sink initiation.


Instruction:
Here you have a function in Python 3, explain what it does
def fileset(self, name, from_study=None, format=None):  # @ReservedAssignment @IgnorePep8
        if isinstance(name, BaseFileset):
            if from_study is None and name.derived:
                from_study = name.study.name
            name = name.name
        try:
            format_dct = self._filesets[(name, from_study)]
        except KeyError:
            available = [
                ('{}(format={})'.format(f.name, f._resource_name)
                 if f._resource_name is not None else f.name)
                for f in self.filesets if f.from_study == from_study]
            other_studies = [
                (f.from_study if f.from_study is not None else '<root>')
                for f in self.filesets if f.name == name]
            if other_studies:
                msg = (". NB: matching fileset(s) found for '{}' study(ies) "
                       "('{}')".format(name, "', '".join(other_studies)))
            else:
                msg = ''
            raise ArcanaNameError(
                name,
                ("{} doesn't have a fileset named '{}'{} "
                   "(available '{}'){}"
                   .format(self, name,
                           (" from study '{}'".format(from_study)
                            if from_study is not None else ''),
                           "', '".join(available), msg)))
        else:
            if format is None:
                all_formats = list(format_dct.values())
                if len(all_formats) > 1:
                    raise ArcanaNameError(
                        "Multiple filesets found for '{}'{} in {} with formats"
                        " {}. Need to specify a format"
                        .format(name, ("in '{}'".format(from_study)
                                       if from_study is not None else ''),
                                self, "', '".join(format_dct.keys())))
                fileset = all_formats[0]
            else:
                try:
                    if isinstance(format, str):
                        fileset = format_dct[format]
                    else:
                        try:
                            fileset = format_dct[format.ext]
                        except KeyError:
                            fileset = None
                            for rname, rfileset in format_dct.items():
                                if rname in format.resource_names(
                                        self.tree.repository.type):
                                    fileset = rfileset
                                    break
                            if fileset is None:
                                raise
                except KeyError:
                    raise ArcanaNameError(
                        format,
                        ("{} doesn't have a fileset named '{}'{} with "
                         "format '{}' (available '{}'){}"
                           .format(self, name,
                                   (" from study '{}'".format(from_study)
                                    if from_study is not None else ''),
                                   format,
                                   "', '".join(format_dct.keys()), msg)))

        return fileset

Response: Returns the fileset with the given name produced by the given study or from the given spec.


Instruction:
Can you create a Python 3 function that
gets the field with the given name produced by the given study.

Response:
def field(self, name, from_study=None):
        """
        Gets the field named 'name' produced by the Study named 'study' if
        provided. If a spec is passed instead of a str to the name argument,
        then the study will be set from the spec iff it is derived

        Parameters
        ----------
        name : str | BaseField
            The name of the field or a spec matching the given name
        study : str | None
            Name of the study that produced the field if derived. If None
            and a spec is passed instaed of string to the name argument then
            the study name will be taken from the spec instead.
        """
        if isinstance(name, BaseField):
            if from_study is None and name.derived:
                from_study = name.study.name
            name = name.name
        try:
            return self._fields[(name, from_study)]
        except KeyError:
            available = [d.name for d in self.fields
                         if d.from_study == from_study]
            other_studies = [(d.from_study if d.from_study is not None
                              else '<root>')
                             for d in self.fields
                             if d.name == name]
            if other_studies:
                msg = (". NB: matching field(s) found for '{}' study(ies) "
                       "('{}')".format(name, "', '".join(other_studies)))
            else:
                msg = ''
            raise ArcanaNameError(
                name, ("{} doesn't have a field named '{}'{} "
                       "(available '{}')"
                       .format(
                           self, name,
                           (" from study '{}'".format(from_study)
                            if from_study is not None else ''),
                           "', '".join(available), msg)))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def record(self, pipeline_name, from_study):
        try:
            return self._records[(pipeline_name, from_study)]
        except KeyError:
            found = []
            for sname, pnames in groupby(sorted(self._records,
                                                key=itemgetter(1)),
                                         key=itemgetter(1)):
                found.append(
                    "'{}' for '{}'".format("', '".join(p for p, _ in pnames),
                                           sname))
            raise ArcanaNameError(
                (pipeline_name, from_study),
                ("{} doesn't have a provenance record for pipeline '{}' "
                 "for '{}' study (found {})".format(
                     self, pipeline_name, from_study,
                     '; '.join(found))))

Response: Returns the provenance record for a given pipeline and from_study.


Instruction:
Can you generate the documentation for the following Python 3 function
def find_mismatch(self, other, indent=''):
        if self != other:
            mismatch = "\n{}{}".format(indent, type(self).__name__)
        else:
            mismatch = ''
        sub_indent = indent + '  '
        if len(list(self.filesets)) != len(list(other.filesets)):
            mismatch += ('\n{indent}mismatching summary fileset lengths '
                         '(self={} vs other={}): '
                         '\n{indent}  self={}\n{indent}  other={}'
                         .format(len(list(self.filesets)),
                                 len(list(other.filesets)),
                                 list(self.filesets),
                                 list(other.filesets),
                                 indent=sub_indent))
        else:
            for s, o in zip(self.filesets, other.filesets):
                mismatch += s.find_mismatch(o, indent=sub_indent)
        if len(list(self.fields)) != len(list(other.fields)):
            mismatch += ('\n{indent}mismatching summary field lengths '
                         '(self={} vs other={}): '
                         '\n{indent}  self={}\n{indent}  other={}'
                         .format(len(list(self.fields)),
                                 len(list(other.fields)),
                                 list(self.fields),
                                 list(other.fields),
                                 indent=sub_indent))
        else:
            for s, o in zip(self.fields, other.fields):
                mismatch += s.find_mismatch(o, indent=sub_indent)
        return mismatch

Response: Returns a string that contains the string that contains the mismatch of two TreeNode objects.


Instruction:
Can you tell what is the following Python 3 function doing
def nodes(self, frequency=None):
        if frequency is None:
            nodes = chain(*(self._nodes(f)
                            for f in ('per_study', 'per_subject',
                                      'per_visit', 'per_session')))
        else:
            nodes = self._nodes(frequency=frequency)
        return nodes

Response: Returns an iterator over all nodes in the tree for the specified frequency.


Instruction:
Make a summary of the following Python 3 code
def find_mismatch(self, other, indent=''):
        mismatch = super(Tree, self).find_mismatch(other, indent)
        sub_indent = indent + '  '
        if len(list(self.subjects)) != len(list(other.subjects)):
            mismatch += ('\n{indent}mismatching subject lengths '
                         '(self={} vs other={}): '
                         '\n{indent}  self={}\n{indent}  other={}'
                         .format(len(list(self.subjects)),
                                 len(list(other.subjects)),
                                 list(self.subjects),
                                 list(other.subjects),
                                 indent=sub_indent))
        else:
            for s, o in zip(self.subjects, other.subjects):
                mismatch += s.find_mismatch(o, indent=sub_indent)
        if len(list(self.visits)) != len(list(other.visits)):
            mismatch += ('\n{indent}mismatching visit lengths '
                         '(self={} vs other={}): '
                         '\n{indent}  self={}\n{indent}  other={}'
                         .format(len(list(self.visits)),
                                 len(list(other.visits)),
                                 list(self.visits),
                                 list(other.visits),
                                 indent=sub_indent))
        else:
            for s, o in zip(self.visits, other.visits):
                mismatch += s.find_mismatch(o, indent=sub_indent)
        return mismatch

Response: Used in debugging unittests


Instruction:
Write a Python 3 script to
fill in tree with additional empty subjects and or visits to maintain order.

Response:
def _fill_empty_sessions(self, fill_subjects, fill_visits):
        """
        Fill in tree with additional empty subjects and/or visits to
        allow the study to pull its inputs from external repositories
        """
        if fill_subjects is None:
            fill_subjects = [s.id for s in self.subjects]
        if fill_visits is None:
            fill_visits = [v.id for v in self.complete_visits]
        for subject_id in fill_subjects:
            try:
                subject = self.subject(subject_id)
            except ArcanaNameError:
                subject = self._subjects[subject_id] = Subject(
                    subject_id, [], [], [])
            for visit_id in fill_visits:
                try:
                    subject.session(visit_id)
                except ArcanaNameError:
                    session = Session(subject_id, visit_id, [], [])
                    subject._sessions[visit_id] = session
                    try:
                        visit = self.visit(visit_id)
                    except ArcanaNameError:
                        visit = self._visits[visit_id] = Visit(
                            visit_id, [], [], [])
                    visit._sessions[subject_id] = session


Instruction:
How would you explain what the following Python 3 function does
def construct(cls, repository, filesets=(), fields=(), records=(),
                  file_formats=(), **kwargs):
        """
        Return the hierarchical tree of the filesets and fields stored in a
        repository

        Parameters
        ----------
        respository : Repository
            The repository that the tree comes from
        filesets : list[Fileset]
            List of all filesets in the tree
        fields : list[Field]
            List of all fields in the tree
        records : list[Record]
            List of all records in the tree

        Returns
        -------
        tree : arcana.repository.Tree
            A hierarchical tree of subject, session and fileset
            information for the repository
        """
        # Sort the data by subject and visit ID
        filesets_dict = defaultdict(list)
        for fset in filesets:
            if file_formats:
                fset.set_format(file_formats)
            filesets_dict[(fset.subject_id, fset.visit_id)].append(fset)
        fields_dict = defaultdict(list)
        for field in fields:
            fields_dict[(field.subject_id, field.visit_id)].append(field)
        records_dict = defaultdict(list)
        for record in records:
            records_dict[(record.subject_id, record.visit_id)].append(record)
        # Create all sessions
        subj_sessions = defaultdict(list)
        visit_sessions = defaultdict(list)
        for sess_id in set(chain(filesets_dict, fields_dict,
                                 records_dict)):
            if None in sess_id:
                continue  # Save summaries for later
            subj_id, visit_id = sess_id
            session = Session(
                subject_id=subj_id, visit_id=visit_id,
                filesets=filesets_dict[sess_id],
                fields=fields_dict[sess_id],
                records=records_dict[sess_id])
            subj_sessions[subj_id].append(session)
            visit_sessions[visit_id].append(session)
        subjects = []
        for subj_id in subj_sessions:
            subjects.append(Subject(
                subj_id,
                sorted(subj_sessions[subj_id]),
                filesets_dict[(subj_id, None)],
                fields_dict[(subj_id, None)],
                records_dict[(subj_id, None)]))
        visits = []
        for visit_id in visit_sessions:
            visits.append(Visit(
                visit_id,
                sorted(visit_sessions[visit_id]),
                filesets_dict[(None, visit_id)],
                fields_dict[(None, visit_id)],
                records_dict[(None, visit_id)]))
        return Tree(sorted(subjects),
                    sorted(visits),
                    repository,
                    filesets_dict[(None, None)],
                    fields_dict[(None, None)],
                    records_dict[(None, None)],
                    **kwargs)

Response: Constructs a new tree of all filesets fields and records and stores the summary for later tree of filesets and fields.


Instruction:
Write a Python 3 function for
returning all nodes related to the Session for the specified frequency

Response:
def nodes(self, frequency=None):
        """
        Returns all nodes of the specified frequency that are related to
        the given Session

        Parameters
        ----------
        frequency : str | None
            The frequency of the nodes to return

        Returns
        -------
        nodes : iterable[TreeNode]
            All nodes related to the Session for the specified frequency
        """
        if frequency is None:
            []
        elif frequency == 'per_session':
            return [self]
        elif frequency in ('per_visit', 'per_subject'):
            return [self.parent]
        elif frequency == 'per_study':
            return [self.parent.parent]


Instruction:
Implement a Python 3 function for
writing data on the asyncio Protocol

Response:
def write_data(self, data, response_required=None, timeout=5.0, raw=False):
        """Write data on the asyncio Protocol"""
        if self._transport is None:
            return

        if self._paused:
            return

        if self._waiting_for_response:
            LOG.debug("queueing write %s", data)
            self._queued_writes.append((data, response_required, timeout))
            return

        if response_required:
            self._waiting_for_response = response_required
            if timeout > 0:
                self._timeout_task = self.loop.call_later(
                    timeout, self._response_required_timeout)

        if not raw:
            cksum = 256 - reduce(lambda x, y: x+y, map(ord, data)) % 256
            data = data + '{:02X}'.format(cksum)
            if int(data[0:2], 16) != len(data)-2:
                LOG.debug("message length wrong: %s", data)

        LOG.debug("write_data '%s'", data)
        self._transport.write((data + '\r\n').encode())


Instruction:
Here you have a function in Python 3, explain what it does
def unwrap_querystring_lists(obj):
    new_dict = {
        key: (obj[key][0]
              if len(obj[key]) == 1 else obj[key])
        for key in obj.keys()
        }
    return new_dict

Response: Convert responder querystring params pulling values out of list


Instruction:
How would you explain what the following Python 3 function does
def pipeline_getter(self):
        "For duck-typing with *Spec types"
        if not self.derivable:
            raise ArcanaUsageError(
                "There is no pipeline getter for {} because it doesn't "
                "fallback to a derived spec".format(self))
        return self._fallback.pipeline_getter

Response: For duck - typing with *Spec types


Instruction:
How would you explain what the following Python 3 function does
def prerequisites(self):
        # Loop through the inputs to the pipeline and add the instancemethods
        # for the pipelines to generate each of the processed inputs
        prereqs = defaultdict(set)
        for input in self.inputs:  # @ReservedAssignment
            spec = self._study.spec(input)
            # Could be an input to the study or optional acquired spec
            if spec.is_spec and spec.derived:
                prereqs[spec.pipeline_getter].add(input.name)
        return prereqs

Response: Returns a dictionary of all prerequisite names that are used in the pipeline.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def study_inputs(self):
        return set(chain(
            (i for i in self.inputs if not i.derived),
            *(self.study.pipeline(p, required_outputs=r).study_inputs
              for p, r in self.prerequisites.items())))

Response:
Returns all inputs of the study used by the pipeline including inputs
              of prerequisites and inputs
              of prerequisites recursively.


Instruction:
Write a Python 3 script to
add a processing Node to the pipeline.

Response:
def add(self, name, interface, inputs=None, outputs=None,
            requirements=None, wall_time=None, annotations=None, **kwargs):
        """
        Adds a processing Node to the pipeline

        Parameters
        ----------
        name : str
            Name for the node
        interface : nipype.Interface
            The interface to use for the node
        inputs : dict[str, (str, FileFormat) | (Node, str)]
            Connections from inputs of the pipeline and outputs of other nodes
            to inputs of node. The keys of the dictionary are the field names
            and the values are 2-tuple containing either the name of the data
            spec and the data format it is expected in for pipeline inputs or
            the sending Node and the the name of an output of the sending Node.
            Note that pipeline inputs can be specified outside this method
            using the 'connect_input' method and connections between nodes with
            the the 'connect' method.
        outputs : dict[str, (str, FileFormat)]
            Connections to outputs of the pipeline from fields of the
            interface. The keys of the dictionary are the names of the data
            specs that will be written to and the values are the interface
            field name and the data format it is produced in. Note that output
            connections can also be specified using the 'connect_output'
            method.
        requirements : list(Requirement)
            List of required packages need for the node to run (default: [])
        wall_time : float
            Time required to execute the node in minutes (default: 1)
        mem_gb : int
            Required memory for the node in GB
        n_procs : int
            Preferred number of threads to run the node on (default: 1)
        annotations : dict[str, *]
            Additional annotations to add to the node, which may be used by
            the Processor node to optimise execution (e.g. 'gpu': True)
        iterfield : str
            Name of field to be passed an iterable to iterator over.
            If present, a MapNode will be created instead of a regular node
        joinsource : str
            Name of iterator field to join. Typically one of the implicit
            iterators (i.e. Study.SUBJECT_ID or Study.VISIT_ID)
            to join over the subjects and/or visits
        joinfield : str
            Name of field to pass the joined list when creating a JoinNode

        Returns
        -------
        node : Node
            The Node object that has been added to the pipeline
        """
        if annotations is None:
            annotations = {}
        if requirements is None:
            requirements = []
        if wall_time is None:
            wall_time = self.study.processor.default_wall_time
        if 'mem_gb' not in kwargs or kwargs['mem_gb'] is None:
            kwargs['mem_gb'] = self.study.processor.default_mem_gb
        if 'iterfield' in kwargs:
            if 'joinfield' in kwargs or 'joinsource' in kwargs:
                raise ArcanaDesignError(
                    "Cannot provide both joinsource and iterfield to when "
                    "attempting to add '{}' node to {}"
                    .foramt(name, self._error_msg_loc))
            node_cls = self.study.environment.node_types['map']
        elif 'joinsource' in kwargs or 'joinfield' in kwargs:
            if not ('joinfield' in kwargs and 'joinsource' in kwargs):
                raise ArcanaDesignError(
                    "Both joinsource and joinfield kwargs are required to "
                    "create a JoinNode (see {})".format(name,
                                                        self._error_msg_loc))
            joinsource = kwargs['joinsource']
            if joinsource in self.study.ITERFIELDS:
                self._iterator_joins.add(joinsource)
            node_cls = self.study.environment.node_types['join']
            # Prepend name of pipeline of joinsource to match name of nodes
            kwargs['joinsource'] = '{}_{}'.format(self.name, joinsource)
        else:
            node_cls = self.study.environment.node_types['base']
        # Create node
        node = node_cls(self.study.environment,
                        interface,
                        name="{}_{}".format(self._name, name),
                        requirements=requirements,
                        wall_time=wall_time,
                        annotations=annotations,
                        **kwargs)
        # Ensure node is added to workflow
        self._workflow.add_nodes([node])
        # Connect inputs, outputs and internal connections
        if inputs is not None:
            assert isinstance(inputs, dict)
            for node_input, connect_from in inputs.items():
                if isinstance(connect_from[0], basestring):
                    input_spec, input_format = connect_from
                    self.connect_input(input_spec, node,
                                       node_input, input_format)
                else:
                    conn_node, conn_field = connect_from
                    self.connect(conn_node, conn_field, node, node_input)
        if outputs is not None:
            assert isinstance(outputs, dict)
            for output_spec, (node_output, output_format) in outputs.items():
                self.connect_output(output_spec, node, node_output,
                                    output_format)
        return node


Instruction:
How would you code a function in Python 3 to
connect a study fileset_spec as an input to the provided node.

Response:
def connect_input(self, spec_name, node, node_input, format=None, **kwargs):  # @ReservedAssignment @IgnorePep8
        """
        Connects a study fileset_spec as an input to the provided node

        Parameters
        ----------
        spec_name : str
            Name of the study data spec (or one of the IDs from the iterator
            nodes, 'subject_id' or 'visit_id') to connect to the node
        node : arcana.Node
            The node to connect the input to
        node_input : str
            Name of the input on the node to connect the fileset spec to
        format : FileFormat | None
            The file format the input is expected in. If it differs
            from the format in data spec or of study input then an implicit
            conversion is performed. If None the file format in the data spec
            is assumed
        """
        if spec_name in self.study.ITERFIELDS:
            self._iterator_conns[spec_name].append((node, node_input, format))
        else:
            name = self._map_name(spec_name, self._input_map)
            if name not in self.study.data_spec_names():
                raise ArcanaDesignError(
                    "Proposed input '{}' to {} is not a valid spec name ('{}')"
                    .format(name, self._error_msg_loc,
                            "', '".join(self.study.data_spec_names())))
            self._input_conns[name].append((node, node_input, format, kwargs))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def connect_output(self, spec_name, node, node_output, format=None,   # @ReservedAssignment @IgnorePep8
                       **kwargs):
        """
        Connects an output to a study fileset spec

        Parameters
        ----------
        spec_name : str
            Name of the study fileset spec to connect to
        node : arcana.Node
            The node to connect the output from
        node_output : str
            Name of the output on the node to connect to the fileset
        format : FileFormat | None
            The file format the output is returned in. If it differs
            from the format in data spec then an implicit conversion is
            performed. If None the it is assumed to be returned in the file
            format of the entry the data spec
        """
        name = self._map_name(spec_name, self._output_map)
        if name not in self.study.data_spec_names():
            raise ArcanaDesignError(
                "Proposed output '{}' to {} is not a valid spec name ('{}')"
                .format(name, self._error_msg_loc,
                        "', '".join(self.study.data_spec_names())))
        if name in self._output_conns:
            prev_node, prev_node_output, _, _ = self._output_conns[name]
            logger.info(
                "Reassigning '{}' output from {}:{} to {}:{} in {}"
                .format(name, prev_node.name, prev_node_output,
                        node.name, node_output, self._error_msg_loc))
        self._output_conns[name] = (node, node_output, format, kwargs)

Response: Connects an output from a study fileset to a specific node.


Instruction:
How would you explain what the following Python 3 function does
def _map_name(self, name, mapper):
        if mapper is not None:
            if isinstance(mapper, basestring):
                name = mapper + name
            try:
                name = mapper[name]
            except KeyError:
                pass
        return name

Response: Maps a spec name to a new value based on the provided mapper


Instruction:
Write a Python 3 function that can
check whether the fileset matches the requested file format

Response:
def requires_conversion(cls, fileset, file_format):
        """Checks whether the fileset matches the requested file format"""
        if file_format is None:
            return False
        try:
            filset_format = fileset.format
        except AttributeError:
            return False  # Field input
        else:
            return (file_format != filset_format)


Instruction:
Explain what the following Python 3 code does
def save_graph(self, fname, style='flat', format='png', **kwargs):  # @ReservedAssignment @IgnorePep8
        fname = os.path.expanduser(fname)
        if not fname.endswith('.png'):
            fname += '.png'
        orig_dir = os.getcwd()
        tmpdir = tempfile.mkdtemp()
        os.chdir(tmpdir)
        workflow = self._workflow
        workflow.write_graph(graph2use=style, format=format, **kwargs)
        os.chdir(orig_dir)
        try:
            shutil.move(os.path.join(tmpdir, 'graph_detailed.{}'
                                     .format(format)), fname)
        except IOError as e:
            if e.errno == errno.ENOENT:
                shutil.move(os.path.join(tmpdir, 'graph.{}'.format(format)),
                            fname)
            else:
                raise
        shutil.rmtree(tmpdir)

Response: Saves a graph of the pipeline to file fname.


Instruction:
Can you create a Python 3 function that
returns the iterators that the pipeline contains for each input frequency.

Response:
def iterators(self, frequency=None):
        """
        Returns the iterators (i.e. subject_id, visit_id) that the pipeline
        iterates over

        Parameters
        ----------
        frequency : str | None
            A selected data frequency to use to determine which iterators are
            required. If None, all input frequencies of the pipeline are
            assumed
        """
        iterators = set()
        if frequency is None:
            input_freqs = list(self.input_frequencies)
        else:
            input_freqs = [frequency]
        for freq in input_freqs:
            iterators.update(self.study.FREQUENCIES[freq])
        return iterators


Instruction:
Given the following Python 3 function, write the documentation
def _unwrap_maps(self, name_maps, name, study=None, **inner_maps):
        # Set values of name and study
        name = name_maps.get('name', name)
        name = name_maps.get('prefix', '') + name
        study = name_maps.get('study', study)
        # Flatten input and output maps, combining maps from inner nests with
        # those in the "mods" dictionary
        maps = {}
        for mtype in ('input_map', 'output_map'):
            try:
                inner_map = inner_maps[mtype]
            except KeyError:
                try:
                    maps[mtype] = name_maps[mtype]  # Only outer map
                except KeyError:
                    pass  # No maps
            else:
                try:
                    outer_map = name_maps[mtype]
                except KeyError:
                    maps[mtype] = inner_map  # Only inner map
                else:
                    # Work through different combinations of  inner and outer
                    # map types (i.e. str & str, str & dict, dict & str, and
                    # dict & dict) and combine into a single map
                    if isinstance(outer_map, basestring):
                        if isinstance(inner_map, basestring):
                            # Concatenate prefixes
                            maps[mtype] = outer_map + inner_map
                        elif isinstance(inner_map, dict):
                            # Add outer_map prefix to all values in inner map
                            # dictionary
                            maps[mtype] = {k: outer_map + v
                                           for k, v in inner_map.items()}
                        else:
                            raise ArcanaDesignError(
                                "Unrecognised type for name map in '{}' "
                                "pipeline can be str or dict[str,str]: {}"
                                .format(name, inner_map))
                    elif isinstance(outer_map, dict):
                        if isinstance(inner_map, basestring):
                            # Strip inner map prefix from outer dictionary
                            # (which should have prefix included). This should
                            # be an unlikely case I imagine
                            maps[mtype] = {k[len(inner_map):]: v
                                           for k, v in outer_map.items()}
                        elif isinstance(inner_map, dict):
                            # Chain outer_map dictionary to inner map
                            # dictionary
                            maps[mtype] = deepcopy(outer_map)
                            maps[mtype].update(
                                {k: outer_map.get(v, v)
                                 for k, v in inner_map.items()})
                        else:
                            raise ArcanaDesignError(
                                "Unrecognised type for name map in '{}' "
                                "pipeline can be str or dict[str,str]: {}"
                                .format(name, inner_map))
                    else:
                        raise ArcanaDesignError(
                            "Unrecognised type for name map in '{}' "
                            "pipeline can be str or dict[str,str]: {}"
                            .format(name, outer_map))
        try:
            outer_maps = name_maps['name_maps']
        except KeyError:
            pass
        else:
            name, study, maps = self._unwrap_maps(
                outer_maps, name=name, study=study, **maps)
        return name, study, maps

Response:
Unwraps potentially nested name - mapping dictionaries to get values
        for name input_map output_map and study.


Instruction:
Can you write a function in Python 3 where it
caps the construction of the pipeline.

Response:
def cap(self):
        """
        "Caps" the construction of the pipeline, signifying that no more inputs
        and outputs are expected to be added and therefore the input and output
        nodes can be created along with the provenance.
        """
        to_cap = (self._inputnodes, self._outputnodes, self._prov)
        if to_cap == (None, None, None):
            self._inputnodes = {
                f: self._make_inputnode(f) for f in self.input_frequencies}
            self._outputnodes = {
                f: self._make_outputnode(f) for f in self.output_frequencies}
            self._prov = self._gen_prov()
        elif None in to_cap:
            raise ArcanaError(
                "If one of _inputnodes, _outputnodes or _prov is not None then"
                " they all should be in {}".format(self))