Add quality scores to BiologicalSequence

``BiologicalSequence`` now optionally store quality scores. A biological sequence's quality scores are stored as a 1-D ``numpy.ndarray`` of integers that is the same length as the biological sequence. Quality scores can be provided upon object instantiation via the keyword argument ``quality``, and can be retrieved via the ``BiologicalSequence.quality`` property. ``BiologicalSequence.has_quality`` is also provided for determining whether a biological sequence has quality scores or not.

Made some additional changes that facilitated the quality scores feature:

- Added ``BiologicalSequence.sequence`` property for retrieving the underlying string representing the sequence characters. This was previously (and still is) accessible via ``BiologicalSequence.__str__``. It is provided via a property for convenience and explicitness.

- Added ``BiologicalSequence.equals`` for full control over equality testing of biological sequences. By default, biological sequences must have the same type, underlying sequence of characters, identifier, description, and quality scores to compare equal. These properties can be ignored via the keyword argument ``ignore``. The behavior of ``BiologicalSequence.__eq__``/``__ne__`` remains unchanged (only type and underlying sequence of characters are compared).

- Fixed performance bug when instantiating ``BiologicalSequence`` objects. The previous runtime scaled linearly with sequence length; it is now constant time when the sequence is already a string.

Fixes #616 #623.

# Questions

1. Should `__repr__` include some indication of quality scores? e.g., maybe noting whether they are present?

2. Quality scores are propagated in methods that return new `BiologicalSequence` objects. In some cases, this is very natural (e.g., `__getitem__` and `degap`). However, I'm not sure whether `nondegenerates`, `complement`, and `reverse_complement` should propagate quality scores. The current behavior of `nondegenerates` and `complement` is to simply propagate the quality scores as-is, and `reverse_complement` propagates reversed quality scores, since the biological sequence is reversed. Does this behavior make sense?
isn't it technically:
`other : object`
?