Integrating `zernike.py` and creating a new ZernikeOptic

Ideally this would not be lumped in the same branch / same pull request, but it's not sufficiently straightforward to disentangle these changes that I feel like it'd be worth the trouble.

I did a formatting pass through `optics.py`, but didn't change any functionality except to fix #14 and implement the new optic classes.

There are also a few things left to do, which I'm leaving here for my future reference:

  - [x] Docstrings for `ZernikeOptic` and `ZernikeThinLens`
  - [x] ... or maybe I should just throw out `ZernikeThinLens`, and add pupil_radius to `ThinLens`...
  - [x] Figure out where the JW-specific stuff that used to be in `zernike.py` should live in WebbPSF
  - [x] On a related note, a way to swap out the basis set for `ZernikeOptic`
  - [x] Add tests to the suite for #14 and sanity checking of the `ZernikeOptic`
  - [x] Add ZernikeOptic to `__all__`
I suggest adding a shortcut here that `if coefficient == 0: continue` before the multiply-and-add. That would help optimize for the common case where many of the terms are 0, for instance piston, tip, & tilt right at the start of the coefficients list.