• Django and Memcached

    Apparently it seems that both Django and Memcached work together flawlessly, but it fails silently most of the time which is hard to debug. One thing I've learned is never cache any queryset with Memcached since it wouldn't complain anything but doesn't do anything either. If you like to cache queryset, then using LoMemCache, FileBasedCache, DummyCache or whatever which is not Memcached. Everything will be all good.

    Otherwise, you can separate cache into couple things then push queryset to one which is not Memcached.

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211'
        },
        'queryset': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
        },
    }

    Then you can using get_cache to pick whatever you want

    from django.core.cache import get_cache, cache
    mycache = get_cache('queryset')
    

    While cache will still point to 'default' or Memcached one.

  • Python: Performance Benchmark

    `[item for sublist in l for item in sublist] is faster than the shortcuts posted so far.

    For evidence, as always, you can use the timeit module in the standard library:

    $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
    10000 loops, best of 3: 143 usec per loop
    
    $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
    1000 loops, best of 3: 969 usec per loop
    
    $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x, y: x+y,l)'
    1000 loops, best of 3: 1.1 msec per loop
    
  • PostgreSQL 101

    I found that PostgreSQL works differently to MySQL. PostgreSQL will accept command from both command shell ($) and PostgreSQL shell (postgres=#). When you create database, drop database, you can do from command shell:

    $ createdb <database-name> -E UTF8
    $ dropdb <database-name>
    

    while charset support listed here. or you can create database inside postgres shell.

    $ psql
    postgres=# create database <database-name>
    postgres=# drop database <database-name>
    

    To do some basic query, it’s pretty like MySQL. However, it’s vastly different when it comes to list/describe

    postgres=# \l  # show databases
    postgres=# \connect <database-name>  # use database
    <database-name>=# \d  # show tables
    <database-name>=# \d <table-name>  # show columns
    <database-name>=# \d+ <table-name>  # describe table
    

    Configure for remote connection

    Server side

    Edit /etc/postgres/x.x/main/postgresql.conf

    listen_addresses = '*'
    

    Add line to /etc/postgres/x.x/main/pg_hba.conf

    host  all  all  0.0.0.0/0  md5
    

    or you could do things like 192.168.1.1/24 if you want to limit to your subnet.

    Creating remote user isn’t anything different from what local user is:

    $ psql template1
    template1=# create user <user-name> with password '<your-password>';
    template1=# \connect <database-name>;
    <database-name>=> GRANT USAGE ON SCHEMA public to <user-name>;
    <database-name>=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO <user-name>;
    <database-name>=> GRANT UPDATE ON ALL TABLES IN SCHEMA public TO <user-name>;
    <database-name>=> GRANT ALL ON ALL TABLES IN SCHEMA public TO <user-name>;
    <database-name>=> ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO <user-name>;
    <database-name>=> GRANT USAGE, SELECT ON SEQUENCE <table_name>_id_seq TO <user-name>;
    <database-name>=> GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA <schema_name> TO <user-name>;
    <database-name>=> \q
    

    Client side

    Pretty much like MySQL

    $ psql -h <postgres-server> -d <database-name> -U <user-name>
    

    If you don’t have postgresql client yet

    # apt-get install postgresql-client-x.x
    

    while x.x means version, e.g. postgresql-client-9.1

  • การติดตั้ง Django: 101

    จริงๆแล้วการติดตั้งก็ไม่ได้มีวิธีเดียวครับ แต่การติดตั้งข้างล่างนี้จะเป็นการติดตั้งโดยใช้ virtualenv ด้วยซึ่งจะทำให้ package แยกกันโดยอิสระในแต่ละ project ที่เราทำงานครับ เวลาลบก็ลบง่าย เพราะไม่เกี่ยวกับระบบเลย จะเป็นการติดตั้งสำหรับแค่ตัวเราเท่านั้น

    Django for OSX

    สิ่งที่จำเป็นต้องมี คือ HomeBrew ถ้ายังไม่มีสามารถติดตั้งผ่าน Terminal โดยพิมคำสั่งตามนี้

    $ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
    

    หลังจากติดตั้ง brew แล้ว เราก็มาเริ่มลงสิ่งที่จำเป็นในชีวิตกันครับ

    $ brew install git mercurial
    

    หลังจากนั้นก็ติดตั้ง database ตามชอบใจ

    ถ้าใช้ MySQL

    $ brew install mysql
    

    ถ้าใช้ PostgreSQL

    $ brew install postgresql
    

    ต่อมาก็ลงเรื่องของ python กันต่อครับ สิ่งที่จำเป็นในชีวิตของ python ก็คือตัวหาและลง library ที่มีอยู่เยอะแยะมากมาย

    $ sudo easy_install pip
    

    easy_install เป็น package manager ตัวนึงของ python ที่เดี๋ยวก็ไม่ค่อยจะใช้กันแล้วเพราะ pip ทำได้ดีกว่ามากๆ ที่เราต้องใช้ easy_install นั้นเพราะเราไม่มี package manager อื่นที่มี pip กันเลยทีเดียวใน OSX ก็เลยต้องใช้มันลง pip ก่อน ส่วนการใช้ sudo ผมคิดว่าน่าจะเหมาะสมแล้วเพราะ pip ก็เป็น package manager ตัวนึงไม่น่าที่จะต้องทำให้แบ่งตาม user และสิ่งที่เราต้องทำต่อไปคือ เราต้องทำต่อไปคือ ลง virtualenv

    $ sudo pip install virtualenv virtualenvwrapper
    

    ส่วนนี้ก็ยังลงในระบบกันต่อไป เพราะประเด็นเราคือแยก แต่ละ virtualenv ตามแต่ละ project เราจะต้องทำให้ command shell เรารู้จัก virtualenv ด้วยการใส่ใน ~/.bash_profile

    # python virtualwrapper
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    แล้วก็

    $ source ~/.bash_profile
    

    เพื่อให้ command shell เรารับสิ่งที่เราใส่ไปครับ เท่านี้เครื่องของเราก็พร้อมที่จะใช้งาน django กันแล้ว หลังจากนี้เราก็ทำการสร้าง virtualenv กันครับ

    $ mkvirtualenv django  # จริงๆ จะเป็นชื่ออะไรก็ได้นะครับ ตามใจตรงนี้
    

    เท่านี้เราก็แทบจะเรียกว่า เครื่องเราพร้อมกับการใช้ django แล้วครับ ถึงเวลาเริ่มจริงๆแล้ว

    $ workon django
    (django)$ pip install django
    (django)$ mkdir -p project
    (django)$ cd project
    (django) project$ ./manage.py runserver
    

    เป็นอันเสร็จสมบูรณ์

    Django for Debian

    ก็จะเป็นแค่สำหรับ distro ที่เป็น debian นะครับ เพราะปกติผมก็ใช้ debian เป็นหลักครับ เช่น Debian, Ubuntu, Mint, … ถ้าเป็น Arch หรือ Fedora หรืออย่างอื่นก็จะมีคำสั่งต่างกันออกไปเล็กน้อยนะครับ ก่อนอื่นก็ลงโปรแกรมที่จำเป็นต่อชีวิต

    $ sudo apt-get install build-essential git mercurial python-pip python-dev
    

    มันก็แล้วแต่จะใช้ database อะไรนะครับ

    • SQLite ก็ไม่ต้องทำอะไรเพิ่มเติม
    • MySQL

        $ sudo apt-get install mysql-server
        $ sudo apt-get build-dep python-mysqldb
      
    • PostgreSQL

        $ sudo apt-get install postgresql
        $ sudo apt-get build-dep python-psycopg2
      

    ติดตั้งกันต่อ คราวนี้เป็น virtualenv ครับ

    $ sudo pip install virtualenv virtualenvwrapper
    

    หลังจากนั้นก็ต้องใส่ virtualenv path หน่อย เพื่อให้เราใช้งานมันง่ายๆ

    $ vi ~/.bashrc
    

    เพิ่มบรรทัดนี้ด้านล่าง

    # python virtualwrapper
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    จากนั้นก็ reload ซักที

    $ source ~/.bashrc
    

    จริงๆแล้ว อาจจะใช้ nano แทน vi ก็ได้ครับ แต่เชื่อเถอะครับ ถ้ายังไม่เคยใช้ vi ลองทนใช้ดูแล้วจะไม่อยากใช้อย่างอื่นอีกเลย หลังจากนี้เราก็ทำการสร้าง virtualenv กันครับ

    $ mkvirtualenv django  # จริงๆ จะเป็นชื่ออะไรก็ได้นะครับ ตามใจตรงนี้
    

    เท่านี้เราก็แทบจะเรียกว่า เครื่องเราพร้อมกับการใช้ django แล้วครับ ถึงเวลาเริ่มจริงๆแล้ว

    $ workon django
    (django)$ pip install django
    (django)$ mkdir -p project
    (django)$ cd project
    (django) project$ ./manage.py runserver
    

    เป็นอันเสร็จสมบูรณ์

  • Share Printer from Linux box to Windows

    Of course, I know it needed samba, but I had difficulty sharing one to Windows PC which I didn’t really get into much since the day I moved away from Windows. This was what I did to get it work.

    $ /etc/samba/smb.conf
    

    Find these lines and uncomment them; if you can’t find, type.

    printcap name = cups
    printing = cups
    

    [printers] section should look similar to this

    [printers]
    comment = All Printers
    browseable = yes
    path = /var/spool/samba
    printable = yes
    public = yes
    guest ok = yes
    create mask = 0700
    use client driver = yes
    path = /tmp
    

    Then you have to restart samba.

    $ sudo service smbd restart
    

    For some, you might have to use samba instead of smbd. That’s varied by distros. However, after adding printer to your Windows box, you should be able to print. I find it’s easier to navigate to \\linux-box-name in file explorer. Find printer there, then right-click to connect and add there. Add printer via Devices and Printer and auto discovery thing isn’t impressed me 99% of the time.