Development Workflow
===========================
This section describes the Pykaryote development workflow. It covers topics such as git, coding style, testing, profiling, and packaging.

Git
-------
Pykaryote uses ``git``, a distributed version control system, to keep track of changes in the code. If you haven't used ``git`` before, find a tutorial online. To use git with Pykaryote, you should at least understand commiting, branching, pushing, pulling, rebaseing and interactive rebaseing.

Guidelines:

* Development work should be done from the ``dev`` branch
	* Only ``rebase`` onto ``master`` for a stable release
* Branch early, branch often
	* Create a new branch for every new feature
	* ``rebase`` back into ``dev`` when you are done
* Use ``rebase`` instead of ``merge``
	* This keeps commit history clean and linear.
* Clean up commit history by rebaseing interactively
	* Interactive rebaseing is amazing. It allows you to easily reorder, edit, and squash commits together. Learn it. Use it.

Coding Style
--------------
For its first two years of development, Pykaryote has not had a definitive coding style. As a result, the code is ugly and inconsistent.

To ensure clean code, Pykaryote has adopted `PEP 08 <http://www.python.org/dev/peps/pep-0008/>`_ as its official style guide. If you have never read a style guide before, your code is ugly. Go read `PEP 08 <http://www.python.org/dev/peps/pep-0008/>`_ now.

Guidelines:

* Keep lines a maximum of 80 characters
	* This forces you to keep code readable and ensures that code will fit in everyones editor window.
	* Set your editor to display a guideline on the 80th column.
* Use single instead of double quotes for string literals.
* Use the ``string.format()`` method instead of ``%`` syntax for format strings.
	* ``%`` syntax is deprecated
	* Good::

		'hello {}'.format('world')

	* Bad::

		'hello %s' % 'world'

* All classes and methods should have a doc string.
	* If possible, format doc strings with `Sphinx syntax <http://sphinx-doc.org/rest.html>`_.
	* At the very least, make sure doc strings are `PEP 08 <http://www.python.org/dev/peps/pep-0008/>`_ compliant.

Adding Configuration Options
------------------------------
.. Note::

	The code for loading simulation configuration files is super hacky and gross. If you have time, re-write ``config.py`` and get rid of ``global_generator.py``. It should only take a few hours. Ideally, `ConfigParser` would be used to load the current configuration file on top of the default ``master.cfg``. JSON should be used instead of calls to eval.

Configuration options are loaded from ``config.py``, which is auto-generated by ``global_generator.py``. Every time you add or remove a configuration option, you must add it to ``master.cfg`` and then run ``global_generator.py`` to re-build ``config.py``.

Unit Testing
---------------
Pykaryote has very few unit tests. They can be run with the ``pyk-test`` command.

pyk-test does two things. First, it runs tests with the `unittest <http://docs.python.org/2/library/unittest.html>`_ framework. Next, ``pyk-test`` runs the command line utilities, making sure they do not crash. Output of the command line utilities is not checked for correctness.

As of version 1.0, test coverage is less than 1%. It would be nice to have more coverage.

Guidelines:

* Write unit tests before adding a new feature.
* Ensure all tests pass before pushing code.

Profiling
--------------
Before optimizing, always profile using python's built in profiler.

Profiling is done with the ``pyk-profile`` command, which profiles a simulation with the random seed set to 1337.

Before running ``pyk-profile``, enable Cython profiling by adding the following compiler directive to the top of all ``.pyx`` files::

	# cython: profile=True

Be sure to disable profiling when packaging for release, as code is slower with profiling enabled.

.. Note::
	Profiling can be easily enabled and disabled using the included ``enable_profiling.sh`` and ``disabled_profiling.sh`` bash scripts.

Once profiling is enabled, rebuild Pykaryote with::

	$ python setup.py build_ext --inplace

To profile a comparison, run::

	$ pyk-profile

This will run a simulation and save statistics to ``Profile.prof`` in the current directory. To analyze profile data interactively, run::

	$ python -m pstats Profile.prof

You will be presented with a prompt. Use these commands to print the top 10 functions by runtime::

	% sort time
	% stats 10

For more information, use the internal help::

	% help
	% help sort
	% help stats

More information on ``pstats`` can be found in `this tutorial <http://stefaanlippens.net/python_profiling_with_pstats_interactive_mode>`_.

Documentation
---------------------------
Pykaryote's documentation is created using `Sphinx <http://sphinx-doc.org/>`_. It is located in the docs directory.

Sphinx uses the ``reStructuredText`` markup language. To update the documentation, edit the ``.rst`` files.

When you are done making your changes, move into the ``docs`` directory and build the documentation with::

	$ make html

If you run into an error, ensure that ``sphinx`` is installed::

	$ pip install sphinx

Packaging for Release
--------------------------
Pykaryote uses `setuptools <http://pythonhosted.org/setuptools/>`_ for packaging. Distribution is done through `PyPI <https://pypi.python.org/pypi>`_, the Python Package Index.

To build an ``.egg`` for your current platform, run::

	$ python setup.py bdist_egg

To build a source distribution, run::
	
	$ python setup.py sdist

Test the newly packaged release in a fresh virtual machine. When everything is working correctly, upload to PyPI with::

	$ python setup.py sdist bdist_egg upload

You will be prompted for a user name and password. For access to the pykaryote PyPI account, contact Professor Serita Nelesen.
