#! /usr/bin/env python

import subprocess

class Node(object):
  NUM = 0

  def __init__(self):
    Node.NUM += 1
    self.num = Node.NUM
    self.data = []

  def add(self, datum):
    self.data.append(datum)

  # len() is not necessary for `item in collection` construct
  # def __len__(self):
  #   return len(self.data)

  def __iter__(self):
    return iter(self.data)

  def __getitem__(self, key):
    if isinstance(key, int):
      if 0 <= key < len(self.data):
        return self.data[key]
      else:
        raise Exception(f'{key!r} is out of range')
    else:
      raise Exception(f'{key!r} is an invalid key')

def dive(root, indent=0):
  print(f'{" "*(indent*2)}{root.num}')
  for node in root:
    dive(node, indent+1)

root = Node()
root.add(Node())
root.add(Node())

subprocess.Popen('banner Diving', shell=True).wait()
dive(root)
print('')

print(f'root[0].num = {root[0].num}')

try:
  root[10]
except Exception as e:
  print(f'Caught: {e!s}')

try:
  root[-1]
except Exception as e:
  print(f'Caught: {e!s}')

try:
  root[1.0]
except Exception as e:
  print(f'Caught: {e!s}')

try:
  root['foo']
except Exception as e:
  print(f'Caught: {e!s}')
