20241019 ◎

I suddenly felt happiness with no specific reason when I drove home. (maybe a side effect of the high-dose steroids)

I did not feel like doing anything, but I managed to go jogging, work out, and do some research. Congrats!

issubclass(bool, int) is True

I was writing tests and noticed an interesting behavior (at least to me) regarding Python's bool and int classes.

In [1]: isinstance(True, int)
Out[1]: True

In [2]: isinstance(False, int)
Out[2]: True

In [3]: issubclass(bool, int)
Out[3]: True

3. Data model: numbers.Integral - Python 3.13.0 documentation

There are two types of integers:

Integers (int)

These represent numbers in an unlimited range, subject to available (virtual) memory only. For the purpose of shift and mask operations, a binary representation is assumed, and negative numbers are represented in a variant of 2’s complement which gives the illusion of an infinite string of sign bits extending to the left.

Booleans (bool)

These represent the truth values False and True. The two objects representing the values False and True are the only Boolean objects. The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings “False” or “True” are returned, respectively.

So basically, False is 0 and True is 1 internally, and they are just converted to the strings "False" and "True" when they are represented to users.

I will keep this in my brain just in case.

Retry: Disjoint Set Union

I did not understand the details, but it should be helpful to remember the code to get familiar with the logic gradually.

def find_parent(i: int, parent: list[int]) -> int:
    if parent[parent[i]] == parent[i]:
        return parent[i]
    return find_parent(parent[i], parent)


def union_sets(i: int, j: int, parent: list[int], size: list[int]) -> None:
    parent_i: int = find_parent(i, parent)
    parent_j: int = find_parent(j, parent)

    if parent_i == parent_j:
        return

    if size[i] < size[j]:
        size[parent_j] += size[parent_i]
        parent[parent_i] = parent_j
    else:
        size[parent_i] += size[parent_j]
        parent[parent_j] = parent_i

    return


def count_disjoint_set(n_node: int, edges: list[tuple[int, int]]) -> int:
    parent: list[int] = list(range(n_node))
    size: list[int] = [1] * n_node

    for i, j in edges:
        union_sets(i, j, parent, size)

    for i in range(n_node):
        find_parent(i, parent)

    count: int = 0
    for i in range(n_node):
        if parent[i] == i:  # count the leader
            count += 1

    print("result" + "-" * 40)
    print(f"{edges=}")
    print(f"{parent=}")
    print(f"{size=}")
    print(f"{count=}")

    return count


if __name__ == "__main__":
    # (0, 2, 3, 4), (1, 5), (6, 9), (7), (8)
    n_node: int = 10
    edges: list[tuple[int, int]] = [
        (0, 2),
        (2, 3),
        (4, 3),
        (4, 0),
        (5, 1),
        (6, 9),
    ]
    count_disjoint_set(n_node, edges)

    # (0, 1, 2, 5), (3, 4), (6, 7, 8), (9)
    n_node: int = 10
    edges: list[tuple[int, int]] = [
        (0, 1),
        (0, 2),
        (1, 2),
        (3, 4),
        (5, 2),
        (6, 7),
        (7, 8),
    ]
    count_disjoint_set(n_node, edges)

Seafood Salad 300 Tuna salad 300 Yogurt 500 Tajin 400 Protein shake 100 Mashed potatoes 200

Total 1800 kcal

4 mi run, pull-ups, push-ups


MUST:

TODO:


index 20241018 20241020