prompter: Can you explain how this C function works? It adds 2 numbers in BASE number system.
long int add(long int a, long int b) {
    long int sum=0;
    long int k=1;
    int c=0;
    while(a || b || c) {
        sum+=k*(c-c%BASE)/BASE;
        c=a%10+b%10;
        sum+=c%BASE*k;
        if(sum>=BASE*k)
        {
            c=5;
            sum-=BASE*k;
        }
        k*=10;
        a/=10;
        b/=10;
    }
    return sum;
}
assistant: This C function adds two numbers in a given base number system. The base is specified by the value of the constant BASE. The function takes two long integers as input and returns their sum in the same base.

The function works by iterating through the digits of the two input numbers from right to left. It adds the corresponding digits of the two numbers and keeps track of any carry-over digits. The function then calculates the sum of the digits and the carry-over digit in the specified base and adds it to the final sum.

I hope that helps! Let me know if you have any further questions or if there’s anything else I can help you with.
prompter: could you translate it to python
assistant: Sure, here you go:

```python
def add(a: int, b: int, base: int = 10) -> int:
    """
    Add two numbers and returns the sum in the given base number system as an integer.
    Default base is 10 (decimal system).

    Args:
        a (int): LHS number to add
        b (int): RHS number to add
        base (int): The base number system to use. Defaults to 10 (decimal system).

    Returns:
        int: The sum of the two numbers in the given base number system.
        Note: that the sum is returned as an integer, not a string (the represented
        value should be interpreted through the string representation of the number!)
    """
    sum = 0
    k = 1  # multiplier
    c = 0  # carry

    # while there are still digits to add or there is a carry
    # (that is, they are not all 0)
    while a or b or c:
        # sum the carry and the next digit of each number
        sum += k * (c - c % base) // base
        c = a % 10 + b % 10
        sum += c % base * k  # add the carry to the sum
        # if the sum is greater than the base, then there is a carry
        if sum >= base * k:
            c = 5
            sum -= base * k
        # move to the next digit
        k = 10
        a //= 10
        b //= 10

    return sum
```

Here is a simple test:

```python
def test_add():
    assert add(1, 2) == 3
    assert add(1, 2, base=2) == 11
    assert add(1, 2, base=3) == 10
    assert add(1, 2, base=4) == 3
    assert add(1, 2, base=5) == 3
```

Note, however, that the function will not work in all cases. It is recommended to not do this integer based but instead use strings like so:

```python
BS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n: int, b: int = 10) -> str:
    # modified from https://stackoverflow.com/questions/2267362/how-to-convert-an-integer-to-a-string-in-any-base
    assert b <= len(BS), (
        f"unsupported base {b}. At most {len(BS)} is supported. "
        "Increase the BS string if more is required"
    )
    assert n >= 0, "Negative numbers are not supported"
    result = ""
    while n >= 0:
        result += BS[n % b]
        n //= b
    return result[::-1] or "0"


def add(a: int, b: int, base: int = 10) -> str:
    n = a + b
    return to_base(n, base)
```

This use the `to_base` function which converts a number to a string in some given base. It supports bases upto 36 (note how length of `BS` is 36). You can increase the length of the `BS` string to support further bases. 



If the output is desired to be an integer, you can simply convert the string via an `int()` like this:

```python
def add_as_str(a: int, b: int, base: int = 10) -> int:
    return int(add(a, b, base))
```

Note, however, that `add_as_str` like the C function from before suffers from the same limitation that it cannot use symbols except those from 0-9 (i.e. the digits) as it needs to output an integer! 
So, use strings for such representations and avoid integers if you can.


On a side note: one could also use NumPy's `base_repr` function instead of the above `to_base` function:

```python
import numpy as np

np.base_repr(30, 4)  # output will be '132'
```

However, this has a hard limit of the max possible base being 36. One can manually add further ones to the `to_base` function though (as described above).