Tuesday, September 3, 2013

In python, objects are referred as references

Python uses shallow copy for object copying. If you see this code, The value b.a.val is modified externally.
class A(object):
    def __init__(self):
        self.val = 20
    
class B(object):
    def __init__(self, a):
        self.a = a
    
if __name__ == "__main__":
    a = A()

    b = B(a)
    print b.a.val # 20
    a.val = 40
    print b.a.val # 40
You need to use copy.deepcopy to avoid this pitfall.
from copy import *

class A(object):
    def __init__(self):
        self.val = 20
    
class B(object):
    def __init__(self, a):
        self.a = deepcopy(a)
        
    
if __name__ == "__main__":
    a = A()

    b = B(a)
    
    print b.a.val
    a.val = 40
    print b.a.val

Friday, August 16, 2013

doctest and then run sphinx

When you need to run unit-test and make documentation for it with Python. doctest and sphinx is the one of the best choices you can have.
"""
This is the "example" module.

The example module supplies one function, factorial().  For example,

>>> factorial(5)
120

"""

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    If the result is small enough to fit in an int, return an int.
    Else return a long.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    """
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
        
if __name__ == "__main__":
    import doctest
    doctest.testmod()
Then execute `sphinx-quickstart`, modify `conf.py` to make Python importable the source code directory. Finally, run make html.
Screen Shot 2013 08 16 at 4 45 11 PM

Thursday, August 15, 2013

Directives in reST

In reST, directive is a general block of explicit markup. It is widely used extension method for reST. You can think of it a method call with a parameter. For example, the image directive is a function that has an input as path to the picture; it returns an output of HTML img tag.
> .. image:: ./image/img.png

> <img alt="./image/img.png" src="./image/img.png" />
reST also enables to incorporate img tag wherever you want with |…| attached in front of the image directive.
|bio| is bio

.. |bio| image:: ./image/img.png

<p><img alt="bio" src="./image/img.png" /> is bio

Maybe, one the most popular directives is code block in Sphinx. This is an example of Python code block, but you can use other languages such as Ruby, C, and even reST itself.
.. code_block:: python
  
   python code ...

You have python code, how to document your API with Sphinx?

Simple four steps to get the HTML files from your python code

You just need four steps.
  • Execute sphinx_quickstart, and make sure that you check autodoc mode on:> autodoc: automatically insert docstrings from modules (y/N) [n]: y
  • In conf.py, add the path to your source code: sys.insert('./../src')
  • Execute sphinx-apidoc -o . ../src/
  • Execute make html
Now, you will have your python code in HTML format.

Include reST documents into index

Topic and comments

topic directive creates

tag in HTML. It seems to be pretty useful in describing what the reST document does.

.. topic:: What is Sphinx and the RST syntax ?
 
   CONTENTS ...
When you just use two dots, it works as a comment.

toctree

When you open the index.html, you will see nothing in the contents. It is because there is nothing under the toctree directive. Open the index.rst file which is the main reST for your project. You need to add the modules.
.. toctree::
   :maxdepth: 2
   
   hello1
You may not want to show toctree. This will notify Sphinx of the document hierarchy, but skip inserting links into the document.
.. toctree::
   :hidden:
You can make toctree numbered with :numbered: field.
.. toctree::
    :maxdepth: 1
    :numbered:

:doc:`…`

In this case, you can explicitly include the reST document with :doc:`…` field.
:doc:`hello1`
  Instructions on how to get the distribution.

API documentation

In step3, we can get (semi) automatically generated API documentation file from Sphinx with sphinx-apidoc command. Whenever you want to add more documentation to it, you have to do it manually.

Including math in the documentation

Add 'sphinx.ext.pngmath' in the extensions list. Then, use math directive or field:
:math:`a^2 + b^2 = c^2`.

.. math::

(a + b)^2 = a^2 + 2ab + b^2
(a - b)^2 = a^2 - 2ab + b^2
You need to specify the latex location in your computer. sphinx-build -b html -D pngmath_latex=`which latex` . _build/html.

Useful Sphinx knowledge

Extensions

In conf.py, you can add more Sphinx features with extensions list.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.viewcode','sphinx.ext.todo']

References

Wednesday, August 14, 2013

Type checking in Python

Python's value has a type, however a variable can be assigned to any typed value.
>>> a = A()
>>> a is A
False
>>> id(a)
3567120
>>> id(A)
2377856

>>> id(type(a))
2377856

>>> type(a) is A
True

>>> a.__class__ is A
True

>>> isinstance(a, A)
True

Equalities

It seems to be simple to compare two values: 1 == 1 or 2 == 3? However, when a variable is assigned to a value, it's a little bit more complicated: x = 3, y = 3, x == y? The different type of data can represent the same value: 1.0 == 0?

Lisp

> (= 1.0 1)
T

> (eql 1.0 1)
NIL

> (eql (cons 'a nil) (cons 'a nil)
NIL

> (setf x (cons 'a nil))
> (eql x x)
T

> (equal x (cons 'a nil))
T

C/C++

int x = 10;
int y = 20;

x == y // equal in Lisp
&x == &y // eql in Lisp
10 == 20 // = in Lisp

Python

>>> x = 10
>>> id(x)
1764365084

>>> y = 10
>>> id(y)
1764365084

>>> x is y // eql in LISP
True

>>> x == y // equal in LISP
True

>>> a = [1,2,3]
>>> a == [1,2,3]
True

>>> a is [1,2,3]
False

>>> id(a)
4359792
>>> id([1,2,3])
4225424

Reference

Merge two lists in Python

When you merge two lists with Python, you can use the overloaded '+' operator.
a = [1,2,3]
b = [2,3,4]

>>> a + b
[1, 2, 3, 2, 3, 4]
However, when you don't want the duplicate values, you need to use set. '+' operator is not supported in a set, so use union() method.
>>> set(a).union(b)
set([1, 2, 3, 4])
You can convert a set to list with list() method.
>>> list(set(a).union(b))
[1, 2, 3, 4]
Refer to set in python document.