วันจันทร์ที่ 31 สิงหาคม พ.ศ. 2552

install django on windows

ในที่สุดก็ลองมาจับ django (web framework ทางฝั่งพี่ python)
หลังจากที่จับ turbogear อยู่นานประมาณนึงครับ ใจริงก็ยังเป็นสาวก Turbogear อยู่น้าาาา
วันนี้ก็ลองเล่น ๆ ดู ครับ จะพยายาม
จริง ๆ ก็ recommend ให้ลงบน linux เพราะมันทำมาเพื่อสิ่งนั้น
แต่ developer ไทยน้อยคนคงใช้ linux บนเครื่องส่วนตัว ที่ทำงาน เนื่องจาก มันเอาไว้เล่นเกมส์ไม่ได้ !!!
ไม่เกี่ยว คือมันเปิด และจัดการงานเอกสาร๖(เช่น Word, Excell)ไม่สวย ถึง ห่วยแตก
office เลยยังต้องยกให้ windows เป็นผู้ชนะ คร๊าาาาาาบ
อีกอย่างคงกิน resource น่าดูครับ ถ้าต้องใช้ vmware ในการสร้าง linux บน windows และการทำงาน
แบบสลับไปมา ให้ยุ่งยาก
เอ่า นอกเรื่องมาพอสมควร เริ่มเลยดีฟ่า

ขั้นแรก ก็ทำการลง python ในกรณี windows นั้น
ไปเอามาจากที่นี่นะครับ แนะนำว่า ต้องลงท้ายว่า
Windows installer << สำหรับ เครื่องทั่วๆ ไป
Windows AMD64 installer << สำหรับพวก 'บ้าพลัง' เครื่องแรงที่ลง os เป็น 64 ครับ
โดยเช็คจาก คลิ๊กขวาที่
My Computer(สำหรับ windowsXP) หรือ
Computer(สำหรับ windows7)
แล้วเลือก Properties แล้วก็พยายามดูนะ
version Python ที่แนะนำ ควรเป็น 2.5 - 2.6 << ยังไม่แนะนำ 3.0 นะครับ
Python
ส่วนใหญ่จะเป็นแกมบังคับให้ลงที่

C:\Python25 << อันนี้สมมติเป็น v 2.5 ครับ

ไม่ควรแสดงความฉลาดโดยการไปเลี่ยน Path ให้มันเองครับ
เพราะ tool ต่าง ๆที่จะลงในส่วนใหญ่จะบังคับ path นี้อยู่แล้ว เดี๋ยวจะหาว่า พี่ไม่เตือนนะน้อง

ต่อจากนั้นก็ลงอย่างอื่นก่อน(ทำไมยังไม่ได้ลง django ซะที) ส่วนใหญ่เค้าพูดกันว่าให้ลงก่อน ผมก็ไม่เข้าใจ?
เป็น driver database ครับ เลือกตามความประสงค์ครับ ตามนี้
1.PostgreSQL << ฟรี ๆ outsource หน้าชื่นตาบาน แต่ user รวยๆ บอกผมเลือก Oracle เซ็งเป็ด!!!
จะลง psycopg

2.MySQL << ฟรีสำหรับทดลอง แต่ถ้าเอามาทำเงินต้องเสียตัง แต่ง่ายต่อการเรียนรู้ ถ้าจะเริ่มครับ
จะลง MySQLdb

3.SQLite << ไม่รู้ว่าเคยได้ยินกันเปล่าครับ ก็ฟรีอะ แต่ไม่รู้รายละเอียดเท่าไร ท่าทางไม่ค่อยแข็งแรงเท่าสองตัวบน
จะลง pysqlite

4.Oracle << ยอมรับกันทั่วโลกครับ เพราะพี่ท่านทุนหนาไปซื้องานที่เค้าจะเกิด และจะดังเอามาเป่าดับเล่น
user ค่อยข้างเชื่อใจ จริง ๆ feature ค่อยข้างมากมาย ถ้าซื้อมาแล้วเอาไว้เก็บข้อมูลอย่างเดียว บอกได้เลยว่า
เสียดายตังมากมายครับ แต่เอาเถอะนะ คนจ่ายเค้าจะเอา
จะลง cx_Oracle

*driver database ที่กล่าวมาข้างต้นนี้ ถ้า link เสียก็ใช้ชื่อไป search เอาเองนะครับ แต่ถ้าจะกรุณาก็แจ้ง
ให้กระผมทราบหน่อยก็ดีครับเผื่อจะได้เป็นประโยชน์ในการ update ในภายภาคหน้า
**อย่าลืมนะครับ เวลา download มาเลือกเป็น version ของ windows ครับ ไม่งั้นมันจะไม่ไปลงใน

C:\Python25\Lib\site-packages

เป็น path สำหรับ plugin สำหรับ Python ก็ว่าได้ ส่วนใหญ่เวลาลงแล้วจะไปรวมกันในนี้ครับ
ไม่เชื่อเข้าไปดูนะครับ

ถึงเวลาพระเอกแล้ววววววว
ลง django
เข้าไปที่ web django แล้วก็
load มาเลยครับ file นี้ Django-1.1.tar.gz
เสร็จแล้วก็นำมาแยกด้วย winrar หรือ อะไรก็ได้ที่มันจะคลาย zip file นี้ออกมาได้ครับ
ก็จะได้ folder

D:\python\Django-1.1

ตอนนี้ผมเอาไว้ drive D:\python ครับ อันนี้สร้างเอง จะเอาไว้ที่ใหนก็ได้นะครับ
หลังจากนั้นก็เข้าไปยัง path ดังกล่าวด้วย command prompt แล้วก็พิมพ์คำสั่ง

D:\python\Django-1.1>python setup.py install

ก็จะมีข้อความขึ้นตามนี้

running install
running build
running build_py
running build_scripts
running install_lib
running install_scripts
running install_data
running install_egg_info
Removing C:\Python25\Lib\site-packages\Django-1.1-py2.5.egg-info
Writing C:\Python25\Lib\site-packages\Django-1.1-py2.5.egg-info


ในที่นี้ไม่แน่ใจว่ามันมีอะไรเปลี่ยนแปลงหรืออะไรจำเป็นหรือเปล่าครับ ไว้ทราบเรื่องจะแจ้งให้อีกที

ต่อมาก็เริ่ม start new project กันดีกว่า(นี่แหละเวลาแห่งการรอคอยยยยย)
สมติ path ขึ้นมา จะใช้เป็นอะไรก็ได้นะครับ

D:\python\project


ถ้าเป็น linux เมื่อลงเสร็จจะใช้แค่

django-admin.py startproject testproject


แต่ผมพยามยามแระ ทำแล้วมันดันไปเรียก popup ของ python shellscript ขึ้ันมา เวรกรำแล้วสิ
บังเอิญมาเจอ blog ที่นึงเค้าเขียนไว้ เต็ม path ลองมาลองดูก็ได้เป็นตามด้านลางนี้ครับ
ในที่นี้ให้ชื่อ project ว่า testproject

D:\python\project>D:\python\Django-1.1\django\bin\django-admin.py startproject testproject
D:\python\project>

... เงียบ ... เหมือนไม่มีอะไรเกิดขึ้น
แต่ลอง dir ดู
ว้าวววว ออกมาและครับ
D:\python\project>dir
Volume in drive D is Project
Volume Serial Number is 664E-B00A

Directory of D:\python\project

31-08-09 03:05 <DIR> .
31-08-09 03:05 <DIR> ..
31-08-09 03:05 <DIR> testproject


ลองไปดูข้าในกันครับว่ามีอะไรบ้าง

D:\python\project\testproject>dir
Volume in drive D is Project
Volume Serial Number is 664E-B00A

Directory of D:\python\project\testproject

31-08-09 03:05 <DIR> .
31-08-09 03:05 <DIR> ..
31-08-09 03:05 557 manage.py
31-08-09 03:05 2,862 settings.py
31-08-09 03:05 569 urls.py
31-08-09 03:05 0 __init__.py


มีแค่นี้ !!! เทียบกับ turbogear แล้ว ผมทำอะไรผิดเปล่าหว่า ทำไมน้อยจัง
เอาเป็นว่า ทำใจดีเชื่อใจตัวเอง
ไป start เลยดีกว่า เพราะยังไม่รู้จะเขียนอะไรดี

D:\python\project\testproject>python manage.py runserver
Validating models...
0 errors found

Django version 1.1, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[31/Aug/2009 03:12:42] "GET / HTTP/1.1" 200 2063


ไม่ติดปัญหาอย่างที่คิด โดยการเข้า browser
http://localhost:8000/


แล้วบนหน้า web จะมีคำว่า
It worked!
Congratulations on your first Django-powered page.

ขึ้นต้นครับ

เวลาจะ stop ก็ใช้ Ctrl + Break
แต่ผมก็เผลือใช้ Ctrl + c ครับ เพราะ ชินมือครับ ไม่แน่ใจว่าต่างเปล่า
เพราะเวลาผมใช้ Ctrl + Break มันก็ขึ้นที่ command prompt ว่า
^C
เลยเอาเป็นว่าแบบคิดไปเองนะ ว่าผ่าน!!!

อ่า เสร็จไปหนึ่ง แค่ลงก็เหงื่อท่วมแระ กว่าจะรู้ว่า create new project บน windows อย่างไง
เกือบจะหลวมตัวไปใช้
How to use Django with Apache and mod_wsgi
ถึงกับงานเข้าเลย เพราะ ต้องอธิบายอีกสองตัว

จบในส่วน install django กับ create new project ไว้แค่นี้ก่อน
เรื่องจะเขียนอะไรคงเป็นบทหน้าแระครับ

วันพุธที่ 26 สิงหาคม พ.ศ. 2552

java batch list model

ตัว java class model ตัวนี้ เขียนขึ้น เนื่องจากเกิดปัญหา การเก็บข้อมูลเป็น list โดยแต่ละ
list มีหัวข้อคนละชุด งงหละสิ
ถ้ามองก็คล้าย database ครับ(จริง ๆ ก็ทำเพื่อสิ่งนั้น)
คือ ผมมีข้อมูล
A ประกอบไปด้วย A1, A2, A3, - A10
B ประกอบไปด้วย Ba, Bb, Bc, Bd, - Bz
C ประกอบไปด้วย Ca2, Ca4, Ca8, Cb2, Cb4, Cb8
คร่าว ๆ ประมาณนี้

แล้วถ้าผมอยู่ ๆ ต้องการเพิ่ม
D ประกอบไปด้วย ก, ข, ค, ง, - ฮ

แล้วต้องการลบ A กับ B ออกจากระบบ

แล้วต้องการดูว่า ตอนนี้เหลืออะไรอยู่บ้าง เหลืออยู่เท่าไร

แล้วสมมติว่าอนาตค
อาจต้องการ เพิ่มหรือลด บางตัวแปร
อาจต้องการ เพิ่มหรือลด ข้อมูลในบางแปร

จากข้างบนนี้ ปัญหาคือ แล้วผมจะเอาอะไรไปเก็บข้อมูลที่ระบุอะไรไม่ได้ นี้
ไม่รู้อะไรจะมาอะไรจะไป จะทำอย่างไงให้ยืดหยุ่น
กรณี list ข้อมูลไม่ใช่แค่ text

รายละเอียด
...(เดี๋ยวว่างมาเขียนต่อนะ ดู ๆ code กันไปก่อน)

ตัวนี้ คุณ Notto เป็นคนช่วยแปลงให้เข้ากับ java v.1.4 ครับ เนื่องจาก ตอนแรกผมจะใส่
type Generic เป็น Object กับ String

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BatchListModel {

    private Set idSet;
    private Map batchDataMap;

    public BatchListModel() {
        idSet = new HashSet();
        batchDataMap = new HashMap();
    }

    public void putAllStringData(String id, List list) {
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            String item = (String) iterator.next();
            putStringData(id, item);
        }
    }

    public void putAllObjectData(String id, List list) {
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Object item = (Object) iterator.next();
            putObjectData(id, item);
        }
    }

    public void putStringData(String id, String obj) {
        idSet.add(id);
        List objList = (List) batchDataMap.get(id);
        if (null == objList) {
            objList = new LinkedList();
        }
        objList.add(obj);
        batchDataMap.put(id, objList);
    }

    public void putObjectData(String id, Object obj) {
        idSet.add(id);
        List objList = (List) batchDataMap.get(id);
        if (null == objList) {
            objList = new LinkedList();
        }
        objList.add(obj);
        batchDataMap.put(id, objList);
    }

    public List getData(String id) {
        List objList = (List) batchDataMap.get(id);
        return objList;
    }

    public int getSize(String id) {
        int size = 0;
        try {
            List objList = (List) batchDataMap.get(id);
            if (null != objList) {
                size = objList.size();
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return size;
    }

    public Set getId() {
        return idSet;
    }

    public Set getId(String id) {
        Set newStrSet = new HashSet();
        for (Iterator iterator = getId().iterator(); iterator.hasNext();) {
            String str = (String) iterator.next();
            if (str.equalsIgnoreCase(id)) {
                newStrSet.add(str);
            }
        }
        return newStrSet;
    }

    public int getIdSize(String id) {
        int size = 0;
        try {
            Set objList = getId(id);
            if (null != objList) {
                size = objList.size();
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return size;
    }

    public void removeDataById(String id) {
        batchDataMap.remove(id);
    }

    public void clear() {
        this.clearId();
        this.clearData();
    }

    public void clearId() {
        idSet.clear();
    }

    public void clearData() {
        batchDataMap.clear();
    }
}

วันอังคารที่ 25 สิงหาคม พ.ศ. 2552

Java for loop list & map ,Python for loop array & map

ในส่วนของการเขียน program นั้น ย่อมต้องมีเรื่องการอ่าน data มากมายเข้ามาเกี่ยวข้องเป็นธรรมดา
ถ้าเป็นเรื่อง List การวนดึงข้อมูลก็คงไม่ใช่เรื่องยุ่งยาก แต่สำหรับ ดังตัวอย่าง
List<String> strList = new LinkedList<String>();
strList.add("comment1-hi,");
strList.add("comment2-i");
strList.add("comment3-am");
strList.add("comment4-Programmer");

for(String str : strList){
    System.out.println(" >> " + str):
}
แต่ในกรณีข้อมูล ที่เป็น Map<String, String> งงว่าทำไมไม่ทำ for ได้ แต่ก็่ช่างครับ
เราย่อมมีวิธีตามนี้เลยครับ
Map<String, String> strMap = new HashMap<String, String>();
strMap.put("comment1", "hi,");
strMap.put("comment2", "i");
strMap.put("comment3", "am");
strMap.put("comment4", "Programmer");
แบบ โบราณ ทำไว้เผื่อจะเอา keys ไปทำอย่างอื่น -.-" คิดเผื่อ เหอ ๆ
Set<String> keys = strMap.keySet();
for( String key : keys ) {
    System.out.println( " >> " + key + "-" + strMap.get( key ) );
}
แบบใหม่ใช้แล้วทิ้ง ^_^
for( Map.Entry<String, String> entry : strMap.entrySet() ) {
    System.out.println( " >> " + entry.getKey() + "-" + entry.getValue() );
}
ลองไปดู python เล่น ๆ ซิ (python จะไม่มี map นะครับ เขาใช้ dict คล้ายกัน)
strDict = {}
strDict['comment1'] = 'hi,'
strDict['comment2'] = 'i,'
strDict['comment3'] = 'am'
strDict['comment4'] = 'Programmer'
เวลาดีงข้อมูลออกมาก็
for k in strDict:
    print ' >> %s-%s' %(k, strDict[k])
!อ่าว เสร็จแล้วหรอ
งั้นไปดู list ของ python กันบ้าง จริง ๆ ก็คือ array แบบ java ครับ
strList = []
strList.append("comment1-hi,");
strList.append("comment2-i");
strList.append("comment3-am");
strList.append("comment4-Programmer");
เอ้าาา วนซิ
for l in strList:
    print ' >>', l
ถ้าลองเพิ่มว่า จะ print เฉพาะ comment ที่ลงท้ายเลขคู่ java จะยาวใหมน้อ ....
เมื่อรู้อย่างนี้แล้ว ก็เลิกเขียนจาวา แล้วไปเขียน python กันดีกว่า อิอิ

วันศุกร์ที่ 7 สิงหาคม พ.ศ. 2552

ubuntu auto script startup

หลายคนที่เกี่ยวข้องกับ server นั้น จะเจอปัญหาที่ว่า เวลาที่เครื่อง server down ไปเนื่องจากสาเหตุอะไรก็แล้วแต่
คนดูแลนั้น ก็จะต้องมานั่ง start service ทีละตัวๆ แต่ถ้าวันนั้น มีการ down server บ่อยก็ต้องมานั่งทำงาน
ซ้ำ ๆ แบบนี้หลายรอบ พาลจะทำให้หลุดได้ ในกรณีที่มี application มากมายก่ายกอง บนนั้น

ในส่วนของ ubuntu หากเราต้องการให้ เมื่อ server มีการ run process ที่เราต้องการ ในตอนที่ server มี
การ start ขึ้นามาใหม่ ขั้นแรก ก็ให้เขียน shellscript file ที่ใช้สำหรับ start application ไว้ สักที่
เช่น สร้างเป็น(ในส่วนนี้ยังไม่ยกตัวอย่าง shellscript นะครับ ยังไม่ประเเด็น)

file : /home/user/script_start_app.sh

หลังจากนั้น ก็เข้ามายุ่งกับ

file : /etc/rc.local


เรียกมาแก้ไขโดย คำสั่ง

$ sudo vi /etc/rc.local

หลังจากนั้น ก็จะมี request password ให้ใส่ ก็ทำการใส่ก็จำเข้ามาหน้า edit ครับ
ที่ต้อง sudo เนื่องจากเป็นระบบหลักครับ อาจทำให้ ระบบเสียหายได้ถ้ามีการแก้ไข เปลี่ยนแปลง
คนแก้ไขจึงต้องเป็น admin เพื่อรับรองความปลอดภัย ระดับนึงครับ

ก็เพิ่ม recode ตามนี้ไป

echo 'start : /home/user/script_start_app.sh'
/home/user/script_start_app.sh >> /home/user/log/scriptstart.log

exit 0


** ในส่วน >> /path/logfile คือการให้ ข้อความ ที่เรา echo ไปออกไว้ที่ใหน

หลังจากนั้น ก็จะพบว่า เมื่อทำการ restart เครื่องแล้วก็จะมีการ start script ดังกล่าวเสมอ

เพิ่มเติม
กรณีที่เราไม่ต้องการให้การ start script เป็นสิทธิ root เนื่องจากเรามี user ที่จำเพราะเจาะจง หรือมีการใช้งานหลากหลาย ก็จะเพิ่มเติม ในส่วน script ดังนี้

su -l user -s /script.sh


ตัวอย่างเช่น

echo 'start : /home/user/script_start_app.sh'
su -l user1 -s /home/user/script_start_app.sh >> /home/user1/log/scriptstart.log
su -l user2 -s /home/user/script_start_app.sh >> /home/user2/log/scriptstart.log
su -l user2 -s /home/user/script_start_web.sh >> /home/user2/log/scriptstart.log

exit 0


และ อีกวิธีก็เป็น การใช้ crontab เข้ามาช่วยในการเช็ค ว่า ถ้า process ตาย ก็จะทำการ start โดยเช็คทุก ๆ
กี่นาทีตามกำหนด แต่จะอันตรายกว่า เนื่องจาก ถ้าapplication มี error ที่ร้ายแรง อาจทำให้มีการทำงานผิดพลาด
ซ้ำ ๆ เกิดขึ้น

วันพุธที่ 5 สิงหาคม พ.ศ. 2552

datetime python

ในส่วนนี้จะเป็นตัวอย่างเกี่ยวกับการใช้ datetime ใน python ซึ่งเราจะพบเจอบ่อยมาก

ตัวอย่าง

1.การดึงเวลาปัจจุบัน ของเครื่องขณะนั้น
from datetime import datetime
>>> now = datetime.now()
>>> now
datetime.datetime(2009, 8, 5, 19, 9, 47, 870000)


เรียงลำดับ ก็ได้ได้เป็น
(2009, 8, 5, 19, 9, 47, 870000)
(ปี, เดือน, วัน, ชั่วโมง, นาที, วินาที, หน่วยที่น้อยกว่า วินาที)

2.การแปลงจาก datetime ให้อยู่ใน format
>>> from datetime import datetime
>>> now = datetime.now()
>>> now
datetime.datetime(2009, 8, 5, 19, 20, 14, 90000)
>>> now.strftime("%d/%m/%y %H:%M:%S")
'05/08/09 19:20:14'


detail ตัวแปรต่าง ๆ ก็เทียบจากตารางข้างล่างนี้ครับ
อ้างอิง : 9.1.7. strftime() Behaviorl

3.การแปลงจาก str เป็น datetime ด้วย format
>>> from datetime import datetime
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)


4.การเลื่อน วัน-เวลา
>>> from datetime import datetime, timedelta
>>> now = datetime.now()
>>> now
datetime.datetime(2009, 8, 5, 19, 9, 47, 870000)

>>> d1 = timedelta(days=1)
>>> now + d1
datetime.datetime(2009, 8, 6, 19, 9, 47, 870000)