Added a setup.py file to simplify installation, and added custom exceptions