Merge pull request #522 from vpzee/master

Corrected lines to be no longer than 78 characters.
This commit is contained in:
Ian Cordasco
2015-03-01 10:03:19 -06:00
24 changed files with 494 additions and 429 deletions
+49 -38
View File
@@ -29,31 +29,33 @@ following lines::
With these settings, newlines are inserted after 79 characters and indentation
is set to 4 spaces per tab. If you also use Vim for other languages, there is a
handy plugin called indent_, which handles indentation settings for Python source
files.
handy plugin called indent_, which handles indentation settings for Python
source files.
There is also a handy syntax plugin called syntax_ featuring some improvements over
the syntax file included in Vim 6.1.
There is also a handy syntax plugin called syntax_ featuring some improvements
over the syntax file included in Vim 6.1.
These plugins supply you with a basic environment for developing in Python.
To get the most out of Vim, you should continually check your code for syntax
errors and PEP8 compliance. Luckily PEP8_ and Pyflakes_ will do this for you.
If your Vim is compiled with :option:`+python` you can also utilize some very handy
plugins to do these checks from within the editor.
If your Vim is compiled with :option:`+python` you can also utilize some very
handy plugins to do these checks from within the editor.
For PEP8 checking, install the vim-pep8_ plugin, and for pyflakes you can
install vim-pyflakes_. Now you can map the functions ``Pep8()`` or ``Pyflakes()``
to any hotkey or action you want in Vim. Both plugins will display errors at
the bottom of the screen, and provide an easy way to jump to the corresponding
line. It's very handy to call these functions whenever you save a file. In
order to do this, add the following lines to your :file:`.vimrc`::
install vim-pyflakes_. Now you can map the functions ``Pep8()`` or
``Pyflakes()`` to any hotkey or action you want in Vim. Both plugins will
display errors at the bottom of the screen, and provide an easy way to jump to
the corresponding line. It's very handy to call these functions whenever you
save a file. In order to do this, add the following lines to your
:file:`.vimrc`::
autocmd BufWritePost *.py call Pyflakes()
autocmd BufWritePost *.py call Pep8()
If you are already using syntastic_, you can set it to run Pyflakes on write
and show errors and warnings in the quickfix window. An example configuration
to do that which also shows status and warning messages in the statusbar would be::
to do that which also shows status and warning messages in the statusbar would
be::
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
@@ -112,8 +114,8 @@ TextMate
--------
`TextMate <http://macromates.com/>`_ brings Apple's approach to operating
systems into the world of text editors. By bridging UNIX underpinnings and GUI,
TextMate cherry-picks the best of both worlds to the benefit of expert
systems into the world of text editors. By bridging UNIX underpinnings and
GUI, TextMate cherry-picks the best of both worlds to the benefit of expert
scripters and novice users alike.
Sublime Text
@@ -124,18 +126,21 @@ Sublime Text
extraordinary features and amazing performance.
Sublime Text has excellent support for editing Python code and uses Python for
its plugin API. It also has a diverse variety of plugins, `some of which <https://github.com/SublimeLinter/SublimeLinter>`_
allow for in-editor PEP8 checking and code "linting".
its plugin API. It also has a diverse variety of plugins,
`some of which <https://github.com/SublimeLinter/SublimeLinter>`_ allow for
in-editor PEP8 checking and code "linting".
Atom
----
`Atom <https://atom.io/>`_ is a hackable text editor for the 21st century,
built on atom-shell, and based on everything we love about our favorite editors.
built on atom-shell, and based on everything we love about our favorite
editors.
Atom is web native (HTML, CSS, JS), focusing on modular design and easy plugin development.
It comes with native package control and plethora of packages. Recommended for Python
development is `Linter <https://github.com/AtomLinter/Linter>`_ combined with
Atom is web native (HTML, CSS, JS), focusing on modular design and easy plugin
development. It comes with native package control and plethora of packages.
Recommended for Python development is
`Linter <https://github.com/AtomLinter/Linter>`_ combined with
`linter-flake8 <https://github.com/AtomLinter/linter-flake8>`_.
@@ -147,9 +152,10 @@ PyCharm / IntelliJ IDEA
`PyCharm <http://www.jetbrains.com/pycharm/>`_ is developed by JetBrains, also
known for IntelliJ IDEA. Both share the same code base and most of PyCharm's
features can be brought to IntelliJ with the free `Python Plug-In <http://plugins.intellij.net/plugin/?id=631>`_.
There are two versions of PyCharm: Professional Edition (Free 30-day trial)
and Community Edition(Apache 2.0 License) with fewer features.
features can be brought to IntelliJ with the free
`Python Plug-In <http://plugins.intellij.net/plugin/?id=631>`_. There are two
versions of PyCharm: Professional Edition (Free 30-day trial) and Community
Edition(Apache 2.0 License) with fewer features.
Eclipse
@@ -172,9 +178,10 @@ Spyder
------
`Spyder <http://code.google.com/p/spyderlib/>`_ is an IDE specifically geared
toward working with scientific Python libraries (namely `Scipy <http://www.scipy.org/>`_).
It includes integration with pyflakes_, `pylint <http://www.logilab.org/857>`_
and `rope <http://rope.sourceforge.net/>`_.
toward working with scientific Python libraries (namely
`Scipy <http://www.scipy.org/>`_). It includes integration with pyflakes_,
`pylint <http://www.logilab.org/857>`_ and
`rope <http://rope.sourceforge.net/>`_.
Spyder is open-source (free), offers code completion, syntax highlighting,
a class and function browser, and object inspection.
@@ -195,11 +202,13 @@ NINJA-IDE
`NINJA-IDE <http://www.ninja-ide.org/>`_ (from the recursive acronym: "Ninja-IDE
Is Not Just Another IDE") is a cross-platform IDE, specially designed to build
Python applications, and runs on Linux/X11, Mac OS X and Windows desktop operating
systems. Installers for these platforms can be downloaded from the website.
Python applications, and runs on Linux/X11, Mac OS X and Windows desktop
operating systems. Installers for these platforms can be downloaded from the
website.
NINJA-IDE is open-source software (GPLv3 licence) and is developed in Python and
Qt. The source files can be downloaded from `GitHub <https://github.com/ninja-ide>`_.
NINJA-IDE is open-source software (GPLv3 licence) and is developed
in Python and Qt. The source files can be downloaded from
`GitHub <https://github.com/ninja-ide>`_.
Eric (The Eric Python IDE)
@@ -210,8 +219,8 @@ offering sourcecode autocompletion, syntax highlighting, support for version
control systems, python 3 support, integrated web browser, python shell,
integrated debugger and a flexible plug-in system. Written in python, it is
based on the Qt gui toolkit, integrating the Scintilla editor control. Eric
is an open-source software project (GPLv3 licence) with more than ten years of active
development.
is an open-source software project (GPLv3 licence) with more than ten years of
active development.
Interpreter Tools
@@ -221,15 +230,16 @@ Interpreter Tools
Virtual Environments
--------------------
A Virtual Environment is a tool to keep the dependencies required by different projects
in separate places, by creating virtual Python environments for them. It solves the
"Project X depends on version 1.x but, Project Y needs 4.x" dilemma, and keeps
your global site-packages directory clean and manageable.
A Virtual Environment is a tool to keep the dependencies required by different
projects in separate places, by creating virtual Python environments for them.
It solves the "Project X depends on version 1.x but, Project Y needs 4.x"
dilemma, and keeps your global site-packages directory clean and manageable.
For example, you can work on a project which requires Django 1.3 while also
maintaining a project which requires Django 1.0.
To start using and see more information: `Virtual Environments <http://github.com/kennethreitz/python-guide/blob/master/docs/dev/virtualenvs.rst>`_ docs.
To start using and see more information:
`Virtual Environments <http://github.com/kennethreitz/python-guide/blob/master/docs/dev/virtualenvs.rst>`_ docs.
Other Tools
:::::::::::
@@ -273,7 +283,8 @@ BPython
-------
`bpython <http://bpython-interpreter.org/>`_ is an alternative interface to the
Python interpreter for Unix-like operating systems. It has the following features:
Python interpreter for Unix-like operating systems. It has the following
features:
* In-line syntax highlighting.
* Readline-like autocomplete with suggestions displayed as you type.
+9 -8
View File
@@ -1,10 +1,10 @@
Virtual Environments
====================
A Virtual Environment is a tool to keep the dependencies required by different projects
in separate places, by creating virtual Python environments for them. It solves the
"Project X depends on version 1.x but, Project Y needs 4.x" dilemma, and keeps
your global site-packages directory clean and manageable.
A Virtual Environment is a tool to keep the dependencies required by different
projects in separate places, by creating virtual Python environments for them.
It solves the "Project X depends on version 1.x but, Project Y needs 4.x"
dilemma, and keeps your global site-packages directory clean and manageable.
For example, you can work on a project which requires Django 1.3 while also
maintaining a project which requires Django 1.0.
@@ -32,10 +32,11 @@ Basic Usage
$ cd my_project_folder
$ virtualenv venv
``virtualenv venv`` will create a folder in the current directory which will contain
the Python executable files, and a copy of the ``pip`` library which you can use to
install other packages. The name of the virtual environment (in this case, it was ``venv``)
can be anything; omitting the name will place the files in the current directory instead.
``virtualenv venv`` will create a folder in the current directory which will
contain the Python executable files, and a copy of the ``pip`` library which you
can use to install other packages. The name of the virtual environment (in this
case, it was ``venv``) can be anything; omitting the name will place the files
in the current directory instead.
This creates a copy of Python in whichever directory you ran the command in,
placing it in a folder named :file:`venv`.
+2 -1
View File
@@ -84,4 +84,5 @@ first-time Pythonista, and the authors to the Guide will gladly help if you
have any questions about the appropriateness, completeness, or accuracy of
a contribution.
To get started working on The Hitchhiker's Guide, see the :doc:`/notes/contribute` page.
To get started working on The Hitchhiker's Guide,
see the :doc:`/notes/contribute` page.
+38 -35
View File
@@ -7,9 +7,9 @@ Beginner
The Python Tutorial
~~~~~~~~~~~~~~~~~~~~
This is the official tutorial. It covers all the basics, and offers a tour of the
language and the standard library. Recommended for those who need a quickstart
guide to the language.
This is the official tutorial. It covers all the basics, and offers a tour of
the language and the standard library. Recommended for those who need a
quickstart guide to the language.
`The Python Tutorial <http://docs.python.org/tutorial/index.html>`_
@@ -18,15 +18,16 @@ Learn Python Interactive Tutorial
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Learnpython.org is an easy non-intimidating way to get introduced to Python.
The website takes the same approach used on the popular `Try Ruby <http://tryruby.org/>`_
website, it has an interactive Python interpreter built into the site that
allows you to go through the lessons without having to install Python locally.
The website takes the same approach used on the popular
`Try Ruby <http://tryruby.org/>`_ website, it has an interactive Python
interpreter built into the site that allows you to go through the lessons
without having to install Python locally.
`Learn Python <http://www.learnpython.org/>`_
If you want a more traditional book, *Python For You and Me* is an
excellent resource for learning all aspects of the language.
If you want a more traditional book, *Python For You and Me* is an excellent
resource for learning all aspects of the language.
`Python for You and Me <http://pymbook.readthedocs.org/>`_
@@ -121,8 +122,8 @@ More information about test driven development can be found at these resources:
A Byte of Python
~~~~~~~~~~~~~~~~
A free introductory book that teaches Python at the beginner level, it assumes no
previous programming experience.
A free introductory book that teaches Python at the beginner level, it assumes
no previous programming experience.
`A Byte of Python for Python 2.x <http://www.ibiblio.org/swaroopch/byteofpython/read/>`_
`A Byte of Python for Python 3.x <http://swaroopch.com/notes/Python_en-Preface/>`_
@@ -142,8 +143,9 @@ Advanced
Pro Python
~~~~~~~~~~
This book is for intermediate to advanced Python programmers who are looking to understand how
and why Python works the way it does and how they can take their code to the next level.
This book is for intermediate to advanced Python programmers who are looking to
understand how and why Python works the way it does and how they can take their
code to the next level.
`Pro Python <http://propython.com>`_
@@ -169,8 +171,8 @@ A Guide to Python's Magic Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a collection of blog posts by Rafe Kettler which explain 'magic methods'
in Python. Magic methods are surrounded by double underscores (i.e. __init__) and
can make classes and objects behave in different and magical ways.
in Python. Magic methods are surrounded by double underscores (i.e. __init__)
and can make classes and objects behave in different and magical ways.
`A Guide to Python's Magic Methods <http://www.rafekettler.com/magicmethods.html>`_
@@ -181,17 +183,17 @@ For Engineers and Scientists
A Primer on Scientific Programming with Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A Primer on Scientific Programming with Python, written by Hans Petter Langtangen,
mainly covers Python's usage in the scientific field. In the book, examples are
chosen from mathematics and the natural sciences.
A Primer on Scientific Programming with Python, written by Hans Petter
Langtangen, mainly covers Python's usage in the scientific field. In the book,
examples are chosen from mathematics and the natural sciences.
`A Primer on Scientific Programming with Python <http://www.springer.com/mathematics/computational+science+%26+engineering/book/978-3-642-30292-3>`_
Numerical Methods in Engineering with Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Numerical Methods in Engineering with Python, written by Jaan Kiusalaas, puts the
emphasis on numerical methods and how to implement them in Python.
Numerical Methods in Engineering with Python, written by Jaan Kiusalaas,
puts the emphasis on numerical methods and how to implement them in Python.
`Numerical Methods in Engineering with Python <http://www.cambridge.org/us/academic/subjects/engineering/engineering-mathematics-and-programming/numerical-methods-engineering-python-2nd-edition>`_
@@ -201,9 +203,9 @@ Miscellaneous topics
Problem Solving with Algorithms and Data Structures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem Solving with Algorithms and Data Structures covers a range of data structures and
algorithms. All concepts are illustrated with Python code along with interactive samples
that can be run directly in the browser.
Problem Solving with Algorithms and Data Structures covers a range of data
structures and algorithms. All concepts are illustrated with Python code along
with interactive samples that can be run directly in the browser.
`Problem Solving with Algorithms and Data Structures
<http://www.interactivepython.org/courselib/static/pythonds/index.html>`_
@@ -211,9 +213,10 @@ that can be run directly in the browser.
Programming Collective Intelligence
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Programming Collective Intelligence introduces a wide array of basic machine learning and
data mining methods. The exposition is not very mathematically formal, but rather focuses
on explaining the underlying intuition and shows how to implement the algorithms in Python.
Programming Collective Intelligence introduces a wide array of basic machine
learning and data mining methods. The exposition is not very mathematically
formal, but rather focuses on explaining the underlying intuition and shows
how to implement the algorithms in Python.
`Programming Collective Intelligence <http://shop.oreilly.com/product/9780596529321.do>`_
@@ -232,17 +235,17 @@ as writing C extensions.
The Python Language Reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is Python's reference manual, it covers the syntax and the core semantics of the
language.
This is Python's reference manual, it covers the syntax and the core semantics
of the language.
`The Python Language Reference <http://docs.python.org/reference/index.html>`_
Python Pocket Reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Python Pocket Reference, written by Mark Lutz, is an easy to use reference to the
core language, with descriptions of commonly used modules and toolkits. It covers
Python 3 and 2.6 versions.
Python Pocket Reference, written by Mark Lutz, is an easy to use reference to
the core language, with descriptions of commonly used modules and toolkits. It
covers Python 3 and 2.6 versions.
`Python Pocket Reference <http://shop.oreilly.com/product/9780596158095.do>`_
@@ -259,11 +262,11 @@ Writing Idiomatic Python
~~~~~~~~~~~~~~~~~~~~~~~~
"Writing Idiomatic Python", written by Jeff Knupp, contains the most common and
important Python idioms in a format that maximizes identification and understanding.
Each idiom is presented as a recommendation of a way to write some commonly
used piece of code, followed by an explanation of why the idiom is important.
It also contains two code samples for each idiom: the "Harmful" way to write it
and the "Idiomatic" way.
important Python idioms in a format that maximizes identification and
understanding. Each idiom is presented as a recommendation of a way to write
some commonly used piece of code, followed by an explanation of why the idiom
is important. It also contains two code samples for each idiom: the "Harmful"
way to write it and the "Idiomatic" way.
`For Python 2.7.3+ <http://www.amazon.com/Writing-Idiomatic-Python-2-7-3-Knupp/dp/1482372177/>`_
+4 -4
View File
@@ -35,15 +35,15 @@ new releases, jobs, etc. related to Python.
Python News
~~~~~~~~~~~~~
Python News is the news section in the official Python web site (www.python.org). It briefly
highlights the news from the Python community.
Python News is the news section in the official Python web site
(www.python.org). It briefly highlights the news from the Python community.
`Python News <http://www.python.org/news/>`_
Import Python Weekly
~~~~~~~~~~~~~~~~
Weekly Python Newsletter containing Python Articles, Projects, Videos, Tweets delivered in your inbox.
Keep Your Python Programming Skills Updated.
Weekly Python Newsletter containing Python Articles, Projects, Videos, Tweets
delivered in your inbox. Keep Your Python Programming Skills Updated.
`Import Python Weekly Newsletter <http://www.importpython.com/newsletter/>`_
+49 -42
View File
@@ -38,8 +38,8 @@ server.
run('git pull')
run('touch app.wsgi')
With the previous code saved in a file named :file:`fabfile.py`, we can check memory
usage with:
With the previous code saved in a file named :file:`fabfile.py`, we can check
memory usage with:
.. code-block:: console
@@ -72,10 +72,10 @@ programs, and host grouping.
Salt
----
`Salt <http://saltstack.org/>`_ is an open source infrastructure management tool.
It supports remote command execution from a central point (master host) to multiple
hosts (minions). It also supports system states which can be used to configure
multiple servers using simple template files.
`Salt <http://saltstack.org/>`_ is an open source infrastructure management
tool. It supports remote command execution from a central point (master host)
to multiple hosts (minions). It also supports system states which can be used
to configure multiple servers using simple template files.
Salt supports Python versions 2.6 and 2.7 and can be installed via pip:
@@ -83,8 +83,9 @@ Salt supports Python versions 2.6 and 2.7 and can be installed via pip:
$ pip install salt
After configuring a master server and any number of minion hosts, we can run arbitrary
shell commands or use pre-built modules of complex commands on our minions.
After configuring a master server and any number of minion hosts, we can run
arbitrary shell commands or use pre-built modules of complex commands on our
minions.
The following command lists all available minion hosts, using the ping module.
@@ -92,21 +93,24 @@ The following command lists all available minion hosts, using the ping module.
$ salt '*' test.ping
The host filtering is accomplished by matching the minion id, or using the grains system.
The `grains <http://docs.saltstack.org/en/latest/topics/targeting/grains.html>`_ system
uses static host information like the operating system version or the CPU architecture to
provide a host taxonomy for the Salt modules.
The host filtering is accomplished by matching the minion id,
or using the grains system. The
`grains <http://docs.saltstack.org/en/latest/topics/targeting/grains.html>`_
system uses static host information like the operating system version or the
CPU architecture to provide a host taxonomy for the Salt modules.
The following command lists all available minions running CentOS using the grains system:
The following command lists all available minions running CentOS using the
grains system:
.. code-block:: console
$ salt -G 'os:CentOS' test.ping
Salt also provides a state system. States can be used to configure the minion hosts.
Salt also provides a state system. States can be used to configure the minion
hosts.
For example, when a minion host is ordered to read the following state file, it will install
and start the Apache server:
For example, when a minion host is ordered to read the following state file,
it will install and start the Apache server:
.. code-block:: yaml
@@ -241,28 +245,29 @@ Puppet
------
`Puppet <http://puppetlabs.com>`_ is IT Automation and configuration management
software from Puppet Labs that allows System Administrators to define the state of
their IT Infrastructure, thereby providing an elegant way to manage their fleet of
physical and virtual machines.
software from Puppet Labs that allows System Administrators to define the state
of their IT Infrastructure, thereby providing an elegant way to manage their
fleet of physical and virtual machines.
Puppet is available both as an Open Source and an Enterprise variant. Modules are
small, shareable units of code written to automate or define the state of a system.
`Puppet Forge <https://forge.puppetlabs.com/>`_ is a repository for modules written
by the community for Open Source and Enterprise Puppet.
Puppet is available both as an Open Source and an Enterprise variant. Modules
are small, shareable units of code written to automate or define the state of a
system. `Puppet Forge <https://forge.puppetlabs.com/>`_ is a repository for
modules written by the community for Open Source and Enterprise Puppet.
Puppet Agents are installed on nodes whose state needs to be monitored or changed.
A desginated server known as the Puppet Master is responsible for orchastrating the
agent nodes.
Puppet Agents are installed on nodes whose state needs to be monitored or
changed. A desginated server known as the Puppet Master is responsible for
orchastrating the agent nodes.
Agent nodes send basic facts about the system such as to the operating system, kernel,
architecture, ip address, hostname etc. to the Puppet Master.
The Puppet Master then compiles a catalog with information provided by the agents on
how each node should be configured and sends it to the agent. The agent enforces the
change as prescribed in the catalog and sends a report back to the Puppet Master.
Agent nodes send basic facts about the system such as to the operating system,
kernel, architecture, ip address, hostname etc. to the Puppet Master.
The Puppet Master then compiles a catalog with information provided by the
agents on how each node should be configured and sends it to the agent. The
agent enforces the change as prescribed in the catalog and sends a report back
to the Puppet Master.
Facter is an interesting tool that ships with Puppet that pulls basic facts about
the system. These facts can be referenced as a variable while writing your
Puppet modules.
Facter is an interesting tool that ships with Puppet that pulls basic facts
about the system. These facts can be referenced as a variable while writing
your Puppet modules.
.. code-block:: console
@@ -273,8 +278,8 @@ Puppet modules.
$ facter operatingsystem
Ubuntu
Writing Modules in Puppet is pretty straight forward. Puppet Manifests together form
Puppet Modules. Puppet manifest end with an extension of ``.pp``.
Writing Modules in Puppet is pretty straight forward. Puppet Manifests together
form Puppet Modules. Puppet manifest end with an extension of ``.pp``.
Here is an example of 'Hello World' in Puppet.
.. code-block:: puppet
@@ -285,9 +290,10 @@ Here is an example of 'Hello World' in Puppet.
#the notification message by default.
}
Here is another example with system based logic. Note how the operatingsystem fact
is being used as a variable prepended with the ``$`` sign. Similarly, this holds true
for other facts such as hostname which can be referenced by ``$hostname``
Here is another example with system based logic. Note how the operatingsystem
fact is being used as a variable prepended with the ``$`` sign. Similarly, this
holds true for other facts such as hostname which can be referenced by
``$hostname``
.. code-block:: puppet
@@ -298,9 +304,10 @@ for other facts such as hostname which can be referenced by ``$hostname``
},
}
There are several resource types for Puppet but the package-file-service paradigm is all
you need for undertaking majority of the configuration management. The following Puppet code makes sure
that the OpenSSH-Server package is installed in a system and the sshd service is notified to restart
There are several resource types for Puppet but the package-file-service
paradigm is all you need for undertaking majority of the configuration
management. The following Puppet code makes sure that the OpenSSH-Server
package is installed in a system and the sshd service is notified to restart
everytime the sshd configuration file is changed.
.. code-block:: puppet
+8 -8
View File
@@ -62,15 +62,15 @@ which provides the following features:
Travis-CI
---------
`Travis-CI <https://travis-ci.org/>`_ is a distributed CI server which builds tests
for open source projects for free. It provides multiple workers to run Python tests
on and seamlessly integrates with GitHub. You can even have it comment on your Pull
Requests whether this particular changeset breaks the build or not. So if you are
hosting your code on GitHub, travis-ci is a great and easy way to get started with
Continuous Integration.
`Travis-CI <https://travis-ci.org/>`_ is a distributed CI server which builds
tests for open source projects for free. It provides multiple workers to run
Python tests on and seamlessly integrates with GitHub. You can even have it
comment on your Pull Requests whether this particular changeset breaks the
build or not. So if you are hosting your code on GitHub, travis-ci is a great
and easy way to get started with Continuous Integration.
In order to get started, add a :file:`.travis.yml` file to your repository with this
example content::
In order to get started, add a :file:`.travis.yml` file to your repository with
this example content::
language: python
python:
+5 -4
View File
@@ -45,10 +45,11 @@ library is designed to have a familiar socket-style API.
RabbitMQ
--------
RabbitMQ is an open source message broker software that implements the Advanced Message Queuing Protocol (AMQP).
The RabbitMQ server is written in the Erlang programming language and is built on the Open Telecom Platform
framework for clustering and failover. Client libraries to interface with the broker are available
for all major programming languages.
RabbitMQ is an open source message broker software that implements the Advanced
Message Queuing Protocol (AMQP). The RabbitMQ server is written in the Erlang
programming language and is built on the Open Telecom Platform framework for
clustering and failover. Client libraries to interface with the broker are
available for all major programming languages.
- `Homepage <http://www.rabbitmq.com/>`_
- `GitHub Organization <https://github.com/rabbitmq?page=1>`_
+3 -3
View File
@@ -9,9 +9,9 @@ library that provides cryptographic recipes and primitives. It supports
Python 2.6-2.7, Python 3.2+ and PyPy.
Cryptography is divided into two layers of recipes and hazardous materials (hazmat).
The recipes layer provides simple API for proper symmetric encryption and the
hazmat layer provides low-level cryptographic primitives.
Cryptography is divided into two layers of recipes and hazardous materials
(hazmat). The recipes layer provides simple API for proper symmetric
encryption and the hazmat layer provides low-level cryptographic primitives.
+21 -13
View File
@@ -30,39 +30,47 @@ Django ORM
The Django ORM is the interface used by `Django <http://www.djangoproject.com>`_
to provide database access.
It's based on the idea of `models <https://docs.djangoproject.com/en/1.3/#the-model-layer>`_,
It's based on the idea of
`models <https://docs.djangoproject.com/en/1.3/#the-model-layer>`_,
an abstraction that makes it easier to manipulate data in Python.
The basics:
- Each model is a Python class that subclasses django.db.models.Model.
- Each attribute of the model represents a database field.
- Django gives you an automatically-generated database-access API; see `Making queries <https://docs.djangoproject.com/en/dev/topics/db/queries/>`__.
- Django gives you an automatically-generated database-access API; see
`Making queries <https://docs.djangoproject.com/en/dev/topics/db/queries/>`__.
peewee
------
`peewee <http://docs.peewee-orm.com/en/latest/>`_ is another ORM with a focus on being lightweight with support for
Python 2.6+ and 3.2+ which supports SQLite, MySQL and Postgres by default. The `model layer <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#model-definition>`_
is similar to that of the Django ORM and it has `SQL-like methods <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#retrieving-data>`_
to query data. While SQLite, MySQL and Postgres are supported out-of-the-box, there is a `collection of add-ons <https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#playhouse>`_
`peewee <http://docs.peewee-orm.com/en/latest/>`_ is another ORM with a focus
on being lightweight with support for Python 2.6+ and 3.2+ which supports
SQLite, MySQL and Postgres by default. The
`model layer <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#model-definition>`_
is similar to that of the Django ORM and it has
`SQL-like methods <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#retrieving-data>`_
to query data. While SQLite, MySQL and Postgres are supported out-of-the-box,
there is a `collection of add-ons <https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#playhouse>`_
available.
PonyORM
-------
`PonyORM <http://ponyorm.com/>`_ is an ORM that takes a different approach to querying the database. Instead of writing
an SQL-like language or boolean expressions, Python's generator syntax is used. There's also an graphical schema editor
that can generate PonyORM entities for you. It supports Python 2.6+ and Python 3.3+ and can connect to SQLite, MySQL,
Postgres & Oracle
`PonyORM <http://ponyorm.com/>`_ is an ORM that takes a different approach to
querying the database. Instead of writing an SQL-like language or boolean
expressions, Python's generator syntax is used. There's also an graphical
schema editor that can generate PonyORM entities for you. It supports Python
2.6+ and Python 3.3+ and can connect to SQLite, MySQL, Postgres & Oracle
SQLObject
---------
`SQLObject <http://www.sqlobject.org/>`_ is yet another ORM. It supports a wide variety of databases: Common database systems
MySQL, Postgres and SQLite and more exotic systems like SAP DB, SyBase and MSSQL. It only supports Python 2 from
Python 2.6 upwards.
`SQLObject <http://www.sqlobject.org/>`_ is yet another ORM. It supports a wide
variety of databases: Common database systems MySQL, Postgres and SQLite and
more exotic systems like SAP DB, SyBase and MSSQL. It only supports Python 2
from Python 2.6 upwards.
.. There's no official information on this on their page, this information was gathered by looking at their source code
+6 -5
View File
@@ -22,8 +22,8 @@ GTk
PyGTK provides Python bindings for the GTK+ toolkit. Like the GTK+ library
itself, it is currently licensed under the GNU LGPL. It is worth noting that
PyGTK only currently supports the Gtk-2.X API (NOT Gtk-3.0). It is currently
recommended that PyGTK not be used for new projects and that existing applications
be ported from PyGTK to PyGObject.
recommended that PyGTK not be used for new projects and that existing
applications be ported from PyGTK to PyGObject.
Kivy
----
@@ -33,7 +33,8 @@ interaction design and rapid prototyping, while making your code reusable
and deployable.
Kivy is written in Python, based on OpenGL and supports different input devices
such as: Mouse, Dual Mouse, TUIO, WiiMote, WM_TOUCH, HIDtouch, Apple's products and so on.
such as: Mouse, Dual Mouse, TUIO, WiiMote, WM_TOUCH, HIDtouch, Apple's products
and so on.
Kivy is actively being developed by a community and is free to use. It operates
on all major platforms (Linux, OSX, Windows, Android).
@@ -62,8 +63,8 @@ PyjamasDesktop (pyjs Desktop)
-----------------------------
PyjamasDesktop is a port of Pyjamas. PyjamasDesktop is application widget set
for desktop and a cross-platform framework. (After release v0.6 PyjamasDesktop
is a part of Pyjamas (Pyjs)). Briefly, it allows the exact same Python web application
source code to be executed as a standalone desktop application.
is a part of Pyjamas (Pyjs)). Briefly, it allows the exact same Python web
application source code to be executed as a standalone desktop application.
`Python Wiki for PyjamasDesktop <http://wiki.python.org/moin/PyjamasDesktop>`_.
+7 -5
View File
@@ -9,17 +9,19 @@ Python Imaging Library
----------------------
The `Python Imaging Library <http://www.pythonware.com/products/pil/>`_, or PIL
for short, is *the* library for image manipulation in Python. Unfortunately, its
development has stagnated, with its last release in 2009.
for short, is *the* library for image manipulation in Python. Unfortunately,
its development has stagnated, with its last release in 2009.
Luckily for you, there's an actively-developed fork of PIL called `Pillow <http://python-pillow.github.io/>`_ -
it's easier to install, runs on all operating systems, and supports Python 3.
Luckily for you, there's an actively-developed fork of PIL called
`Pillow <http://python-pillow.github.io/>`_ - it's easier to install, runs on
all operating systems, and supports Python 3.
Installation
~~~~~~~~~~~~
Before installing Pillow, you'll have to install Pillow's prerequisites. Find
the instructions for your platform `here <https://pypi.python.org/pypi/Pillow/2.1.0#platform-specific-instructions>`_.
the instructions for your platform
`here <https://pypi.python.org/pypi/Pillow/2.1.0#platform-specific-instructions>`_.
After that, it's straightforward:
+14 -5
View File
@@ -1,7 +1,9 @@
JSON
====
The `json <https://docs.python.org/2/library/json.html>`_ library can parse JSON from strings or files. The library parses JSON into a Python dictionary or list. It can also convert Python dictionaries or lists into JSON strings.
The `json <https://docs.python.org/2/library/json.html>`_ library can parse
JSON from strings or files. The library parses JSON into a Python dictionary
or list. It can also convert Python dictionaries or lists into JSON strings.
Parsing JSON
------------
@@ -43,14 +45,21 @@ You can also convert the following to JSON:
simplejson
----------
The JSON library was added to Python in version 2.6. If you're using an earlier version of Python, the `simplejson <https://simplejson.readthedocs.org/en/latest/>`_ library is available via PyPI.
The JSON library was added to Python in version 2.6.
If you're using an earlier version of Python, the
`simplejson <https://simplejson.readthedocs.org/en/latest/>`_ library is
available via PyPI.
simplejson mimics the json standard library. It is available so that developers that use older versions of Python can use the latest features available in the json lib.
simplejson mimics the json standard library. It is available so that developers
that use older versions of Python can use the latest features available in the
json lib.
You can start using simplejson when the json library is not available by importing simplejson under a different name:
You can start using simplejson when the json library is not available by
importing simplejson under a different name:
.. code-block:: python
import simplejson as json
After importing simplejson as json, the above examples will all work as if you were using the standard json library.
After importing simplejson as json, the above examples will all work as if you
were using the standard json library.
+5 -3
View File
@@ -7,7 +7,8 @@ Twisted
`Twisted <http://twistedmatrix.com/trac/>`_ is an event-driven networking
engine. It can be used to build applications around many different networking
protocols, including http servers and clients, applications using SMTP, POP3,
IMAP or SSH protocols, instant messaging and `much more <http://twistedmatrix.com/trac/wiki/Documentation>`_.
IMAP or SSH protocols, instant messaging
and `much more <http://twistedmatrix.com/trac/wiki/Documentation>`_.
PyZMQ
-----
@@ -30,5 +31,6 @@ For a quick start, read the `ZeroMQ guide <http://zguide.zeromq.org/page:all>`_.
gevent
------
`gevent <http://www.gevent.org/>`_ is a coroutine-based Python networking library
that uses greenlets to provide a high-level synchronous API on top of the libev event loop.
`gevent <http://www.gevent.org/>`_ is a coroutine-based Python networking
library that uses greenlets to provide a high-level synchronous API on top of
the libev event loop.
+10 -8
View File
@@ -95,9 +95,10 @@ Rpy2
----
`Rpy2 <http://rpy.sourceforge.net/rpy2.html>`_ is a Python binding for the R
statistical package allowing the execution of R functions from Python and passing
data back and forth between the two environments. Rpy2 is the object oriented
implementation of the `Rpy <http://rpy.sourceforge.net/rpy.html>`_ bindings.
statistical package allowing the execution of R functions from Python and
passing data back and forth between the two environments. Rpy2 is the object
oriented implementation of the `Rpy <http://rpy.sourceforge.net/rpy.html>`_
bindings.
PsychoPy
--------
@@ -121,11 +122,12 @@ Unofficial Windows Binaries for Python Extension Packages
---------------------------------------------------------
Many people who do scientific computing are on Windows, yet many of the
scientific computing packages are notoriously difficult to build and install
on this platform. `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_
however, has compiled a list of Windows binaries for many useful Python packages.
The list of packages has grown from a mainly scientific Python resource to a more
general list. If you're on Windows, you may want to check it out.
scientific computing packages are notoriously difficult to build and install on
this platform. `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_
however, has compiled a list of Windows binaries for many useful Python
packages. The list of packages has grown from a mainly scientific Python
resource to a more general list. If you're on Windows, you may want to check it
out.
Anaconda
--------
+4 -3
View File
@@ -19,9 +19,10 @@ lxml and Requests
`lxml <http://lxml.de/>`_ is a pretty extensive library written for parsing
XML and HTML documents very quickly, even handling messed up tags in the
process. We will also be using the `Requests <http://docs.python-requests.org/en/latest/>`_
module instead of the already built-in urllib2 module due to improvements in speed and
readability. You can easily install both using ``pip install lxml`` and
process. We will also be using the
`Requests <http://docs.python-requests.org/en/latest/>`_ module instead of the
already built-in urllib2 module due to improvements in speed and readability.
You can easily install both using ``pip install lxml`` and
``pip install requests``.
Let's start with the imports:
+22 -23
View File
@@ -92,9 +92,10 @@ Support can be found on its `mailing list <http://werkzeug.pocoo.org/community/#
Tornado
--------
`Tornado <http://www.tornadoweb.org/>`_ is a scalable, non-blocking web server and web application framework with
a relative simple usage. Tornado is known for its high performance.
It was initially developed for `friendfeed <http://friendfeed.com/>`_ , a real time chat and blog system.
`Tornado <http://www.tornadoweb.org/>`_ is a scalable, non-blocking web server
and web application framework with a relative simple usage. Tornado is known
for its high performance. It was initially developed for
`friendfeed <http://friendfeed.com/>`_ , a real time chat and blog system.
In the Jinja2 template engine example it is used to serve the rendered pages.
@@ -108,9 +109,9 @@ and functionality and can thus not be considered lightweight. On the other
hand, it does not provide all the functionality Django does. Instead Pyramid
brings basic support for most regular tasks and provides a great deal of
extensibility. Additionally, Pyramid has a huge focus on complete
`documentation <http://docs.pylonsproject.org/en/latest/docs/pyramid.html>`__. As
a little extra it comes with the Werkzeug Debugger which allows you to debug a
running web application in the browser.
`documentation <http://docs.pylonsproject.org/en/latest/docs/pyramid.html>`__.
As a little extra it comes with the Werkzeug Debugger which allows you to debug
a running web application in the browser.
**Support** can also be found in the
`documentation <http://docs.pylonsproject.org/en/latest/index.html#support-desc>`__.
@@ -250,9 +251,10 @@ Gondor
~~~~~~
`Gondor <https://gondor.io/>`_ is a PaaS specialized for deploying Django
and Pinax applications. Gondor recommends Django version 1.6 and supports any WSGI application on
Python version 2.7. Gondor can automatically configure your Django site if you
use :file:`local_settings.py` for site-specific configuration information.
and Pinax applications. Gondor recommends Django version 1.6 and supports any
WSGI application on Python version 2.7. Gondor can automatically configure your
Django site if you use :file:`local_settings.py` for site-specific configuration
information.
Gondor has a guide on deploying `Django projects <https://gondor.io/support/django/setup/>`_.
@@ -260,23 +262,20 @@ Gondor has a guide on deploying `Django projects <https://gondor.io/support/djan
Templating
::::::::::
Most WSGI applications are responding to HTTP requests to serve
content in HTML or other markup languages. Instead of generating directly
textual content from Python, the concept of separation of concerns
advises us to use templates. A template engine manages a suite of
template files, with a system of hierarchy and inclusion to
avoid unnecessary repetition, and is in charge of rendering
(generating) the actual content, filling the static content
of the templates with the dynamic content generated by the
application.
Most WSGI applications are responding to HTTP requests to serve content in HTML
or other markup languages. Instead of generating directly textual content from
Python, the concept of separation of concerns advises us to use templates. A
template engine manages a suite of template files, with a system of hierarchy
and inclusion to avoid unnecessary repetition, and is in charge of rendering
(generating) the actual content, filling the static content of the templates
with the dynamic content generated by the application.
As template files are
sometimes written by designers or front-end developers,
it can be difficult to handle increasing complexity.
sometimes written by designers or front-end developers, it can be difficult to
handle increasing complexity.
Some general good practices apply to the part of the
application passing dynamic content to the template engine,
and to the templates themselves.
Some general good practices apply to the part of the application passing
dynamic content to the template engine, and to the templates themselves.
- Template files should be passed only the dynamic
content that is needed for rendering the template. Avoid
+20 -15
View File
@@ -5,33 +5,36 @@ Packaging your code is important.
You'll need to package your code first before sharing it with other developers.
The `Python Packaging Guide <https://python-packaging-user-guide.readthedocs.org/en/latest/>`_ provides an extensive guide on creating and maintaining Python packages.
The `Python Packaging Guide <https://python-packaging-user-guide.readthedocs.org/en/latest/>`_
provides an extensive guide on creating and maintaining Python packages.
For Python Developers
:::::::::::::::::::::
If you're writing an open source Python module, `PyPI <http://pypi.python.org>`_,
more properly known as *The Cheeseshop*, is the place to host it.
If you're writing an open source Python module, `PyPI <http://pypi.python.org>`_
, more properly known as *The Cheeseshop*, is the place to host it.
Pip vs. easy_install
--------------------
Use `pip <http://pypi.python.org/pypi/pip>`_. More details `here <http://stackoverflow.com/questions/3220404/why-use-pip-over-easy-install>`_
Use `pip <http://pypi.python.org/pypi/pip>`_. More details
`here <http://stackoverflow.com/questions/3220404/why-use-pip-over-easy-install>`_
Personal PyPI
-------------
If you want to install packages from a source other than PyPI, (say, if
your packages are *proprietary*), you can do it by hosting a simple http server,
running from the directory which holds those packages which need to be installed.
your packages are *proprietary*), you can do it by hosting a simple http
server, running from the directory which holds those packages which need to be
installed.
**Showing an example is always beneficial**
For example, if you want to install a package called :file:`MyPackage.tar.gz`, and
assuming this is your directory structure:
For example, if you want to install a package called :file:`MyPackage.tar.gz`,
and assuming this is your directory structure:
- archive
@@ -55,8 +58,8 @@ package installer. Using Pip, you would do it like:
Having a folder with the same name as the package name is **crucial** here.
I got fooled by that, one time. But if you feel that creating a folder called
:file:`MyPackage` and keeping :file:`MyPackage.tar.gz` inside that, is *redundant*,
you can still install MyPackage using:
:file:`MyPackage` and keeping :file:`MyPackage.tar.gz` inside that, is
*redundant*, you can still install MyPackage using:
.. code-block:: console
@@ -65,16 +68,18 @@ you can still install MyPackage using:
pypiserver
++++++++++
`Pypiserver <https://pypi.python.org/pypi/pypiserver>`_ is a minimal PyPI compatible server.
It can be used to serve a set of packages to easy_install or pip. It includes helpful
features like an administrative command (:option:`-U`) which will update all its packages to their
latest versions found on PyPI.
`Pypiserver <https://pypi.python.org/pypi/pypiserver>`_ is a minimal PyPI
compatible server. It can be used to serve a set of packages to easy_install
or pip. It includes helpful features like an administrative command
(:option:`-U`) which will update all its packages to their latest versions
found on PyPI.
S3-Hosted PyPi
++++++++++++++
One simple option for a personal PyPi server is to use Amazon S3. A prerequisite for this is that you have an Amazon AWS account with an S3 bucket.
One simple option for a personal PyPi server is to use Amazon S3. A
prerequisite for this is that you have an Amazon AWS account with an S3 bucket.
1. **Install all your requirements from PyPi or another source**
2. **Install pip2pi**
+45 -43
View File
@@ -6,51 +6,53 @@ Further Configuration of Pip and Virtualenv
Requiring an active virtual environment for ``pip``
---------------------------------------------------
By now it should be clear that using virtual envirtonments is a great way to keep
your development environment clean and keeping different projects' requirements
separate.
By now it should be clear that using virtual envirtonments is a great way to
keep your development environment clean and keeping different projects'
requirements separate.
When you start working on many different projects, it can be hard to remember to
activate the related virtual environment when you come back to a specific project.
As a result of this, it is very easy to install packages globally while thinking
that you are actually installing the package for the virtual environment of the
project. Over time this can result in a messy global package list.
activate the related virtual environment when you come back to a specific
project. As a result of this, it is very easy to install packages globally
while thinking that you are actually installing the package for the virtual
environment of the project. Over time this can result in a messy global package
list.
In order to make sure that you install packages to your active virtual environment
when you use ``pip install``, consider adding the following two lines to your
:file:`~/.bashrc` file:
In order to make sure that you install packages to your active virtual
environment when you use ``pip install``, consider adding the following two
lines to your :file:`~/.bashrc` file:
.. code-block:: console
export PIP_REQUIRE_VIRTUALENV=true
After saving this change and sourcing the :file:`~/.bashrc` file with ``source ~/.bashrc``,
pip will no longer let you install packages if you are not in a virtual environment.
If you try to use ``pip install`` outside of a virtual environment pip will gently
remind you that an activated virtual environment is needed to install packages.
After saving this change and sourcing the :file:`~/.bashrc` file with
``source ~/.bashrc``, pip will no longer let you install packages if you are not
in a virtual environment. If you try to use ``pip install`` outside of a
virtual environment pip will gently remind you that an activated virtual
environment is needed to install packages.
.. code-block:: console
$ pip install requests
Could not find an activated virtualenv (required).
You can also do this configuration by editing your :file:`pip.conf` or :file:`pip.ini`
file. :file:`pip.conf` is used by Unix and Mac OS X operating systems and it can be
found at:
You can also do this configuration by editing your :file:`pip.conf` or
:file:`pip.ini` file. :file:`pip.conf` is used by Unix and Mac OS X operating
systems and it can be found at:
.. code-block:: console
$HOME/.pip/pip.conf
Similarly, the :file:`pip.ini` file is used by Windows operating systems and it can
be found at:
Similarly, the :file:`pip.ini` file is used by Windows operating systems and it
can be found at:
.. code-block:: console
%HOME%\pip\pip.ini
If you don't have a :file:`pip.conf` or :file:`pip.ini` file at these locations, you can
create a new file with the correct name for your operating system.
If you don't have a :file:`pip.conf` or :file:`pip.ini` file at these locations,
you can create a new file with the correct name for your operating system.
If you already have a configuration file, just add the following line under the
``[global]`` settings to require an active virtual environment:
@@ -68,9 +70,9 @@ add the following lines to this new file:
require-virtualenv = true
You will of course need to install some packages globally (usually ones that you
use across different projects consistenly) and this can be accomplished by adding
the following to your :file:`~/.bashrc` file:
You will of course need to install some packages globally (usually ones that
you use across different projects consistenly) and this can be accomplished by
adding the following to your :file:`~/.bashrc` file:
.. code-block:: console
@@ -78,38 +80,38 @@ the following to your :file:`~/.bashrc` file:
PIP_REQUIRE_VIRTUALENV="" pip "$@"
}
After saving the changes and sourcing your :file:`~/.bashrc` file you can now install
packages globally by running ``gpip install``. You can change the name of the
function to anything you like, just keep in mind that you will have to use that
name when trying to install packages globally with pip.
After saving the changes and sourcing your :file:`~/.bashrc` file you can now
install packages globally by running ``gpip install``. You can change the name
of the function to anything you like, just keep in mind that you will have to
use that name when trying to install packages globally with pip.
Caching packages for future use
-------------------------------
Every developer has preferred libraries and when you are working on a lot of
different projects, you are bound to have some overlap between the libraries that
you use. For example, you may be using the ``requests`` library in a lot of different
projects.
different projects, you are bound to have some overlap between the libraries
that you use. For example, you may be using the ``requests`` library in a lot
of different projects.
It is surely unnecessary to re-download the same packages/libraries each time you
start working on a new project (and in a new virtual environmen as a result).
It is surely unnecessary to re-download the same packages/libraries each time
you start working on a new project (and in a new virtual environmen as a result).
Fortunately, you can configure pip in such a way that it tries to reuse already
installed packages.
On UNIX systems, you can add the following line to your :file:`.bashrc` or :file:`.bash_profile`
file.
On UNIX systems, you can add the following line to your :file:`.bashrc` or
:file:`.bash_profile` file.
.. code-block:: console
export PIP_DOWNLOAD_CACHE=$HOME/.pip/cache
You can set the path to anywhere you like (as long as you have write
access). After adding this line, ``source`` your :file:`.bashrc` (or :file:`.bash_profile`)
file and you will be all set.
access). After adding this line, ``source`` your :file:`.bashrc`
(or :file:`.bash_profile`) file and you will be all set.
Another way of doing the same configuration is via the :file:`pip.conf` or :file:`pip.ini`
files, depending on your system. If you are on Windows, you can add the following
line to your :file:`pip.ini` file under ``[global]`` settings:
Another way of doing the same configuration is via the :file:`pip.conf` or
:file:`pip.ini` files, depending on your system. If you are on Windows, you can
add the following line to your :file:`pip.ini` file under ``[global]`` settings:
.. code-block:: console
@@ -123,6 +125,6 @@ Similarly, on UNIX systems you should simply add the following line to your
download-cache = $HOME/.pip/cache
Even though you can use any path you like to store your cache, it is recommended
that you create a new folder *in* the folder where your :file:`pip.conf` or :file:`pip.ini`
file lives. If you don't trust yourself with all of this path voodoo, just use
the values provided here and you will be fine.
that you create a new folder *in* the folder where your :file:`pip.conf` or
:file:`pip.ini` file lives. If you don't trust yourself with all of this path
voodoo, just use the values provided here and you will be fine.
+3 -4
View File
@@ -2,10 +2,9 @@ Choosing a License
==================
Your source publication *needs* a license. In the US, if no license is
specified, users have no legal right to download, modify, or
distribute. Furthermore, people can't contribute to your code unless
you tell them what rules to play by. Choosing a license is complicated, so
here are some pointers:
specified, users have no legal right to download, modify, or distribute.
Furthermore, people can't contribute to your code unless you tell them what
rules to play by. Choosing a license is complicated, so here are some pointers:
Open source. There are plenty of `open source licenses
<http://opensource.org/licenses/alphabetical>`_ available to choose
+9 -11
View File
@@ -23,11 +23,10 @@ the goal is to display a help statement for a command line application.
Other reasons why logging is better than ``print``:
- The `log record`_, which is created with every logging event, contains
readily available diagnostic information such as the file name,
full path, function, and line number of the logging event.
- Events logged in included modules are automatically accessible via the
root logger
to your application's logging stream, unless you filter them out.
readily available diagnostic information such as the file name, full path,
function, and line number of the logging event.
- Events logged in included modules are automatically accessible via the root
logger to your application's logging stream, unless you filter them out.
- Logging can be selectively silenced by using the method
:meth:`logging.Logger.setLevel` or disabled by setting the attribute
:attr:`logging.Logger.disabled` to ``True``.
@@ -83,15 +82,14 @@ application environment.
There are at least three ways to configure a logger:
- Using an INI-formatted file:
- **Pro**: possible to update configuration while running
using the function :func:`logging.config.listen` to listen
on a socket.
- **Pro**: possible to update configuration while running using the
function :func:`logging.config.listen` to listen on a socket.
- **Con**: less control (*e.g.* custom subclassed filters or loggers)
than possible when configuring a logger in code.
- Using a dictionary or a JSON-formatted file:
- **Pro**: in addition to updating while running, it is possible to
load from a file using the :mod:`json` module, in the standard
library since Python 2.6.
- **Pro**: in addition to updating while running, it is possible to load
from a file using the :mod:`json` module, in the standard library since
Python 2.6.
- **Con**: less control than when configuring a logger in code.
- Using code:
- **Pro**: complete control over the configuration.
+74 -71
View File
@@ -34,8 +34,8 @@ to do it poorly. Some signs of a poorly structured project
include:
- Multiple and messy circular dependencies: if your classes
Table and Chair in :file:`furn.py` need to import Carpenter from :file:`workers.py`
to answer a question such as ``table.isdoneby()``,
Table and Chair in :file:`furn.py` need to import Carpenter from
:file:`workers.py` to answer a question such as ``table.isdoneby()``,
and if conversely the class Carpenter needs to import Table and Chair,
to answer the question ``carpenter.whatdo()``, then you
have a circular dependency. In this case you will have to resort to
@@ -85,17 +85,17 @@ in one file, and all low-level operations in another file. In this case,
the interface file needs to import the low-level file. This is done with the
``import`` and ``from ... import`` statements.
As soon as you use `import` statements you use modules. These can be either built-in
modules such as `os` and `sys`, third-party modules you have installed in your
environment, or your project's internal modules.
As soon as you use `import` statements you use modules. These can be either
built-in modules such as `os` and `sys`, third-party modules you have installed
in your environment, or your project's internal modules.
To keep in line with the style guide, keep module names short, lowercase, and
be sure to avoid using special symbols like the dot (.) or question mark (?).
So a file name like :file:`my.spam.py` is one you should avoid! Naming this way
will interfere with the way Python looks for modules.
In the case of `my.spam.py` Python expects to find a :file:`spam.py` file in a folder named :file:`my`
which is not the case. There is an
In the case of `my.spam.py` Python expects to find a :file:`spam.py` file in a
folder named :file:`my` which is not the case. There is an
`example <http://docs.python.org/tutorial/modules.html#packages>`_ of how the
dot notation should be used in the Python docs.
@@ -106,18 +106,18 @@ Aside from some naming restrictions, nothing special is required for a Python
file to be a module, but you need to understand the import mechanism in order
to use this concept properly and avoid some issues.
Concretely, the ``import modu`` statement will look for the proper file, which is
:file:`modu.py` in the same directory as the caller if it exists. If it is not
found, the Python interpreter will search for :file:`modu.py` in the "path"
Concretely, the ``import modu`` statement will look for the proper file, which
is :file:`modu.py` in the same directory as the caller if it exists. If it is
not found, the Python interpreter will search for :file:`modu.py` in the "path"
recursively and raise an ImportError exception if it is not found.
Once :file:`modu.py` is found, the Python interpreter will execute the module in an
isolated scope. Any top-level statement in :file:`modu.py` will be executed,
Once :file:`modu.py` is found, the Python interpreter will execute the module in
an isolated scope. Any top-level statement in :file:`modu.py` will be executed,
including other imports if any. Function and class definitions are stored in
the module's dictionary.
Then, the module's variables, functions, and classes will be available to the caller
through the module's namespace, a central concept in programming that is
Then, the module's variables, functions, and classes will be available to the
caller through the module's namespace, a central concept in programming that is
particularly helpful and powerful in Python.
In many languages, an ``include file`` directive is used by the preprocessor to
@@ -127,14 +127,15 @@ means that you generally don't have to worry that the included code could have
unwanted effects, e.g. override an existing function with the same name.
It is possible to simulate the more standard behavior by using a special syntax
of the import statement: ``from modu import *``. This is generally considered bad
practice. **Using** ``import *`` **makes code harder to read and makes dependencies less
compartmentalized**.
of the import statement: ``from modu import *``. This is generally considered
bad practice. **Using** ``import *`` **makes code harder to read and makes
dependencies less compartmentalized**.
Using ``from modu import func`` is a way to pinpoint the function you want to
import and put it in the global namespace. While much less harmful than ``import
*`` because it shows explicitly what is imported in the global namespace, its
only advantage over a simpler ``import modu`` is that it will save a little typing.
only advantage over a simpler ``import modu`` is that it will save a little
typing.
**Very bad**
@@ -176,29 +177,32 @@ Packages
Python provides a very straightforward packaging system, which is simply an
extension of the module mechanism to a directory.
Any directory with an :file:`__init__.py` file is considered a Python package. The
different modules in the package are imported in a similar manner as plain
modules, but with a special behavior for the :file:`__init__.py` file, which is used to
gather all package-wide definitions.
Any directory with an :file:`__init__.py` file is considered a Python package.
The different modules in the package are imported in a similar manner as plain
modules, but with a special behavior for the :file:`__init__.py` file, which is
used to gather all package-wide definitions.
A file :file:`modu.py` in the directory :file:`pack/` is imported with the statement ``import
pack.modu``. This statement will look for an :file:`__init__.py` file in :file:`pack`, execute
all of its top-level statements. Then it will look for a file named :file:`pack/modu.py` and
A file :file:`modu.py` in the directory :file:`pack/` is imported with the
statement ``import pack.modu``. This statement will look for an
:file:`__init__.py` file in :file:`pack`, execute all of its top-level
statements. Then it will look for a file named :file:`pack/modu.py` and
execute all of its top-level statements. After these operations, any variable,
function, or class defined in :file:`modu.py` is available in the pack.modu namespace.
function, or class defined in :file:`modu.py` is available in the pack.modu
namespace.
A commonly seen issue is to add too much code to :file:`__init__.py`
files. When the project complexity grows, there may be sub-packages and
sub-sub-packages in a deep directory structure. In this case, importing a single item
from a sub-sub-package will require executing all :file:`__init__.py` files met while
traversing the tree.
sub-sub-packages in a deep directory structure. In this case, importing a
single item from a sub-sub-package will require executing all
:file:`__init__.py` files met while traversing the tree.
Leaving an :file:`__init__.py` file empty is considered normal and even a good practice,
if the package's modules and sub-packages do not need to share any code.
Leaving an :file:`__init__.py` file empty is considered normal and even a good
practice, if the package's modules and sub-packages do not need to share any
code.
Lastly, a convenient syntax is available for importing deeply nested packages:
``import very.deep.module as mod``. This allows you to use `mod` in place of the verbose
repetition of ``very.deep.module``.
``import very.deep.module as mod``. This allows you to use `mod` in place of the
verbose repetition of ``very.deep.module``.
Object-oriented programming
---------------------------
@@ -232,27 +236,28 @@ functionality. The problem, as pointed out by the discussions about functional
programming, comes from the "state" part of the equation.
In some architectures, typically web applications, multiple instances of Python
processes are spawned to respond to external requests that can
happen at the same time. In this case, holding some state into instantiated
objects, which means keeping some static information about the world, is prone
to concurrency problems or race-conditions. Sometimes, between the initialization of
the state of an object (usually done with the ``__init__()`` method) and the actual use
processes are spawned to respond to external requests that can happen at the
same time. In this case, holding some state into instantiated objects, which
means keeping some static information about the world, is prone to concurrency
problems or race-conditions. Sometimes, between the initialization of the state
of an object (usually done with the ``__init__()`` method) and the actual use
of the object state through one of its methods, the world may have changed, and
the retained state may be outdated. For example, a request may load an item in
memory and mark it as read by a user. If another request requires the deletion
of this item at the same time, it may happen that the deletion actually occurs after
the first process loaded the item, and then we have to mark as read a deleted
object.
of this item at the same time, it may happen that the deletion actually occurs
after the first process loaded the item, and then we have to mark as read a
deleted object.
This and other issues led to the idea that using stateless functions is a
better programming paradigm.
Another way to say the same thing is to suggest using functions and procedures
with as few implicit contexts and side-effects as possible. A function's
implicit context is made up of any of the global variables or items in the persistence layer
that are accessed from within the function. Side-effects are the changes that a function makes
to its implicit context. If a function saves or deletes data in a global variable or
in the persistence layer, it is said to have a side-effect.
implicit context is made up of any of the global variables or items in the
persistence layer that are accessed from within the function. Side-effects are
the changes that a function makes to its implicit context. If a function saves
or deletes data in a global variable or in the persistence layer, it is said to
have a side-effect.
Carefully isolating functions with context and side-effects from functions with
logic (called pure functions) allow the following benefits:
@@ -314,19 +319,18 @@ of the function logic.
Dynamic typing
--------------
Python is dynamically typed, which means that variables
do not have a fixed type. In fact, in Python, variables are very
different from what they are in many other languages, specifically
statically-typed languages. Variables are not a segment of the computer's
memory where some value is written, they are 'tags' or 'names' pointing
to objects. It is therefore possible for the variable 'a' to be set to
the value 1, then to the value 'a string', then to a function.
Python is dynamically typed, which means that variables do not have a fixed
type. In fact, in Python, variables are very different from what they are in
many other languages, specifically statically-typed languages. Variables are not
a segment of the computer's memory where some value is written, they are 'tags'
or 'names' pointing to objects. It is therefore possible for the variable 'a' to
be set to the value 1, then to the value 'a string', then to a function.
The dynamic typing of Python is often considered to be a weakness, and indeed
it can lead to complexities and hard-to-debug code. Something
named 'a' can be set to many different things, and the developer or the
maintainer needs to track this name in the code to make sure it has not
been set to a completely unrelated object.
it can lead to complexities and hard-to-debug code. Something named 'a' can be
set to many different things, and the developer or the maintainer needs to track
this name in the code to make sure it has not been set to a completely unrelated
object.
Some guidelines help to avoid this issue:
@@ -370,26 +374,25 @@ grows and each assignment is separated by other lines of code, including
'if' branches and loops, it becomes harder to ascertain what a given
variable's type is.
Some coding practices, like functional programming, recommend never reassigning a variable.
In Java this is done with the `final` keyword. Python does not have a `final` keyword
and it would be against its philosophy anyway. However, it may be a good
discipline to avoid assigning to a variable more than once, and it helps
in grasping the concept of mutable and immutable types.
Some coding practices, like functional programming, recommend never reassigning
a variable. In Java this is done with the `final` keyword. Python does not have
a `final` keyword and it would be against its philosophy anyway. However, it may
be a good discipline to avoid assigning to a variable more than once, and it
helps in grasping the concept of mutable and immutable types.
Mutable and immutable types
---------------------------
Python has two kinds of built-in or user-defined types.
Mutable types are those that allow in-place modification
of the content. Typical mutables are lists and dictionaries:
All lists have mutating methods, like :py:meth:`list.append` or :py:meth:`list.pop`, and
can be modified in place. The same goes for dictionaries.
Mutable types are those that allow in-place modification of the content. Typical
mutables are lists and dictionaries: All lists have mutating methods, like
:py:meth:`list.append` or :py:meth:`list.pop`, and can be modified in place.
The same goes for dictionaries.
Immutable types provide no method for changing their content.
For instance, the variable x set to the integer 6 has no "increment" method. If you
want to compute x + 1, you have to create another integer and give it
a name.
Immutable types provide no method for changing their content. For instance, the
variable x set to the integer 6 has no "increment" method. If you want to
compute x + 1, you have to create another integer and give it a name.
.. code-block:: python
@@ -451,8 +454,8 @@ with calls to ``append()``.
One final thing to mention about strings is that using ``join()`` is not always
best. In the instances where you are creating a new string from a pre-determined
number of strings, using the addition operator is actually faster, but in cases
like above or in cases where you are adding to an existing string, using ``join()``
should be your preferred method.
like above or in cases where you are adding to an existing string, using
``join()`` should be your preferred method.
.. code-block:: python
+82 -72
View File
@@ -11,8 +11,8 @@ recognised fact that code is read much more often than it is written.
One reason for Python code to be easily read and understood is its relatively
complete set of Code Style guidelines and "Pythonic" idioms.
Moreover, when a veteran Python developer (a Pythonista) points to portions of code
and says they are not "Pythonic", it usually means that these lines
Moreover, when a veteran Python developer (a Pythonista) points to portions of
code and says they are not "Pythonic", it usually means that these lines
of code do not follow the common guidelines and fail to express the intent in
what is considered the best (hear: most readable) way.
@@ -86,40 +86,42 @@ Function arguments
Arguments can be passed to functions in four different ways.
1. **Positional arguments** are mandatory and have no default values. They are the
simplest form of arguments and they can be used for the few function arguments
that are fully part of the function's meaning and their order is natural. For
instance, in ``send(message, recipient)`` or ``point(x, y)`` the user of the
function has no difficulty remembering that those two functions require two
arguments, and in which order.
1. **Positional arguments** are mandatory and have no default values. They are
the simplest form of arguments and they can be used for the few function
arguments that are fully part of the function's meaning and their order is
natural. For instance, in ``send(message, recipient)`` or ``point(x, y)``
the user of the function has no difficulty remembering that those two
functions require two arguments, and in which order.
In those two cases, it is possible to use argument names when calling the functions
and, doing so, it is possible to switch the order of arguments, calling for instance
``send(recipient='World', message='Hello')`` and ``point(y=2, x=1)`` but this
reduces readability and is unnecessarily verbose, compared to the more straightforward
calls to ``send('Hello', 'World')`` and ``point(1, 2)``.
In those two cases, it is possible to use argument names when calling the
functions and, doing so, it is possible to switch the order of arguments,
calling for instance ``send(recipient='World', message='Hello')`` and
``point(y=2, x=1)`` but this reduces readability and is unnecessarily verbose,
compared to the more straightforward calls to ``send('Hello', 'World')`` and
``point(1, 2)``.
2. **Keyword arguments** are not mandatory and have default values. They are often
used for optional parameters sent to the function. When a function has more than
two or three positional parameters, its signature is more difficult to remember
and using keyword arguments with default values is helpful. For instance, a more
complete ``send`` function could be defined as ``send(message, to, cc=None, bcc=None)``.
Here ``cc`` and ``bcc`` are optional, and evaluate to ``None`` when they are not
passed another value.
2. **Keyword arguments** are not mandatory and have default values. They are
often used for optional parameters sent to the function. When a function has
more than two or three positional parameters, its signature is more difficult
to remember and using keyword arguments with default values is helpful. For
instance, a more complete ``send`` function could be defined as
``send(message, to, cc=None, bcc=None)``. Here ``cc`` and ``bcc`` are
optional, and evaluate to ``None`` when they are not passed another value.
Calling a function with keyword arguments can be done in multiple ways in Python,
for example it is possible to follow the order of arguments in the definition without
explicitly naming the arguments, like in ``send('Hello', 'World', 'Cthulhu', 'God')``,
sending a blind carbon copy to God. It would also be possible to name arguments in
another order, like in ``send('Hello again', 'World', bcc='God', cc='Cthulhu')``.
Those two possibilities are better avoided without any strong reason to not
follow the syntax that is the closest to the function definition: ``send('Hello',
'World', cc='Cthulhu', bcc='God')``.
Calling a function with keyword arguments can be done in multiple ways in
Python, for example it is possible to follow the order of arguments in the
definition without explicitly naming the arguments, like in
``send('Hello', 'World', 'Cthulhu', 'God')``, sending a blind carbon copy to
God. It would also be possible to name arguments in another order, like in
``send('Hello again', 'World', bcc='God', cc='Cthulhu')``. Those two
possibilities are better avoided without any strong reason to not follow the
syntax that is the closest to the function definition:
``send('Hello', 'World', cc='Cthulhu', bcc='God')``.
As a side note, following `YAGNI <http://en.wikipedia.org/wiki/You_ain't_gonna_need_it>`_
principle, it is often harder to remove an optional argument (and its logic inside the
function) that was added "just in case" and is seemingly never used, than to add a
new optional argument and its logic when needed.
principle, it is often harder to remove an optional argument (and its logic
inside the function) that was added "just in case" and is seemingly never used,
than to add a new optional argument and its logic when needed.
3. The **arbitrary argument list** is the third way to pass arguments to a
function. If the function intention is better expressed by a signature with an
@@ -139,11 +141,12 @@ it explicitly: ``send(message, recipients)`` and call it with ``send('Hello',
the recipient list as a list beforehand, and it opens the possibility to pass
any sequence, including iterators, that cannot be unpacked as other sequences.
4. The **arbitrary keyword argument dictionary** is the last way to pass arguments
to functions. If the function requires an undetermined series of named
arguments, it is possible to use the ``**kwargs`` construct. In the function
body, ``kwargs`` will be a dictionary of all the passed named arguments that
have not been caught by other keyword arguments in the function signature.
4. The **arbitrary keyword argument dictionary** is the last way to pass
arguments to functions. If the function requires an undetermined series of
named arguments, it is possible to use the ``**kwargs`` construct. In the
function body, ``kwargs`` will be a dictionary of all the passed named
arguments that have not been caught by other keyword arguments in the
function signature.
The same caution as in the case of *arbitrary argument list* is necessary, for
similar reasons: these powerful techniques are to be used when there is a
@@ -158,8 +161,8 @@ Python functions that are:
* easy to read (the name and arguments need no explanations)
* easy to change (adding a new keyword argument does not break other parts of the
code)
* easy to change (adding a new keyword argument does not break other parts of
the code)
Avoid the magical wand
~~~~~~~~~~~~~~~~~~~~~~
@@ -198,8 +201,8 @@ give a lot of mechanisms to prevent any misuse, is expressed by the saying: "We
are all consenting adults".
This doesn't mean that, for example, no properties are considered private, and
that no proper encapsulation is possible in Python. Rather, instead of relying on
concrete walls erected by the developers between their code and other's, the
that no proper encapsulation is possible in Python. Rather, instead of relying
on concrete walls erected by the developers between their code and other's, the
Python community prefers to rely on a set of conventions indicating that these
elements should not be accessed directly.
@@ -217,27 +220,29 @@ but making a public property private might be a much harder operation.
Returning values
~~~~~~~~~~~~~~~~
When a function grows in complexity it is not uncommon to use multiple return statements
inside the function's body. However, in order to keep a clear intent and a sustainable
readability level, it is preferable to avoid returning meaningful values from many
output points in the body.
When a function grows in complexity it is not uncommon to use multiple return
statements inside the function's body. However, in order to keep a clear intent
and a sustainable readability level, it is preferable to avoid returning
meaningful values from many output points in the body.
There are two main cases for returning values in a function: the result of the function
return when it has been processed normally, and the error cases that indicate a wrong
input parameter or any other reason for the function to not be able to complete its
computation or task.
There are two main cases for returning values in a function: the result of the
function return when it has been processed normally, and the error cases that
indicate a wrong input parameter or any other reason for the function to not be
able to complete its computation or task.
If you do not wish to raise exceptions for the second case, then returning a value, such
as None or False, indicating that the function could not perform correctly might be needed. In this
case, it is better to return as early as the incorrect context has been detected. It will
help to flatten the structure of the function: all the code after the return-because-of-error
statement can assume the condition is met to further compute the function's main result.
If you do not wish to raise exceptions for the second case, then returning a
value, such as None or False, indicating that the function could not perform
correctly might be needed. In this case, it is better to return as early as the
incorrect context has been detected. It will help to flatten the structure of
the function: all the code after the return-because-of-error statement can
assume the condition is met to further compute the function's main result.
Having multiple such return statements is often necessary.
However, when a function has multiple main exit points for its normal course, it becomes
difficult to debug the returned result, so it may be preferable to keep a single exit
point. This will also help factoring out some code paths, and the multiple exit points
are a probable indication that such a refactoring is needed.
However, when a function has multiple main exit points for its normal course,
it becomes difficult to debug the returned result, so it may be preferable to
keep a single exit point. This will also help factoring out some code paths,
and the multiple exit points are a probable indication that such a refactoring
is needed.
.. code-block:: python
@@ -256,14 +261,15 @@ are a probable indication that such a refactoring is needed.
Idioms
------
A programming idiom, put simply, is a *way* to write code. The notion of programming idioms
is discussed amply at `c2 <http://c2.com/cgi/wiki?ProgrammingIdiom>`_ and at `Stack Overflow <http://stackoverflow.com/questions/302459/what-is-a-programming-idiom>`_.
A programming idiom, put simply, is a *way* to write code. The notion of
programming idioms is discussed amply at `c2 <http://c2.com/cgi/wiki?ProgrammingIdiom>`_
and at `Stack Overflow <http://stackoverflow.com/questions/302459/what-is-a-programming-idiom>`_.
Idiomatic Python code is often referred to as being *Pythonic*.
Although there usually is one --- and preferably only one --- obvious way to do it;
*the* way to write idiomatic Python code can be non-obvious to Python beginners. So,
good idioms must be consciously acquired.
Although there usually is one --- and preferably only one --- obvious way to do
it; *the* way to write idiomatic Python code can be non-obvious to Python
beginners. So, good idioms must be consciously acquired.
Some common Python idioms follow:
@@ -346,16 +352,19 @@ Instead, use a list comprehension:
four_lists = [[] for __ in xrange(4)]
A common idiom for creating strings is to use :py:meth:`str.join` on an empty string.
A common idiom for creating strings is to use :py:meth:`str.join` on an empty
string.
.. code-block:: python
letters = ['s', 'p', 'a', 'm']
word = ''.join(letters)
This will set the value of the variable *word* to 'spam'. This idiom can be applied to lists and tuples.
This will set the value of the variable *word* to 'spam'. This idiom can be
applied to lists and tuples.
Sometimes we need to search through a collection of things. Let's look at two options: lists and dictionaries.
Sometimes we need to search through a collection of things. Let's look at two
options: lists and dictionaries.
Take the following code for example:
@@ -374,8 +383,9 @@ Even though both functions look identical, because *lookup_dict* is utilizing
the fact that dictionaries in Python are hashtables, the lookup performance
between the two is very different. Python will have to go through each item
in the list to find a matching case, which is time consuming. By analysing
the hash of the dictionary, finding keys in the dictionary can be done very quickly.
For more information see this `StackOverflow <http://stackoverflow.com/questions/513882/python-list-vs-dict-for-look-up-table>`_
the hash of the dictionary, finding keys in the dictionary can be done very
quickly. For more information see this
`StackOverflow <http://stackoverflow.com/questions/513882/python-list-vs-dict-for-look-up-table>`_
page.
Zen of Python
@@ -604,11 +614,11 @@ Line Continuations
~~~~~~~~~~~~~~~~~~
When a logical line of code is longer than the accepted limit, you need to
split it over multiple physical lines. The Python interpreter will join consecutive
lines if the last character of the line is a backslash. This is helpful
in some cases, but should usually be avoided because of its fragility: a white space
added to the end of the line, after the backslash, will break the code and may
have unexpected results.
split it over multiple physical lines. The Python interpreter will join
consecutive lines if the last character of the line is a backslash. This is
helpful in some cases, but should usually be avoided because of its fragility:
a white space added to the end of the line, after the backslash, will break the
code and may have unexpected results.
A better solution is to use parentheses around your elements. Left with an
unclosed parenthesis on an end-of-line the Python interpreter will join the
+5 -5
View File
@@ -20,11 +20,11 @@ Some general rules of testing:
- Try hard to make tests that run fast. If one single test needs more than a
few milliseconds to run, development will be slowed down or the tests will
not be run as often as is desirable. In some cases, tests can't be fast because
they need a complex data structure to work on, and this data structure must
be loaded every time the test runs. Keep these heavier tests in a separate
test suite that is run by some scheduled task, and run all other tests as
often as needed.
not be run as often as is desirable. In some cases, tests can't be fast
because they need a complex data structure to work on, and this data structure
must be loaded every time the test runs. Keep these heavier tests in a
separate test suite that is run by some scheduled task, and run all other
tests as often as needed.
- Learn your tools and learn how to run a single test or a test case. Then,
when developing a function inside a module, run this function's tests very