# Usage of augmentedtree - detailed examples¶

This chapter shows more detailed examples than within the chapter Basic Usage. These simplified examples are taken from existing projects and resembles the major issues augmentedtree was written for.

**Accessing values** - Example on how to retrieve nested values. - Using the nested example data - items are selected using a single key. - Refining the selection retrieves exact values.

**Usage of Schemas** - Getting a quick view on the relevant (by your definition) values. - How to define schemas - How the data looks without schemas - How the data looks with schemas - How schemas effect selecting items

**Use-case of the *or*-conditional selection** in combination with setting multiple values.

## Accessing values - ‘Where did I put it again?’¶

Did you ever wondered ‘Where did i put it?’? You were about to write an analysis script and put the configuration values into a JSON dump beforehand by another preliminary process. Or you can’t remember the structure of the nested output and its key names?

### Nested example data¶

The exemplary data can be found within a json-file.

[1]:

import json

# load and show the nested data
print(json.dumps(nested_data, indent="  "))

{
"section-name": {
"7h3-P4r7-Y0u-C4n7-R3m-3mb3r": {
"metatype": "my-man",
"type": "worker",
"metadata-2": "value needed for a function",
"name-of-this-item": "Gerry",
"items": [
{
"arg-1": "Not this one.",
"arg-2": "Not this one either."
},
{
"name": "get-cracking",
"arg-1": "This one you want."
}
]
},
"another-parameter": [
1,
2,
3
]
}
},
"etc.": "..."
}


### Selecting specific items¶

In this example all items with a key arg-1 are selected using select(*path_parts). The desired value can be obtained by knowing the item’s index.

[2]:

from augmentedtree import AugmentedTree, ALL_ITEMS

# augment the nested data
atree = AugmentedTree(nested_data)

# get a selection of all items with the key 'arg-1'

# take a look on the selected items using the explicit print method of
# the selection

# in this example get all values from the selection using a slice (ALL_ITEMS)
# equivalent to [:] (using ALL_ITEMS makes the code more understandable)

# here it is known the desired arg-1 is at the end.


#0 Not this one.
#1 This one you want.

arg-1 of 'get-cracking': This one you want.


### Refining the selection¶

In the prior example knowledge of the items occurrence is required to obtain the desired value. In cases where you don’t know the position of the item a refinement of the selection comes handy. Exact values/items can be retrieved using where(*path_parts).

[3]:

arg1_selection = atree.select("arg-1")
# here: using 'where' on the prior made selection returns only one value
crackpoint = arg1_selection.where("get-cracking")

crackpoint.print()

# which can be accessed using the first index


#0 This one you want.

arg-1 of 'get-cracking': This one you want.


## Usage of Schemas - Getting a quick view on the relevant values¶

With schemas a more semantic like behavior can be applied to the nested data. Schemas are defined using dictionaries and it planned to implement JSON-schemas.

### Interpretation of metadata within this package¶

By using schemas values can be classified as metadata. In this context values are classified as metadata

• if these values are not essential for the impression of your data, therefore can be hidden from the view.
• Additional not essential values which can be understood as attributes of an entity. These will be used selecting values by where.
• Besides attributes there can be data, which is not directly related for the entity but is used for process control. E.g. an unique identifier generated at runtime.

The distinction is based on your interpretation. What do you want to tell the viewer?

Example: A blue tennis ball will be enough data for the majority to depict such an object. Since the default color of tennis balls is yellow, the color blue in that case is essential to forward this information, to make the deviation of the standard clear. Diameter, mass, manufacturer, production date, etc. are additional attributes of a tennis ball, but are needed for specific occasions only. (“Pass me the blue ACME tennis ball, which was made before 2020.02.02”). An ‘runtime metadata’ of a tennis ball is the store’s article number for the cashier system.

### Using schemas¶

Schemas are defined by a dictionary with specific entries. The recommend way to define a schema is by using the construct-method of MappingSchemaBuilder. For further explanation see the section Schemas.

schema = MappingSchemaBuilder.construct(
identifier=("key-within-the-target-mapping", "identifier"),
primarykey="key-which-value-is-used-as-primekey",
primaryname="key-which-value-is-used-as-primename",
}


In the example below three schemas are used for the nested data, giving the output a different meaning.

Schemas have to be explicitly defined for usage using the use_MappingSchema_schema() method.

[4]:

from augmentedtree import MappingSchema, use_mappingtree_schemas, MappingSchemaBuilder

"resources/nested_data_of_examples.json",
"detailed/example-1-schemas"
)
schemas = MappingSchemaBuilder.construct_from_collection(schemas_as_kwargs)

# How an example schema definition looks like.
GERRY_SCHEMA = {
MappingSchema.IDENTIFIER: ("metatype", "my-man"),
MappingSchema.PRIMARYKEY: "type",
MappingSchema.PRIMARYNAME: "name-of-this-item",
MappingSchema.METAFIELDKEYS: [
"metatype",
"type",
"name-of-this-item",
]
}

use_mappingtree_schemas(GERRY_SCHEMA, *schemas)



### Representation without schemas¶

This output shows the nested data in its ‘natural’ occurrence.

[5]:

tree_like_it_is = AugmentedTree(nested_data, use_schemas=False)
tree_like_it_is.print()

{..}
section-name:
7h3-P4r7-Y0u-C4n7-R3m-3mb3r:
metatype: my-man
type: worker
metadata-2: value needed for a function
name-of-this-item: Gerry
items:
0.
arg-1: Not this one.
arg-2: Not this one either.
1.
name: get-cracking
arg-1: This one you want.
another-parameter: [1, 2, 3]
etc.: ...



### Representation using schemas¶

Using schemas can reduce the needed vertical space and increase readability.

[6]:

tree_using_schemas = AugmentedTree(nested_data)
tree_using_schemas.print()

{..}
section-name:
worker: Gerry
arg-1: Not this one.
arg-2: Not this one either.
arg-1: This one you want.
another-parameter: [1, 2, 3]
etc.: ...



### Impact of schemas on selecting items¶

Using schemas also makes selecting items more natural to he user.

[7]:

atree = AugmentedTree(nested_data)

# get a selection of all 'arg-1' items with 'get-cracking' in the path


#0 This one you want.


Schemas can be redefined setting the override_existing parameter of use_MappingSchema_schema to True. In the following example the field arg-1 is added to the metadata and will be hidden from the standard view (compare to prior output above). Metadata can be additionally listed using the additional_columns parameter of the tree item’s print-method.

[8]:

TASK_SCHEMA = MappingSchemaBuilder.construct(
primarykey="name",
primaryname="class",
)

tree_using_schemas = AugmentedTree(nested_data)

                                              @arg-1                arg-2
{..}                                  '                    '
section-name:                       '                    '
worker: Gerry                     '                    '
arg-2: Not this one either. ' Not this one.      ' Not this one either.
get-cracking: WorkerTask      ' This one you want. '
another-parameter: [1, 2, 3]    '                    '
etc.: ...                           '                    '



## Use-case of the or-conditional selection¶

The next example combines the ‘usage of schemas’ for shortening the view, and setting multiple values at once, where a specific set of values need to be changed.

Here some script went wrong. After the ‘bug’ was fixed and a lot of job files has to be ‘reset’ to a specific configuration.

The nested data is a broadly simplified example. It consists of a list with 4 dictionaries resembling what could be simple task definitions.

[9]:

from augmentedtree import use_mappingtree_schemas, AugmentedTree, MappingSchema, ALL_ITEMS

import json

[
{
"state": "done",
},
{
"state": "done",
},
{
"state": "done",
"args": "sandwich",
},
{
"state": "failed",
"args": "sandwich",
}
]


By using schemas the meaning is be made easier to read and needed vertical space shortened.

[10]:

schema_parameters = read_from_json_file("resources/nested_data_of_examples.json", address="detailed/tasklist-schemas")
schemas = MappingSchemaBuilder.construct_from_collection(schema_parameters)

use_mappingtree_schemas(*schemas)


[..]
state: done
state: done
prepare. sandwich
state: done
eat. sandwich
state: failed



Now we get to part, where we want to reset 3 specific tasks, because the first task doesn’t need to be repeated. After the selection using the ‘or’ condition for the first path part, we check if the selection returned something.

[11]:

tasks_to_repeat = task_tree.select(("take", "prepare", "eat"), "state")


[..]