You have to build a pyramid.

This pyramid should be built from characters from a given string.

You have to create the code for these four methods:
```python
watch_pyramid_from_the_side(characters):

watch_pyramid_from_above(characters):

count_visible_characters_of_the_pyramid(characters):

count_all_characters_of_the_pyramid(characters):
```

The first method ("FromTheSide") shows the pyramid as you would see from the side.
The second method ("FromAbove") shows the pyramid as you would see from above.
The third method ("CountVisibleCharacters") should return the count of all characters, that are visible from outside the pyramid.
The forth method ("CountAllCharacters") should count all characters of the pyramid. Consider that the pyramid is completely solid and has no holes or rooms in it.

Every character will be used for building one layer of the pyramid. So the length of the given string will be the height of the pyramid. Every layer will be built with stones from the given character. There is no limit of stones.
The pyramid should have perfect angles of 45 degrees.

Example: Given string: "abc"

Pyramid from the side:
```
  c
 bbb
aaaaa
```
Pyramid from above:
```
aaaaa
abbba
abcba
abbba
aaaaa
```
Count of visible stones/characters: 
```
25
```
Count of all used stones/characters:
```
35
```

There is no meaning in the order or the choice of the characters. It should work the same for example "aaaaa" or "54321".

Hint: Your output for the side must always be a rectangle! So spaces at the end of a line must not be deleted or trimmed!

If the string is null or empty, you should exactly return this value for the watch-methods and -1 for the count-methods.

Have fun coding it and please don't forget to vote and rank this kata! :-) 

I have created other katas. Have a look if you like coding and challenges.

```python

USER_FILENAME = "<user_code>"
import sys, json, builtins
import math, heapq, bisect, itertools, functools, collections, statistics, fractions, decimal, operator, array, random, re, string, os, pathlib
try:
    import resource as _res
except Exception:
    _res = None
from collections import Counter, defaultdict, deque, OrderedDict
from functools import lru_cache, reduce
from itertools import accumulate, permutations, combinations, product
from math import gcd, ceil, floor, sqrt
from decimal import Decimal
try:
    from typing import *
except Exception:
    pass
try:
    sys.setrecursionlimit(1_000_000)
except Exception:
    pass
try:
    import site as _site
    try:
        _sys_sites = _site.getsitepackages() if hasattr(_site, "getsitepackages") else []
        for _p in _sys_sites:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
    try:
        _usp = _site.getusersitepackages()
        if isinstance(_usp, str):
            _usp = [_usp]
        for _p in _usp:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
except Exception:
    pass

def _disabled_input(*args, **kwargs):
    raise RuntimeError("input() is disabled in callable mode")
builtins.input = _disabled_input

ns = {"__name__": "__judge__"}  # prevent if __name__ == "__main__" blocks
for _k, _v in list(globals().items()):
    if not _k.startswith("_"):
        ns[_k] = _v
_CODE = 'def watch_pyramid_from_the_side(characters=None):\n    """Display from the pyramid from the side"""\n    if characters is None:\n        return None\n    elif characters == \'\':\n        return \'\'\n    characters = characters[::-1]\n    length = len(characters)\n    output = []\n    num = 1\n    for i in range(len(characters)):\n        output.append((length-i-1)*\' \' +(num*characters[i]) + (length-i-1)*\' \')\n        num += 2\n    return \'\\n\'.join(output)\n\ndef watch_pyramid_from_above(characters=None):\n    """Print the pyramid from the side."""\n    if characters is None:\n        return None\n    elif characters == \'\':\n        return \'\'\n    size = len(characters)\n    output = []\n    for i in range(size):\n        output.append(characters[:i] + characters[i]*(size-1-i) + characters[i])\n    output.extend(output[:-1][::-1])\n    return \'\\n\'.join([row + row[:-1][::-1] for row in output])\n\n\ndef count_visible_characters_of_the_pyramid(characters=None):\n    """Return the count of letters visible on the pyramid."""\n    if not characters:\n        return -1\n    return ((len(characters)*2)-1)**2\n\n\ndef count_all_characters_of_the_pyramid(characters=None):\n    """Return the count of letters used in the pyramid."""\n    if not characters:\n        return -1\n    return sum([(2*num+1)**2 for num in range(len(characters))])'
_co = compile(_CODE, USER_FILENAME, "exec")
exec(_co, ns, ns)

_target = None
_fn_name = 'watch_pyramid_from_the_side'
if _fn_name:
    if "Solution" in ns:
        try:
            _obj = ns["Solution"]()
            if hasattr(_obj, _fn_name):
                _target = getattr(_obj, _fn_name)
        except Exception:
            _target = None
    if _target is None and _fn_name in ns and callable(ns[_fn_name]):
        _target = ns[_fn_name]
# Fallback: if there's exactly one user-defined function, use it
if _target is None:
    _cands = [v for k, v in ns.items() if callable(v) and getattr(v, "__module__", "") in ("__judge__", "__main__")]
    _user_funcs = [c for c in _cands if getattr(c, "__name__", "").startswith("_") is False]
    if len(_user_funcs) == 1:
        _target = _user_funcs[0]
if _target is None:
    raise RuntimeError(f"Could not resolve callable '{_fn_name}'")

_raw = sys.stdin.read().strip()
if _raw:
    _parsed = json.loads(_raw)
    if isinstance(_parsed, dict):
        _kwargs = _parsed.get("kwargs", {})
        _args = _parsed.get("args", [])
    else:
        _args, _kwargs = _parsed, {}
else:
    _args, _kwargs = [], {}
if not isinstance(_args, (list, tuple)):
    _args = [_args]
_res = _target(*_args, **_kwargs)
try:
    sys.stdout.write(repr(_res) + "\n")
except Exception:
    pass

```

Measured memory_bytes: 5568