Instruction:
How would you implement a function in Python 3 that
assigns new types to resources.

Response:
def assign_types_to_resources(resource_types,**kwargs):
    """
        Assign new types to list of resources.
        This function checks if the necessary
        attributes are present and adds them if needed. Non existing attributes
        are also added when the type is already assigned. This means that this
        function can also be used to update resources, when a resource type has
        changed.
    """
    #Remove duplicate values from types by turning it into a set
    type_ids = list(set([rt.type_id for rt in resource_types]))

    db_types = db.DBSession.query(TemplateType).filter(TemplateType.id.in_(type_ids)).options(joinedload_all('typeattrs')).all()

    types = {}
    for db_type in db_types:
        if types.get(db_type.id) is None:
            types[db_type.id] = db_type
    log.debug("Retrieved all the appropriate template types")
    res_types = []
    res_attrs = []
    res_scenarios = []

    net_id = None
    node_ids = []
    link_ids = []
    grp_ids  = []
    for resource_type in resource_types:
        ref_id  = resource_type.ref_id
        ref_key = resource_type.ref_key
        if resource_type.ref_key == 'NETWORK':
            net_id = ref_id
        elif resource_type.ref_key == 'NODE':
            node_ids.append(ref_id)
        elif resource_type.ref_key == 'LINK':
            link_ids.append(ref_id)
        elif resource_type.ref_key == 'GROUP':
            grp_ids.append(ref_id)
    if net_id:
        net = db.DBSession.query(Network).filter(Network.id==net_id).one()
    nodes = _get_nodes(node_ids)
    links = _get_links(link_ids)
    groups = _get_groups(grp_ids)
    for resource_type in resource_types:
        ref_id  = resource_type.ref_id
        ref_key = resource_type.ref_key
        type_id = resource_type.type_id
        if ref_key == 'NETWORK':
            resource = net
        elif ref_key == 'NODE':
            resource = nodes[ref_id]
        elif ref_key == 'LINK':
            resource = links[ref_id]
        elif ref_key == 'GROUP':
            resource = groups[ref_id]

        ra, rt, rs= set_resource_type(resource, type_id, types)
        if rt is not None:
            res_types.append(rt)
        if len(ra) > 0:
            res_attrs.extend(ra)
        if len(rs) > 0:
            res_scenarios.extend(rs)

    log.debug("Retrieved all the appropriate resources")
    if len(res_types) > 0:
        new_types = db.DBSession.execute(ResourceType.__table__.insert(), res_types)
    if len(res_attrs) > 0:
        new_res_attrs = db.DBSession.execute(ResourceAttr.__table__.insert(), res_attrs)
        new_ras = db.DBSession.query(ResourceAttr).filter(and_(ResourceAttr.id>=new_res_attrs.lastrowid, ResourceAttr.id<(new_res_attrs.lastrowid+len(res_attrs)))).all()

    ra_map = {}
    for ra in new_ras:
        ra_map[(ra.ref_key, ra.attr_id, ra.node_id, ra.link_id, ra.group_id, ra.network_id)] = ra.id

    for rs in res_scenarios:
        rs['resource_attr_id'] = ra_map[(rs['ref_key'], rs['attr_id'], rs['node_id'], rs['link_id'], rs['group_id'], rs['network_id'])]

    if len(res_scenarios) > 0:
        new_scenarios = db.DBSession.execute(ResourceScenario.__table__.insert(), res_scenarios)
    #Make DBsession 'dirty' to pick up the inserts by doing a fake delete.

    db.DBSession.query(ResourceAttr).filter(ResourceAttr.attr_id==None).delete()

    ret_val = [t for t in types.values()]
    return ret_val


Instruction:
Can you implement a function in Python 3 that
checks if the type_1_id and type_2_id are compatible with the resource type.

Response:
def check_type_compatibility(type_1_id, type_2_id):
    """
        When applying a type to a resource, it may be the case that the resource already
        has an attribute specified in the new type, but the template which defines this
        pre-existing attribute has a different unit specification to the new template.

        This function checks for any situations where different types specify the same
        attributes, but with different units.
    """
    errors = []

    type_1 = db.DBSession.query(TemplateType).filter(TemplateType.id==type_1_id).options(joinedload_all('typeattrs')).one()
    type_2 = db.DBSession.query(TemplateType).filter(TemplateType.id==type_2_id).options(joinedload_all('typeattrs')).one()
    template_1_name = type_1.template.name
    template_2_name = type_2.template.name

    type_1_attrs=set([t.attr_id for t in type_1.typeattrs])
    type_2_attrs=set([t.attr_id for t in type_2.typeattrs])

    shared_attrs = type_1_attrs.intersection(type_2_attrs)

    if len(shared_attrs) == 0:
        return []

    type_1_dict = {}
    for t in type_1.typeattrs:
        if t.attr_id in shared_attrs:
            type_1_dict[t.attr_id]=t

    for ta in type_2.typeattrs:
        type_2_unit_id = ta.unit_id
        type_1_unit_id = type_1_dict[ta.attr_id].unit_id

        fmt_dict = {
                    'template_1_name': template_1_name,
                    'template_2_name': template_2_name,
                    'attr_name':       ta.attr.name,
                    'type_1_unit_id':  type_1_unit_id,
                    'type_2_unit_id':  type_2_unit_id,
                    'type_name' :      type_1.name
                }

        if type_1_unit_id is None and type_2_unit_id is not None:
            errors.append("Type %(type_name)s in template %(template_1_name)s"
                          " stores %(attr_name)s with no units, while template"
                          "%(template_2_name)s stores it with unit %(type_2_unit_id)s"%fmt_dict)
        elif type_1_unit_id is not None and type_2_unit_id is None:
            errors.append("Type %(type_name)s in template %(template_1_name)s"
                          " stores %(attr_name)s in %(type_1_unit_id)s."
                          " Template %(template_2_name)s stores it with no unit."%fmt_dict)
        elif type_1_unit_id != type_2_unit_id:
            errors.append("Type %(type_name)s in template %(template_1_name)s"
                          " stores %(attr_name)s in %(type_1_unit_id)s, while"
                          " template %(template_2_name)s stores it in %(type_2_unit_id)s"%fmt_dict)
        return errors


Instruction:
Write a Python 3 script for
assigning a new type to a resource.

Response:
def assign_type_to_resource(type_id, resource_type, resource_id,**kwargs):
    """Assign new type to a resource. This function checks if the necessary
    attributes are present and adds them if needed. Non existing attributes
    are also added when the type is already assigned. This means that this
    function can also be used to update resources, when a resource type has
    changed.
    """

    if resource_type == 'NETWORK':
        resource = db.DBSession.query(Network).filter(Network.id==resource_id).one()
    elif resource_type == 'NODE':
        resource = db.DBSession.query(Node).filter(Node.id==resource_id).one()
    elif resource_type == 'LINK':
        resource = db.DBSession.query(Link).filter(Link.id==resource_id).one()
    elif resource_type == 'GROUP':
        resource = db.DBSession.query(ResourceGroup).filter(ResourceGroup.id==resource_id).one()

    res_attrs, res_type, res_scenarios = set_resource_type(resource, type_id, **kwargs)

    type_i = db.DBSession.query(TemplateType).filter(TemplateType.id==type_id).one()
    if resource_type != type_i.resource_type:
        raise HydraError("Cannot assign a %s type to a %s"%
                         (type_i.resource_type,resource_type))

    if res_type is not None:
        db.DBSession.bulk_insert_mappings(ResourceType, [res_type])

    if len(res_attrs) > 0:
        db.DBSession.bulk_insert_mappings(ResourceAttr, res_attrs)

    if len(res_scenarios) > 0:
        db.DBSession.bulk_insert_mappings(ResourceScenario, res_scenarios)

    #Make DBsession 'dirty' to pick up the inserts by doing a fake delete.
    db.DBSession.query(Attr).filter(Attr.id==None).delete()

    db.DBSession.flush()

    return db.DBSession.query(TemplateType).filter(TemplateType.id==type_id).one()


Instruction:
Make a summary of the following Python 3 code
def set_resource_type(resource, type_id, types={}, **kwargs):

    ref_key = resource.ref_key

    existing_attr_ids = []
    for res_attr in resource.attributes:
        existing_attr_ids.append(res_attr.attr_id)

    if type_id in types:
        type_i = types[type_id]
    else:
        type_i = db.DBSession.query(TemplateType).filter(TemplateType.id==type_id).options(joinedload_all('typeattrs')).one()

    type_attrs = dict()
    for typeattr in type_i.typeattrs:
        type_attrs[typeattr.attr_id]={
                            'is_var':typeattr.attr_is_var,
                            'default_dataset_id': typeattr.default_dataset.id if typeattr.default_dataset else None}

    # check if attributes exist
    missing_attr_ids = set(type_attrs.keys()) - set(existing_attr_ids)

    # add attributes if necessary
    new_res_attrs = []

    #This is a dict as the length of the list may not match the new_res_attrs
    #Keyed on attr_id, as resource_attr_id doesn't exist yet, and there should only
    #be one attr_id per template.
    new_res_scenarios = {}
    for attr_id in missing_attr_ids:
        ra_dict = dict(
            ref_key = ref_key,
            attr_id = attr_id,
            attr_is_var = type_attrs[attr_id]['is_var'],
            node_id    = resource.id   if ref_key == 'NODE' else None,
            link_id    = resource.id   if ref_key == 'LINK' else None,
            group_id   = resource.id   if ref_key == 'GROUP' else None,
            network_id = resource.id   if ref_key == 'NETWORK' else None,

        )
        new_res_attrs.append(ra_dict)

        if type_attrs[attr_id]['default_dataset_id'] is not None:
            if hasattr(resource, 'network'):
                for s in resource.network.scenarios:

                    if new_res_scenarios.get(attr_id) is None:
                        new_res_scenarios[attr_id] = {}

                    new_res_scenarios[attr_id][s.id] =  dict(
                        dataset_id = type_attrs[attr_id]['default_dataset_id'],
                        scenario_id = s.id,
                        #Not stored in the DB, but needed to connect the RA ID later.
                        attr_id = attr_id,
                        ref_key = ref_key,
                        node_id    = ra_dict['node_id'],
                        link_id    = ra_dict['link_id'],
                        group_id   = ra_dict['group_id'],
                        network_id = ra_dict['network_id'],
                    )

    resource_type = None
    for rt in resource.types:
        if rt.type_id == type_i.id:
            break
        else:
            errors = check_type_compatibility(rt.type_id, type_i.id)
            if len(errors) > 0:
                raise HydraError("Cannot apply type %s to resource as it "
                                 "conflicts with type %s. Errors are: %s"
                                 %(type_i.name, resource.get_name(),
                                   rt.templatetype.name, ','.join(errors)))
    else:
        # add type to tResourceType if it doesn't exist already
        resource_type = dict(
            node_id    = resource.id   if ref_key == 'NODE' else None,
            link_id    = resource.id   if ref_key == 'LINK' else None,
            group_id   = resource.id   if ref_key == 'GROUP' else None,
            network_id = resource.id   if ref_key == 'NETWORK' else None,
            ref_key    = ref_key,
            type_id    = type_id,
        )

    return new_res_attrs, resource_type, new_res_scenarios

Response: Set this resource to a certain type.


Instruction:
Write a Python 3 script to
remove a resource type from a resource

Response:
def remove_type_from_resource( type_id, resource_type, resource_id,**kwargs):
    """
        Remove a resource type trom a resource
    """
    node_id = resource_id if resource_type == 'NODE' else None
    link_id = resource_id if resource_type == 'LINK' else None
    group_id = resource_id if resource_type == 'GROUP' else None

    resourcetype = db.DBSession.query(ResourceType).filter(
                                        ResourceType.type_id==type_id,
                                        ResourceType.ref_key==resource_type,
                                        ResourceType.node_id == node_id,
    ResourceType.link_id == link_id,
    ResourceType.group_id == group_id).one()

    db.DBSession.delete(resourcetype)
    db.DBSession.flush()

    return 'OK'


Instruction:
Can you generate a brief explanation for the following Python 3 code
def add_template(template, **kwargs):
    tmpl = Template()
    tmpl.name = template.name
    if template.description:
        tmpl.description = template.description
    if template.layout:
        tmpl.layout = get_layout_as_string(template.layout)

    db.DBSession.add(tmpl)

    if template.templatetypes is not None:
        types = template.templatetypes
        for templatetype in types:
            ttype = _update_templatetype(templatetype)
            tmpl.templatetypes.append(ttype)

    db.DBSession.flush()
    return tmpl

Response: Add a template and a type and typeattrs.


Instruction:
Create a Python 3 function to
update the template and a type and typeattrs.

Response:
def update_template(template,**kwargs):
    """
        Update template and a type and typeattrs.
    """
    tmpl = db.DBSession.query(Template).filter(Template.id==template.id).one()
    tmpl.name = template.name
    if template.description:
        tmpl.description = template.description

    #Lazy load the rest of the template
    for tt in tmpl.templatetypes:
        for ta in tt.typeattrs:
            ta.attr

    if template.layout:
        tmpl.layout = get_layout_as_string(template.layout)

    type_dict = dict([(t.id, t) for t in tmpl.templatetypes])
    existing_templatetypes = []

    if template.types is not None or template.templatetypes is not None:
        types = template.types if template.types is not None else template.templatetypes
        for templatetype in types:
            if templatetype.id is not None:
                type_i = type_dict[templatetype.id]
                _update_templatetype(templatetype, type_i)
                existing_templatetypes.append(type_i.id)
            else:
                #Give it a template ID if it doesn't have one
                templatetype.template_id = template.id
                new_templatetype_i = _update_templatetype(templatetype)
                existing_templatetypes.append(new_templatetype_i.id)

    for tt in tmpl.templatetypes:
        if tt.id not in existing_templatetypes:
            delete_templatetype(tt.id)

    db.DBSession.flush()

    return tmpl


Instruction:
Can you generate the documentation for the following Python 3 function
def delete_template(template_id,**kwargs):
    try:
        tmpl = db.DBSession.query(Template).filter(Template.id==template_id).one()
    except NoResultFound:
        raise ResourceNotFoundError("Template %s not found"%(template_id,))
    db.DBSession.delete(tmpl)
    db.DBSession.flush()
    return 'OK'

Response: Delete a template and its type and typeattrs.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_templates(load_all=True, **kwargs):
    if load_all is False:
        templates = db.DBSession.query(Template).all()
    else:
        templates = db.DBSession.query(Template).options(joinedload_all('templatetypes.typeattrs')).all()

    return templates

Response:
Get all templates.
        Args:
            load_all Boolean: Returns just the template entry or the full template structure (template types and type attrs)
        Returns:
            List of Template objects


Instruction:
Write a Python 3 script for
getting a specific resource template by ID.

Response:
def get_template(template_id,**kwargs):
    """
        Get a specific resource template template, by ID.
    """
    try:
        tmpl_i = db.DBSession.query(Template).filter(Template.id==template_id).options(joinedload_all('templatetypes.typeattrs.default_dataset.metadata')).one()

        #Load the attributes.
        for tmpltype_i in tmpl_i.templatetypes:
            for typeattr_i in tmpltype_i.typeattrs:
                typeattr_i.attr

        return tmpl_i
    except NoResultFound:
        raise HydraError("Template %s not found"%template_id)


Instruction:
How would you code a function in Python 3 to
get a specific resource template by name.

Response:
def get_template_by_name(name,**kwargs):
    """
        Get a specific resource template, by name.
    """
    try:
        tmpl_i = db.DBSession.query(Template).filter(Template.name == name).options(joinedload_all('templatetypes.typeattrs.default_dataset.metadata')).one()
        return tmpl_i
    except NoResultFound:
        log.info("%s is not a valid identifier for a template",name)
        raise HydraError('Template "%s" not found'%name)


Instruction:
How would you code a function in Python 3 to
add a template type to the hierarchy.

Response:
def add_templatetype(templatetype,**kwargs):
    """
        Add a template type with typeattrs.
    """

    type_i = _update_templatetype(templatetype)

    db.DBSession.flush()

    return type_i


Instruction:
How would you implement a function in Python 3 that
updates a resource type and its typeattrs.

Response:
def update_templatetype(templatetype,**kwargs):
    """
        Update a resource type and its typeattrs.
        New typeattrs will be added. typeattrs not sent will be ignored.
        To delete typeattrs, call delete_typeattr
    """

    tmpltype_i = db.DBSession.query(TemplateType).filter(TemplateType.id == templatetype.id).one()

    _update_templatetype(templatetype, tmpltype_i)

    db.DBSession.flush()

    return tmpltype_i


Instruction:
Here you have a function in Python 3, explain what it does
def _set_typeattr(typeattr, existing_ta = None):
    if existing_ta is None:
        ta = TypeAttr(attr_id=typeattr.attr_id)
    else:
        ta = existing_ta

    ta.unit_id = typeattr.unit_id
    ta.type_id = typeattr.type_id
    ta.data_type = typeattr.data_type

    if hasattr(typeattr, 'default_dataset_id') and typeattr.default_dataset_id is not None:
        ta.default_dataset_id = typeattr.default_dataset_id

    ta.description        = typeattr.description

    ta.properties         = typeattr.get_properties()

    ta.attr_is_var        = typeattr.is_var if typeattr.is_var is not None else 'N'

    ta.data_restriction = _parse_data_restriction(typeattr.data_restriction)

    if typeattr.dimension_id is None:
        # All right. Check passed
        pass
    else:

        if typeattr.attr_id is not None and typeattr.attr_id > 0:
            # Getting the passed attribute, so we need to check consistency between attr dimension id and typeattr dimension id
            attr = ta.attr

            if attr is not None and attr.dimension_id is not None and attr.dimension_id != typeattr.dimension_id or \
               attr is not None and attr.dimension_id is not None:
                # In this case there is an inconsistency between attr.dimension_id and typeattr.dimension_id
                raise HydraError("Cannot set a dimension on type attribute which "
                                "does not match its attribute. Create a new attribute if "
                                "you want to use attribute %s with dimension_id %s"%
                                (attr.name, typeattr.dimension_id))
        elif typeattr.attr_id is None and typeattr.name is not None:
            # Getting/creating the attribute by typeattr dimension id and typeattr name
            # In this case the dimension_id "null"/"not null" status is ininfluent
            attr = _get_attr_by_name_and_dimension(typeattr.name, typeattr.dimension_id)

            ta.attr_id = attr.id
            ta.attr = attr

    _check_dimension(ta)

    if existing_ta is None:
        log.debug("Adding ta to DB")
        db.DBSession.add(ta)

    return ta

Response: Sets the type attributes of the current node.


Instruction:
Implement a Python 3 function for
updating a template type in the database.

Response:
def _update_templatetype(templatetype, existing_tt=None):
    """
        Add or update a templatetype. If an existing template type is passed in,
        update that one. Otherwise search for an existing one. If not found, add.
    """
    if existing_tt is None:
        if "id" in templatetype and templatetype.id is not None:
            tmpltype_i = db.DBSession.query(TemplateType).filter(TemplateType.id == templatetype.id).one()
        else:
            tmpltype_i = TemplateType()
    else:
        tmpltype_i = existing_tt

    tmpltype_i.template_id = templatetype.template_id
    tmpltype_i.name        = templatetype.name
    tmpltype_i.description = templatetype.description
    tmpltype_i.alias       = templatetype.alias

    if templatetype.layout is not None:
        tmpltype_i.layout = get_layout_as_string(templatetype.layout)

    tmpltype_i.resource_type = templatetype.resource_type

    ta_dict = {}
    for t in tmpltype_i.typeattrs:
        ta_dict[t.attr_id] = t

    existing_attrs = []

    if templatetype.typeattrs is not None:
        for typeattr in templatetype.typeattrs:
            if typeattr.attr_id in ta_dict:
                ta = _set_typeattr(typeattr, ta_dict[typeattr.attr_id])
                existing_attrs.append(ta.attr_id)
            else:
                ta = _set_typeattr(typeattr)
                tmpltype_i.typeattrs.append(ta)
                existing_attrs.append(ta.attr_id)

    log.debug("Deleting any type attrs not sent")
    for ta in ta_dict.values():
        if ta.attr_id not in existing_attrs:
            delete_typeattr(ta)

    if existing_tt is None:
        db.DBSession.add(tmpltype_i)

    return tmpltype_i


Instruction:
Write a Python 3 script to
delete a template type and its typeattrs.

Response:
def delete_templatetype(type_id,template_i=None, **kwargs):
    """
        Delete a template type and its typeattrs.
    """
    try:
        tmpltype_i = db.DBSession.query(TemplateType).filter(TemplateType.id == type_id).one()
    except NoResultFound:
        raise ResourceNotFoundError("Template Type %s not found"%(type_id,))

    if template_i is None:
        template_i = db.DBSession.query(Template).filter(Template.id==tmpltype_i.template_id).one()

    template_i.templatetypes.remove(tmpltype_i)

    db.DBSession.delete(tmpltype_i)
    db.DBSession.flush()


Instruction:
Can you tell what is the following Python 3 function doing
def get_templatetype(type_id,**kwargs):

    templatetype = db.DBSession.query(TemplateType).filter(
                        TemplateType.id==type_id).options(
                        joinedload_all("typeattrs")).one()

    return templatetype

Response: Get a specific resource type by ID.


Instruction:
Make a summary of the following Python 3 code
def get_templatetype_by_name(template_id, type_name,**kwargs):

    try:
        templatetype = db.DBSession.query(TemplateType).filter(TemplateType.id==template_id, TemplateType.name==type_name).one()
    except NoResultFound:
        raise HydraError("%s is not a valid identifier for a type"%(type_name))

    return templatetype

Response: Get a specific resource type by name.


Instruction:
Write a Python 3 script to
add an typeattr to an existing type.

Response:
def add_typeattr(typeattr,**kwargs):
    """
        Add an typeattr to an existing type.
    """

    tmpltype = get_templatetype(typeattr.type_id, user_id=kwargs.get('user_id'))

    ta = _set_typeattr(typeattr)

    tmpltype.typeattrs.append(ta)

    db.DBSession.flush()

    return ta


Instruction:
Here you have a function in Python 3, explain what it does
def delete_typeattr(typeattr,**kwargs):

    tmpltype = get_templatetype(typeattr.type_id, user_id=kwargs.get('user_id'))

    ta = db.DBSession.query(TypeAttr).filter(TypeAttr.type_id == typeattr.type_id,
                                          TypeAttr.attr_id == typeattr.attr_id).one()

    tmpltype.typeattrs.remove(ta)

    db.DBSession.flush()

    return 'OK'

Response: Remove an typeattr from an existing type


Instruction:
Can you implement a function in Python 3 that
validates a resource attribute against the resource scenario.

Response:
def validate_attr(resource_attr_id, scenario_id, template_id=None):
    """
        Check that a resource attribute satisfies the requirements of all the types of the
        resource.
    """
    rs = db.DBSession.query(ResourceScenario).\
                        filter(ResourceScenario.resource_attr_id==resource_attr_id,
        ResourceScenario.scenario_id==scenario_id).options(
        joinedload_all("resourceattr")).options(
        joinedload_all("dataset")
        ).one()

    error = None

    try:
        _do_validate_resourcescenario(rs, template_id)
    except HydraError as e:

        error = JSONObject(dict(
                 ref_key = rs.resourceattr.ref_key,
                 ref_id  = rs.resourceattr.get_resource_id(),
                 ref_name = rs.resourceattr.get_resource().get_name(),
                 resource_attr_id = rs.resource_attr_id,
                 attr_id          = rs.resourceattr.attr.id,
                 attr_name        = rs.resourceattr.attr.name,
                 dataset_id       = rs.dataset_id,
                 scenario_id=scenario_id,
                 template_id=template_id,
                 error_text=e.args[0]))
    return error


Instruction:
Here you have a function in Python 3, explain what it does
def validate_attrs(resource_attr_ids, scenario_id, template_id=None):
    multi_rs = db.DBSession.query(ResourceScenario).\
                            filter(ResourceScenario.resource_attr_id.in_(resource_attr_ids),\
                                   ResourceScenario.scenario_id==scenario_id).\
                                   options(joinedload_all("resourceattr")).\
                                   options(joinedload_all("dataset")).all()

    errors = []
    for rs in multi_rs:
        try:
            _do_validate_resourcescenario(rs, template_id)
        except HydraError as e:

            error = dict(
                     ref_key = rs.resourceattr.ref_key,
                     ref_id  = rs.resourceattr.get_resource_id(),
                     ref_name = rs.resourceattr.get_resource().get_name(),
                     resource_attr_id = rs.resource_attr_id,
                     attr_id          = rs.resourceattr.attr.id,
                     attr_name        = rs.resourceattr.attr.name,
                     dataset_id       = rs.dataset_id,
                     scenario_id      = scenario_id,
                     template_id      = template_id,
                     error_text       = e.args[0])

            errors.append(error)

    return errors

Response: Check that multiple resource attribute ids satisfy the requirements of the types of resources to the scenario.


Instruction:
Make a summary of the following Python 3 code
def _do_validate_resourcescenario(resourcescenario, template_id=None):
    res = resourcescenario.resourceattr.get_resource()

    types = res.types

    dataset = resourcescenario.dataset

    if len(types) == 0:
        return

    if template_id is not None:
        if template_id not in [r.templatetype.template_id for r in res.types]:
            raise HydraError("Template %s is not used for resource attribute %s in scenario %s"%\
                             (template_id, resourcescenario.resourceattr.attr.name,
                             resourcescenario.scenario.name))

    #Validate against all the types for the resource
    for resourcetype in types:
        #If a specific type has been specified, then only validate
        #against that type and ignore all the others
        if template_id is not None:
            if resourcetype.templatetype.template_id != template_id:
                continue
        #Identify the template types for the template
        tmpltype = resourcetype.templatetype
        for ta in tmpltype.typeattrs:
            #If we find a template type which mactches the current attribute.
            #we can do some validation.
            if ta.attr_id == resourcescenario.resourceattr.attr_id:
                if ta.data_restriction:
                    log.debug("Validating against %s", ta.data_restriction)
                    validation_dict = eval(ta.data_restriction)
                    dataset_util.validate_value(validation_dict, dataset.get_val())

Response: Perform a check to ensure a resource scenario s datasets are correct given what the resource attribute of that resource is specified.


Instruction:
Can you create a Python 3 function that
gives a network, scenario and template, ensure that all the nodes, links & groups in the network have the correct resource attributes as defined by the types in the template. Also ensure valid entries in tresourcetype. This validation will not fail if a resource has more than the required type, but will fail if it has fewer or if any attribute has a conflicting dimension or unit.

Response:
def validate_network(network_id, template_id, scenario_id=None):
    """
        Given a network, scenario and template, ensure that all the nodes, links & groups
        in the network have the correct resource attributes as defined by the types in the template.
        Also ensure valid entries in tresourcetype.
        This validation will not fail if a resource has more than the required type, but will fail if
        it has fewer or if any attribute has a conflicting dimension or unit.
    """

    network = db.DBSession.query(Network).filter(Network.id==network_id).options(noload('scenarios')).first()

    if network is None:
        raise HydraError("Could not find network %s"%(network_id))

    resource_scenario_dict = {}
    if scenario_id is not None:
        scenario = db.DBSession.query(Scenario).filter(Scenario.id==scenario_id).first()

        if scenario is None:
            raise HydraError("Could not find scenario %s"%(scenario_id,))

        for rs in scenario.resourcescenarios:
            resource_scenario_dict[rs.resource_attr_id] = rs

    template = db.DBSession.query(Template).filter(Template.id == template_id).options(joinedload_all('templatetypes')).first()

    if template is None:
        raise HydraError("Could not find template %s"%(template_id,))

    resource_type_defs = {
        'NETWORK' : {},
        'NODE'    : {},
        'LINK'    : {},
        'GROUP'   : {},
    }
    for tt in template.templatetypes:
        resource_type_defs[tt.resource_type][tt.id] = tt

    errors = []
    #Only check if there are type definitions for a network in the template.
    if resource_type_defs.get('NETWORK'):
        net_types = resource_type_defs['NETWORK']
        errors.extend(_validate_resource(network, net_types, resource_scenario_dict))

    #check all nodes
    if resource_type_defs.get('NODE'):
        node_types = resource_type_defs['NODE']
        for node in network.nodes:
            errors.extend(_validate_resource(node, node_types, resource_scenario_dict))

    #check all links
    if resource_type_defs.get('LINK'):
        link_types = resource_type_defs['LINK']
        for link in network.links:
            errors.extend(_validate_resource(link, link_types, resource_scenario_dict))

    #check all groups
    if resource_type_defs.get('GROUP'):
        group_types = resource_type_defs['GROUP']
        for group in network.resourcegroups:
            errors.extend(_validate_resource(group, group_types, resource_scenario_dict))

    return errors


Instruction:
Implement a function in Python 3 to
get an existing network into an xml template.

Response:
def get_network_as_xml_template(network_id,**kwargs):
    """
        Turn an existing network into an xml template
        using its attributes.
        If an optional scenario ID is passed in, default
        values will be populated from that scenario.
    """
    template_xml = etree.Element("template_definition")

    net_i = db.DBSession.query(Network).filter(Network.id==network_id).one()

    template_name = etree.SubElement(template_xml, "template_name")
    template_name.text = "TemplateType from Network %s"%(net_i.name)
    layout = _get_layout_as_etree(net_i.layout)

    resources = etree.SubElement(template_xml, "resources")
    if net_i.attributes:
        net_resource    = etree.SubElement(resources, "resource")

        resource_type   = etree.SubElement(net_resource, "type")
        resource_type.text   = "NETWORK"

        resource_name   = etree.SubElement(net_resource, "name")
        resource_name.text   = net_i.name

        layout = _get_layout_as_etree(net_i.layout)
        if layout is not None:
            net_resource.append(layout)

        for net_attr in net_i.attributes:
            _make_attr_element_from_resourceattr(net_resource, net_attr)

        resources.append(net_resource)

    existing_types = {'NODE': [], 'LINK': [], 'GROUP': []}
    for node_i in net_i.nodes:
        node_attributes = node_i.attributes
        attr_ids = [res_attr.attr_id for res_attr in node_attributes]
        if len(attr_ids) > 0 and attr_ids not in existing_types['NODE']:

            node_resource    = etree.Element("resource")

            resource_type   = etree.SubElement(node_resource, "type")
            resource_type.text   = "NODE"

            resource_name   = etree.SubElement(node_resource, "name")
            resource_name.text   = node_i.node_name

            layout = _get_layout_as_etree(node_i.layout)

            if layout is not None:
                node_resource.append(layout)

            for node_attr in node_attributes:
                _make_attr_element_from_resourceattr(node_resource, node_attr)

            existing_types['NODE'].append(attr_ids)
            resources.append(node_resource)

    for link_i in net_i.links:
        link_attributes = link_i.attributes
        attr_ids = [link_attr.attr_id for link_attr in link_attributes]
        if len(attr_ids) > 0 and attr_ids not in existing_types['LINK']:
            link_resource    = etree.Element("resource")

            resource_type   = etree.SubElement(link_resource, "type")
            resource_type.text   = "LINK"

            resource_name   = etree.SubElement(link_resource, "name")
            resource_name.text   = link_i.link_name

            layout = _get_layout_as_etree(link_i.layout)

            if layout is not None:
                link_resource.append(layout)

            for link_attr in link_attributes:
                _make_attr_element_from_resourceattr(link_resource, link_attr)

            existing_types['LINK'].append(attr_ids)
            resources.append(link_resource)

    for group_i in net_i.resourcegroups:
        group_attributes = group_i.attributes
        attr_ids = [group_attr.attr_id for group_attr in group_attributes]
        if len(attr_ids) > 0 and attr_ids not in existing_types['GROUP']:
            group_resource    = etree.Element("resource")

            resource_type   = etree.SubElement(group_resource, "type")
            resource_type.text   = "GROUP"

            resource_name   = etree.SubElement(group_resource, "name")
            resource_name.text   = group_i.group_name

            for group_attr in group_attributes:
                _make_attr_element_from_resourceattr(group_resource, group_attr)

            existing_types['GROUP'].append(attr_ids)
            resources.append(group_resource)

    xml_string = etree.tostring(template_xml, encoding="unicode")

    return xml_string


Instruction:
Can you generate the documentation for the following Python 3 function
def _make_attr_element_from_typeattr(parent, type_attr_i):

    attr = _make_attr_element(parent, type_attr_i.attr)

    if type_attr_i.unit_id is not None:
        attr_unit    = etree.SubElement(attr, 'unit')
        attr_unit.text = units.get_unit(type_attr_i.unit_id).abbreviation

    attr_is_var    = etree.SubElement(attr, 'is_var')
    attr_is_var.text = type_attr_i.attr_is_var

    if type_attr_i.data_type is not None:
        attr_data_type    = etree.SubElement(attr, 'data_type')
        attr_data_type.text = type_attr_i.data_type

    if type_attr_i.data_restriction is not None:
        attr_data_restriction    = etree.SubElement(attr, 'restrictions')
        attr_data_restriction.text = type_attr_i.data_restriction

    return attr

Response: This function creates an attribute element from a type_attr element.


Instruction:
Here you have a function in Python 3, explain what it does
def _make_attr_element_from_resourceattr(parent, resource_attr_i):

    attr = _make_attr_element(parent, resource_attr_i.attr)

    attr_is_var    = etree.SubElement(attr, 'is_var')
    attr_is_var.text = resource_attr_i.attr_is_var

    return attr

Response: This function creates an attribute element from a resource attribute.


Instruction:
Here you have a function in Python 3, explain what it does
def _make_attr_element(parent, attr_i):
    attr = etree.SubElement(parent, "attribute")

    attr_name      = etree.SubElement(attr, 'name')
    attr_name.text = attr_i.name

    attr_desc      = etree.SubElement(attr, 'description')
    attr_desc.text = attr_i.description

    attr_dimension = etree.SubElement(attr, 'dimension')
    attr_dimension.text = units.get_dimension(attr_i.dimension_id, do_accept_dimension_id_none=True).name

    return attr

Response: Create an attribute element from an attribute DB object


Instruction:
Can you generate the documentation for the following Python 3 function
def get_etree_layout_as_dict(layout_tree):
    layout_dict = dict()

    for item in layout_tree.findall('item'):
        name  = item.find('name').text
        val_element = item.find('value')
        value = val_element.text.strip()
        if value == '':
            children = val_element.getchildren()
            value = etree.tostring(children[0], pretty_print=True, encoding="unicode")
        layout_dict[name] = value
    return layout_dict

Response: Convert a layout tree to a dict.


Instruction:
Implement a function in Python 3 to
convert a dict to an etree. Element

Response:
def _get_layout_as_etree(layout_dict):
    """
    Convert something that looks like this:
    {
        'color' : ['red'],
        'shapefile' : ['blah.shp']
    }

    Into something that looks like this:
    <layout>
        <item>
            <name>color</name>
            <value>red</value>
        </item>
        <item>
            <name>shapefile</name>
            <value>blah.shp</value>
        </item>
    </layout>
    """
    if layout_dict is None:
        return None

    layout = etree.Element("layout")
    layout_dict = eval(layout_dict)
    for k, v in layout_dict.items():
        item = etree.SubElement(layout, "item")
        name = etree.SubElement(item, "name")
        name.text = k
        value = etree.SubElement(item, "value")
        value.text = str(v)

    return layout


Instruction:
Make a summary of the following Python 3 code
def valueFromDataset(cls, datatype, value, metadata=None, tmap=None):
        if tmap is None:
            tmap = typemap
        obj = cls.fromDataset(datatype, value, metadata=metadata, tmap=tmap)
        return obj.value

Response:
Return the value contained by dataset argument after casting to
          correct type and performing type - specific validation.


Instruction:
Can you implement a function in Python 3 that
returns an instance of the class corresponding to the specified datatype and value.

Response:
def fromDataset(datatype, value, metadata=None, tmap=None):
        """
          Return a representation of dataset argument as an instance

          of the class corresponding to its datatype
        """
        if tmap is None:
            tmap = typemap
        return tmap[datatype.upper()].fromDataset(value, metadata=metadata)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def exists_dimension(dimension_name,**kwargs):
    try:
        dimension = db.DBSession.query(Dimension).filter(Dimension.name==dimension_name).one()
        # At this point the dimension exists
        return True
    except NoResultFound:
        # The dimension does not exist
        raise False

Response: Returns True if the dimension exists False otherwise.


Instruction:
How would you implement a function in Python 3 that
converts a value from one unit to another unit.

Response:
def convert_units(values, source_measure_or_unit_abbreviation, target_measure_or_unit_abbreviation,**kwargs):
    """
        Convert a value from one unit to another one.

        Example::

            >>> cli = PluginLib.connect()
            >>> cli.service.convert_units(20.0, 'm', 'km')
            0.02
        Parameters:
            values: single measure or an array of measures
            source_measure_or_unit_abbreviation: A measure in the source unit, or just the abbreviation of the source unit, from which convert the provided measure value/values
            target_measure_or_unit_abbreviation: A measure in the target unit, or just the abbreviation of the target unit, into which convert the provided measure value/values

        Returns:
            Always a list
    """
    if numpy.isscalar(values):
        # If it is a scalar, converts to an array
        values = [values]
    float_values = [float(value) for value in values]
    values_to_return = convert(float_values, source_measure_or_unit_abbreviation, target_measure_or_unit_abbreviation)

    return values_to_return


Instruction:
Given the following Python 3 function, write the documentation
def convert(values, source_measure_or_unit_abbreviation, target_measure_or_unit_abbreviation):

    source_dimension = get_dimension_by_unit_measure_or_abbreviation(source_measure_or_unit_abbreviation)
    target_dimension = get_dimension_by_unit_measure_or_abbreviation(target_measure_or_unit_abbreviation)

    if source_dimension == target_dimension:
        source=JSONObject({})
        target=JSONObject({})
        source.unit_abbreviation, source.factor = _parse_unit(source_measure_or_unit_abbreviation)
        target.unit_abbreviation, target.factor = _parse_unit(target_measure_or_unit_abbreviation)

        source.unit_data = get_unit_by_abbreviation(source.unit_abbreviation)
        target.unit_data = get_unit_by_abbreviation(target.unit_abbreviation)

        source.conv_factor = JSONObject({'lf': source.unit_data.lf, 'cf': source.unit_data.cf})
        target.conv_factor = JSONObject({'lf': target.unit_data.lf, 'cf': target.unit_data.cf})

        if isinstance(values, float):
            # If values is a float => returns a float
            return (source.conv_factor.lf / target.conv_factor.lf * (source.factor * values)
                    + (source.conv_factor.cf - target.conv_factor.cf)
                    / target.conv_factor.lf) / target.factor
        elif isinstance(values, list):
            # If values is a list of floats => returns a list of floats
            return [(source.conv_factor.lf / target.conv_factor.lf * (source.factor * value)
                    + (source.conv_factor.cf - target.conv_factor.cf)
                    / target.conv_factor.lf) / target.factor for value in values]
    else:
        raise HydraError("Unit conversion: dimensions are not consistent.")

Response: Convert a value or a list of values from an unit to another one.


Instruction:
How would you explain what the following Python 3 function does
def get_empty_dimension(**kwargs):
    dimension = JSONObject(Dimension())
    dimension.id = None
    dimension.name = ''
    dimension.description = ''
    dimension.project_id = None
    dimension.units = []
    return dimension

Response: Returns an empty dimension object initialized with empty values


Instruction:
How would you explain what the following Python 3 function does
def get_dimension(dimension_id, do_accept_dimension_id_none=False,**kwargs):
    if do_accept_dimension_id_none == True and dimension_id is None:
        # In this special case, the method returns a dimension with id None
        return get_empty_dimension()

    try:
        dimension = db.DBSession.query(Dimension).filter(Dimension.id==dimension_id).one()

        #lazy load units
        dimension.units

        return JSONObject(dimension)
    except NoResultFound:
        # The dimension does not exist
        raise ResourceNotFoundError("Dimension %s not found"%(dimension_id))

Response: Given a dimension id returns all its data


Instruction:
Can you implement a function in Python 3 that
returns a list of objects describing all the dimensions with all the units.

Response:
def get_dimensions(**kwargs):
    """
        Returns a list of objects describing all the dimensions with all the units.
    """
    dimensions_list = db.DBSession.query(Dimension).options(load_only("id")).all()
    return_list = []
    for dimension in dimensions_list:
        return_list.append(get_dimension(dimension.id))

    return return_list


Instruction:
Here you have a function in Python 3, explain what it does
def get_dimension_by_name(dimension_name,**kwargs):
    try:
        if dimension_name is None:
            dimension_name = ''
        dimension = db.DBSession.query(Dimension).filter(func.lower(Dimension.name)==func.lower(dimension_name.strip())).one()

        return get_dimension(dimension.id)

    except NoResultFound:
        # The dimension does not exist
        raise ResourceNotFoundError("Dimension %s not found"%(dimension_name))

Response: Returns all the data for a given dimension name.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_unit(unit_id, **kwargs):
    try:
        unit = db.DBSession.query(Unit).filter(Unit.id==unit_id).one()
        return JSONObject(unit)
    except NoResultFound:
        # The dimension does not exist
        raise ResourceNotFoundError("Unit %s not found"%(unit_id))

Response: Returns a single unit


Instruction:
How would you explain what the following Python 3 function does
def get_units(**kwargs):
    units_list = db.DBSession.query(Unit).all()
    units = []
    for unit in units_list:
        new_unit = JSONObject(unit)
        units.append(new_unit)

    return units

Response: Returns all the units in the database


Instruction:
Can you write a function in Python 3 where it
returns the physical dimension a given unit abbreviation of a measure or the measure itself refers to.

Response:
def get_dimension_by_unit_measure_or_abbreviation(measure_or_unit_abbreviation,**kwargs):
    """
        Return the physical dimension a given unit abbreviation of a measure, or the measure itself, refers to.
        The search key is the abbreviation or the full measure
    """

    unit_abbreviation, factor = _parse_unit(measure_or_unit_abbreviation)

    units = db.DBSession.query(Unit).filter(Unit.abbreviation==unit_abbreviation).all()

    if len(units) == 0:
        raise HydraError('Unit %s not found.'%(unit_abbreviation))
    elif len(units) > 1:
        raise HydraError('Unit %s has multiple dimensions not found.'%(unit_abbreviation))
    else:
        dimension = db.DBSession.query(Dimension).filter(Dimension.id==units[0].dimension_id).one()
        return str(dimension.name)


Instruction:
Can you generate the documentation for the following Python 3 function
def get_dimension_by_unit_id(unit_id, do_accept_unit_id_none=False, **kwargs):
    if do_accept_unit_id_none == True and unit_id is None:
        # In this special case, the method returns a dimension with id None
        return get_empty_dimension()

    try:
        dimension = db.DBSession.query(Dimension).join(Unit).filter(Unit.id==unit_id).filter().one()
        return get_dimension(dimension.id)
    except NoResultFound:
        # The dimension does not exist
        raise ResourceNotFoundError("Unit %s not found"%(unit_id))

Response: Returns the Dimension a given unit id refers to.


Instruction:
Explain what the following Python 3 code does
def get_unit_by_abbreviation(unit_abbreviation, **kwargs):
    try:
        if unit_abbreviation is None:
            unit_abbreviation = ''
        unit_i = db.DBSession.query(Unit).filter(Unit.abbreviation==unit_abbreviation.strip()).one()
        return JSONObject(unit_i)
    except NoResultFound:
        # The dimension does not exist
        raise ResourceNotFoundError("Unit '%s' not found"%(unit_abbreviation))

Response: Returns a single unit by abbreviation. Used as utility function to resolve string to id


Instruction:
How would you implement a function in Python 3 that
adds a dimension to the DB

Response:
def add_dimension(dimension,**kwargs):
    """
        Add the dimension defined into the object "dimension" to the DB
        If dimension["project_id"] is None it means that the dimension is global, otherwise is property of a project
        If the dimension exists emits an exception
    """
    if numpy.isscalar(dimension):
        # If it is a scalar, converts to an Object
        dimension = {'name': dimension}

    new_dimension = Dimension()
    new_dimension.name = dimension["name"]

    if "description" in dimension and dimension["description"] is not None:
        new_dimension.description = dimension["description"]
    if "project_id" in dimension and dimension["project_id"] is not None:
        new_dimension.project_id = dimension["project_id"]

    # Save on DB
    db.DBSession.add(new_dimension)
    db.DBSession.flush()

    # Load all the record
    db_dimension = db.DBSession.query(Dimension).filter(Dimension.id==new_dimension.id).one()

    return JSONObject(db_dimension)


Instruction:
Can you generate the documentation for the following Python 3 function
def update_dimension(dimension,**kwargs):
    db_dimension = None
    dimension = JSONObject(dimension)
    try:
        db_dimension = db.DBSession.query(Dimension).filter(Dimension.id==dimension.id).filter().one()

        if "description" in dimension and dimension["description"] is not None:
            db_dimension.description = dimension["description"]
        if "project_id" in dimension and dimension["project_id"] is not None and dimension["project_id"] != "" and dimension["project_id"].isdigit():
            db_dimension.project_id = dimension["project_id"]
    except NoResultFound:
        raise ResourceNotFoundError("Dimension (ID=%s) does not exist"%(dimension.id))

    db.DBSession.flush()
    return JSONObject(db_dimension)

Response: Update a dimension in the DB.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def delete_dimension(dimension_id,**kwargs):
    try:
        dimension = db.DBSession.query(Dimension).filter(Dimension.id==dimension_id).one()

        db.DBSession.query(Unit).filter(Unit.dimension_id==dimension.id).delete()

        db.DBSession.delete(dimension)
        db.DBSession.flush()
        return True
    except NoResultFound:
        raise ResourceNotFoundError("Dimension (dimension_id=%s) does not exist"%(dimension_id))

Response: Delete a dimension from the DB. Raises and exception if the dimension does not exist.


Instruction:
Can you write a function in Python 3 where it
adds all the dimensions contained in the passed list to the current node.

Response:
def bulk_add_dimensions(dimension_list, **kwargs):
    """
        Save all the dimensions contained in the passed list.
    """
    added_dimensions = []
    for dimension in dimension_list:
        added_dimensions.append(add_dimension(dimension, **kwargs))

    return JSONObject({"dimensions": added_dimensions})


Instruction:
How would you code a function in Python 3 to
add a unit to the DB.

Response:
def add_unit(unit,**kwargs):
    """
        Add the unit defined into the object "unit" to the DB
        If unit["project_id"] is None it means that the unit is global, otherwise is property of a project
        If the unit exists emits an exception

        A minimal example:

        .. code-block:: python

            new_unit = dict(

                name      = 'Teaspoons per second',
                abbreviation = 'tsp s^-1',
                cf        = 0,               # Constant conversion factor
                lf        = 1.47867648e-05,  # Linear conversion factor
                dimension_id = 2,
                description  = 'A flow of one teaspoon per second.',
            )
            add_unit(new_unit)

    """

    new_unit = Unit()
    new_unit.dimension_id   = unit["dimension_id"]
    new_unit.name           = unit['name']

    # Needed to uniform abbr to abbreviation
    new_unit.abbreviation = unit['abbreviation']

    # Needed to uniform into to description
    new_unit.description = unit['description']

    new_unit.lf             = unit['lf']
    new_unit.cf             = unit['cf']

    if ('project_id' in unit) and (unit['project_id'] is not None):
        # Adding dimension to the "user" dimensions list
        new_unit.project_id = unit['project_id']

    # Save on DB
    db.DBSession.add(new_unit)
    db.DBSession.flush()

    return JSONObject(new_unit)


Instruction:
How would you explain what the following Python 3 function does
def bulk_add_units(unit_list, **kwargs):
    # for unit in unit_list:
    #     add_unit(unit, **kwargs)

    added_units = []
    for unit in unit_list:
        added_units.append(add_unit(unit, **kwargs))

    return JSONObject({"units": added_units})

Response: Add all the units contained in the passed list to the current page.


Instruction:
Write a Python 3 function that can
delete a unit from the DB. Raises and exception if the unit does not exist

Response:
def delete_unit(unit_id, **kwargs):
    """
        Delete a unit from the DB.
        Raises and exception if the unit does not exist
    """

    try:
        db_unit = db.DBSession.query(Unit).filter(Unit.id==unit_id).one()

        db.DBSession.delete(db_unit)
        db.DBSession.flush()
        return True
    except NoResultFound:
        raise ResourceNotFoundError("Unit (ID=%s) does not exist"%(unit_id))


Instruction:
How would you explain what the following Python 3 function does
def update_unit(unit, **kwargs):
    try:

        db_unit = db.DBSession.query(Unit).join(Dimension).filter(Unit.id==unit["id"]).filter().one()

        db_unit.name = unit["name"]

        # Needed to uniform into to description
        db_unit.abbreviation = unit.abbreviation
        db_unit.description = unit.description

        db_unit.lf = unit["lf"]
        db_unit.cf = unit["cf"]
        if "project_id" in unit and unit['project_id'] is not None and unit['project_id'] != "":
            db_unit.project_id = unit["project_id"]
    except NoResultFound:
        raise ResourceNotFoundError("Unit (ID=%s) does not exist"%(unit["id"]))

    db.DBSession.flush()
    return JSONObject(db_unit)

Response: Update a unit in the DB.


Instruction:
Can you generate the documentation for the following Python 3 function
def convert_dataset(dataset_id, target_unit_abbreviation,**kwargs):

    ds_i = db.DBSession.query(Dataset).filter(Dataset.id==dataset_id).one()

    dataset_type = ds_i.type

    dsval = ds_i.get_val()
    source_unit_abbreviation = get_unit(ds_i.unit_id).abbreviation

    if source_unit_abbreviation is not None:
        if dataset_type == 'scalar':
            new_val = convert(float(dsval), source_unit_abbreviation, target_unit_abbreviation)
        elif dataset_type == 'array':
            dim = array_dim(dsval)
            vecdata = arr_to_vector(dsval)
            newvec = convert(vecdata, source_unit_abbreviation, target_unit_abbreviation)
            new_val = vector_to_arr(newvec, dim)
        elif dataset_type == 'timeseries':
            new_val = []
            for ts_time, ts_val in dsval.items():
                dim = array_dim(ts_val)
                vecdata = arr_to_vector(ts_val)
                newvec = convert(vecdata, source_unit_abbreviation, target_unit_abbreviation)
                newarr = vector_to_arr(newvec, dim)
                new_val.append(ts_time, newarr)
        elif dataset_type == 'descriptor':
            raise HydraError('Cannot convert descriptor.')

        new_dataset = Dataset()
        new_dataset.type   = ds_i.type
        new_dataset.value  = str(new_val) # The data type is TEXT!!!
        new_dataset.name   = ds_i.name

        new_dataset.unit_id   = get_unit_by_abbreviation(target_unit_abbreviation).id
        new_dataset.hidden = 'N'
        new_dataset.set_metadata(ds_i.get_metadata_as_dict())
        new_dataset.set_hash()

        existing_ds = db.DBSession.query(Dataset).filter(Dataset.hash==new_dataset.hash).first()

        if existing_ds is not None:
            db.DBSession.expunge_all()
            return existing_ds.id

        db.DBSession.add(new_dataset)
        db.DBSession.flush()

        return new_dataset.id

    else:
        raise HydraError('Dataset has no units.')

Response: Convert a whole dataset to a new unit.


Instruction:
Create a Python 3 function for
validating that the resource and attributes in the template are in the data.

Response:
def validate_resource_attributes(resource, attributes, template, check_unit=True, exact_match=False,**kwargs):
    """
        Validate that the resource provided matches the template.
        Only passes if the resource contains ONLY the attributes specified
        in the template.

        The template should take the form of a dictionary, as should the
        resources.

        *check_unit*: Makes sure that if a unit is specified in the template, it
                      is the same in the data
        *exact_match*: Ensures that all the attributes in the template are in
                       the data also. By default this is false, meaning a subset
                       of the template attributes may be specified in the data.
                       An attribute specified in the data *must* be defined in
                       the template.

        @returns a list of error messages. An empty list indicates no
        errors were found.
    """
    errors = []
    #is it a node or link?
    res_type = 'GROUP'
    if resource.get('x') is not None:
        res_type = 'NODE'
    elif resource.get('node_1_id') is not None:
        res_type = 'LINK'
    elif resource.get('nodes') is not None:
        res_type = 'NETWORK'

    #Find all the node/link/network definitions in the template
    tmpl_res = template['resources'][res_type]

    #the user specified type of the resource
    res_user_type = resource.get('type')

    #Check the user specified type is in the template
    if res_user_type is None:
        errors.append("No type specified on resource %s"%(resource['name']))

    elif tmpl_res.get(res_user_type) is None:
        errors.append("Resource %s is defined as having type %s but "
                      "this type is not specified in the template."%
                      (resource['name'], res_user_type))

    #It is in the template. Now check all the attributes are correct.
    tmpl_attrs = tmpl_res.get(res_user_type)['attributes']

    attrs = {}
    for a in attributes.values():
        attrs[a['id']] = a

    for a in tmpl_attrs.values():
        if a.get('id') is not None:
            attrs[a['id']] = {'name':a['name'], 'unit':a.get('unit'), 'dimen':a.get('dimension')}

    if exact_match is True:
        #Check that all the attributes in the template are in the data.
        #get all the attribute names from the template
        tmpl_attr_names = set(tmpl_attrs.keys())
        #get all the attribute names from the data for this resource
        resource_attr_names = []
        for ra in resource['attributes']:
            attr_name = attrs[ra['attr_id']]['name']
            resource_attr_names.append(attr_name)
        resource_attr_names = set(resource_attr_names)

        #Compare the two lists to ensure they are the same (using sets is easier)
        in_tmpl_not_in_resource = tmpl_attr_names - resource_attr_names
        in_resource_not_in_tmpl = resource_attr_names - tmpl_attr_names

        if len(in_tmpl_not_in_resource) > 0:
            errors.append("Template has defined attributes %s for type %s but they are not"
                            " specified in the Data."%(','.join(in_tmpl_not_in_resource),
                                                    res_user_type ))

        if len(in_resource_not_in_tmpl) > 0:
            errors.append("Resource %s (type %s) has defined attributes %s but this is not"
                            " specified in the Template."%(resource['name'],
                                                        res_user_type,
                                                        ','.join(in_resource_not_in_tmpl)))

    #Check that each of the attributes specified on the resource are valid.
    for res_attr in resource['attributes']:

        attr = attrs.get(res_attr['attr_id'])

        if attr is None:
            errors.append("An attribute mismatch has occurred. Attr %s is not "
                          "defined in the data but is present on resource %s"
                          %(res_attr['attr_id'], resource['name']))
            continue

        #If an attribute is not specified in the template, then throw an error
        if tmpl_attrs.get(attr['name']) is None:
            errors.append("Resource %s has defined attribute %s but this is not"
                          " specified in the Template."%(resource['name'], attr['name']))
        else:
            #If the dimensions or units don't match, throw an error

            tmpl_attr = tmpl_attrs[attr['name']]

            if tmpl_attr.get('data_type') is not None:
                if res_attr.get('type') is not None:
                    if tmpl_attr.get('data_type') != res_attr.get('type'):
                        errors.append("Error in data. Template says that %s on %s is a %s, but data suggests it is a %s"%
                            (attr['name'], resource['name'], tmpl_attr.get('data_type'), res_attr.get('type')))

            attr_dimension = 'dimensionless' if attr.get('dimension') is None else attr.get('dimension')
            tmpl_attr_dimension = 'dimensionless' if tmpl_attr.get('dimension') is None else tmpl_attr.get('dimension')

            if attr_dimension.lower() != tmpl_attr_dimension.lower():
                errors.append("Dimension mismatch on resource %s for attribute %s"
                              " (template says %s on type %s, data says %s)"%
                              (resource['name'], attr.get('name'),
                               tmpl_attr.get('dimension'), res_user_type, attr_dimension))

            if check_unit is True:
                if tmpl_attr.get('unit') is not None:
                    if attr.get('unit') != tmpl_attr.get('unit'):
                        errors.append("Unit mismatch for resource %s with unit %s "
                                      "(template says %s for type %s)"
                                      %(resource['name'], attr.get('unit'),
                                        tmpl_attr.get('unit'), res_user_type))

    return errors


Instruction:
Make a summary of the following Python 3 code
def encode(encoding, data):
    data = ensure_bytes(data, 'utf8')
    try:
        return ENCODINGS_LOOKUP[encoding].code + ENCODINGS_LOOKUP[encoding].converter.encode(data)
    except KeyError:
        raise ValueError('Encoding {} not supported.'.format(encoding))

Response:
Encodes the given data using the specified encoding that is specified
   .


Instruction:
How would you code a function in Python 3 to
return the codec used to encode the given data.

Response:
def get_codec(data):
    """
    Returns the codec used to encode the given data

    :param data: multibase encoded data
    :type data: str or bytes
    :return: the :py:obj:`multibase.Encoding` object for the data's codec
    :raises ValueError: if the codec is not supported
    """
    try:
        key = ensure_bytes(data[:CODE_LENGTH], 'utf8')
        codec = ENCODINGS_LOOKUP[key]
    except KeyError:
        raise ValueError('Can not determine encoding for {}'.format(data))
    else:
        return codec


Instruction:
Can you create a Python 3 function that
decodes the multibase encoded data

Response:
def decode(data):
    """
    Decode the multibase decoded data
    :param data: multibase encoded data
    :type data: str or bytes
    :return: decoded data
    :rtype: str
    :raises ValueError: if the data is not multibase encoded
    """
    data = ensure_bytes(data, 'utf8')
    codec = get_codec(data)
    return codec.converter.decode(data[CODE_LENGTH:])


Instruction:
Can you write a function in Python 3 where it
generates a new key pair from a secret.

Response:
def ed25519_generate_key_pair_from_secret(secret):
    """
    Generate a new key pair.
    Args:
        secret (:class:`string`): A secret that serves as a seed
    Returns:
        A tuple of (private_key, public_key) encoded in base58.
    """

    # if you want to do this correctly, use a key derivation function!
    if not isinstance(secret, bytes):
        secret = secret.encode()

    hash_bytes = sha3.keccak_256(secret).digest()
    sk = Ed25519SigningKeyFromHash.generate(hash_bytes=hash_bytes)
    # Private key
    private_value_base58 = sk.encode(encoding='base58')

    # Public key
    public_value_compressed_base58 = sk.get_verifying_key().encode(encoding='base58')

    return private_value_base58, public_value_compressed_base58


Instruction:
Write a Python 3 function for
generating a cryptographic key pair.

Response:
def generate_key_pair(secret=None):
    """Generates a cryptographic key pair.
    Args:
        secret (:class:`string`): A secret that serves as a seed
    Returns:
        :class:`~bigchaindb.common.crypto.CryptoKeypair`: A
        :obj:`collections.namedtuple` with named fields
        :attr:`~bigchaindb.common.crypto.CryptoKeypair.private_key` and
        :attr:`~bigchaindb.common.crypto.CryptoKeypair.public_key`.
    """
    if secret:
        keypair_raw = ed25519_generate_key_pair_from_secret(secret)
        return CryptoKeypair(
            *(k.decode() for k in keypair_raw))
    else:
        return generate_keypair()


Instruction:
Implement a Python 3 function for
getting the role arn from X - Role - ARN header and REMOTE -ADDR.

Response:
def _get_role_arn():
    """
    Return role arn from X-Role-ARN header,
    lookup role arn from source IP,
    or fall back to command line default.
    """
    role_arn = bottle.request.headers.get('X-Role-ARN')
    if not role_arn:
        role_arn = _lookup_ip_role_arn(bottle.request.environ.get('REMOTE_ADDR'))
    if not role_arn:
        role_arn = _role_arn
    return role_arn


Instruction:
Implement a function in Python 3 to
collect data into fixed - length chunks or blocks

Response:
def _chunk_with_padding(self, iterable, n, fillvalue=None):
        "Collect data into fixed-length chunks or blocks"
        # _chunk_with_padding('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
        args = [iter(iterable)] * n
        return zip_longest(*args, fillvalue=fillvalue)


Instruction:
Make a summary of the following Python 3 code
def marshall(values):
    serialized = {}
    for key in values:
        serialized[key] = _marshall_value(values[key])
    return serialized

Response: Marshall a dict into something DynamoDB likes.


Instruction:
Can you implement a function in Python 3 that
transforms a response payload from DynamoDB to a native dict

Response:
def unmarshall(values):
    """
    Transform a response payload from DynamoDB to a native dict

    :param dict values: The response payload from DynamoDB
    :rtype: dict
    :raises ValueError: if an unsupported type code is encountered

    """
    unmarshalled = {}
    for key in values:
        unmarshalled[key] = _unmarshall_dict(values[key])
    return unmarshalled


Instruction:
Can you write a function in Python 3 where it
transforms a value into a AttributeValue dict

Response:
def _marshall_value(value):
    """
    Recursively transform `value` into an AttributeValue `dict`

    :param mixed value: The value to encode
    :rtype: dict
    :raises ValueError: for unsupported types

    Return the value as dict indicating the data type and transform or
    recursively process the value if required.

    """
    if PYTHON3 and isinstance(value, bytes):
        return {'B': base64.b64encode(value).decode('ascii')}
    elif PYTHON3 and isinstance(value, str):
        return {'S': value}
    elif not PYTHON3 and isinstance(value, str):
        if is_binary(value):
            return {'B':  base64.b64encode(value).decode('ascii')}
        return {'S': value}
    elif not PYTHON3 and isinstance(value, unicode):
        return {'S': value.encode('utf-8')}
    elif isinstance(value, dict):
        return {'M': marshall(value)}
    elif isinstance(value, bool):
        return {'BOOL': value}
    elif isinstance(value, (int, float)):
        return {'N': str(value)}
    elif isinstance(value, datetime.datetime):
        return {'S': value.isoformat()}
    elif isinstance(value, uuid.UUID):
        return {'S': str(value)}
    elif isinstance(value, list):
        return {'L': [_marshall_value(v) for v in value]}
    elif isinstance(value, set):
        if PYTHON3 and all([isinstance(v, bytes) for v in value]):
            return {'BS': _encode_binary_set(value)}
        elif PYTHON3 and all([isinstance(v, str) for v in value]):
            return {'SS': sorted(list(value))}
        elif all([isinstance(v, (int, float)) for v in value]):
            return {'NS': sorted([str(v) for v in value])}
        elif not PYTHON3 and all([isinstance(v, str) for v in value]) and \
                all([is_binary(v) for v in value]):
            return {'BS': _encode_binary_set(value)}
        elif not PYTHON3 and all([isinstance(v, str) for v in value]) and \
                all([is_binary(v) is False for v in value]):
            return {'SS': sorted(list(value))}
        else:
            raise ValueError('Can not mix types in a set')
    elif value is None:
        return {'NULL': True}
    raise ValueError('Unsupported type: %s' % type(value))


Instruction:
Here you have a function in Python 3, explain what it does
def _unwrap_result(action, result):
    if not result:
        return
    elif action in {'DeleteItem', 'PutItem', 'UpdateItem'}:
        return _unwrap_delete_put_update_item(result)
    elif action == 'GetItem':
        return _unwrap_get_item(result)
    elif action == 'Query' or action == 'Scan':
        return _unwrap_query_scan(result)
    elif action == 'CreateTable':
        return _unwrap_create_table(result)
    elif action == 'DescribeTable':
        return _unwrap_describe_table(result)
    return result

Response: Unwrap a request response and return only the response data.


Instruction:
Write a Python 3 script to
invoke the `ListTables`_ function. Returns an array of table names associated with the current account and endpoint. The output from *ListTables* is paginated, with each page returning a maximum of ``100`` table names. :param str exclusive_start_table_name: The first table name that this operation will evaluate. Use the value that was returned for ``LastEvaluatedTableName`` in a previous operation, so that you can obtain the next page of results. :param int limit: A maximum number of table names to return. If this parameter is not specified, the limit is ``100``. .. _ListTables: http://docs.aws.amazon.com/amazondynamodb/ latest/APIReference/API_ListTables.html

Response:
def list_tables(self, exclusive_start_table_name=None, limit=None):
        """
        Invoke the `ListTables`_ function.

        Returns an array of table names associated with the current account
        and endpoint. The output from *ListTables* is paginated, with each page
        returning a maximum of ``100`` table names.

        :param str exclusive_start_table_name: The first table name that this
            operation will evaluate. Use the value that was returned for
            ``LastEvaluatedTableName`` in a previous operation, so that you can
            obtain the next page of results.
        :param int limit: A maximum number of table names to return. If this
            parameter is not specified, the limit is ``100``.

        .. _ListTables: http://docs.aws.amazon.com/amazondynamodb/
           latest/APIReference/API_ListTables.html

        """
        payload = {}
        if exclusive_start_table_name:
            payload['ExclusiveStartTableName'] = exclusive_start_table_name
        if limit:
            payload['Limit'] = limit
        return self.execute('ListTables', payload)


Instruction:
Make a summary of the following Python 3 code
def put_item(self, table_name, item,
                 condition_expression=None,
                 expression_attribute_names=None,
                 expression_attribute_values=None,
                 return_consumed_capacity=None,
                 return_item_collection_metrics=None,
                 return_values=None):
        """Invoke the `PutItem`_ function, creating a new item, or replaces an
        old item with a new item. If an item that has the same primary key as
        the new item already exists in the specified table, the new item
        completely replaces the existing item. You can perform a conditional
        put operation (add a new item if one with the specified primary key
        doesn't exist), or replace an existing item if it has certain attribute
        values.

        For more information about using this API, see Working with Items in
        the Amazon DynamoDB Developer Guide.

        :param str table_name: The table to put the item to
        :param dict item: A map of attribute name/value pairs, one for each
            attribute. Only the primary key attributes are required; you can
            optionally provide other attribute name-value pairs for the item.

            You must provide all of the attributes for the primary key. For
            example, with a simple primary key, you only need to provide a
            value for the partition key. For a composite primary key, you must
            provide both values for both the partition key and the sort key.

            If you specify any attributes that are part of an index key, then
            the data types for those attributes must match those of the schema
            in the table's attribute definition.
        :param str condition_expression: A condition that must be satisfied in
            order for a conditional *PutItem* operation to succeed. See the
            `AWS documentation for ConditionExpression <http://docs.aws.amazon.
            com/amazondynamodb/latest/APIReference/API_PutItem.html#DDB-Put
            Item-request-ConditionExpression>`_ for more information.
        :param dict expression_attribute_names: One or more substitution tokens
            for attribute names in an expression. See the `AWS documentation
            for ExpressionAttributeNames <http://docs.aws.amazon.com/amazon
            dynamodb/latest/APIReference/API_PutItem.html#DDB-PutItem-request-
            ExpressionAttributeNames>`_ for more information.
        :param dict expression_attribute_values: One or more values that can be
            substituted in an expression. See the `AWS documentation
            for ExpressionAttributeValues <http://docs.aws.amazon.com/amazon
            dynamodb/latest/APIReference/API_PutItem.html#DDB-PutItem-request-
            ExpressionAttributeValues>`_ for more information.
        :param str return_consumed_capacity: Determines the level of detail
            about provisioned throughput consumption that is returned in the
            response. Should be ``None`` or one of ``INDEXES`` or ``TOTAL``
        :param str return_item_collection_metrics: Determines whether item
            collection metrics are returned.
        :param str return_values: Use ``ReturnValues`` if you want to get the
            item attributes as they appeared before they were updated with the
            ``PutItem`` request.
        :rtype: tornado.concurrent.Future

        .. _PutItem: http://docs.aws.amazon.com/amazondynamodb/
           latest/APIReference/API_PutItem.html

        """
        payload = {'TableName': table_name, 'Item': utils.marshall(item)}
        if condition_expression:
            payload['ConditionExpression'] = condition_expression
        if expression_attribute_names:
            payload['ExpressionAttributeNames'] = expression_attribute_names
        if expression_attribute_values:
            payload['ExpressionAttributeValues'] = expression_attribute_values
        if return_consumed_capacity:
            payload['ReturnConsumedCapacity'] = return_consumed_capacity
        if return_item_collection_metrics:
            payload['ReturnItemCollectionMetrics'] = 'SIZE'
        if return_values:
            _validate_return_values(return_values)
            payload['ReturnValues'] = return_values
        return self.execute('PutItem', payload)

Response: Invoke the PutItem method in DynamoDB to add or replace an existing item.


Instruction:
Create a Python 3 function to
invoke the `GetItem`_ function. :param str table_name: table to retrieve the item from :param dict key_dict: key to use for retrieval. This will be marshalled for you so a native :class:`dict` works. :param bool consistent_read: Determines the read consistency model: If set to :py:data`True`, then the operation uses strongly consistent reads; otherwise, the operation uses eventually consistent reads. :param dict expression_attribute_names: One or more substitution tokens for attribute names in an expression. :param str projection_expression: A string that identifies one or more attributes to retrieve from the table. These attributes can include scalars, sets, or elements of a JSON document. The attributes in the expression must be separated by commas. If no attribute names are specified, then all attributes will be returned. If any of the requested attributes are not found, they will not appear in the result. :param str return_consumed_capacity: Determines the level of detail about provisioned throughput consumption that is returned in the response: - INDEXES: The response includes the aggregate consumed capacity for the operation, together with consumed capacity for each table and secondary index that was accessed. Note that some operations, such as *GetItem* and *BatchGetItem*, do not access any indexes at all. In these cases, specifying INDEXES will only return consumed capacity information for table(s). - TOTAL: The response includes only the aggregate consumed capacity for the operation. - NONE: No consumed capacity details are included in the response. :rtype: tornado.concurrent.Future .. _GetItem: http://docs.aws.amazon.com/amazondynamodb/ latest/APIReference/API_GetItem.html

Response:
def get_item(self, table_name, key_dict,
                 consistent_read=False,
                 expression_attribute_names=None,
                 projection_expression=None,
                 return_consumed_capacity=None):
        """
        Invoke the `GetItem`_ function.

        :param str table_name: table to retrieve the item from
        :param dict key_dict: key to use for retrieval.  This will
            be marshalled for you so a native :class:`dict` works.
        :param bool consistent_read: Determines the read consistency model: If
            set to :py:data`True`, then the operation uses strongly consistent
            reads; otherwise, the operation uses eventually consistent reads.
        :param dict expression_attribute_names: One or more substitution tokens
            for attribute names in an expression.
        :param str projection_expression: A string that identifies one or more
            attributes to retrieve from the table. These attributes can include
            scalars, sets, or elements of a JSON document. The attributes in
            the expression must be separated by commas. If no attribute names
            are specified, then all attributes will be returned. If any of the
            requested attributes are not found, they will not appear in the
            result.
        :param str return_consumed_capacity: Determines the level of detail
            about provisioned throughput consumption that is returned in the
            response:

              - INDEXES: The response includes the aggregate consumed
                capacity for the operation, together with consumed capacity for
                each table and secondary index that was accessed. Note that
                some operations, such as *GetItem* and *BatchGetItem*, do not
                access any indexes at all. In these cases, specifying INDEXES
                will only return consumed capacity information for table(s).
              - TOTAL: The response includes only the aggregate consumed
                capacity for the operation.
              - NONE: No consumed capacity details are included in the
                response.
        :rtype: tornado.concurrent.Future

        .. _GetItem: http://docs.aws.amazon.com/amazondynamodb/
           latest/APIReference/API_GetItem.html

        """
        payload = {'TableName': table_name,
                   'Key': utils.marshall(key_dict),
                   'ConsistentRead': consistent_read}
        if expression_attribute_names:
            payload['ExpressionAttributeNames'] = expression_attribute_names
        if projection_expression:
            payload['ProjectionExpression'] = projection_expression
        if return_consumed_capacity:
            _validate_return_consumed_capacity(return_consumed_capacity)
            payload['ReturnConsumedCapacity'] = return_consumed_capacity
        return self.execute('GetItem', payload)


Instruction:
Write a Python 3 function for
invoking the `UpdateItem`_ function. Edits an existing item's attributes, or adds a new item to the table if it does not already exist. You can put, delete, or add attribute values. You can also perform a conditional update on an existing item (insert a new attribute name-value pair if it doesn't exist, or replace an existing name-value pair if it has certain expected attribute values). :param str table_name: The name of the table that contains the item to update :param dict key_dict: A dictionary of key/value pairs that are used to define the primary key values for the item. For the primary key, you must provide all of the attributes. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key. :param str condition_expression: A condition that must be satisfied in order for a conditional *UpdateItem* operation to succeed. One of: ``attribute_exists``, ``attribute_not_exists``, ``attribute_type``, ``contains``, ``begins_with``, ``size``, ``=``, ``<>``, ``<``, ``>``, ``<=``, ``>=``, ``BETWEEN``, ``IN``, ``AND``, ``OR``, or ``NOT``. :param str update_expression: An expression that defines one or more attributes to be updated, the action to be performed on them, and new value(s) for them. :param dict expression_attribute_names: One or more substitution tokens for attribute names in an expression. :param dict expression_attribute_values: One or more values that can be substituted in an expression. :param str return_consumed_capacity: Determines the level of detail about provisioned throughput consumption that is returned in the response. See the `AWS documentation for ReturnConsumedCapacity <http://docs.aws.amazon.com/ amazondynamodb/latest/APIReference/API_UpdateItem.html#DDB-Update Item-request-ReturnConsumedCapacity>`_ for more information. :param str return_item_collection_metrics: Determines whether item collection metrics are returned. :param str return_values: Use ReturnValues if you want to get the item attributes as they appeared either before or after they were updated. See the `AWS documentation for ReturnValues <http://docs. aws.amazon.com/amazondynamodb/latest/APIReference/ API_UpdateItem.html#DDB-UpdateItem-request-ReturnValues>`_ :rtype: tornado.concurrent.Future .. _UpdateItem: http://docs.aws.amazon.com/amazondynamodb/ latest/APIReference/API_UpdateItem.html

Response:
def update_item(self, table_name, key_dict,
                    condition_expression=None,
                    update_expression=None,
                    expression_attribute_names=None,
                    expression_attribute_values=None,
                    return_consumed_capacity=None,
                    return_item_collection_metrics=None,
                    return_values=None):
        """Invoke the `UpdateItem`_ function.

        Edits an existing item's attributes, or adds a new item to the table
        if it does not already exist. You can put, delete, or add attribute
        values. You can also perform a conditional update on an existing item
        (insert a new attribute name-value pair if it doesn't exist, or replace
        an existing name-value pair if it has certain expected attribute
        values).

        :param str table_name: The name of the table that contains the item to
            update
        :param dict key_dict: A dictionary of key/value pairs that are used to
            define the primary key values for the item. For the primary key,
            you must provide all of the attributes. For example, with a simple
            primary key, you only need to provide a value for the partition
            key. For a composite primary key, you must provide values for both
            the partition key and the sort key.
        :param str condition_expression: A condition that must be satisfied in
            order for a conditional *UpdateItem* operation to succeed. One of:
            ``attribute_exists``, ``attribute_not_exists``, ``attribute_type``,
            ``contains``, ``begins_with``, ``size``, ``=``, ``<>``, ``<``,
            ``>``, ``<=``, ``>=``, ``BETWEEN``, ``IN``, ``AND``, ``OR``, or
            ``NOT``.
        :param str update_expression: An expression that defines one or more
            attributes to be updated, the action to be performed on them, and
            new value(s) for them.
        :param dict expression_attribute_names: One or more substitution tokens
            for attribute names in an expression.
        :param dict expression_attribute_values: One or more values that can be
            substituted in an expression.
        :param str return_consumed_capacity: Determines the level of detail
            about provisioned throughput consumption that is returned in the
            response. See the `AWS documentation
            for ReturnConsumedCapacity <http://docs.aws.amazon.com/
            amazondynamodb/latest/APIReference/API_UpdateItem.html#DDB-Update
            Item-request-ReturnConsumedCapacity>`_ for more information.
        :param str return_item_collection_metrics: Determines whether item
            collection metrics are returned.
        :param str return_values: Use ReturnValues if you want to get the item
            attributes as they appeared either before or after they were
            updated. See the `AWS documentation for ReturnValues <http://docs.
            aws.amazon.com/amazondynamodb/latest/APIReference/
            API_UpdateItem.html#DDB-UpdateItem-request-ReturnValues>`_
        :rtype: tornado.concurrent.Future

        .. _UpdateItem: http://docs.aws.amazon.com/amazondynamodb/
           latest/APIReference/API_UpdateItem.html

        """
        payload = {'TableName': table_name,
                   'Key': utils.marshall(key_dict),
                   'UpdateExpression': update_expression}
        if condition_expression:
            payload['ConditionExpression'] = condition_expression
        if expression_attribute_names:
            payload['ExpressionAttributeNames'] = expression_attribute_names
        if expression_attribute_values:
            payload['ExpressionAttributeValues'] = \
                utils.marshall(expression_attribute_values)
        if return_consumed_capacity:
            _validate_return_consumed_capacity(return_consumed_capacity)
            payload['ReturnConsumedCapacity'] = return_consumed_capacity
        if return_item_collection_metrics:
            _validate_return_item_collection_metrics(
                return_item_collection_metrics)
            payload['ReturnItemCollectionMetrics'] = \
                return_item_collection_metrics
        if return_values:
            _validate_return_values(return_values)
            payload['ReturnValues'] = return_values
        return self.execute('UpdateItem', payload)


Instruction:
Can you tell what is the following Python 3 function doing
def query(self, table_name,
              index_name=None,
              consistent_read=None,
              key_condition_expression=None,
              filter_expression=None,
              expression_attribute_names=None,
              expression_attribute_values=None,
              projection_expression=None,
              select=None,
              exclusive_start_key=None,
              limit=None,
              scan_index_forward=True,
              return_consumed_capacity=None):
        """A `Query`_ operation uses the primary key of a table or a secondary
        index to directly access items from that table or index.

        :param str table_name: The name of the table containing the requested
            items.
        :param bool consistent_read: Determines the read consistency model: If
            set to ``True``, then the operation uses strongly consistent reads;
            otherwise, the operation uses eventually consistent reads. Strongly
            consistent reads are not supported on global secondary indexes. If
            you query a global secondary index with ``consistent_read`` set to
            ``True``, you will receive a
            :exc:`~sprockets_dynamodb.exceptions.ValidationException`.
        :param dict exclusive_start_key: The primary key of the first
            item that this operation will evaluate. Use the value that was
            returned for ``LastEvaluatedKey`` in the previous operation. In a
            parallel scan, a *Scan* request that includes
            ``exclusive_start_key`` must specify the same segment whose
            previous *Scan* returned the corresponding value of
            ``LastEvaluatedKey``.
        :param dict expression_attribute_names: One or more substitution tokens
            for attribute names in an expression.
        :param dict expression_attribute_values: One or more values that can be
            substituted in an expression.
        :param str key_condition_expression: The condition that specifies the
            key value(s) for items to be retrieved by the *Query* action. The
            condition must perform an equality test on a single partition key
            value, but can optionally perform one of several comparison tests
            on a single sort key value. The partition key equality test is
            required. For examples see `KeyConditionExpression
            <https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/
            Query.html#Query.KeyConditionExpressions>.
        :param str filter_expression: A string that contains conditions that
            DynamoDB applies after the *Query* operation, but before the data
            is returned to you. Items that do not satisfy the criteria are not
            returned. Note that a filter expression is applied after the items
            have already been read; the process of filtering does not consume
            any additional read capacity units. For more information, see
            `Filter Expressions <http://docs.aws.amazon.com/amazondynamodb/
            latest/developerguide/QueryAndScan.html#FilteringResults>`_ in the
            Amazon DynamoDB Developer Guide.
        :param str projection_expression:
        :param str index_name: The name of a secondary index to query. This
            index can be any local secondary index or global secondary index.
            Note that if you use this parameter, you must also provide
            ``table_name``.
        :param int limit: The maximum number of items to evaluate (not
            necessarily the number of matching items). If DynamoDB processes
            the number of items up to the limit while processing the results,
            it stops the operation and returns the matching values up to that
            point, and a key in ``LastEvaluatedKey`` to apply in a subsequent
            operation, so that you can pick up where you left off. Also, if the
            processed data set size exceeds 1 MB before DynamoDB reaches this
            limit, it stops the operation and returns the matching values up to
            the limit, and a key in ``LastEvaluatedKey`` to apply in a
            subsequent operation to continue the operation. For more
            information, see `Query and Scan <http://docs.aws.amazon.com/amazo
            ndynamodb/latest/developerguide/QueryAndScan.html>`_ in the Amazon
            DynamoDB Developer Guide.
        :param str return_consumed_capacity: Determines the level of detail
            about provisioned throughput consumption that is returned in the
            response:

              - ``INDEXES``: The response includes the aggregate consumed
                capacity for the operation, together with consumed capacity for
                each table and secondary index that was accessed. Note that
                some operations, such as *GetItem* and *BatchGetItem*, do not
                access any indexes at all. In these cases, specifying
                ``INDEXES`` will only return consumed capacity information for
                table(s).
              - ``TOTAL``: The response includes only the aggregate consumed
                capacity for the operation.
              - ``NONE``: No consumed capacity details are included in the
                response.
        :param bool scan_index_forward: Specifies the order for index
            traversal: If ``True`` (default), the traversal is performed in
            ascending order; if ``False``, the traversal is performed in
            descending order. Items with the same partition key value are
            stored in sorted order by sort key. If the sort key data type is
            *Number*, the results are stored in numeric order. For type
            *String*, the results are stored in order of ASCII character code
            values. For type *Binary*, DynamoDB treats each byte of the binary
            data as unsigned. If set to ``True``, DynamoDB returns the results
            in the order in which they are stored (by sort key value). This is
            the default behavior. If set to ``False``, DynamoDB reads the
            results in reverse order by sort key value, and then returns the
            results to the client.
        :param str select: The attributes to be returned in the result. You can
            retrieve all item attributes, specific item attributes, the count
            of matching items, or in the case of an index, some or all of the
            attributes projected into the index. Possible values are:

              - ``ALL_ATTRIBUTES``: Returns all of the item attributes from the
                specified table or index. If you query a local secondary index,
                then for each matching item in the index DynamoDB will fetch
                the entire item from the parent table. If the index is
                configured to project all item attributes, then all of the data
                can be obtained from the local secondary index, and no fetching
                is required.
              - ``ALL_PROJECTED_ATTRIBUTES``: Allowed only when querying an
                index. Retrieves all attributes that have been projected into
                the index. If the index is configured to project all
                attributes, this return value is equivalent to specifying
                ``ALL_ATTRIBUTES``.
              - ``COUNT``: Returns the number of matching items, rather than
                the matching items themselves.
        :rtype: dict

        .. _Query: http://docs.aws.amazon.com/amazondynamodb/
           latest/APIReference/API_Query.html

        """
        payload = {'TableName': table_name,
                   'ScanIndexForward': scan_index_forward}
        if index_name:
            payload['IndexName'] = index_name
        if consistent_read is not None:
            payload['ConsistentRead'] = consistent_read
        if key_condition_expression:
            payload['KeyConditionExpression'] = key_condition_expression
        if filter_expression:
            payload['FilterExpression'] = filter_expression
        if expression_attribute_names:
            payload['ExpressionAttributeNames'] = expression_attribute_names
        if expression_attribute_values:
            payload['ExpressionAttributeValues'] = \
                utils.marshall(expression_attribute_values)
        if projection_expression:
            payload['ProjectionExpression'] = projection_expression
        if select:
            _validate_select(select)
            payload['Select'] = select
        if exclusive_start_key:
            payload['ExclusiveStartKey'] = utils.marshall(exclusive_start_key)
        if limit:
            payload['Limit'] = limit
        if return_consumed_capacity:
            _validate_return_consumed_capacity(return_consumed_capacity)
            payload['ReturnConsumedCapacity'] = return_consumed_capacity
        return self.execute('Query', payload)

Response: A Query operation uses the primary key of a table or secondary index to directly access items from that table or index.