Instruction:
How would you explain what the following Python 3 function does
def dump_array( the_array, write, array_name ):

  write( "  static const unsigned char  " + array_name +
         "[" + repr( len( the_array ) ) + "L] =\n" )
  write( "  {\n" )

  line  = ""
  comma = "    "
  col   = 0

  for value in the_array:
    line += comma
    line += "%3d" % ord( value )
    comma = ","
    col  += 1

    if col == 16:
      col   = 0
      comma = ",\n    "

    if len( line ) > 1024:
      write( line )
      line = ""

  write( line + "\n  };\n\n\n" )

Response: dumps a given encoding


Instruction:
Can you generate a brief explanation for the following Python 3 code
def  file_exists( pathname ):
    result = 1
    try:
        file = open( pathname, "r" )
        file.close()
    except:
        result = None
        sys.stderr.write( pathname + " couldn't be accessed\n" )

    return result

Response: checks that a given file exists


Instruction:
Can you write a function in Python 3 where it
builds a list of input files from command - line arguments

Response:
def  make_file_list( args = None ):
    """builds a list of input files from command-line arguments"""
    file_list = []
    # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' )

    if not args:
        args = sys.argv[1 :]

    for pathname in args:
        if string.find( pathname, '*' ) >= 0:
            newpath = glob.glob( pathname )
            newpath.sort()  # sort files -- this is important because
                            # of the order of files
        else:
            newpath = [pathname]

        file_list.extend( newpath )

    if len( file_list ) == 0:
        file_list = None
    else:
        # now filter the file list to remove non-existing ones
        file_list = filter( file_exists, file_list )

    return file_list


Instruction:
Can you write a function in Python 3 where it
parses a DelegationSet element and populates the zone.

Response:
def parse_delegation_set(zone, e_delegation_set):
    """
    Parses a DelegationSet tag. These often accompany HostedZone tags in
    responses like CreateHostedZone and GetHostedZone.

    :param HostedZone zone: An existing HostedZone instance to populate.
    :param lxml.etree._Element e_delegation_set: A DelegationSet element.
    """

    e_nameservers = e_delegation_set.find('./{*}NameServers')

    nameservers = []
    for e_nameserver in e_nameservers:
        nameservers.append(e_nameserver.text)

    zone._nameservers = nameservers


Instruction:
Explain what the following Python 3 code does
def writeblocks(blocks):
        data = []
        codes = [[block.code, block.write()] for block in blocks]
        codes[-1][0] |= 128
        for code, datum in codes:
            byte = chr_(code)
            if len(datum) > 2**24:
                raise error("block is too long to write")
            length = struct.pack(">I", len(datum))[-3:]
            data.append(byte + length + datum)
        return b"".join(data)

Response: Render metadata blocks as a byte string.


Instruction:
Can you implement a function in Python 3 that
consolidates FLAC padding metadata blocks.

Response:
def group_padding(blocks):
        """Consolidate FLAC padding metadata blocks.

        The overall size of the rendered blocks does not change, so
        this adds several bytes of padding for each merged block.
        """

        paddings = [b for b in blocks if isinstance(b, Padding)]
        for p in paddings:
            blocks.remove(p)
        # total padding size is the sum of padding sizes plus 4 bytes
        # per removed header.
        size = sum(padding.length for padding in paddings)
        padding = Padding()
        padding.length = size + 4 * (len(paddings) - 1)
        blocks.append(padding)


Instruction:
How would you explain what the following Python 3 function does
def delete(self, filename=None):
        if filename is None:
            filename = self.filename
        for s in list(self.metadata_blocks):
            if isinstance(s, VCFLACDict):
                self.metadata_blocks.remove(s)
                self.tags = None
                self.save()
                break

Response: Remove Vorbis comments from a file.


Instruction:
How would you explain what the following Python 3 function does
def load(self, filename):

        self.metadata_blocks = []
        self.tags = None
        self.cuesheet = None
        self.seektable = None
        self.filename = filename
        fileobj = StrictFileObject(open(filename, "rb"))
        try:
            self.__check_header(fileobj)
            while self.__read_metadata_block(fileobj):
                pass
        finally:
            fileobj.close()

        try:
            self.metadata_blocks[0].length
        except (AttributeError, IndexError):
            raise FLACNoHeaderError("Stream info block not found")

Response: Load file information from a filename.


Instruction:
Write a Python 3 function that can
save the metadata blocks to a file.

Response:
def save(self, filename=None, deleteid3=False):
        """Save metadata blocks to a file.

        If no filename is given, the one most recently loaded is used.
        """

        if filename is None:
            filename = self.filename
        f = open(filename, 'rb+')

        try:
            # Ensure we've got padding at the end, and only at the end.
            # If adding makes it too large, we'll scale it down later.
            self.metadata_blocks.append(Padding(b'\x00' * 1020))
            MetadataBlock.group_padding(self.metadata_blocks)

            header = self.__check_header(f)
            # "fLaC" and maybe ID3
            available = self.__find_audio_offset(f) - header
            data = MetadataBlock.writeblocks(self.metadata_blocks)

            # Delete ID3v2
            if deleteid3 and header > 4:
                available += header - 4
                header = 4

            if len(data) > available:
                # If we have too much data, see if we can reduce padding.
                padding = self.metadata_blocks[-1]
                newlength = padding.length - (len(data) - available)
                if newlength > 0:
                    padding.length = newlength
                    data = MetadataBlock.writeblocks(self.metadata_blocks)
                    assert len(data) == available

            elif len(data) < available:
                # If we have too little data, increase padding.
                self.metadata_blocks[-1].length += (available - len(data))
                data = MetadataBlock.writeblocks(self.metadata_blocks)
                assert len(data) == available

            if len(data) != available:
                # We couldn't reduce the padding enough.
                diff = (len(data) - available)
                insert_bytes(f, diff, header)

            f.seek(header - 4)
            f.write(b"fLaC" + data)

            # Delete ID3v1
            if deleteid3:
                try:
                    f.seek(-128, 2)
                except IOError:
                    pass
                else:
                    if f.read(3) == b"TAG":
                        f.seek(-128, 2)
                        f.truncate()
        finally:
            f.close()


Instruction:
Can you create a Python 3 function that
parses an Alias tag beneath a ResourceRecordSet and returns the two values .

Response:
def parse_rrset_alias(e_alias):
    """
    Parses an Alias tag beneath a ResourceRecordSet, spitting out the two values
    found within. This is specific to A records that are set to Alias.

    :param lxml.etree._Element e_alias: An Alias tag beneath a ResourceRecordSet.
    :rtype: tuple
    :returns: A tuple in the form of ``(alias_hosted_zone_id, alias_dns_name)``.
    """

    alias_hosted_zone_id = e_alias.find('./{*}HostedZoneId').text
    alias_dns_name = e_alias.find('./{*}DNSName').text
    return alias_hosted_zone_id, alias_dns_name


Instruction:
Here you have a function in Python 3, explain what it does
def parse_rrset_record_values(e_resource_records):

    records = []

    for e_record in e_resource_records:
        for e_value in e_record:
            records.append(e_value.text)

    return records

Response:
Used to parse the various Values from the ResourceRecords tags on
    most rrset types.


Instruction:
Can you implement a function in Python 3 that
parses the API responses for the method.

Response:
def list_resource_record_sets_by_zone_id_parser(e_root, connection, zone_id):
    """
    Parses the API responses for the
    :py:meth:`route53.connection.Route53Connection.list_resource_record_sets_by_zone_id`
    method.

    :param lxml.etree._Element e_root: The root node of the etree parsed
        response from the API.
    :param Route53Connection connection: The connection instance used to
        query the API.
    :param str zone_id: The zone ID of the HostedZone these rrsets belong to.
    :rtype: ResourceRecordSet
    :returns: A generator of fully formed ResourceRecordSet instances.
    """

    # The rest of the list pagination tags are handled higher up in the stack.
    # We'll just worry about the ResourceRecordSets tag, which has
    # ResourceRecordSet tags nested beneath it.
    e_rrsets = e_root.find('./{*}ResourceRecordSets')

    for e_rrset in e_rrsets:
        yield parse_rrset(e_rrset, connection, zone_id)


Instruction:
Given the following Python 3 function, write the documentation
def nameservers(self):

        # If this HostedZone was instantiated by ListHostedZones, the nameservers
        # attribute didn't get populated. If the user requests it, we'll
        # lazy load by querying it in after the fact. It's safe to cache like
        # this since  these nameserver values won't change.
        if not self._nameservers:
            # We'll just snatch the nameserver values from a fresh copy
            # via GetHostedZone.
            hosted_zone = self.connection.get_hosted_zone_by_id(self.id)
            self._nameservers = hosted_zone._nameservers

        return self._nameservers

Response: Returns a list of nameserver strings for this Hosted Zone.


Instruction:
Create a Python 3 function to
delete this Hosted Zone.

Response:
def delete(self, force=False):
        """
        Deletes this hosted zone. After this method is ran, you won't be able
        to add records, or do anything else with the zone. You'd need to
        re-create it, as zones are read-only after creation.

        :keyword bool force: If ``True``, delete the
            :py:class:`HostedZone <route53.hosted_zone.HostedZone>`, even if it
            means nuking all associated record sets. If ``False``, an
            exception is raised if this
            :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
            has record sets.
        :rtype: dict
        :returns: A dict of change info, which contains some details about
            the request.
        """

        self._halt_if_already_deleted()

        if force:
            # Forcing deletion by cleaning up all record sets first. We'll
            # do it all in one change set.
            cset = ChangeSet(connection=self.connection, hosted_zone_id=self.id)

            for rrset in self.record_sets:
                # You can delete a HostedZone if there are only SOA and NS
                # entries left. So delete everything but SOA/NS entries.
                if rrset.rrset_type not in ['SOA', 'NS']:
                    cset.add_change('DELETE', rrset)

            if cset.deletions or cset.creations:
                # Bombs away.
                self.connection._change_resource_record_sets(cset)

        # Now delete the HostedZone.
        retval = self.connection.delete_hosted_zone_by_id(self.id)

        # Used to protect against modifying a deleted HostedZone.
        self._is_deleted = True

        return retval


Instruction:
How would you explain what the following Python 3 function does
def _add_record(self, record_set_class, name, values, ttl=60, weight=None,
                    region=None,set_identifier=None, alias_hosted_zone_id=None,
                    alias_dns_name=None):
        """
        Convenience method for creating ResourceRecordSets. Most of the calls
        are basically the same, this saves on repetition.

        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created ResourceRecordSet sub-class
             instance.
        """

        self._halt_if_already_deleted()

        rrset_kwargs = dict(
            connection=self.connection,
            zone_id=self.id,
            name=name,
            ttl=ttl,
            records=values,
            weight=weight,
            region=region,
            set_identifier=set_identifier,
            )

        if alias_hosted_zone_id or alias_dns_name:
            rrset_kwargs.update(dict(
                alias_hosted_zone_id=alias_hosted_zone_id,
                alias_dns_name=alias_dns_name
            ))

        rrset = record_set_class(**rrset_kwargs)

        cset = ChangeSet(connection=self.connection, hosted_zone_id=self.id)
        cset.add_change('CREATE', rrset)

        change_info = self.connection._change_resource_record_sets(cset)

        return rrset, change_info

Response: Internal method to create a new ResourceRecordSet and return it.


Instruction:
Can you write a function in Python 3 where it
creates and returns an A record.

Response:
def create_a_record(self, name, values, ttl=60, weight=None, region=None,
                     set_identifier=None, alias_hosted_zone_id=None,
                     alias_dns_name=None):
        """
        Creates and returns an A record attached to this hosted zone.

        :param str name: The fully qualified name of the record to add.
        :param list values: A list of value strings for the record.
        :keyword int ttl: The time-to-live of the record (in seconds).
        :keyword int weight: *For weighted record sets only*. Among resource record
            sets that have the same combination of DNS name and type, a value
            that determines what portion of traffic for the current resource
            record set is routed to the associated location. Ranges from 0-255.
        :keyword str region: *For latency-based record sets*. The Amazon EC2 region
            where the resource that is specified in this resource record set
            resides.
        :keyword str set_identifier: *For weighted and latency resource record
            sets only*. An identifier that differentiates among multiple
            resource record sets that have the same combination of DNS name
            and type. 1-128 chars.
        :keyword str alias_hosted_zone_id: Alias A records have this specified.
            It appears to be the hosted zone ID for the ELB the Alias points at.
        :keyword str alias_dns_name: Alias A records have this specified. It is
            the DNS name for the ELB that the Alias points to.
        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created
            :py:class:`AResourceRecordSet <route53.resource_record_set.AResourceRecordSet>`
            instance.
        """

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(AResourceRecordSet, **values)


Instruction:
Here you have a function in Python 3, explain what it does
def create_aaaa_record(self, name, values, ttl=60, weight=None, region=None,
                        set_identifier=None):
        """
        Creates an AAAA record attached to this hosted zone.

        :param str name: The fully qualified name of the record to add.
        :param list values: A list of value strings for the record.
        :keyword int ttl: The time-to-live of the record (in seconds).
        :keyword int weight: *For weighted record sets only*. Among resource record
            sets that have the same combination of DNS name and type, a value
            that determines what portion of traffic for the current resource
            record set is routed to the associated location. Ranges from 0-255.
        :keyword str region: *For latency-based record sets*. The Amazon EC2 region
            where the resource that is specified in this resource record set
            resides.
        :keyword str set_identifier: *For weighted and latency resource record
            sets only*. An identifier that differentiates among multiple
            resource record sets that have the same combination of DNS name
            and type. 1-128 chars.
        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created AAAAResourceRecordSet instance.
        """

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(AAAAResourceRecordSet, **values)

Response: Creates an AAAA record.


Instruction:
Can you generate the documentation for the following Python 3 function
def create_cname_record(self, name, values, ttl=60, weight=None, region=None,
                           set_identifier=None):
        """
        Creates a CNAME record attached to this hosted zone.

        :param str name: The fully qualified name of the record to add.
        :param list values: A list of value strings for the record.
        :keyword int ttl: The time-to-live of the record (in seconds).
        :keyword int weight: *For weighted record sets only*. Among resource record
            sets that have the same combination of DNS name and type, a value
            that determines what portion of traffic for the current resource
            record set is routed to the associated location. Ranges from 0-255.
        :keyword str region: *For latency-based record sets*. The Amazon EC2 region
            where the resource that is specified in this resource record set
            resides.
        :keyword str set_identifier: *For weighted and latency resource record
            sets only*. An identifier that differentiates among multiple
            resource record sets that have the same combination of DNS name
            and type. 1-128 chars.
        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created CNAMEResourceRecordSet instance.
        """

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(CNAMEResourceRecordSet, **values)

Response: Creates a new CNAME record.


Instruction:
Explain what the following Python 3 code does
def create_mx_record(self, name, values, ttl=60):

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(MXResourceRecordSet, **values)

Response: Creates a MX record attached to this hosted zone.


Instruction:
Can you tell what is the following Python 3 function doing
def create_ns_record(self, name, values, ttl=60):

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(NSResourceRecordSet, **values)

Response: Creates a new NS record.


Instruction:
Can you tell what is the following Python 3 function doing
def create_ptr_record(self, name, values, ttl=60):

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(PTRResourceRecordSet, **values)

Response: Creates a PTR record attached to this hosted zone.


Instruction:
Create a Python 3 function for
creating a new SPF record.

Response:
def create_spf_record(self, name, values, ttl=60):
        """
        Creates a SPF record attached to this hosted zone.

        :param str name: The fully qualified name of the record to add.
        :param list values: A list of value strings for the record.
        :keyword int ttl: The time-to-live of the record (in seconds).
        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created SPFResourceRecordSet instance.
        """

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(SPFResourceRecordSet, **values)


Instruction:
Can you generate the documentation for the following Python 3 function
def create_srv_record(self, name, values, ttl=60):

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(SRVResourceRecordSet, **values)

Response: Creates a SRV record attached to this hosted zone.


Instruction:
Write a Python 3 function for
creating a TXT record for the specified hosted zone.

Response:
def create_txt_record(self, name, values, ttl=60, weight=None, region=None,
                          set_identifier=None):
        """
        Creates a TXT record attached to this hosted zone.

        :param str name: The fully qualified name of the record to add.
        :param list values: A list of value strings for the record.
        :keyword int ttl: The time-to-live of the record (in seconds).
        :keyword int weight: *For weighted record sets only*. Among resource record
            sets that have the same combination of DNS name and type, a value
            that determines what portion of traffic for the current resource
            record set is routed to the associated location. Ranges from 0-255.
        :keyword str region: *For latency-based record sets*. The Amazon EC2 region
            where the resource that is specified in this resource record set
            resides.
        :keyword str set_identifier: *For weighted and latency resource record
            sets only*. An identifier that differentiates among multiple
            resource record sets that have the same combination of DNS name
            and type. 1-128 chars.
        :rtype: tuple
        :returns: A tuple in the form of ``(rrset, change_info)``, where
            ``rrset`` is the newly created TXTResourceRecordSet instance.
        """

        self._halt_if_already_deleted()

        # Grab the params/kwargs here for brevity's sake.
        values = locals()
        del values['self']

        return self._add_record(TXTResourceRecordSet, **values)


Instruction:
Make a summary of the following Python 3 code
def RegisterTXXXKey(cls, key, desc):
        frameid = "TXXX:" + desc

        def getter(id3, key):
            return list(id3[frameid])

        def setter(id3, key, value):
            try:
                frame = id3[frameid]
            except KeyError:
                enc = 0
                # Store 8859-1 if we can, per MusicBrainz spec.
                try:
                    for v in value:
                        v.encode('latin_1')
                except UnicodeError:
                    enc = 3

                id3.add(mutagen.id3.TXXX(encoding=enc, text=value, desc=desc))
            else:
                frame.text = value

        def deleter(id3, key):
            del(id3[frameid])

        cls.RegisterKey(key, getter, setter, deleter)

Response: Register a user - defined text frame key.


Instruction:
How would you explain what the following Python 3 function does
def get_change_values(change):

    action, rrset = change

    if action == 'CREATE':
        # For creations, we want the current values, since they don't need to
        # match an existing record set.
        values = dict()
        for key, val in rrset._initial_vals.items():
            # Pull from the record set's attributes, which are the current
            # values.
            values[key] = getattr(rrset, key)
        return values
    else:
        # We can look at the initial values dict for deletions, since we
        # have to match against the values currently in Route53.
        return rrset._initial_vals

Response: Get the change values for the current record set.


Instruction:
Here you have a function in Python 3, explain what it does
def write_change(change):

    action, rrset = change

    change_vals = get_change_values(change)

    e_change = etree.Element("Change")

    e_action = etree.SubElement(e_change, "Action")
    e_action.text = action

    e_rrset = etree.SubElement(e_change, "ResourceRecordSet")

    e_name = etree.SubElement(e_rrset, "Name")
    e_name.text = change_vals['name']

    e_type = etree.SubElement(e_rrset, "Type")
    e_type.text = rrset.rrset_type

    if change_vals.get('set_identifier'):
        e_set_id = etree.SubElement(e_rrset, "SetIdentifier")
        e_set_id.text = change_vals['set_identifier']

    if change_vals.get('weight'):
        e_weight = etree.SubElement(e_rrset, "Weight")
        e_weight.text = change_vals['weight']

    if change_vals.get('alias_hosted_zone_id') or change_vals.get('alias_dns_name'):
        e_alias_target = etree.SubElement(e_rrset, "AliasTarget")

        e_hosted_zone_id = etree.SubElement(e_alias_target, "HostedZoneId")
        e_hosted_zone_id.text = change_vals['alias_hosted_zone_id']
        e_dns_name = etree.SubElement(e_alias_target, "DNSName")
        e_dns_name.text = change_vals['alias_dns_name']

    if change_vals.get('region'):
        e_weight = etree.SubElement(e_rrset, "Region")
        e_weight.text = change_vals['region']

    e_ttl = etree.SubElement(e_rrset, "TTL")
    e_ttl.text = str(change_vals['ttl'])

    if rrset.is_alias_record_set():
        # A record sets in Alias mode don't have any resource records.
        return e_change

    e_resource_records = etree.SubElement(e_rrset, "ResourceRecords")

    for value in change_vals['records']:
        e_resource_record = etree.SubElement(e_resource_records, "ResourceRecord")
        e_value = etree.SubElement(e_resource_record, "Value")
        e_value.text = value

    return e_change

Response: Writes a Change to the XML file.


Instruction:
Can you tell what is the following Python 3 function doing
def change_resource_record_set_writer(connection, change_set, comment=None):

    e_root = etree.Element(
        "ChangeResourceRecordSetsRequest",
        xmlns=connection._xml_namespace
    )

    e_change_batch = etree.SubElement(e_root, "ChangeBatch")

    if comment:
        e_comment = etree.SubElement(e_change_batch, "Comment")
        e_comment.text = comment

    e_changes = etree.SubElement(e_change_batch, "Changes")

    # Deletions need to come first in the change sets.
    for change in change_set.deletions + change_set.creations:
        e_changes.append(write_change(change))

    e_tree = etree.ElementTree(element=e_root)

    #print(prettyprint_xml(e_root))

    fobj = BytesIO()
    # This writes bytes.
    e_tree.write(fobj, xml_declaration=True, encoding='utf-8', method="xml")
    return fobj.getvalue().decode('utf-8')

Response: This function creates a new change resource record set request.


Instruction:
Can you tell what is the following Python 3 function doing
def validate_integer(self, action, index, value_if_allowed, prior_value,
                         text, validation_type, trigger_type, widget_name):
        """Check if text Entry is valid (number).

        I have no idea what all these arguments are doing here but took this from
        https://stackoverflow.com/questions/8959815/restricting-the-value-in-tkinter-entry-widget
        """
        if(action == '1'):
            if text in '0123456789.-+':
                try:
                    int(value_if_allowed)
                    return True
                except ValueError:
                    return False
            else:
                return False
        else:
            return True

Response: Check if text Entry is valid integer.


Instruction:
How would you explain what the following Python 3 function does
def alias_item(self, alias):
        ident = self.alias[alias]
        return self.items[ident]

Response: Gets an item by its alias.


Instruction:
Create a Python 3 function to
freeze dict into tuple.

Response:
def freeze_dict(dict_):
    """Freezes ``dict`` into ``tuple``.

    A typical usage is packing ``dict`` into hashable.

    e.g.::

        >>> freeze_dict({'a': 1, 'b': 2})
        (('a', 1), ('b', 2))
    """
    pairs = dict_.items()
    key_getter = operator.itemgetter(0)
    return tuple(sorted(pairs, key=key_getter))


Instruction:
Implement a Python 3 function for
joining the map structure into HTML attributes.

Response:
def join_html_attrs(attrs):
    """Joins the map structure into HTML attributes.

    The return value is a 2-tuple ``(template, ordered_values)``. It should be
    passed into :class:`markupsafe.Markup` to prevent XSS attacked.

    e.g.::

        >>> join_html_attrs({'href': '/', 'data-active': 'true'})
        ('data-active="{0}" href="{1}"', ['true', '/'])
    """
    attrs = collections.OrderedDict(freeze_dict(attrs or {}))
    template = ' '.join('%s="{%d}"' % (k, i) for i, k in enumerate(attrs))
    return template, list(attrs.values())


Instruction:
Can you generate the documentation for the following Python 3 function
def init_app(self, app):
        # connects app-level signals
        appcontext_pushed.connect(self.initialize_bars, app)
        # integrate with jinja template
        app.add_template_global(self, 'nav')

Response: Initializes an app to work with this extension.


Instruction:
Explain what the following Python 3 code does
def initialize_bars(self, sender=None, **kwargs):
        for bar in self.bars.values():
            for initializer in bar.initializers:
                initializer(self)

Response: Calls the initializers of all bound navigation bars.


Instruction:
How would you explain what the following Python 3 function does
def bind_bar(self, sender=None, **kwargs):
        bar = kwargs.pop('bar')
        self.bars[bar.name] = bar

Response: Binds a navigation bar into this extension instance.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def url(self):
        if self.is_internal:
            return url_for(self.endpoint, **self.args)
        return self._url

Response: The final url of this navigation item.


Instruction:
Can you write a function in Python 3 where it
trues if the current request has the same endpoint with the item.

Response:
def is_current(self):
        """``True`` if current request has same endpoint with the item.

        The property should be used in a bound request context, or the
        :class:`RuntimeError` may be raised.
        """
        if not self.is_internal:
            return False  # always false for external url
        has_same_endpoint = (request.endpoint == self.endpoint)
        has_same_args = (request.view_args == self.args)
        return has_same_endpoint and has_same_args


Instruction:
Given the following Python 3 function, write the documentation
def config_path(self, value):
        self._config_path = value or ''
        if not isinstance(self._config_path, str):
            raise BadArgumentError("config_path must be string: {}".format(
                self._config_path))

Response: Set the config_path of the resource.


Instruction:
Explain what the following Python 3 code does
def dictionary(self, value):
        self._dictionary = value or {}
        if not isinstance(self._dictionary, dict):
            raise BadArgumentError("dictionary must be dict: {}".format(
                self._dictionary))

Response: Set the dictionary of the user s account.


Instruction:
Explain what the following Python 3 code does
def api_options(self):
        options = 0
        if self._ignore_uppercase:
            options |= 1
        if self._ignore_digits:
            options |= 2
        if self._ignore_urls:
            options |= 4
        if self._find_repeat_words:
            options |= 8
        if self._ignore_latin:
            options |= 16
        if self._flag_latin:
            options |= 128
        if self._by_words:
            options |= 256
        if self._ignore_capitalization:
            options |= 512
        if self._ignore_roman_numerals:
            options |= 2048
        return options

Response: returns the current api options as a bitmask


Instruction:
Can you write a function in Python 3 where it
validates that the metric class is valid.

Response:
def validate(metric_class):
    """
    Does basic Metric option validation.
    """
    if not hasattr(metric_class, 'label'):
        raise ImproperlyConfigured("No 'label' attribute found for metric %s." % metric_class.__name__)

    if not hasattr(metric_class, 'widget'):
        raise ImproperlyConfigured("No 'widget' attribute found for metric %s." % metric_class.__name__)


Instruction:
Explain what the following Python 3 code does
def get_statistic_by_name(stat_name):

    if stat_name == 'ALL':
        return get_statistic_models()

    for stat in get_statistic_models():
        if stat.__name__ == stat_name:
            return stat

    raise Exception, _("%(stat)s cannot be found.") % {'stat': stat_name}

Response: Returns a stat object based on the given class name.


Instruction:
Can you tell what is the following Python 3 function doing
def calculate_statistics(stat, frequencies):
    stats = ensure_list(stat)
    frequencies = ensure_list(frequencies)

    for stat in stats:
        for f in frequencies:
            print "Calculating %s (%s)..." % (stat.__name__, settings.STATISTIC_FREQUENCY_DICT[f])
            stat.calculate(f)

Response: Calculates all of the metrics associated with the registered gadgets.


Instruction:
Write a Python 3 function for
resetting the specified statistic s data for the given frequency / ies.

Response:
def reset_statistics(stat, frequencies, reset_cumulative, recalculate=False):
    """
    Resets the specified statistic's data (deletes it) for the given
    frequency/ies.
    """

    stats = ensure_list(stat)
    frequencies = ensure_list(frequencies)

    for s in stats:
        for f in frequencies:
            if not s.cumulative or reset_cumulative:
                print "Resetting %s (%s)..." % (s.__name__, settings.STATISTIC_FREQUENCY_DICT[f])
                s.objects.filter(frequency=f).delete()
            elif s.cumulative and not reset_cumulative:
                print "Skipping %s because it is cumulative." % s.__name__

    if recalculate:
        print "Recalculating statistics..."
        calculate_statistics(stats, frequencies)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def autodiscover():
    from django.conf import settings
    from django.utils.importlib import import_module
    from django.utils.module_loading import module_has_submodule

    for app in settings.INSTALLED_APPS:
        mod = import_module(app)
        # Attempt to import the app's gadgets module.
        try:
            import_module('%s.gadgets' % app)
        except:
            # Decide whether to bubble up this error. If the app just
            # doesn't have a gadgets module, we can ignore the error
            # attempting to import it, otherwise we want it to bubble up.
            if module_has_submodule(mod, 'gadgets'):
                raise

Response: Auto - discover INSTALLED_APPS gadgets. py modules and fail silently when there is no gadgets module.


Instruction:
Can you write a function in Python 3 where it
returns a CSV dump of all of the specified metric s counts and cumulative counts.

Response:
def csv_dump(request, uid):
    """
    Returns a CSV dump of all of the specified metric's counts
    and cumulative counts.
    """

    metric = Metric.objects.get(uid=uid)
    frequency = request.GET.get('frequency', settings.STATISTIC_FREQUENCY_DAILY)

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s%s.csv' % (uid, datetime.datetime.now().strftime("%Y%m%d-%H%M"))

    writer = csv.writer(response)
    writer.writerow([_('Date/time'), _('Count'), _('Cumulative count')])
    for stat in metric.statistics.filter(frequency=frequency).order_by('date_time'):
        writer.writerow([stat.date_time.strftime(settings.CSV_DATETIME_FORMAT), stat.count, stat.cumulative_count])

    return response


Instruction:
Make a summary of the following Python 3 code
def calculate(cls, frequency=settings.STATISTIC_FREQUENCY_DAILY, verbose=settings.STATISTIC_CALCULATION_VERBOSE):
        if verbose:
            print _("Calculating statistics for %(class)s...") % {'class': cls.get_label()}

        start_datetime = None
        end_datetime = None

        # get the latest statistic
        latest_stat = cls.get_latest(frequency)

        # work out today's date, truncated to midnight
        today = datetime.strptime(datetime.now().strftime("%Y %m %d"), "%Y %m %d")
        now = datetime.now()

        # if this statistic only has cumulative stats available
        if cls.cumulative:
            if frequency == settings.STATISTIC_FREQUENCY_HOURLY:
                # truncate to the nearest hour
                start_datetime = datetime.strptime(now.strftime("%Y %m %d %H:00:00"), "%Y %m %d %H:%M:%S")
            elif frequency == settings.STATISTIC_FREQUENCY_DAILY:
                start_datetime = today
            elif frequency == settings.STATISTIC_FREQUENCY_WEEKLY:
                # truncate today to the start of this week
                start_datetime = datetime.strptime(today.strftime("%Y %W 0"), "%Y %W %w")
            elif frequency == settings.STATISTIC_FREQUENCY_MONTHLY:
                # truncate today to the start of this month
                start_datetime = datetime.strptime(today.strftime("%Y %m 1"), "%Y %m %d")

            stat, created = cls.objects.get_or_create(date_time=start_datetime, frequency=frequency)
            stat.cumulative_count = cls.get_cumulative()
            stat.count = (stat.cumulative_count-latest_stat.cumulative_count) if latest_stat else stat.cumulative_count
        else:
            # get the date/time at which we should start calculating
            start_datetime = cls.get_start_datetime() if latest_stat is None else latest_stat.date_time
            # truncate the start date/time to the appropriate frequency
            if frequency == settings.STATISTIC_FREQUENCY_HOURLY:
                start_datetime = datetime.strptime(start_datetime.strftime("%Y %m %d %H:00:00"), "%Y %m %d %H:%M:%S")
                end_datetime = start_datetime+timedelta(hours=1)
            elif frequency == settings.STATISTIC_FREQUENCY_DAILY:
                start_datetime = datetime.strptime(start_datetime.strftime("%Y %m %d"), "%Y %m %d")
                end_datetime = start_datetime+timedelta(days=1)
            elif frequency == settings.STATISTIC_FREQUENCY_WEEKLY:
                # start at the beginning of the week of the latest stat
                start_datetime = datetime.strptime(start_datetime.strftime("%Y %W 0"), "%Y %W %w")-timedelta(days=7)
                end_datetime = start_datetime+timedelta(days=7)
            elif frequency == settings.STATISTIC_FREQUENCY_MONTHLY:
                # start at the beginning of the month of the latest stat
                start_datetime = datetime.strptime(start_datetime.strftime("%Y %m 1"), "%Y %m %d")
                end_datetime = datetime.strptime((start_datetime+timedelta(days=33)).strftime("%Y %m 1"), "%Y %m %d")

            # if we're doing the normal count
            while start_datetime < now:
                count = cls.get_count(start_datetime, end_datetime)
                cumulative_count = 0
                if isinstance(count, tuple):
                    cumulative_count = count[1]
                    count = count[0]
                else:
                    cumulative_count = (latest_stat.cumulative_count+count) if latest_stat else count

                stat, created = cls.objects.get_or_create(date_time=start_datetime, frequency=frequency)
                stat.count = count
                stat.cumulative_count = cumulative_count
                stat.save()

                latest_stat = stat

                # update the dates/time window
                start_datetime = end_datetime
                if frequency == settings.STATISTIC_FREQUENCY_HOURLY:
                    end_datetime += timedelta(hours=1)
                elif frequency == settings.STATISTIC_FREQUENCY_DAILY:
                    end_datetime += timedelta(days=1)
                elif frequency == settings.STATISTIC_FREQUENCY_WEEKLY:
                    end_datetime += timedelta(days=7)
                elif frequency == settings.STATISTIC_FREQUENCY_MONTHLY:
                    end_datetime = datetime.strptime((start_datetime+timedelta(days=33)).strftime("%Y %m 1"), "%Y %m %d")

Response: Calculates the statistics for the current statistic and returns a dictionary of the statistics for the current statistic and the current date.


Instruction:
How would you implement a function in Python 3 that
handles the metrics command.

Response:
def handle(self, *args, **kwargs):
        """
        Command handler for the "metrics" command.
        """

        frequency = kwargs['frequency']
        frequencies = settings.STATISTIC_FREQUENCY_ALL if frequency == 'a' else (frequency.split(',') if ',' in frequency else [frequency])

        if kwargs['list']:
            maintenance.list_statistics()

        # if we're supposed to calculate the latest statistics
        elif kwargs['calculate']:
            maintenance.calculate_statistics(maintenance.get_statistic_by_name(kwargs['calculate']), frequencies)

        # pure reset of statistic(s)
        elif kwargs['reset']:
            maintenance.reset_statistics(maintenance.get_statistic_by_name(kwargs['reset']), frequencies, kwargs['reset_cumulative'])

        # recalculation of statistic(s)
        elif kwargs['recalculate']:
            maintenance.reset_statistics(maintenance.get_statistic_by_name(kwargs['recalculate']), frequencies, kwargs['reset_cumulative'], True)


Instruction:
Implement a Python 3 function for
returning the GET array for the specified variable.

Response:
def get_GET_array(request, var_name, fail_silently=True):
    """
    Returns the GET array's contents for the specified variable.
    """

    vals = request.GET.getlist(var_name)
    if not vals:
        if fail_silently:
            return []
        else:
            raise Exception, _("No array called '%(varname)s' in GET variables") % {'varname': var_name}

    return vals


Instruction:
Implement a function in Python 3 to
try to extract a boolean variable from the specified request.

Response:
def get_GET_bool(request, var_name, default=True):
    """
    Tries to extract a boolean variable from the specified request.
    """

    val = request.GET.get(var_name, default)
    if isinstance(val, str) or isinstance(val, unicode):
        val = True if val[0] == 't' else False

    return val


Instruction:
Make a summary of the following Python 3 code
def get_next_colour():

    colour = settings.GECKOBOARD_COLOURS[get_next_colour.cur_colour]

    get_next_colour.cur_colour += 1
    if get_next_colour.cur_colour >= len(settings.GECKOBOARD_COLOURS):
        get_next_colour.cur_colour = 0

    return colour

Response: Gets the next colour in the Geckoboard colour list.


Instruction:
Write a Python 3 script for
returning the GET parameters for a particular Geckoboard view request.

Response:
def get_gecko_params(request, uid=None, days_back=0, cumulative=True,
    frequency=settings.STATISTIC_FREQUENCY_DAILY, min_val=0, max_val=100,
    chart_type='standard', percentage='show', sort=False):
    """
    Returns the default GET parameters for a particular Geckoboard
    view request.
    """

    return {
        'days_back'  : int(request.GET.get('daysback', days_back)),
        'uid'        : request.GET.get('uid', uid),
        'uids'       : get_GET_array(request, 'uids[]'),
        'cumulative' : get_GET_bool(request, 'cumulative', cumulative),
        'frequency'  : request.GET.get('frequency', frequency),
        'min'        : request.GET.get('min', min_val),
        'max'        : request.GET.get('max', max_val),
        'type'       : request.GET.get('type', chart_type),
        'percentage' : request.GET.get('percentage', percentage),
        'sort'       : get_GET_bool(request, 'sort', sort),
    }


Instruction:
Write a Python 3 function that can
return a number widget for the specified metric s cumulative total.

Response:
def geckoboard_number_widget(request):
    """
    Returns a number widget for the specified metric's cumulative total.
    """

    params = get_gecko_params(request, days_back=7)
    metric = Metric.objects.get(uid=params['uid'])
    try:
        latest_stat = metric.statistics.filter(frequency=params['frequency']).order_by('-date_time')[0]
    except IndexError:
        return (0, 0)

    try:
        prev_stat = metric.statistics.filter(frequency=params['frequency'],
            date_time__lte=latest_stat.date_time-timedelta(days=params['days_back'])).order_by('-date_time')[0]
    except IndexError:
        # if there is no previous stat
        return (latest_stat.cumulative_count, 0) if params['cumulative'] else (latest_stat.count, 0)

    return (latest_stat.cumulative_count, prev_stat.cumulative_count) if params['cumulative'] else (latest_stat.count, prev_stat.count)


Instruction:
Given the following Python 3 function, write the documentation
def geckoboard_rag_widget(request):

    params = get_gecko_params(request)
    print params['uids']
    max_date = datetime.now()-timedelta(days=params['days_back'])

    metrics = Metric.objects.filter(uid__in=params['uids'])
    results = [(metric.latest_count(frequency=params['frequency'], count=not params['cumulative'],
        cumulative=params['cumulative'], max_date=max_date), metric.title) for metric in metrics]

    return tuple(results)

Response: Returns a tuple of the latest count of all metrics in a RAG widget.


Instruction:
Explain what the following Python 3 code does
def geckoboard_pie_chart(request):

    params = get_gecko_params(request, cumulative=True)
    from_date = datetime.now()-timedelta(days=params['days_back'])

    metrics = Metric.objects.filter(uid__in=params['uids'])
    results = [(metric.latest_count(frequency=params['frequency'], count=not params['cumulative'],
        cumulative=params['cumulative']), metric.title, get_next_colour()) for metric in metrics]

    return tuple(results)

Response: Displays a pie chart of the metrics in the uids[] GET variable array.


Instruction:
Write a Python 3 script for
returning the data for a line chart for the specified metric.

Response:
def geckoboard_line_chart(request):
    """
    Returns the data for a line chart for the specified metric.
    """

    params = get_gecko_params(request, cumulative=False, days_back=7)
    metric = Metric.objects.get(uid=params['uid'])

    start_date = datetime.now()-timedelta(days=params['days_back'])
    stats = [s for s in metric.statistics.filter(frequency=params['frequency'],
        date_time__gte=start_date).order_by('date_time')]

    if len(stats) == 0:
        raise Exception, _("No statistics for metric %(metric)s.") % {'metric': params['uid']}

    dates = [stats[0].date_time]

    # get up to 3 dates from the stats
    if len(stats) >= 3:
        mid = len(stats)/2
        if not mid:
            mid = 1
        dates.extend([stats[mid].date_time, stats[-1].date_time])
    elif len(stats) == 2:
        dates.extend([stats[-1].date_time])

    return (
        [s.count for s in stats],
        dates,
        metric.title,
    )


Instruction:
Write a Python 3 function that can
return a Geckoboard - Metrics control for the specified metric.

Response:
def geckoboard_geckometer(request):
    """
    Returns a Geck-o-Meter control for the specified metric.
    """

    params = get_gecko_params(request, cumulative=True)
    metric = Metric.objects.get(uid=params['uid'])

    return (metric.latest_count(frequency=params['frequency'], count=not params['cumulative'],
        cumulative=params['cumulative']), params['min'], params['max'])


Instruction:
Can you write a function in Python 3 where it
returns a funnel chart for the metrics specified in the GET variables.

Response:
def geckoboard_funnel(request, frequency=settings.STATISTIC_FREQUENCY_DAILY):
    """
    Returns a funnel chart for the metrics specified in the GET variables.
    """

    # get all the parameters for this function
    params = get_gecko_params(request, cumulative=True)
    metrics = Metric.objects.filter(uid__in=params['uids'])
    items = [(metric.latest_count(frequency=params['frequency'], count=not params['cumulative'],
        cumulative=params['cumulative']), metric.title) for metric in metrics]

    return {
        'items'     : items,
        'type'      : params['type'],
        'percentage': params['percentage'],
        'sort'      : params['sort'],
    }


Instruction:
Can you implement a function in Python 3 that
returns all of the active statistics for the currently registered gadgets.

Response:
def get_active_stats(self):
        """
        Returns all of the active statistics for the gadgets currently registered.
        """
        stats = []
        for gadget in self._registry.values():
            for s in gadget.stats:
                if s not in stats:
                    stats.append(s)
        return stats


Instruction:
Can you implement a function in Python 3 that
registers a gadget object.

Response:
def register(self, gadget):
        """
        Registers a gadget object.
        If a gadget is already registered, this will raise AlreadyRegistered.
        """
        if gadget in self._registry:
            raise AlreadyRegistered
        else:
            self._registry.append(gadget)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def unregister(self, gadgets):
        gadgets = maintenance.ensure_list(gadgets)
        for gadget in gadgets:
            while gadget in self._registry:
                self._registry.remove(gadget)

Response: Unregisters the specified gadgets from the registry.


Instruction:
Here you have a function in Python 3, explain what it does
def get_context_data(self, **kwargs):
        #max_columns, max_rows = self.get_max_dimension()
        context = {
            'gadgets': self._registry,
            'columns': self.columns,
            'rows': self.rows,
            'column_ratio': 100 - self.columns * 2,
            'row_ratio': 100 - self.rows * 2,
        }
        context.update(kwargs)
        return context

Response: Get the context data for this view.


Instruction:
How would you explain what the following Python 3 function does
def get_model(self, model_name):
        klass = None
        try:
            module_name, class_name = model_name.rsplit('.', 1)
            mod = __import__(module_name, fromlist=[class_name])
            klass = getattr(mod, class_name)
        except ImportError, e:
            self.error('Cannot find app %s %s' % (model_name, e))

        return klass

Response: Get the class object for the given model name.


Instruction:
Can you generate the documentation for the following Python 3 function
def custom(self, code, message):
        if -32000 < code or -32099 > code:
            code = -32603
            message = 'Internal error'
        return JResponse(jsonrpc={
            'id': self.rid,
            'error': {'code': code, 'message': message},
        })

Response:
Specific server side errors use: -32000 to -32099
        reserved for implementation-defined server-errors


Instruction:
Explain what the following Python 3 code does
def string_input(prompt=''):
    v = sys.version[0]
    if v == '3':
        return input(prompt)
    else:
        return raw_input(prompt)

Response: Python 3 input()/Python 2 raw_input()


Instruction:
How would you code a function in Python 3 to
get input from a list of choices

Response:
def choice_input(options=[], prompt='Press ENTER to continue.',
        showopts=True, qopt=False):
    """Get input from a list of choices (q to quit)"""

    choice = None
    if showopts:
        prompt = prompt + ' ' + str(options)
    if qopt:
        prompt = prompt + ' (q to quit)'

    while not choice:
        try:
            choice = string_input(prompt + ' ')
        except SyntaxError:
            if options == []:
                pass
        if choice:
            if choice in options:
                return choice
            elif qopt == True and choice == 'q':
                choice = None
                is_sure = string_input('Are you sure you want to quit? ')
                if is_sure in ('Y', 'y', 'yes'):
                    exit('\nThanks for playing. Goodbye.\n')
            elif options == []:
                return 0
            else:
                print('Answer must be one of ' + str(options) +
                        '. Your answer?')
                if options:
                    choice = None
        elif options == []:
            return 0
        else:
            print('Answer must be one of ' + str(options) +
                    '. Your answer?')


Instruction:
Here you have a function in Python 3, explain what it does
def long_input(prompt='Multi-line input\n' + \
        'Enter EOF on a blank line to end ' + \
        '(ctrl-D in *nix, ctrl-Z in windows)',
        maxlines = None, maxlength = None):
    """Get a multi-line string as input"""

    lines = []
    print(prompt)
    lnum = 1

    try:
        while True:

            if maxlines:

                if lnum > maxlines:
                    break

                else:
                    if maxlength:
                        lines.append(string_input('')[:maxlength])
                    else:
                        lines.append(string_input(''))
                    lnum += 1

            else:
                if maxlength:
                    lines.append(string_input('')[:maxlength])
                else:
                    lines.append(string_input(''))

    except EOFError:
        pass
    finally:
        return '\n'.join(lines)

Response: Get a multi - line string as input


Instruction:
Create a Python 3 function for
getting a list of strings as input

Response:
def list_input(prompt='List input - enter each item on a seperate line\n' + \
        'Enter EOF on a blank line to end ' + \
        '(ctrl-D in *nix, ctrl-Z in windows)',
        maxitems=None, maxlength=None):
    """Get a list of strings as input"""

    lines = []
    print(prompt)
    inum = 1

    try:

        while True:

            if maxitems:

                if inum > maxitems:
                    break
                else:
                    if maxlength:
                        lines.append(string_input('')[:maxlength])
                    else:
                        lines.append(string_input(''))
                    inum += 1

            else:
                if maxlength:
                    lines.append(string_input('')[:maxlength])
                else:
                    lines.append(string_input(''))

    except EOFError:
        pass
    finally:
        return lines


Instruction:
Can you generate a brief explanation for the following Python 3 code
def outfile_input(extension=None):

    fileok = False

    while not fileok:
        filename = string_input('File name? ')
        if extension:
            if not filename.endswith(extension):
                if extension.startswith('.'):
                    filename = filename + extension
                else:
                    filename = filename + '.' + extension
        if os.path.isfile(filename):
            choice = choice_input(prompt=filename + \
                    ' already exists. Overwrite?',
                    options=['y', 'n'])
            if choice == 'y':
                try:
                    nowtime = time.time()
                    with open(filename, 'a') as f:
                        os.utime(filename, (nowtime, nowtime))
                    fileok = True
                except IOError:
                    print('Write permission denied on ' + filename + \
                            '. Try again.')
                except PermissionError:
                    print('Write permission denied on ' + filename + \
                            '. Try again.')
                except FileNotFoundError:
                    print(filename + ': directory not found. Try again.')

        else:
            choice = choice_input(
                    prompt=filename + ' does not exist. Create it?',
                    options=['y', 'n'])
            if choice == 'y':
                try:
                    nowtime = time.time()
                    with open(filename, 'w') as f:
                        os.utime(filename, (nowtime, nowtime))
                    fileok = True
                except IOError:
                    print('Write permission denied on ' + filename + \
                            '. Try again.')
                except PermissionError:
                    print('Write permission denied on ' + filename + \
                            '. Try again.')
                except FileNotFoundError:
                    print(filename + ': directory not found. Try again.')

    return filename

Response: Get an output file name as input


Instruction:
Explain what the following Python 3 code does
def roster(self, year):
        doc = self.get_year_doc(year)
        table = doc('table#roster')
        df = sportsref.utils.parse_table(table)
        df['years_experience'] = (df['years_experience']
                                  .replace('R', 0).replace('', np.nan).astype(float))
        return df

Response: Returns the roster table for the given year.


Instruction:
Write a Python 3 function that can
get the schedule information for a given year.

Response:
def schedule(self, year):
        """Gets schedule information for a team-season.

        :year: The year for which we want the schedule.
        :returns: DataFrame of schedule information.
        """
        doc = self.get_year_doc('{}_games'.format(year))
        table = doc('table#games')
        df = sportsref.utils.parse_table(table)
        return df


Instruction:
Make a summary of the following Python 3 code
def date(self):
        match = re.match(r'(\d{4})(\d{2})(\d{2})', self.boxscore_id)
        year, month, day = map(int, match.groups())
        return datetime.date(year=year, month=month, day=day)

Response:
Returns the date of the game. See Python datetime. date documentation
        for more.


Instruction:
Here you have a function in Python 3, explain what it does
def weekday(self):
        days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
                'Saturday', 'Sunday']
        date = self.date()
        wd = date.weekday()
        return days[wd]

Response: Returns the weekday of the game.


Instruction:
Create a Python 3 function for
returning home team ID.

Response:
def home(self):
        """Returns home team ID.
        :returns: 3-character string representing home team's ID.
        """
        doc = self.get_doc()
        table = doc('table.linescore')
        relURL = table('tr').eq(2)('a').eq(2).attr['href']
        home = sportsref.utils.rel_url_to_id(relURL)
        return home


Instruction:
Can you write a function in Python 3 where it
returns the score of the home team.

Response:
def home_score(self):
        """Returns score of the home team.
        :returns: int of the home score.
        """
        doc = self.get_doc()
        table = doc('table.linescore')
        home_score = table('tr').eq(2)('td')[-1].text_content()
        return int(home_score)


Instruction:
Explain what the following Python 3 code does
def away_score(self):
        doc = self.get_doc()
        table = doc('table.linescore')
        away_score = table('tr').eq(1)('td')[-1].text_content()
        return int(away_score)

Response: Returns the score of the away team.


Instruction:
Can you create a Python 3 function that
returns the team ID of the winning team. Returns NaN if a tie. Returns NaN if a tie.

Response:
def winner(self):
        """Returns the team ID of the winning team. Returns NaN if a tie."""
        hmScore = self.home_score()
        awScore = self.away_score()
        if hmScore > awScore:
            return self.home()
        elif hmScore < awScore:
            return self.away()
        else:
            return None


Instruction:
Explain what the following Python 3 code does
def week(self):
        doc = self.get_doc()
        raw = doc('div#div_other_scores h2 a').attr['href']
        match = re.match(
            r'/years/{}/week_(\d+)\.htm'.format(self.season()), raw
        )
        if match:
            return int(match.group(1))
        else:
            return 21

Response: Returns the week in which this game took place.


Instruction:
Write a Python 3 function for
returning the year ID of the season in which this game took place.

Response:
def season(self):
        """
        Returns the year ID of the season in which this game took place.
        Useful for week 17 January games.

        :returns: An int representing the year of the season.
        """
        date = self.date()
        return date.year - 1 if date.month <= 3 else date.year


Instruction:
Write a Python 3 function for
returning a pandas DataFrame where each row is an entry in the starters table where each row is a dictionary of the values for the keys player_id playerName position team home and offense.

Response:
def starters(self):
        """Returns a DataFrame where each row is an entry in the starters table
        from PFR.

        The columns are:
        * player_id - the PFR player ID for the player (note that this column
        is not necessarily all unique; that is, one player can be a starter in
        multiple positions, in theory).
        * playerName - the listed name of the player; this too is not
        necessarily unique.
        * position - the position at which the player started for their team.
        * team - the team for which the player started.
        * home - True if the player's team was at home, False if they were away
        * offense - True if the player is starting on an offensive position,
        False if defense.

        :returns: A pandas DataFrame. See the description for details.
        """
        doc = self.get_doc()
        a = doc('table#vis_starters')
        h = doc('table#home_starters')
        data = []
        for h, table in enumerate((a, h)):
            team = self.home() if h else self.away()
            for i, row in enumerate(table('tbody tr').items()):
                datum = {}
                datum['player_id'] = sportsref.utils.rel_url_to_id(
                    row('a')[0].attrib['href']
                )
                datum['playerName'] = row('th').text()
                datum['position'] = row('td').text()
                datum['team'] = team
                datum['home'] = (h == 1)
                datum['offense'] = (i <= 10)
                data.append(datum)
        return pd.DataFrame(data)


Instruction:
Explain what the following Python 3 code does
def surface(self):
        doc = self.get_doc()
        table = doc('table#game_info')
        giTable = sportsref.utils.parse_info_table(table)
        return giTable.get('surface', np.nan)

Response: Returns the type of the playing surface on which the game was played.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def over_under(self):
        doc = self.get_doc()
        table = doc('table#game_info')
        giTable = sportsref.utils.parse_info_table(table)
        if 'over_under' in giTable:
            ou = giTable['over_under']
            return float(ou.split()[0])
        else:
            return None

Response: Returns the over - under for the game as a float or np. nan.


Instruction:
Can you implement a function in Python 3 that
returns the dictionary of coin toss - related info.

Response:
def coin_toss(self):
        """Gets information relating to the opening coin toss.

        Keys are:
        * wonToss - contains the ID of the team that won the toss
        * deferred - bool whether the team that won the toss deferred it

        :returns: Dictionary of coin toss-related info.
        """
        doc = self.get_doc()
        table = doc('table#game_info')
        giTable = sportsref.utils.parse_info_table(table)
        if 'Won Toss' in giTable:
            # TODO: finish coinToss function
            pass
        else:
            return None


Instruction:
Given the following Python 3 function, write the documentation
def weather(self):
        doc = self.get_doc()
        table = doc('table#game_info')
        giTable = sportsref.utils.parse_info_table(table)
        if 'weather' in giTable:
            regex = (
                r'(?:(?P<temp>\-?\d+) degrees )?'
                r'(?:relative humidity (?P<relHumidity>\d+)%, )?'
                r'(?:wind (?P<windMPH>\d+) mph, )?'
                r'(?:wind chill (?P<windChill>\-?\d+))?'
            )
            m = re.match(regex, giTable['weather'])
            d = m.groupdict()

            # cast values to int
            for k in d:
                try:
                    d[k] = int(d[k])
                except TypeError:
                    pass

            # one-off fixes
            d['windChill'] = (d['windChill'] if pd.notnull(d['windChill'])
                              else d['temp'])
            d['windMPH'] = d['windMPH'] if pd.notnull(d['windMPH']) else 0
            return d
        else:
            # no weather found, because it's a dome
            # TODO: what's relative humidity in a dome?
            return {
                'temp': 70, 'windChill': 70, 'relHumidity': None, 'windMPH': 0
            }

Response: Returns a dictionary of weather - related info.


Instruction:
Can you generate the documentation for the following Python 3 function
def pbp(self):
        doc = self.get_doc()
        table = doc('table#pbp')
        df = sportsref.utils.parse_table(table)
        # make the following features conveniently available on each row
        df['boxscore_id'] = self.boxscore_id
        df['home'] = self.home()
        df['away'] = self.away()
        df['season'] = self.season()
        df['week'] = self.week()
        feats = sportsref.nfl.pbp.expand_details(df)

        # add team and opp columns by iterating through rows
        df = sportsref.nfl.pbp._add_team_columns(feats)
        # add WPA column (requires diff, can't be done row-wise)
        df['home_wpa'] = df.home_wp.diff()
        # lag score columns, fill in 0-0 to start
        for col in ('home_wp', 'pbp_score_hm', 'pbp_score_aw'):
            if col in df.columns:
                df[col] = df[col].shift(1)
        df.loc[0, ['pbp_score_hm', 'pbp_score_aw']] = 0
        # fill in WP NaN's
        df.home_wp.fillna(method='ffill', inplace=True)
        # fix first play border after diffing/shifting for WP and WPA
        firstPlaysOfGame = df[df.secsElapsed == 0].index
        line = self.line()
        for i in firstPlaysOfGame:
            initwp = sportsref.nfl.winProb.initialWinProb(line)
            df.loc[i, 'home_wp'] = initwp
            df.loc[i, 'home_wpa'] = df.loc[i + 1, 'home_wp'] - initwp
        # fix last play border after diffing/shifting for WP and WPA
        lastPlayIdx = df.index[-1]
        lastPlayWP = df.loc[lastPlayIdx, 'home_wp']
        # if a tie, final WP is 50%; otherwise, determined by winner
        winner = self.winner()
        finalWP = 50. if pd.isnull(winner) else (winner == self.home()) * 100.
        df.loc[lastPlayIdx, 'home_wpa'] = finalWP - lastPlayWP
        # fix WPA for timeouts and plays after timeouts
        timeouts = df[df.isTimeout].index
        for to in timeouts:
            df.loc[to, 'home_wpa'] = 0.
            if to + 2 in df.index:
                wpa = df.loc[to + 2, 'home_wp'] - df.loc[to + 1, 'home_wp']
            else:
                wpa = finalWP - df.loc[to + 1, 'home_wp']
            df.loc[to + 1, 'home_wpa'] = wpa
        # add team-related features to DataFrame
        df = sportsref.nfl.pbp._add_team_features(df)
        # fill distToGoal NaN's
        df['distToGoal'] = np.where(df.isKickoff, 65, df.distToGoal)
        df.distToGoal.fillna(method='bfill', inplace=True)
        df.distToGoal.fillna(method='ffill', inplace=True)  # for last play

        return df

Response: Returns a dataframe of the play - by - play data from the game.


Instruction:
Create a Python 3 function for
returning a dictionary of ref positions and ref IDs of the refs for that game.

Response:
def ref_info(self):
        """Gets a dictionary of ref positions and the ref IDs of the refs for
        that game.

        :returns: A dictionary of ref positions and IDs.
        """
        doc = self.get_doc()
        table = doc('table#officials')
        return sportsref.utils.parse_info_table(table)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def player_stats(self):
        doc = self.get_doc()
        tableIDs = ('player_offense', 'player_defense', 'returns', 'kicking')
        dfs = []
        for tID in tableIDs:
            table = doc('table#{}'.format(tID))
            dfs.append(sportsref.utils.parse_table(table))
        dfs = [df for df in dfs if not df.empty]
        df = reduce(
            lambda x, y: pd.merge(
                x, y, how='outer', on=list(set(x.columns) & set(y.columns))
            ), dfs
        ).reset_index(drop=True)
        return df

Response:
Gets the stats for offense defense returning and kicking of
        individual players in the game.


Instruction:
Can you tell what is the following Python 3 function doing
def snap_counts(self):
        # TODO: combine duplicate players, see 201312150mia - ThomDa03
        doc = self.get_doc()
        table_ids = ('vis_snap_counts', 'home_snap_counts')
        tms = (self.away(), self.home())
        df = pd.concat([
            sportsref.utils.parse_table(doc('table#{}'.format(table_id)))
            .assign(is_home=bool(i), team=tms[i], opp=tms[i*-1+1])
            for i, table_id in enumerate(table_ids)
        ])
        if df.empty:
            return df
        return df.set_index('player_id')

Response: Gets the snap counts for both teams and home players and returns them in a DataFrame.


Instruction:
Create a Python 3 function to
return PyQuery object for the main season URL.

Response:
def get_main_doc(self):
        """Returns PyQuery object for the main season URL.
        :returns: PyQuery object.
        """
        url = (sportsref.nba.BASE_URL +
               '/leagues/NBA_{}.html'.format(self.yr))
        return pq(sportsref.utils.get_html(url))


Instruction:
How would you implement a function in Python 3 that
returns a PyQuery object for a given subpage URL.

Response:
def get_sub_doc(self, subpage):
        """Returns PyQuery object for a given subpage URL.
        :subpage: The subpage of the season, e.g. 'per_game'.
        :returns: PyQuery object.
        """
        html = sportsref.utils.get_html(self._subpage_url(subpage))
        return pq(html)


Instruction:
Can you create a Python 3 function that
returns a list of the team IDs for the given year.

Response:
def get_team_ids(self):
        """Returns a list of the team IDs for the given year.
        :returns: List of team IDs.
        """
        df = self.team_stats_per_game()
        if not df.empty:
            return df.index.tolist()
        else:
            print('ERROR: no teams found')
            return []


Instruction:
Can you tell what is the following Python 3 function doing
def team_ids_to_names(self):
        doc = self.get_main_doc()
        table = doc('table#team-stats-per_game')
        flattened = sportsref.utils.parse_table(table, flatten=True)
        unflattened = sportsref.utils.parse_table(table, flatten=False)
        team_ids = flattened['team_id']
        team_names = unflattened['team_name']
        if len(team_names) != len(team_ids):
            raise Exception("team names and team IDs don't align")
        return dict(zip(team_ids, team_names))

Response: Mapping from 3 - letter team IDs to full team names.


Instruction:
Can you tell what is the following Python 3 function doing
def team_names_to_ids(self):
        d = self.team_ids_to_names()
        return {v: k for k, v in d.items()}

Response: Mapping from full team names to 3 - letter team IDs.


Instruction:
Write a Python 3 script for
returning a DataFrame of BoxScore IDs for every game in the season.

Response:
def schedule(self, kind='R'):
        """Returns a list of BoxScore IDs for every game in the season.
        Only needs to handle 'R' or 'P' options because decorator handles 'B'.

        :param kind: 'R' for regular season, 'P' for playoffs, 'B' for both.
            Defaults to 'R'.
        :returns: DataFrame of schedule information.
        :rtype: pd.DataFrame
        """
        kind = kind.upper()[0]
        dfs = []

        # get games from each month
        for month in ('october', 'november', 'december', 'january', 'february',
                      'march', 'april', 'may', 'june'):
            try:
                doc = self.get_sub_doc('games-{}'.format(month))
            except ValueError:
                continue
            table = doc('table#schedule')
            df = sportsref.utils.parse_table(table)
            dfs.append(df)
        df = pd.concat(dfs).reset_index(drop=True)

        # figure out how many regular season games
        try:
            sportsref.utils.get_html('{}/playoffs/NBA_{}.html'.format(
                sportsref.nba.BASE_URL, self.yr)
            )
            is_past_season = True
        except ValueError:
            is_past_season = False

        if is_past_season:
            team_per_game = self.team_stats_per_game()
            n_reg_games = int(team_per_game.g.sum() // 2)
        else:
            n_reg_games = len(df)

        # subset appropriately based on `kind`
        if kind == 'P':
            return df.iloc[n_reg_games:]
        else:
            return df.iloc[:n_reg_games]


Instruction:
Make a summary of the following Python 3 code
def standings(self):
        doc = self.get_sub_doc('standings')

        east_table = doc('table#divs_standings_E')
        east_df = pd.DataFrame(sportsref.utils.parse_table(east_table))
        east_df.sort_values('wins', ascending=False, inplace=True)
        east_df['seed'] = range(1, len(east_df) + 1)
        east_df['conference'] = 'E'

        west_table = doc('table#divs_standings_W')
        west_df = sportsref.utils.parse_table(west_table)
        west_df.sort_values('wins', ascending=False, inplace=True)
        west_df['seed'] = range(1, len(west_df) + 1)
        west_df['conference'] = 'W'

        full_df = pd.concat([east_df, west_df], axis=0).reset_index(drop=True)
        full_df['team_id'] = full_df.team_id.str.extract(r'(\w+)\W*\(\d+\)', expand=False)
        full_df['gb'] = [gb if isinstance(gb, int) or isinstance(gb, float) else 0
                         for gb in full_df['gb']]
        full_df = full_df.drop('has_class_full_table', axis=1)

        expanded_table = doc('table#expanded_standings')
        expanded_df = sportsref.utils.parse_table(expanded_table)

        full_df = pd.merge(full_df, expanded_df, on='team_id')
        return full_df

Response: Returns a DataFrame containing the standings information.


Instruction:
Given the following Python 3 function, write the documentation
def _get_team_stats_table(self, selector):
        doc = self.get_main_doc()
        table = doc(selector)
        df = sportsref.utils.parse_table(table)
        df.set_index('team_id', inplace=True)
        return df

Response: Helper function for stats tables on season pages. Returns a Pandas DataFrame.


Instruction:
Here you have a function in Python 3, explain what it does
def roy_voting(self):
        url = '{}/awards/awards_{}.html'.format(sportsref.nba.BASE_URL, self.yr)
        doc = pq(sportsref.utils.get_html(url))
        table = doc('table#roy')
        df = sportsref.utils.parse_table(table)
        return df

Response: Returns a DataFrame containing information about ROY voting.


Instruction:
Can you generate the documentation for the following Python 3 function
def linescore(self):
        doc = self.get_main_doc()
        table = doc('table#line_score')

        columns = [th.text() for th in table('tr.thead').items('th')]
        columns[0] = 'team_id'

        data = [
            [sportsref.utils.flatten_links(td) for td in tr('td').items()]
            for tr in table('tr.thead').next_all('tr').items()
        ]

        return pd.DataFrame(data, index=['away', 'home'],
                            columns=columns, dtype='float')

Response: Returns the linescore for the game as a DataFrame.


Instruction:
Write a Python 3 script to
return the year ID of the game took place.

Response:
def season(self):
        """
        Returns the year ID of the season in which this game took place.

        :returns: An int representing the year of the season.
        """
        d = self.date()
        if d.month >= 9:
            return d.year + 1
        else:
            return d.year


Instruction:
Given the following Python 3 function, write the documentation
def _get_player_stats(self, table_id_fmt):

        # get data
        doc = self.get_main_doc()
        tms = self.away(), self.home()
        tm_ids = [table_id_fmt.format(tm) for tm in tms]
        tables = [doc('table#{}'.format(tm_id).lower()) for tm_id in tm_ids]
        dfs = [sportsref.utils.parse_table(table) for table in tables]

        # clean data and add features
        for i, (tm, df) in enumerate(zip(tms, dfs)):
            no_time = df['mp'] == 0
            stat_cols = [col for col, dtype in df.dtypes.items()
                         if dtype != 'object']
            df.loc[no_time, stat_cols] = 0
            df['team_id'] = tm
            df['is_home'] = i == 1
            df['is_starter'] = [p < 5 for p in range(df.shape[0])]
            df.drop_duplicates(subset='player_id', keep='first', inplace=True)

        return pd.concat(dfs)

Response: Returns a DataFrame of player stats from the game.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pbp(self, dense_lineups=False, sparse_lineups=False):
        try:
            doc = self.get_subpage_doc('pbp')
        except:
            raise ValueError(
                'Error fetching PBP subpage for boxscore {}'
                .format(self.boxscore_id)
            )
        table = doc('table#pbp')
        trs = [
            tr for tr in table('tr').items()
            if (not tr.attr['class'] or  # regular data rows
                tr.attr['id'] and tr.attr['id'].startswith('q'))  # qtr bounds
        ]
        rows = [tr.children('td') for tr in trs]
        n_rows = len(trs)
        data = []
        cur_qtr = 0
        bsid = self.boxscore_id

        for i in range(n_rows):
            tr = trs[i]
            row = rows[i]
            p = {}

            # increment cur_qtr when we hit a new quarter
            if tr.attr['id'] and tr.attr['id'].startswith('q'):
                assert int(tr.attr['id'][1:]) == cur_qtr + 1
                cur_qtr += 1
                continue

            # add time of play to entry
            t_str = row.eq(0).text()
            t_regex = r'(\d+):(\d+)\.(\d+)'
            mins, secs, tenths = map(int, re.match(t_regex, t_str).groups())
            endQ = (12 * 60 * min(cur_qtr, 4) +
                    5 * 60 * (cur_qtr - 4 if cur_qtr > 4 else 0))
            secsElapsed = endQ - (60 * mins + secs + 0.1 * tenths)
            p['secs_elapsed'] = secsElapsed
            p['clock_time'] = t_str
            p['quarter'] = cur_qtr

            # handle single play description
            # ex: beginning/end of quarter, jump ball
            if row.length == 2:
                desc = row.eq(1)
                # handle jump balls
                if desc.text().lower().startswith('jump ball: '):
                    p['is_jump_ball'] = True
                    jb_str = sportsref.utils.flatten_links(desc)
                    p.update(
                        sportsref.nba.pbp.parse_play(bsid, jb_str, None)
                    )
                # ignore rows marking beginning/end of quarters
                elif (
                    desc.text().lower().startswith('start of ') or
                    desc.text().lower().startswith('end of ')
                ):
                    continue
                # if another case, log and continue
                else:
                    if not desc.text().lower().startswith('end of '):
                        print(
                            '{}, Q{}, {} other case: {}'
                            .format(self.boxscore_id, cur_qtr,
                                    t_str, desc.text())
                        )
                    continue

            # handle team play description
            # ex: shot, turnover, rebound, foul, sub, etc.
            elif row.length == 6:
                aw_desc, hm_desc = row.eq(1), row.eq(5)
                is_hm_play = bool(hm_desc.text())
                desc = hm_desc if is_hm_play else aw_desc
                desc = sportsref.utils.flatten_links(desc)
                # parse the play
                new_p = sportsref.nba.pbp.parse_play(bsid, desc, is_hm_play)
                if not new_p:
                    continue
                elif isinstance(new_p, list):
                    # this happens when a row needs to be expanded to 2 rows;
                    # ex: double personal foul -> two PF rows

                    # first, update and append the first row
                    orig_p = dict(p)
                    p.update(new_p[0])
                    data.append(p)
                    # second, set up the second row to be appended below
                    p = orig_p
                    new_p = new_p[1]
                elif new_p.get('is_error'):
                    print("can't parse: {}, boxscore: {}"
                          .format(desc, self.boxscore_id))
                    # import pdb; pdb.set_trace()
                p.update(new_p)

            # otherwise, I don't know what this was
            else:
                raise Exception(("don't know how to handle row of length {}"
                                 .format(row.length)))

            data.append(p)

        # convert to DataFrame and clean columns
        df = pd.DataFrame.from_records(data)
        df.sort_values('secs_elapsed', inplace=True, kind='mergesort')
        df = sportsref.nba.pbp.clean_features(df)

        # add columns for home team, away team, boxscore_id, date
        away, home = self.away(), self.home()
        df['home'] = home
        df['away'] = away
        df['boxscore_id'] = self.boxscore_id
        df['season'] = self.season()
        date = self.date()
        df['year'] = date.year
        df['month'] = date.month
        df['day'] = date.day

        def _clean_rebs(df):
            df.reset_index(drop=True, inplace=True)
            no_reb_after = (
                (df.fta_num < df.tot_fta) | df.is_ftm |
                df.get('is_tech_fta', False)
            ).shift(1).fillna(False)
            no_reb_before = (
                (df.fta_num == df.tot_fta)
            ).shift(-1).fillna(False)
            se_end_qtr = df.loc[
                df.clock_time == '0:00.0', 'secs_elapsed'
            ].unique()
            no_reb_when = df.secs_elapsed.isin(se_end_qtr)
            drop_mask = (
                (df.rebounder == 'Team') &
                (no_reb_after | no_reb_before | no_reb_when)
            ).nonzero()[0]
            df.drop(drop_mask, axis=0, inplace=True)
            df.reset_index(drop=True, inplace=True)
            return df

        # get rid of 'rebounds' after FTM, non-final FTA, or tech FTA
        df = _clean_rebs(df)

        # track possession number for each possession
        # TODO: see 201604130PHO, secs_elapsed == 2756
        # things that end a poss:
        # FGM, dreb, TO, end of Q, made last FT, lost jump ball,
        # def goaltending, shot clock violation
        new_poss = (df.off_team == df.home).diff().fillna(False)
        # def rebound considered part of the new possession
        df['poss_id'] = np.cumsum(new_poss) + df.is_dreb
        # create poss_id with rebs -> new possessions for granular groupbys
        poss_id_reb = np.cumsum(new_poss | df.is_reb)

        # make sure plays with the same clock time are in the right order
        # TODO: make sort_cols depend on what cols are in the play?
        # or combine related plays, like and-1 shot and foul
        # issues come up with FGA after timeout in 201604130LAL
        # issues come up with PF between FGA and DREB in 201604120SAS
        sort_cols = [col for col in
                     ['is_reb', 'is_fga', 'is_pf', 'is_tech_foul',
                      'is_ejection', 'is_tech_fta', 'is_timeout', 'is_pf_fta',
                      'fta_num', 'is_viol', 'is_to', 'is_jump_ball', 'is_sub']
                     if col in df.columns]
        asc_true = ['fta_num']
        ascend = [(col in asc_true) for col in sort_cols]
        for label, group in df.groupby([df.secs_elapsed, poss_id_reb]):
            if len(group) > 1:
                df.loc[group.index, :] = group.sort_values(
                    sort_cols, ascending=ascend, kind='mergesort'
                ).values

        # 2nd pass: get rid of 'rebounds' after FTM, non-final FTA, etc.
        df = _clean_rebs(df)

        # makes sure off/def and poss_id are correct for subs after rearranging
        # some possessions above
        df.loc[df['is_sub'], ['off_team', 'def_team', 'poss_id']] = np.nan
        df.off_team.fillna(method='bfill', inplace=True)
        df.def_team.fillna(method='bfill', inplace=True)
        df.poss_id.fillna(method='bfill', inplace=True)
        # make off_team and def_team NaN for jump balls
        if 'is_jump_ball' in df.columns:
            df.loc[df['is_jump_ball'], ['off_team', 'def_team']] = np.nan

        # make sure 'off_team' is always the team shooting FTs, even on techs
        # (impt for keeping track of the score)
        if 'is_tech_fta' in df.columns:
            tech_fta = df['is_tech_fta']
            df.loc[tech_fta, 'off_team'] = df.loc[tech_fta, 'fta_team']
            df.loc[tech_fta, 'def_team'] = np.where(
                df.loc[tech_fta, 'off_team'] == home, away, home
            )
        df.drop('fta_team', axis=1, inplace=True)
        # redefine poss_id_reb
        new_poss = (df.off_team == df.home).diff().fillna(False)
        poss_id_reb = np.cumsum(new_poss | df.is_reb)

        # get rid of redundant subs
        for (se, tm, pnum), group in df[df.is_sub].groupby(
            [df.secs_elapsed, df.sub_team, poss_id_reb]
        ):
            if len(group) > 1:
                sub_in = set()
                sub_out = set()
                # first, figure out who's in and who's out after subs
                for i, row in group.iterrows():
                    if row['sub_in'] in sub_out:
                        sub_out.remove(row['sub_in'])
                    else:
                        sub_in.add(row['sub_in'])
                    if row['sub_out'] in sub_in:
                        sub_in.remove(row['sub_out'])
                    else:
                        sub_out.add(row['sub_out'])
                assert len(sub_in) == len(sub_out)
                # second, add those subs
                n_subs = len(sub_in)
                for idx, p_in, p_out in zip(
                    group.index[:n_subs], sub_in, sub_out
                ):
                    assert df.loc[idx, 'is_sub']
                    df.loc[idx, 'sub_in'] = p_in
                    df.loc[idx, 'sub_out'] = p_out
                    df.loc[idx, 'sub_team'] = tm
                    df.loc[idx, 'detail'] = (
                        '{} enters the game for {}'.format(p_in, p_out)
                    )
                # third, if applicable, remove old sub entries when there are
                # redundant subs
                n_extra = len(group) - len(sub_in)
                if n_extra:
                    extra_idxs = group.index[-n_extra:]
                    df.drop(extra_idxs, axis=0, inplace=True)

        df.reset_index(drop=True, inplace=True)

        # add column for pts and score
        df['pts'] = (df['is_ftm'] + 2 * df['is_fgm'] +
                     (df['is_fgm'] & df['is_three']))
        df['hm_pts'] = np.where(df.off_team == df.home, df.pts, 0)
        df['aw_pts'] = np.where(df.off_team == df.away, df.pts, 0)
        df['hm_score'] = np.cumsum(df['hm_pts'])
        df['aw_score'] = np.cumsum(df['aw_pts'])

        # more helpful columns
        # "play" is differentiated from "poss" by counting OReb as new play
        # "plays" end with non-and1 FGA, TO, last non-tech FTA, or end of qtr
        # (or double lane viol)
        new_qtr = df.quarter.diff().shift(-1).fillna(False).astype(bool)
        and1 = (df.is_fgm & df.is_pf.shift(-1).fillna(False) &
                df.is_fta.shift(-2).fillna(False) &
                ~df.secs_elapsed.diff().shift(-1).fillna(False).astype(bool))
        double_lane = (df.get('viol_type') == 'double lane')
        new_play = df.eval('(is_fga & ~(@and1)) | is_to | @new_qtr |'
                           '(is_fta & ~is_tech_fta & fta_num == tot_fta) |'
                           '@double_lane')
        df['play_id'] = np.cumsum(new_play).shift(1).fillna(0)
        df['hm_off'] = df.off_team == df.home

        # get lineup data
        if dense_lineups:
            df = pd.concat(
                (df, sportsref.nba.pbp.get_dense_lineups(df)), axis=1
            )
        if sparse_lineups:
            df = pd.concat(
                (df, sportsref.nba.pbp.get_sparse_lineups(df)), axis=1
            )

        # TODO: add shot clock as a feature

        return df

Response: Returns a pandas DataFrame of the play - by - play data from the game.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def cache(func):

    CACHE_DIR = appdirs.user_cache_dir('sportsref', getpass.getuser())
    if not os.path.isdir(CACHE_DIR):
        os.makedirs(CACHE_DIR)

    @funcutils.wraps(func)
    def wrapper(url):
        # hash based on the URL
        file_hash = hashlib.md5()
        encoded_url = url.encode(errors='replace')
        file_hash.update(encoded_url)
        file_hash = file_hash.hexdigest()
        filename = '{}/{}'.format(CACHE_DIR, file_hash)

        sport_id = None
        for a_base_url, a_sport_id in sportsref.SITE_ABBREV.items():
            if url.startswith(a_base_url):
                sport_id = a_sport_id
                break
        else:
            print('No sport ID found for {}, not able to check cache'.format(url))

        # check whether cache is valid or stale
        file_exists = os.path.isfile(filename)
        if sport_id and file_exists:
            cur_time = int(time.time())
            mod_time = int(os.path.getmtime(filename))
            days_since_mod = datetime.timedelta(seconds=(cur_time - mod_time)).days
            days_cache_valid = globals()['_days_valid_{}'.format(sport_id)](url)
            cache_is_valid = days_since_mod < days_cache_valid
        else:
            cache_is_valid = False

        # if file found and cache is valid, read from file
        allow_caching = sportsref.get_option('cache')
        if file_exists and cache_is_valid and allow_caching:
            with codecs.open(filename, 'r', encoding='utf-8', errors='replace') as f:
                text = f.read()
        # otherwise, execute function and cache results
        else:
            text = func(url)
            with codecs.open(filename, 'w+', encoding='utf-8') as f:
                f.write(text)
        return text

    return wrapper

Response: A decorator that caches the HTML returned by the specified function.


Instruction:
Here you have a function in Python 3, explain what it does
def get_class_instance_key(cls, args, kwargs):
    l = [id(cls)]
    for arg in args:
        l.append(id(arg))
    l.extend((k, id(v)) for k, v in kwargs.items())
    return tuple(sorted(l))

Response: Returns a unique identifier for a class instantiation.


Instruction:
Write a Python 3 function for
returning the age of the player on a given date.

Response:
def age(self, year, month=2, day=1):
        """Returns the age of the player on a given date.

        :year: int representing the year.
        :month: int representing the month (1-12).
        :day: int representing the day within the month (1-31).
        :returns: Age in years as a float.
        """
        doc = self.get_main_doc()
        date_string = doc('span[itemprop="birthDate"]').attr('data-birth')
        regex = r'(\d{4})\-(\d{2})\-(\d{2})'
        date_args = map(int, re.match(regex, date_string).groups())
        birth_date = datetime.date(*date_args)
        age_date = datetime.date(year=year, month=month, day=day)
        delta = age_date - birth_date
        age = delta.days / 365.
        return age


Instruction:
Given the following Python 3 function, write the documentation
def height(self):
        doc = self.get_main_doc()
        raw = doc('span[itemprop="height"]').text()
        try:
            feet, inches = map(int, raw.split('-'))
            return feet * 12 + inches
        except ValueError:
            return None

Response: Returns the player s height in inches.


Instruction:
Write a Python 3 script to
return the player s weight in pounds.

Response:
def weight(self):
        """Returns the player's weight (in pounds).
        :returns: An int representing a player's weight in pounds.
        """
        doc = self.get_main_doc()
        raw = doc('span[itemprop="weight"]').text()
        try:
            weight = re.match(r'(\d+)lb', raw).group(1)
            return int(weight)
        except ValueError:
            return None


Instruction:
Write a Python 3 function for
returning the player s handedness.

Response:
def hand(self):
        """Returns the player's handedness.
        :returns: 'L' for left-handed, 'R' for right-handed.
        """
        doc = self.get_main_doc()
        hand = re.search(r'Shoots:\s*(L|R)', doc.text()).group(1)
        return hand


Instruction:
How would you code a function in Python 3 to
return when in the draft the player was picked.

Response:
def draft_pick(self):
        """Returns when in the draft the player was picked.
        :returns: TODO
        """
        doc = self.get_main_doc()
        try:
            p_tags = doc('div#meta p')
            draft_p_tag = next(p for p in p_tags.items() if p.text().lower().startswith('draft'))
            draft_pick = int(re.search(r'(\d+)\w{,3}\s+?overall', draft_p_tag.text()).group(1))
            return draft_pick
        except Exception as e:
            return None


Instruction:
Write a Python 3 script to
get a stats table from the player page; helper function that does the work for per-game, per-100-poss, etc. stats. :table_id: the ID of the HTML table. :kind: specifies regular season, playoffs, or both. One of 'R', 'P', 'B'. Defaults to 'R'. :returns: A DataFrame of stats.

Response:
def _get_stats_table(self, table_id, kind='R', summary=False):
        """Gets a stats table from the player page; helper function that does
        the work for per-game, per-100-poss, etc. stats.

        :table_id: the ID of the HTML table.
        :kind: specifies regular season, playoffs, or both. One of 'R', 'P',
            'B'. Defaults to 'R'.
        :returns: A DataFrame of stats.
        """
        doc = self.get_main_doc()
        table_id = 'table#{}{}'.format(
            'playoffs_' if kind == 'P' else '', table_id)
        table = doc(table_id)
        df = sportsref.utils.parse_table(table, flatten=(not summary),
                                         footer=summary)
        return df


Instruction:
Can you implement a function in Python 3 that
returns a DataFrame of per - game box score stats.

Response:
def stats_per_game(self, kind='R', summary=False):
        """Returns a DataFrame of per-game box score stats."""
        return self._get_stats_table('per_game', kind=kind, summary=summary)


Instruction:
How would you explain what the following Python 3 function does
def stats_totals(self, kind='R', summary=False):
        return self._get_stats_table('totals', kind=kind, summary=summary)

Response: Returns a DataFrame of total box score statistics by season.


Instruction:
Write a Python 3 script for
returning a DataFrame of per - minute stats.

Response:
def stats_per36(self, kind='R', summary=False):
        """Returns a DataFrame of per-36-minutes stats."""
        return self._get_stats_table('per_minute', kind=kind, summary=summary)


Instruction:
Can you write a function in Python 3 where it
returns a DataFrame of per - 100 - possession stats.

Response:
def stats_per100(self, kind='R', summary=False):
        """Returns a DataFrame of per-100-possession stats."""
        return self._get_stats_table('per_poss', kind=kind, summary=summary)


Instruction:
How would you implement a function in Python 3 that
returns a DataFrame of advanced stats.

Response:
def stats_advanced(self, kind='R', summary=False):
        """Returns a DataFrame of advanced stats."""
        return self._get_stats_table('advanced', kind=kind, summary=summary)


Instruction:
Write a Python 3 script to
return a DataFrame of shooting stats.

Response:
def stats_shooting(self, kind='R', summary=False):
        """Returns a DataFrame of shooting stats."""
        return self._get_stats_table('shooting', kind=kind, summary=summary)


Instruction:
Can you generate the documentation for the following Python 3 function
def stats_pbp(self, kind='R', summary=False):
        return self._get_stats_table('advanced_pbp', kind=kind,
                                     summary=summary)

Response: Returns a DataFrame of play - by - play stats.


Instruction:
Here you have a function in Python 3, explain what it does
def gamelog_basic(self, year, kind='R'):
        doc = self.get_sub_doc('gamelog/{}'.format(year))
        table = (doc('table#pgl_basic_playoffs')
                 if kind == 'P' else doc('table#pgl_basic'))
        df = sportsref.utils.parse_table(table)
        return df

Response: Returns a DataFrame of the player s basic game - by - game stats for a given season.