Entries are the most basic unit for logging. They are simply a key-value pair.

All examples in the previous sections have logged entries.

unify.log(x=0, y={"a": [1, 2, 3]}, msg="hello", score=0.123)

For example, x, y, msg and score above are all entries.

Entry Contexts

Aside from logging contexts, we can also specify entry contexts.

student_data = {
    "A": [
        ("Alice", "Smith", "23/04/2005"),
        ("Bob", "Johnson", "12/07/2004"),
    ],
    "B": [
        ("Eve", "Brown", "15/09/2003"),
        ("Frank", "Jones", "22/11/2005"),
    ],
    "C": [
        ("Henry", "Miller", "01/01/2004"),
        ("Ian", "Davis", "10/03/2005"),
    ],
}
for grade, students in student_data.items():
    with unify.Entry(grade=grade):
        for first_name, last_name, dob in students:
            unify.log(
                first_name=first_name,
                last_name=last_name,
                data_of_birth=dob
            )

Which will appear like so in the table:

These can also be nested:

student_data = {
    "Maths": {
        "A": [
            ("Alice", "Smith", "23/04/2005"),
            ("Bob", "Johnson", "12/07/2004"),
        ],
        "B": [
            ("Eve", "Brown", "15/09/2003"),
            ("Frank", "Jones", "22/11/2005"),
        ],
        "C": [
            ("Henry", "Miller", "01/01/2004"),
            ("Ian", "Davis", "10/03/2005"),
        ],
    },
    "Physics": {
        "A": [
            ("Frank", "Jones", "22/11/2005"),
        ],
        "B": [
            ("Alice", "Smith", "23/04/2005"),
            ("Eve", "Brown", "15/09/2003"),
            ("Henry", "Miller", "01/01/2004"),
            ("Ian", "Davis", "10/03/2005"),
        ],
        "C": [
            ("Bob", "Johnson", "12/07/2004"),
        ],
    },
}

for subject, studate_data in all_student_data.items():
    with unify.Entry(subject=subject):
        for grade, students in studate_data.items():
            with unify.Entry(grade=grade):
                for first_name, last_name, dob in students:
                    unify.log(
                        first_name=first_name,
                        last_name=last_name, 
                        data_of_birth=dob
                    )

Which will appear in the table like so:

Of course, this is not especially useful for the above example, but if there are many nested function calls processing the data inside the subject or grade contexts, then their use avoids the need to pass around the subject or grade contexts explicitly between all inner function calls, when it’s known that they are constant for all inner computation and logging.

By default, unify.Entry("...") also changes the behaviour of get_logs, returning only the logs which include the entry.

for subject, studate_data in all_student_data.items():
    with unify.Entry(subject=subject):
        for grade, students in studate_data.items():
            with unify.Entry(grade=grade):
                for first_name, last_name, dob in students:
                    unify.log(
                        first_name=first_name,
                        last_name=last_name, 
                        data_of_birth=dob
                    )
                assert len(unify.get_logs()) == len(students)
        assert len(unify.get_logs()) == sum(
            len(students) for students in studate_data.values()
        )

This behaviour can be change by setting unify.Entry("...", mode="read") which will only impact log getting, and unify.Entry("...", mode="write") which will only impact log setting.