วันพุธที่ 13 มกราคม พ.ศ. 2553

Python convert Python syntax color to HTML

หัวข้อนี้น่าสนใจมากครับ สำหรับคนทำ Blog หรือ Web ที่นำเสนอ Code Python
อยากเสนออย่างรุนแรง อาจเป็นเรื่องเก่านะครับ แต่นำมาเล่าใหม่

เพราะเจ้าของ Blog ส่วนใหญ่ที่เรา ๆ เขียนกันนั้น ถ้าเป็น Code Python กันแล้ว
ก็จะมีการนำเสนอ โดยการเขียน code ลงไปใน Blog กับแบบนี้


<code>
<pre>
list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    r = i == len(list) and '%s%s' %(r, l) or '%s%s, ' %(r, l)
    i = i+1
</pre>
</code>


ก็จะได้ผลลัพท์ ดังต่อไปนี้


list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    r = i == len(list) and '%s%s' %(r, l) or '%s%s, ' %(r, l)
    i = i+1


OK รับได้ รับความงามพอสมควร แต่ไม่สวย ก็เคยเห็นคนต่างชาติทำกัน
สีสันดูดีมาก ๆ และก็ไม่ใช่รูปตัดจาก tool มาแปะ กระจอกอันนั้น
เลยพยายามไปหามา ไม่ยอม Blog เราจะกระจอกเกินไปแระ

และแล้ว ความพยายามก็ประสพผมสำเร็จ เจอแล้ว
Pygments
แรก ๆ ก็งงครับ แล้วไง ใช้ไงหรอ -_____-?
อารมณ์ หน้าตาดีแต่กินไม่ได้เลย

เลยไปอ่าน Document เอา ขอโทษนะน้องพี่ก็กร่อมแกร้มพออ่านได้เหมือนกัน หุหุ

เลยไปเจอท่านพี่บอกมากว่า
ให้ลง python ก่อน แล้วก็ตามด้วย easy_install ถ้าเคยลงแล้วก็ข้ามไป

python โหลดที่:
http://www.python.org/download/

ติดตั้ง:

ทดลองว่าเสร็จแล้วโดยลองพิมพ์:

$ python --version
Python 2.6.2


easy_install ทำการ download ez_setup.py โหลดที่:
http://peak.telecommunity.com/dist/ez_setup.py

พิมพ์ command:

$ python ez_setup.py

ทดลองว่าเสร็จแล้วโดยลองพิมพ์:

$ python
>>> import setuptools
>>> setuptools.__version__
'0.6c9'


-----------------------------------------

หลังจากนั้นก็มาถึง Pygments
สูตรสำเร็จ กรณี Windows พิมพ์ว่า

easy_install Pygments


จะขึ้นว่า

C:\Users\Kan>easy_install Pygments
Searching for Pygments
Reading http://pypi.python.org/simple/Pygments/
Reading http://pygments.org/
Reading http://pygments.pocoo.org/
Best match: Pygments 1.2.2
Downloading http://pypi.python.org/packages/2.6/P/Pygments/Pygments-1.2.2-py2.6.
egg#md5=4c78e542315e7ef3a60a265b7eba107e
Processing Pygments-1.2.2-py2.6.egg
creating c:\python26\lib\site-packages\Pygments-1.2.2-py2.6.egg
Extracting Pygments-1.2.2-py2.6.egg to c:\python26\lib\site-packages
Adding Pygments 1.2.2 to easy-install.pth file
Installing pygmentize script to C:\Python26\Scripts

Installed c:\python26\lib\site-packages\pygments-1.2.2-py2.6.egg
Processing dependencies for Pygments
Finished processing dependencies for Pygments

C:\Users\Kan>


ถ้าเป็น Linux จะมีเรื่องสิทธิประกอบ ก็พิมพ์ว่า

# sudo easy_install Pygments


ข้อความที่ขึ้นหลังจากนี้ก็ไม่ค่อยต่างกับ Windows เท่าไร

สามารถ download tar file แล้วมา unpack แล้ว install เองได้โดยใช้คำสั่ง

# sudo python setup.py install

แต่ไม่จำเป็นอย่าเปลืองพลังงาน โลกยิ่งร้อน ๆ อยู่

เสร็จแล้วก็จัดไป โดยขั้นแรก ให้พิมพ์คำว่า
python
ก็จะขึ้นหน้าจอแบบนี้

C:\Users\Kan>python
Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>


หลังจากนั้นก็จัดการพิมพ์ต่อไปว่า

>>> from pygments import highlight
>>> from pygments.lexers import PythonLexer
>>> from pygments.formatters import HtmlFormatter


เพื่อทำการ import library ทั้ง 3 มา
หลังจากนั้นก็เริ่มกันเลย โดยเอา source ที่เราต้องการแปลงให้สวยหรูมา ใส่ตัวแปรชื่อ code

>>> code = '''
... list = ['a', 'b', 'c', 'd']
... r = ''
... i = 1
... for l in list:
... r = i == len(list) and '%s%s' %(r, l) or '%s%s, ' %(r, l)
... i = i+1
... '''


เสร็จแล้วก็ convert ซะโดยคำสั่งตามนี้

>>> print highlight(code, PythonLexer(), HtmlFormatter())


ก็จะมี output ออกมาเป็น

<div class="highlight">
<pre><span class="nb">list</span> <span class="o">=</span> <span class="p">[</span><span class="s">'a'</span><span class="p">,</span> <span class="s">'b'</span><span class="p">,</span> <span class="s">'c'</span><span class="p">,</span> <span class="s">'d'</span><span class="p">]</span>
<span class="n">r</span> <span class="o">=</span> <span class="s">''</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">:</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">i</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span> <span class="ow">and</span> <span class="s">'</span><span class="si">%s%s</span><span class="s">'</span><span class="o">%</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">l</span><span class="p">)</span> <span class="ow">or</span> <span class="s">'</span><span class="si">%s%s</span><span class="s">, '</span> <span class="o">%</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">l</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span>
</pre>
</div>

เยอะแยะ มากมายอย่างที่คิดไว้ ก็แหงสิจะแยกสีมันต้องมีการเปลืองกันเล็กน้อย

เสร็จแล้วก็ Copy เอาไปวางใน Blog
สรุปยังไม่เสร็จ เพราะอะไรอะหรือครับ ถ้าสังเกตุดีดี code ที่เรา Generate ออกมา
ตัว Code มีการอ้างอิงถึง CSS เพื่อเอามาทำเรื่อง style ให้กับ View HTML
CSS อย่าถามว่าคืออะไรนะ โต ๆ กันแล้ว ไปดูบรรทัดต่อมาใน Document
จะมีคำสั่ง Generate CSS สำหรับเรื่องนี้อยู่ คือคำสั่ง

>>> print HtmlFormatter().get_style_defs('.highlight')



ก็จะมี output ออกมาเป็น ซึ่งยาวมิใช่น้อย ก็ก็ไม่มากเกินไป

.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.
.
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */

ประมาณนี้ ไม่โชว์ให้เห็นตอนนี้หมด เปลืองเนื้อที่ครับ
เราก็ copy css style ส่วนนี้ทั้งหมดไปเพิ่มไว้ใน แม่แบบของ Blog นั้น ๆ
แต่ละที่ไม่น่าจะเหมือนกัน ลองศึกษาดูนะครับ ในส่วน BlogSpot จะอยู่ที่
ปรับแต่ง : รูปแบบ : แก้ไข HTML
เผอิญตั้งภาษาไทยไว้ ก็เดา ๆ เอานะไม่น่ายากอะไรครับ

แล้วมาดูผลลัพท์ Code ที่อยู่ใน Blog กันเลย

list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    r = i == len(list) and '%s%s'%(r, l) or '%s%s, ' %(r, l)
    i = i+1

โอ้มันยอดมากเลย ดูดีที่สุดอะ หุหุ

ไม่จำเป็นต้องใส่ tag code ครอบอีกแล้ว

<code>
...code...
</code>


จบแล้ว มีข้อสงสัยถามได้นะครับ ....

Python for loop check islast

คงเคยเจอกันบ่อยแล้วนะครับ สำหรับ Develop ทุกท่าน ที่ต้องมานั่งเขียน loop
แล้วต้องเช็คว่า ถ้าเป็นข้อมูลสุดท้าย ให้ใส่ข้อแม้เพิ่ม หรือปิด ท้ายด้วยอะไรสักอย่าง

ถ้าเป็น code ปกติ เราก็จะเขียนอะไรบางอย่างเพื่อนให้รู้ว่าเป็นข้อมูลสุดท้ายของ list นั้น ๆ

ข้อมูลมีว่า
list = ['a', 'b', 'c', 'd']

ว่าจะเขียนถึง z เอาเป็นว่าไร้สาระ แค่ยกตัวอย่าง ไม่ต้องมากขนาดนั้น
ก็เลยสงสัยจริง ๆ ว่าคนที่ทำ How to หรือตัวอย่าง ทำไมต้องเอา data จริง
หรือข้อมูลมากมายมาทำไม ผมยิ่งมี memory น้อย ๆ อยู่

สิ่งที่ต้องทำคือ ให้ print ข้อมูล ใน list datas โดยให้ใส่ comma ', '
เพื่อแยกข้อมูลในแต่ละช่วง

list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    r = i == len(list) and '%s%s'%(r, l) or '%s%s, ' %(r, l)
    i = i+1

เขียน function มาทำเรื่อง check last นี้ดีกว่า
def for_islast(l):
    i = 1
    for s in l:
        if i < len(l):
            yield s, False
        i = i+1
    yield s, True
เวลาเรียกใช้ก็จะดูดีขึ้นนิดนึง
list = ['a', 'b', 'c', 'd']
r = ''
for l, islast in for_islast(list):
    r = islast and '%s%s'%(r, l) or '%s%s, ' %(r, l)

ในส่วนนี้จะเห็นว่าเขียน code มากขึ้น
แต่ถ้าคิดในแง่ของงานที่มีในลักษณะแบบนี้มาก ๆ
ก็จะเขียนสะดวกขึ้น คือไม่ต้องมีการประกาศตัวแปรที่ไม่ได้ใช้ให้รกอีกมากมาย
และข้อดีของการเขียนขึ้นในลักษณะนี้คือ ความตรงไปตรงมา คือ
เมื่อทำการอ่าน code จะสามารถเข้าใจได้โดยง่ายและไม่ต้องใช้ logic
ในการคิดมากเพื่อให้การอ่าน code เป็นไปด้วยความรวดเร็วครับ

วันศุกร์ที่ 8 มกราคม พ.ศ. 2553

Python list to string on comma ','

ตอนนี้กระผมเริ่มไม่รู้จะเขียนอะไร 555+
คือนึกมุขเท่ ๆ ไม่ค่อยออก ไม่ค่อยอยากเขียน tutorial เท่าไร
มันดูซ้ำกับชาวบ้าน และก็ใน web หลัก ๆ ของ Python ก็แทบจะบอกซะหมดแล้ว
เขียนไปก็เปลืองพื้นที่ชาวบ้านเปล่า ๆ ให้เค้าเอาไว้เตะตะกล้อดีกว่า งึม ๆ
แล้ววันนี้จะนำเสนออะไรดีอะเนี่ย เอาเป็นแนวคิดในการเขียน เล่น ๆ ดีกว่า
ว่าแล้วก็มาใช้สมองอันน้อยนิดกัน

เริ่มจาก มี Logic ที่ว่า ต้องการเอาข้อมูล list มาเรียงเป็น String โดยมี comma ',' กั้น
อื่อ ถ้าเป็นคนทั่วไป ฉลาด ๆ คิดเยอะ ๆ ก็จะประมาณว่า
ให้วน list แล้วนำไปใส่ string ทีละตัว แล้วตามด้วย comma ', '
ตัวสุดท้ายไม่ต้องใส่ comma ', '
list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    if i == len(list):
        r = '%s%s' %(r, l)
    else:
        r = '%s%s, ' %(r, l)
    i = i+1

note
สร้าง i เพื่อเก็บตำแหน่ง ปัจจุบัน จะได้รู้ว่าตัวสุดท้ายหรือยัง

สิ่งที่ได้
'a, b, c, d'

ยอ code หน่อยแล้วกัน
list = ['a', 'b', 'c', 'd']
r = ''
i = 1
for l in list:
    r = i == len(list) and '%s%s' %(r, l) or '%s%s, ' %(r, l)
    i = i+1

เสร็จแล้ว thinking smart ...

--------------------

กะคิดอีกแบบ วนแล้วใส่ comma ', ' ไปก่อน เดี๋ยวเกิดอะไรขึ้น แก้ทีหลัง (แอบหัวเราะ เหอ ๆ ๆ)
ก็จะเขียนขึ้นมาก่อนว่า
list = ['a', 'b', 'c', 'd']
r = ''
for l in list:
    r = '%s%s, ' %(r, l)

สิ่งที่ได้
'a, b, c, d, '

อะเกิน!!! แต่มิใช่ปัญหา ดูแล้ว comma space ', ' ตัวหลังเกินมา
แต่ไม่จำเป็นต้องรู้กระมังว่าตัวหลังคืออะไร รู้แค่กี่ตำแหน่งพอ 2 สินะ
ก็เอาสองตัวหลังออก logic นรก 555+
เพิ่ม code เป็น
list = ['a', 'b', 'c', 'd']
r = ''
for l in list:
    r = '%s%s, ' %(r, l)
if 2 > len(r):
    r = r[0: -2]

สิ่งที่ได้
'a, b, c, d'

ย่อ code หน่อยเพื่อ show power

list = ['a', 'b', 'c', 'd']
r = ''.join(['%s%s, '%(r, l) for l in list])
r = 2 <= len(r) and r[0: -2] or r

อื่อ จบ ๆ ๆ เดี๋ยวจ้างน้อง ๆ มาทำดีกว่า