Posted on 01-04-2014
Filed Under (Technology) by bigbang

Django-Chartit looks like a good tool for drawing some data charts under Python Django framework.

But it is a little hard to get it ready for work. Here I remind of two key steps while using Chartit:

  1. add chartit to your INSTALLED_APPS.
  2. install simplejason if you get ‘use_decimal’ error.

    The error message is something like:

    TypeError at /charts/
    __init__() got an unexpected keyword argument 'use_decimal'
    

I don’t think Chartit is the best choice current now, and I prefer Chart.js instead if you just want to draw some basic charts.

(0) Comments    Read More   

Scarpy recommands using Pillow instead of PIL to get image things done. But under Windows, if you install Pillow directly by

pip install pillow

, there will be an error while you download item images in Scrapy. The error is:

exceptions.IOError: decoder jpeg not available

If you are using Linux, the solution is very simple, just fix this by installing libjpeg and re-installing Pillow.

But under Windows, it is very exhausted to re-compile libjpeg with Pillow or PIL. In this suituation, I recommand to use pre-compiled PIL instead. Just install the pre-compiled PIL library, then you won’t get the above error.

(0) Comments    Read More   
Posted on 05-06-2013
Filed Under (Technology) by bigbang

We know how to generate Win32 Services Installer with Native Win32 C++ Code, but if we want to do it in Python, how?

We can use Python to generate Win32 services by using py2exe and Python Win32 Extensions.

Here we show the basic steps.

1. Use py2exe to Compile Python Script into EXE

For example, if you want to compile hello.py into exe file, just use following command:

python hello.py py2exe

2. create a Windows service script and compile it to Win32 Service

This step is the same as step 1, just need to add Windows Service Wrapper code in Python script.

Copy the code and put into files, and use step1 command to compile the file.

After the compilation, you will get a service_launcher.exe under folder ./dist and you can install the service from there.

  1. You can use it to install the service on the win32 services list, just run your program with the “-install” parameter and you are done!
  2. Use “-remove” to remove the win32 services. Need to stop the Service before removing the Win32 service.

3. Questions & Answers

  1. While compiling, Why get following error?
            raise ImportError, "No module named " + qname
    ImportError: No module named win32com
    

    We need to install Python Win32 Extensions to compile it.

  2. When you start the service in Windows Control Panel, the service failed. How to check the error and debug?

    please check Windows event log error for details.

  3. Error: can’t load dll

    If your script depends on more third party dlls, you also need to copy the dlls into ./dist folder.

    Or you can add your dll path into System Path. NOTE: The thing you need to do with dll, is to add the path to system path, not just for current user.

(0) Comments    Read More   
Posted on 13-03-2013
Filed Under (Technology) by bigbang

If you want to invoke C/C++ third-party library ( third-party libraries are your libraries at the most time ), you just need a script to attach them. At this time, we can use Python ctypes to do this dirty job.

The theme Calling C/C++ from python on StackOverflow has introduced the basic usage of ctypes. The key points are:

  1. If you try to use C library, just load this library and use it.
  2. If you try to use C++ library, you should use keyword extern to wrapper C++ class into functions for C. That means we should put C++ class into C functions, and use keyword extern for statement.

In above two ways, if you get the way to use ctypes to invoke C++ library, then you also get the way to use ctypes to invoke C library. Let’s talk about how to invoke C++ library in details.

For example, there is a C++ class Foo:

#include <iostream>

class Foo{
    public:
        void bar(){
            std::cout << "Hello" << std::endl;
        }
};

Then we wrapper out following C style interfaces:

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
}

We compile the code into library:

g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o

, then we can use Python to invoke this class. You can put the interfaces into a Python class or use them directly:

from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()

    def bar(self):
        lib.Foo_bar(self.obj)

Everything is OK now. We can invoke this Python class like this:

f = Foo()
f.bar() #and you will see "Hello" on the screen

Under Windows, the process is the same if you try to use Python ctypes, but just need to pay attention to following two points:

  1. When start to link to C/C++ library, it is the best idea to use absolute path to load library.

    When I run above code under Windows, I got following error:

    $ python Linkcpp.py
    Traceback (most recent call last):
      File "Linkcpp.py", line 2, in <module>
        lib = cdll.LoadLibrary('./LinkExample')
      File "C:\Python27\lib\ctypes\__init__.py", line 431, in LoadLibrary
        return self._dlltype(name)
      File "C:\Python27\lib\ctypes\__init__.py", line 353, in __init__
        self._handle = _dlopen(self._name, mode)
    WindowsError: [Error 126]
    

    The reason is that I use following code to load library:

    from ctypes import cdll
    lib = cdll.LoadLibrary('./LinkExample')
    

    We can eliminate this error by changing ./LinkExample into E:/PythonCode/LinkCpp/LinkExample which is library’s absolute path under Windows. We can also use LinkExample if the library is under the same folder as the Python script.

    So, to save the debugging time, it is the best way to do it by using absolute path to load library.

    If you get WindowsError: [Error 126] message, the reason is nothing but two

    • Your DLL is not being located.
    • Your DLL depends on other DLLs that cannot be found.

    PS: The dynamic libraries under Windows has two lib & dll files. In this case, we can just use the name of the library.

  2. If the library is written by C++, then we should use extern to wrapper it.

    In the function stated by extern, we can also use the keyword belongs to C++ which is not in C. For example, we can describe our function like this:

    extern int linkExample(const int index, const char* name);
    

    Python ctypes can run it!

    The method of keyword extern in C++ is complicated. Here we just need to state a function to invoke by C, so we can use keyword const in it.

(0) Comments    Read More