<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>nattster &#187; python</title>
	<atom:link href="http://nattster.siamdev.net/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://nattster.siamdev.net</link>
	<description>ลั่ลล้า...</description>
	<lastBuildDate>Sun, 25 Dec 2011 05:13:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Django: QuerySet is not a List</title>
		<link>http://nattster.siamdev.net/2011/11/django-queryset-is-not-a-list/</link>
		<comments>http://nattster.siamdev.net/2011/11/django-queryset-is-not-a-list/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 15:20:03 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=1261</guid>
		<description><![CDATA[เวลาดึงข้อมูลจาก Model เช่น blogs = Blog.objects.all&#40;&#41; # ได้ QuerySet ของบล็อกหลายๆ อัน print blogs&#91;0&#93;.title print blogs&#91;0&#93;.body print blogs&#91;1&#93;.title print blogs&#91;1&#93;.body จะเห็นว่าเราใช้ QuerySet ได้เหมือนเป็นอาเรย์หรือ list เลย แต่สิ่งที่ต้องระวังคือ blogs เป็น QuerySet ไม่ใช่ list เวลาอัพเดทข้อมูลใน model ต้องระวัง bug แบบนี้ 1 2 3 blogs&#91;0&#93;.title = &#34;New Title&#34; blogs&#91;0&#93;.body = &#34;new content&#34; blogs&#91;0&#93;.save&#40;&#41; ถ้ารันโค้ดข้างบนแล้ว blogs[0] จะไม่เปลี่ยนแปลงค่าอะไรเลย เพราะ: blogs[0] ในแต่ละบรรทัดเป็น object คนละอันกัน [...]]]></description>
			<content:encoded><![CDATA[<p>เวลาดึงข้อมูลจาก Model เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">blogs = Blog.<span style="color: black;">objects</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># ได้ QuerySet ของบล็อกหลายๆ อัน</span>
<span style="color: #ff7700;font-weight:bold;">print</span> blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">title</span>
<span style="color: #ff7700;font-weight:bold;">print</span> blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">body</span>
<span style="color: #ff7700;font-weight:bold;">print</span> blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">title</span>
<span style="color: #ff7700;font-weight:bold;">print</span> blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">body</span></pre></div></div>

<p>จะเห็นว่าเราใช้ QuerySet ได้เหมือนเป็นอาเรย์หรือ list เลย<br />
แต่สิ่งที่ต้องระวังคือ <strong>blogs เป็น <a href="https://docs.djangoproject.com/en/dev/ref/models/querysets/">QuerySet</a> ไม่ใช่ list</strong></p>
<p>เวลาอัพเดทข้อมูลใน model ต้องระวัง </p>
<h3>bug แบบนี้</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;">blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">title</span> = <span style="color: #483d8b;">&quot;New Title&quot;</span>
blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">body</span> = <span style="color: #483d8b;">&quot;new content&quot;</span>
blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>ถ้ารันโค้ดข้างบนแล้ว blogs[0] จะไม่เปลี่ยนแปลงค่าอะไรเลย เพราะ:</p>
<ul>
<li>blogs[0] ในแต่ละบรรทัดเป็น object คนละอันกัน (คนละ instance กัน)</li>
<li>การเรียก blogs[0] แต่ละครั้ง QuerySet จะให้ object ใหม่ทุกครั้ง ทำให้การกำหนดค่ามีผลกับ object ในบรรทัดนั้นเฉยๆ</li>
<li>blogs[0].save() ในบรรทัดที่ 3 จะอ่านค่า blogs[0] จาก database และ save() กลับไปโดยยังไม่ได้แก้ไขอะไรเลย</li>
</ul>
<h3>ที่ถูกต้องควรเป็น</h3>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">b = blogs<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
b.<span style="color: black;">title</span> = <span style="color: #483d8b;">&quot;New Title&quot;</span>
b.<span style="color: black;">body</span> = <span style="color: #483d8b;">&quot;new content&quot;</span>
b.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>แต่ถ้าอยากใช้ได้เหมือน list จริงๆ ก็ทำได้โดยบังคับให้ Django มัน evaluate QuerySet ให้กลายเป็น list ด้วยฟังก์ชัน list<br />
เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">blogs = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>blogs<span style="color: black;">&#41;</span></pre></div></div>

<p>มีข้อเสียคือ<br />
* มี large memory overhead<br />
* blogs.filter ต่อไม่ได้&#8230; เพราะโดน evaluate ไปแล้ว<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2011/11/django-queryset-is-not-a-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>รวมความมึนของผม ใน python</title>
		<link>http://nattster.siamdev.net/2011/08/bug-bug-python/</link>
		<comments>http://nattster.siamdev.net/2011/08/bug-bug-python/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 11:30:13 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=1272</guid>
		<description><![CDATA[rules = &#40; &#40; 'foo', 1&#41;, &#40; 'spam', 2&#41;, &#40; 'bar', 3&#41;, &#34;&#34;&#34; ( 'egg', 4), ( 'python', 5), &#34;&#34;&#34; &#41; &#160; for name, val in rules: print name, val โค้ดข้างบนพอรันแล้วจะเจอ ValueError (too many values to unpack) ตอนมองแว๊บแรก ก็คิดว่าโค้ดน่าจะโอเค แค่ comment egg กับ python ออกไปแบบหลายบรรทัด&#8230; แต่จริงๆ แล้วมันไม่ใช่ เราสร้าง list ที่มี (&#8216;foo&#8217;, 1), (&#8216;spam&#8217;, 2), (&#8216;bar&#8217;, [...]]]></description>
			<content:encoded><![CDATA[
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">rules = <span style="color: black;">&#40;</span>
    <span style="color: black;">&#40;</span> <span style="color: #483d8b;">'foo'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#40;</span> <span style="color: #483d8b;">'spam'</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#40;</span> <span style="color: #483d8b;">'bar'</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
<span style="color: #483d8b;">&quot;&quot;&quot;
    ( 'egg', 4),
    ( 'python', 5),
&quot;&quot;&quot;</span>
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> name, val <span style="color: #ff7700;font-weight:bold;">in</span> rules:
    <span style="color: #ff7700;font-weight:bold;">print</span> name, val</pre></div></div>

<p>โค้ดข้างบนพอรันแล้วจะเจอ ValueError (too many values to unpack)<br />
ตอนมองแว๊บแรก ก็คิดว่าโค้ดน่าจะโอเค แค่ comment egg กับ python ออกไปแบบหลายบรรทัด&#8230; แต่จริงๆ แล้วมันไม่ใช่</p>
<p>เราสร้าง list ที่มี (&#8216;foo&#8217;, 1), (&#8216;spam&#8217;, 2), (&#8216;bar&#8217;, 3) และ &#8220;&#8221;" (&#8216;egg&#8217;, 4),&#8230;&#8221;"&#8221; &lt;&#8211; ก้อนนี้เป็น string แบบหลายบรรทัด ไม่ใช่ comment!!</p>
<p>ปล. ตอนนี้มีอยู่ 1 bug, เดี๋ยวมีอะไรเพิ่ม จะเอามาแปะอีกครับ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2011/08/bug-bug-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Closure ใน Python</title>
		<link>http://nattster.siamdev.net/2011/07/closure-in-python/</link>
		<comments>http://nattster.siamdev.net/2011/07/closure-in-python/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 10:21:42 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=1252</guid>
		<description><![CDATA[แฮ่ วันนี้ลองเล่น closure ใน python เต็มที่เลยครับ funcs = &#91;&#93; i=0 def funcfactory&#40;&#41;: global i i += 1 j = i def callback&#40;&#41;: print j funcs.append&#40;callback&#41; &#160; funcfactory&#40;&#41; # ได้ callback ที่มี j = 1 funcfactory&#40;&#41; # ได้ callback ที่มี j = 2 funcfactory&#40;&#41; # ได้ callback ที่มี j = 3 print funcs for f in [...]]]></description>
			<content:encoded><![CDATA[<p>แฮ่ วันนี้ลองเล่น closure ใน python เต็มที่เลยครับ</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">funcs = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
i=<span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">def</span> funcfactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> i
    i += <span style="color: #ff4500;">1</span>
    j = i
    <span style="color: #ff7700;font-weight:bold;">def</span> callback<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> j
    funcs.<span style="color: black;">append</span><span style="color: black;">&#40;</span>callback<span style="color: black;">&#41;</span>
&nbsp;
funcfactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># ได้ callback ที่มี j = 1</span>
funcfactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># ได้ callback ที่มี j = 2</span>
funcfactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># ได้ callback ที่มี j = 3</span>
<span style="color: #ff7700;font-weight:bold;">print</span> funcs
<span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> funcs:
    f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>list funcs จะเก็บ function &#8216;callback&#8217; ที่มีโค้ดแบบเดียวกัน (print j) แต่มี context ต่างกัน (j = 1, 2, 3)</p>
<p>closure = (function, environment ของฟังก์ชั่น)</p>
<p><strong>Edit:</strong> ข้อจำกัดสำคัญของ Closure ใน python คือ &#8220;อ่านได้อย่างเดียว&#8221; วิธีแก้ปัญหาทำได้โดยส่ง reference แทนตามตัวอย่างใน <a href="http://stackoverflow.com/questions/141642/what-limitations-have-closures-in-python-compared-to-language-x-closures?answertab=votes#tab-top">[ref]</a></p>
<p>ใน Python 3 มีคีย์เวิร์ด nonlocal ไว้ใช้อ้างถึงตัวแปรที่อยู่ใน Scope ก่อนหน้าได้<br />
<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2011/07/closure-in-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python วนลูปบน list ที่โตขึ้นเรื่อยๆ</title>
		<link>http://nattster.siamdev.net/2010/12/python-%e0%b8%a7%e0%b8%99%e0%b8%a5%e0%b8%b9%e0%b8%9b%e0%b8%9a%e0%b8%99-list-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b9%82%e0%b8%95%e0%b8%82%e0%b8%b6%e0%b9%89%e0%b8%99%e0%b9%80%e0%b8%a3%e0%b8%b7%e0%b9%88/</link>
		<comments>http://nattster.siamdev.net/2010/12/python-%e0%b8%a7%e0%b8%99%e0%b8%a5%e0%b8%b9%e0%b8%9b%e0%b8%9a%e0%b8%99-list-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b9%82%e0%b8%95%e0%b8%82%e0%b8%b6%e0%b9%89%e0%b8%99%e0%b9%80%e0%b8%a3%e0%b8%b7%e0%b9%88/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 13:15:27 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=1194</guid>
		<description><![CDATA[a = &#91;1&#93; for i in a: print i if len&#40;a&#41; &#60; 10: a.append&#40;i+1&#41; ได้ผลลัพธ์เป็น 1 2 3 4 5 6 7 8 9 10 ตื่นเต้นดี for loop บน list ที่โตขึ้นเรื่อยๆ&#8230; ไม่รู้ว่าจะจบเมื่อไหร่]]></description>
			<content:encoded><![CDATA[
<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">a = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> a:
    <span style="color: #ff7700;font-weight:bold;">print</span> i
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">10</span>:
        a.<span style="color: black;">append</span><span style="color: black;">&#40;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></div></div>

<p>ได้ผลลัพธ์เป็น<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10</p>
<p>ตื่นเต้นดี for loop บน list ที่โตขึ้นเรื่อยๆ&#8230; ไม่รู้ว่าจะจบเมื่อไหร่<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2010/12/python-%e0%b8%a7%e0%b8%99%e0%b8%a5%e0%b8%b9%e0%b8%9b%e0%b8%9a%e0%b8%99-list-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b9%82%e0%b8%95%e0%b8%82%e0%b8%b6%e0%b9%89%e0%b8%99%e0%b9%80%e0%b8%a3%e0%b8%b7%e0%b9%88/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ปลั๊กอิน &#8220;ป้องกัน SPAM&#8221; สำหรับ pidgin</title>
		<link>http://nattster.siamdev.net/2009/06/anti-msn-spam-plugin-for-pidgin/</link>
		<comments>http://nattster.siamdev.net/2009/06/anti-msn-spam-plugin-for-pidgin/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 16:26:44 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[msn]]></category>
		<category><![CDATA[pidgin]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=364</guid>
		<description><![CDATA[เบื่อ SPAM ทาง msn มาก! จะบล็อกคนส่งทิ้งแบบ @rtsp ก็ใจร้ายเกินไป ผมเลยลองเขียนปลั๊กอินไว้ &#8220;กรองข้อความ&#8221; โดยใช้เงื่อนไขง่ายๆ ว่า &#8220;ใน 1 ชม. ที่ผ่านมา ถ้าเธอยังไม่เคยส่งข้อความหาฉันเลย แล้วจู่ๆ ส่ง URL มาให้ ฉันจะขอโยนข้อความนั้นทิ้งซะ (มันต้องเป็น spam แน่เลย!)&#8221; Anti MSN Spam ลองเขียนไว้ 2 version ครับ เขียนด้วย Python กับ C 1. anti-msn-spam.py ลองเขียนตัวต้นแบบด้วย Python ครับ ใช้ dbus คุยกับ pidgin เพื่อเช็คว่ามีข้อความส่งมารึเปล่า (หาอ่านเพิ่มเติมได้จาก wiki นี้) คิดว่าใช้ได้บน linux เท่านั้น เพราะมันใช้ dbus น่ะครับ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nattster.siamdev.net/wp-content/uploads/2009/06/msn_spam.png" rel="lightbox[364]" title="msn_spam"><img src="http://nattster.siamdev.net/wp-content/uploads/2009/06/msn_spam-300x274.png" alt="msn_spam" title="msn_spam" width="300" height="274" class="alignnone size-medium wp-image-365" align="left" /></a> เบื่อ SPAM ทาง msn มาก! จะบล็อกคนส่งทิ้งแบบ <a href="http://twitter.com/rtsp">@rtsp</a> ก็ใจร้ายเกินไป</p>
<p>ผมเลยลองเขียนปลั๊กอินไว้ &#8220;กรองข้อความ&#8221; โดยใช้เงื่อนไขง่ายๆ ว่า<br />
<blockquote>&#8220;ใน 1 ชม. ที่ผ่านมา ถ้าเธอยังไม่เคยส่งข้อความหาฉันเลย แล้วจู่ๆ ส่ง URL มาให้ ฉันจะขอโยนข้อความนั้นทิ้งซะ (มันต้องเป็น spam แน่เลย!)&#8221;</p></blockquote>
<p><span id="more-364"></span></p>
<h3>Anti MSN Spam</h3>
<p>ลองเขียนไว้ 2 version ครับ เขียนด้วย Python กับ C</p>
<h4>1. <a href='http://nattster.siamdev.net/wp-content/uploads/2009/06/anti-msn-spam.py'>anti-msn-spam.py</a></h4>
<p>ลองเขียนตัวต้นแบบด้วย Python ครับ ใช้ dbus คุยกับ pidgin เพื่อเช็คว่ามีข้อความส่งมารึเปล่า (<a href="http://developer.pidgin.im/wiki/DbusHowto">หาอ่านเพิ่มเติมได้จาก wiki นี้</a>)</p>
<p>คิดว่าใช้ได้บน linux เท่านั้น เพราะมันใช้ dbus น่ะครับ<br />
<strong>วิธีใช้:</strong> เปิด pidgin แล้วเรียกคำสั่งต่อไปนี้</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python anti-msn-spam.py</pre></div></div>

<p>พอโปรแกรมจับ SPAM ได้มันก็จะบ่นออกมาทาง command line ว่า &#8220;ข้อความ&#8230;..โดน block ทิ้ง เพราะสงสัยว่าเป็น SPAM&#8221; (โค้ด version python น่าจะทำความเข้าใจได้ง่ายสุดครับ ลองแกะเล่นดูได้นะ <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</p>
<h4>2. <a href='http://nattster.siamdev.net/wp-content/uploads/2009/06/anti_msn_spam_c.zip'>anti_msn_spam_c.zip</a></h4>
<p>version C นี้ไปเอาโค้ด <a href="http://iamhuy.com/blog/?p=84">message_filter.c ของคุณ Huy Phan</a> มาโมดิฟาย&#8230; ของเดิมเค้าเขียนโปรแกรม &#8220;block ข้อความที่มีแต่ smiley&#8221;</p>
<p><strong>วิธีใช้</strong> ดาวน์โหลดไฟล์ zip ไปจะมี anti_msn_spam.c กับ anti_msn_spam.so<br />
<strong>- สำหรับคนใช้ x86 กับ pidgin 2.5.5 (บน linux):</strong><br />
1. สามารถเอาไฟล์ anti_msn_spam.so ไปใส่ไว้ที่ /home/USERNAME/.purple/plugins/anti_msn_spam.so ได้เลย<br />
2. เปิด pidgin ขึ้นมาใหม่ เลือกเมนู Tools->Plugins<br />
3. ติ๊กถูกหน้า &#8220;Anti MSN Spam 1.0&#8243; เป็นอันเสร็จ</p>
<p><strong>- สำหรับคนอื่นๆ (เช่น คนใช้ pidgin บน windows)</strong><br />
น่าจะต้อง compile เองครับ ทำตาม<a href="http://developer.pidgin.im/wiki/CHowTo/BasicPluginHowto">คู่มือนี้เลย</a> เหมือนจะต้องใช้ MinGW มา compile ครับ ถ้าใครพยายามแล้วติดปัญหา ก็แปะคอมเม้นท์มาได้นะครับ <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>โม้ไว้นิ๊สนึง&#8230; ตั้งแต่ลองใช้มา 3-4 สัปดาห์ ก็ยังไม่เจอ SPAM กวนใจอีกเลย ไม่รู้ว่าเค้าเลิกส่ง SPAM กันแล้ว หรือว่า Plugin เราดีจริง หะๆ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2009/06/anti-msn-spam-plugin-for-pidgin/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Psyco ให้โปรแกรมที่เขียนด้วย python ทำงานเร็วขึ้น 2-100 เท่า โดยไม่ต้องแก้โค้ดเดิม</title>
		<link>http://nattster.siamdev.net/2009/03/psyco-python/</link>
		<comments>http://nattster.siamdev.net/2009/03/psyco-python/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 19:36:34 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=250</guid>
		<description><![CDATA[จากคอมเมนท์ข่าว กูเกิลเตรียมพัฒนา Python ขนานใหญ่ ใน blognone ทำให้ผมเพิ่งรู้ว่า java ทำงานได้เร็วกว่า python เพราะมี Java VM ที่เป็น Just-in-Time Compiler (JIT Compiler) JIT Compiler ตามความเข้าใจของผม (งูๆปลาๆ) ตามปกติ Java VM ทำหน้าที่เป็น Interpreter เวลาเรารันโปรแกรมก็จะแปลโค้ดทีละบรรทัดเป็นภาษาเครื่องที่สอดคล้องกัน และเมื่อเจอโค้ดเดิมๆ Interpreter ก็ต้องแปลโค้ดเดิมซ้ำทำให้เสียเวลา JIT Compiler เข้ามาช่วยเพิ่มความเร็วได้ โดยมันจะคอย cache ส่วนของโค้ดที่เคยแปลเป็นภาษาเครื่องไว้ ทำให้เวลาเจอโค้ดเดิมก็สามารถเรียกภาษาเครื่องที่ cache ไว้พ่นใส่ CPU ได้ทันที แล้ว Python มี JIT Compiler ไหม? มีครับ ชื่อว่า Psyco (ไม่ได้สะกดผิดนะ) ได้รู้จักมันครั้งแรกจากคอมเมนท์ข่าวใน blognone อีกเช่นเคย [...]]]></description>
			<content:encoded><![CDATA[<p>จากคอมเมนท์ข่าว <a href="http://www.blognone.com/node/11159 ">กูเกิลเตรียมพัฒนา Python ขนานใหญ่</a> ใน <a href="http://www.blognone.com">blognone</a> ทำให้ผมเพิ่งรู้ว่า java ทำงานได้เร็วกว่า python เพราะมี Java VM ที่เป็น <a href="http://en.wikipedia.org/wiki/Just-in-time_compilation">Just-in-Time Compiler (JIT Compiler)</a></p>
<h3>JIT Compiler ตามความเข้าใจของผม (งูๆปลาๆ)</h3>
<p>ตามปกติ Java VM ทำหน้าที่เป็น Interpreter เวลาเรารันโปรแกรมก็จะแปลโค้ดทีละบรรทัดเป็นภาษาเครื่องที่สอดคล้องกัน และเมื่อเจอโค้ดเดิมๆ Interpreter ก็ต้องแปลโค้ดเดิมซ้ำทำให้เสียเวลา </p>
<p><a href="http://en.wikipedia.org/wiki/Just-in-time_compilation">JIT Compiler</a> เข้ามาช่วยเพิ่มความเร็วได้ โดยมันจะคอย cache ส่วนของโค้ดที่เคยแปลเป็นภาษาเครื่องไว้ ทำให้เวลาเจอโค้ดเดิมก็สามารถเรียกภาษาเครื่องที่ cache ไว้พ่นใส่ CPU ได้ทันที</p>
<h3>แล้ว Python มี JIT Compiler ไหม?</h3>
<p><span id="more-250"></span><br />
มีครับ ชื่อว่า <a href="http://psyco.sourceforge.net/">Psyco</a> (ไม่ได้สะกดผิดนะ) ได้รู้จักมันครั้งแรกจากคอมเมนท์ข่าวใน blognone อีกเช่นเคย คำอธิบายสั้นๆ เกี่ยวกับ Psyco:</p>
<p><strong>มันคืออะไร: </strong> Python extension ที่ช่วยให้รันโปรแกรมเดิมที่เขียนด้วย Python <strong>ให้เร็วขึ้นโดยไม่ต้องแก้โค้ดเดิม</strong><br />
<strong>ประโยชน์: </strong> โปรแกรมรันเร็วขึ้น 2 เท่า ถึง 100 เท่า (โดยทั่วไปเร็วขึ้น 4 เท่า)<br />
<strong>ข้อเสีย: </strong> Psyco ใช้หน่วยความจำเยอะ และรันบน Intel 386-compatible processor ภายใต้ระบบปฏิบัติการใดๆ (ในยุคข้าวยาก หมากแพง แต่แรมถูก จะใช้แรมมากๆ ก็คงไม่เป็นไรมั้งครับ <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<h3>ทดลองกันหน่อย</h3>
<div style="width:50%; float:left; ">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># โปรแกรมปกติ</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
start = <span style="color: #dc143c;">time</span>.<span style="color: black;">clock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> fib<span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> n == <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> n == <span style="color: #ff4500;">1</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> fib<span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>+fib<span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Fib 40 = &quot;</span>, fib<span style="color: black;">&#40;</span><span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
&nbsp;
end =  <span style="color: #dc143c;">time</span>.<span style="color: black;">clock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Duration: &quot;</span>, <span style="color: black;">&#40;</span>end-start<span style="color: black;">&#41;</span>, <span style="color: #483d8b;">&quot; seconds&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Output:</span>
<span style="color: #808080; font-style: italic;"># 165580141</span>
<span style="color: #808080; font-style: italic;"># Duration:  106.025350987  seconds</span></pre></div></div>

</div>
<div style="width:50%; float:left; ">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># ใช้ psyco</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
start = <span style="color: #dc143c;">time</span>.<span style="color: black;">clock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">import</span> psyco          <span style="color: #808080; font-style: italic;">### เพิ่มโค้ดบรรทัดนี้</span>
psyco.<span style="color: black;">full</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>            <span style="color: #808080; font-style: italic;">### กับบรรทัดนี้</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> fib<span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> n == <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> n == <span style="color: #ff4500;">1</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> fib<span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>+fib<span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Fib 40 = &quot;</span>, fib<span style="color: black;">&#40;</span><span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
&nbsp;
end =  <span style="color: #dc143c;">time</span>.<span style="color: black;">clock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Duration: &quot;</span>, <span style="color: black;">&#40;</span>end-start<span style="color: black;">&#41;</span>, <span style="color: #483d8b;">&quot; seconds&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Output:</span>
<span style="color: #808080; font-style: italic;"># 165580141</span>
<span style="color: #808080; font-style: italic;"># Duration:  6.715894129  seconds</span></pre></div></div>

</div>
<p>เฮือก&#8230; จาก 106.0 วินาที ลดเหลือ 6.7 วินาที! พอลองเอา Psyco ไปใช้กับโปรแกรมตัดคำไทย cpskCut ปรากฏว่าบนข้อมูลทดสอบ 5 แสนคำ จากเดิมใช้เวลา 78 วินาที ลดเหลือ 34 วินาที (โดยเพิ่มโค้ดแค่ 2 บรรทัดด้านบนครับ)</p>
<p>ใครอยากลองเอาไปใช้บ้างก็ <a href="http://www.voidspace.org.uk/python/modules.shtml#psyco">ดาวน์โหลด Psyco สำหรับ Python 2.6 ได้ที่นี่</a> ครับ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2009/03/psyco-python/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>AVL Tree ใน python</title>
		<link>http://nattster.siamdev.net/2009/02/avl-tree-in-python/</link>
		<comments>http://nattster.siamdev.net/2009/02/avl-tree-in-python/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 11:25:24 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=172</guid>
		<description><![CDATA[นั่งแอบเขียน AVL Tree ระหว่างนั่งเรียนวิชา Abstract Data Types (ตัวอย่างไม่ดี โปรดอย่าเลียนแบบ ) AVL Tree คือ binary search tree ที่คอยจัดตัวเองให้ balance อยู่เสมอ (subtree ทางซ้าย กับ subtree ทางขวามี depth แตกต่างกันไม่เกิน 2) และการจัดต้นไม้ให้ balance อยู่เสมอทำให้ binary search tree สามารถแทรก/ค้นหา ข้อมูลได้อย่างมีประสิทธิภาพ (ไม่มีปัญหาที่เกิดจากต้นไม้เอียงไปข้างใดข้างหนึ่ง) AVL Tree ที่เขียนเป็น class มี method isLeaf (เช็คว่าเป็นโหนดลูก), depth (หาความลึกของต้นไม้), balance (คำนวณ balance factor สำหรับต้นไม้), LeftRotate (ทำการหมุนต้นไม้ไปทางซ้าย), RightRotate (หมุนต้นไม้ไปทางขวา), [...]]]></description>
			<content:encoded><![CDATA[<p>นั่งแอบเขียน AVL Tree ระหว่างนั่งเรียนวิชา Abstract Data Types (ตัวอย่างไม่ดี โปรดอย่าเลียนแบบ <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</p>
<p><a href="http://en.wikipedia.org/wiki/AVL_tree">AVL Tree</a> คือ binary search tree ที่คอยจัดตัวเองให้ balance อยู่เสมอ (subtree ทางซ้าย กับ subtree ทางขวามี depth แตกต่างกันไม่เกิน 2) และการจัดต้นไม้ให้ balance อยู่เสมอทำให้ binary search tree สามารถแทรก/ค้นหา ข้อมูลได้อย่างมีประสิทธิภาพ (ไม่มีปัญหาที่เกิดจากต้นไม้เอียงไปข้างใดข้างหนึ่ง)</p>
<p>AVL Tree ที่เขียนเป็น class มี method isLeaf (เช็คว่าเป็นโหนดลูก), depth (หาความลึกของต้นไม้), balance (คำนวณ balance factor สำหรับต้นไม้), LeftRotate (ทำการหมุนต้นไม้ไปทางซ้าย), RightRotate (หมุนต้นไม้ไปทางขวา), RLDoubleRotate (หมุนสองครั้งแบบขวา-ซ้าย), LRDoubleRotate (หมุนสองครั้งแบบซ้าย-ขวา), insert (แทรกโหนดลงไปในกราฟ), travel (ท่องไปในต้นไม้), printtree (พิมพ์ต้นไม้)</p>
<p><strong>ตัวอย่างต้นไม้ที่ printtree พิมพ์ออกมา</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff4500;">7</span>
  <span style="color: #ff4500;">6</span>
    <span style="color: #ff4500;">5</span>
<span style="color: #ff4500;">4</span>
    <span style="color: #ff4500;">3</span>
  <span style="color: #ff4500;">2</span>
    <span style="color: #ff4500;">1</span></pre></div></div>

<p>ข้างบนเป็นต้นไม้ที่มี 4 เป็น root และมี 2 กับ 6 เป็นลูกทางซ้ายและขวาตามลำดับ โดย 2 มี 1 และ 3 เป็นลูก&#8230;. วิธี printtree แบบนี้ ได้เทคนิคมาจาก อ.ที่ค่าย สอวน. ศูนย์ ม.ศิลปากร ครับ <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>(โค้ดอยู่ด้านในนะครับ)<br />
<span id="more-172"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># author: Natt Piyapramote &lt;nattster at googlemail&gt;</span>
<span style="color: #ff7700;font-weight:bold;">class</span> AVLTree:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">data</span> = data
        <span style="color: #008000;">self</span>.<span style="color: black;">left</span> = <span style="color: #008000;">None</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">right</span> = <span style="color: #008000;">None</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> isLeaf<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">False</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> depth<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">isLeaf</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
        depth = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            depth = <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            depth = <span style="color: #008000;">max</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, depth<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> depth+<span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> balance<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">isLeaf</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>+<span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> -<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - <span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">depth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> LeftRotate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, root<span style="color: black;">&#41;</span>:
        pivot = root.<span style="color: black;">right</span>
        root.<span style="color: black;">right</span> = pivot.<span style="color: black;">left</span>
        pivot.<span style="color: black;">left</span> = root
        <span style="color: #ff7700;font-weight:bold;">return</span> pivot
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> RightRotate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, root<span style="color: black;">&#41;</span>:
        pivot = root.<span style="color: black;">left</span>
        root.<span style="color: black;">left</span> = pivot.<span style="color: black;">right</span>
        pivot.<span style="color: black;">right</span> = root
        <span style="color: #ff7700;font-weight:bold;">return</span> pivot
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> RLDoubleRotate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, root<span style="color: black;">&#41;</span>:
        root.<span style="color: black;">right</span> = <span style="color: #008000;">self</span>.<span style="color: black;">RightRotate</span><span style="color: black;">&#40;</span>root.<span style="color: black;">right</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">LeftRotate</span><span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> LRDoubleRotate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, root<span style="color: black;">&#41;</span>:
        root.<span style="color: black;">left</span> = <span style="color: #008000;">self</span>.<span style="color: black;">LeftRotate</span><span style="color: black;">&#40;</span>root.<span style="color: black;">left</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">RightRotate</span><span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> insert<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># insert node</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> node.<span style="color: black;">data</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #008000;">self</span>.<span style="color: black;">data</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">left</span> = node
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">left</span> = <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span>node<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">right</span> = node
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">right</span> = <span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span>node<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># rotation needed?</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">balance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">balance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">RightRotate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">LRDoubleRotate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">self</span>.<span style="color: black;">balance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == -<span style="color: #ff4500;">2</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">balance</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">LeftRotate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">RLDoubleRotate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> travel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">travel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">self</span>.<span style="color: black;">data</span>, 
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">travel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> printtree<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, depth=<span style="color: #ff4500;">0</span>, padding=<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;pre order travel to print binary tree&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">right</span>: <span style="color: #008000;">self</span>.<span style="color: black;">right</span>.<span style="color: black;">printtree</span><span style="color: black;">&#40;</span>depth+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">' '</span><span style="color: #66cc66;">*</span>padding<span style="color: #66cc66;">*</span>depth + <span style="color: #66cc66;">`</span><span style="color: #008000;">self</span>.<span style="color: black;">data</span><span style="color: #66cc66;">`</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">left</span>: <span style="color: #008000;">self</span>.<span style="color: black;">left</span>.<span style="color: black;">printtree</span><span style="color: black;">&#40;</span>depth+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
root = AVLTree<span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">6</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">7</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>:
    root = root.<span style="color: black;">insert</span><span style="color: black;">&#40;</span>AVLTree<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
root.<span style="color: black;">printtree</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2009/02/avl-tree-in-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ใช้ python เรียกโปรแกรมอื่น โดยมี timeout</title>
		<link>http://nattster.siamdev.net/2009/01/python-run-subprocess-with-timeout/</link>
		<comments>http://nattster.siamdev.net/2009/01/python-run-subprocess-with-timeout/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 08:06:36 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[subprocess]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=156</guid>
		<description><![CDATA[วันจันทร์ที่ผ่านมาผมนั่งเขียน grader อย่างบ้าคลั่ง เพราะต้องเอามาใช้ตรวจโปรแกรมน้องๆ ในวันอังคาร ผมเขียน grader ด้วยภาษา Python หลายๆคนคงทราบดีว่าโปรแกรม grader เป็นโปรแกรมที่ทำหน้าที่ compile และ run โปรแกรมอื่น เพื่อตรวจสอบว่า input ที่ใส่เข้าไปตรงกับ output ที่ถูกต้องหรือไม่ ถ้าถูกต้องทุก input ก็ถือว่าผ่าน แต่ว่าโปรแกรมที่เอามาตรวจอาจรันแล้วเกิดอาการติดลูป หรือรันไม่รู้จบ เราจึงต้องกำหนด timeout ว่าให้รันได้ไม่เกินกี่วินาที ถ้าโปรแกรมรันนานเกินไป โปรแกรม grader จะต้องหยุดการทำงาน (End Process) ของโปรแกรมที่ถูกตรวจ ปรากฏว่าผมไปค้นๆ ในเน็ตก็ไม่เจอตัวอย่างโปรแกรม python ที่สามารถ รันโปรแกรมอื่น แล้วกำหนด timeout แบบง่ายๆ เลย ผมก็เลยพยายามเขียนเอง ได้โค้ดมาดังนี้ (ใช้ thread และ subprocess) import subprocess from time [...]]]></description>
			<content:encoded><![CDATA[<p>วันจันทร์ที่ผ่านมาผมนั่งเขียน grader อย่างบ้าคลั่ง เพราะต้องเอามาใช้ตรวจโปรแกรมน้องๆ ในวันอังคาร ผมเขียน grader ด้วยภาษา <a href="http://www.python.org/">Python</a> หลายๆคนคงทราบดีว่าโปรแกรม grader เป็นโปรแกรมที่ทำหน้าที่ compile และ run โปรแกรมอื่น เพื่อตรวจสอบว่า input ที่ใส่เข้าไปตรงกับ output ที่ถูกต้องหรือไม่ ถ้าถูกต้องทุก input ก็ถือว่าผ่าน</p>
<p>แต่ว่าโปรแกรมที่เอามาตรวจอาจรันแล้วเกิดอาการติดลูป หรือรันไม่รู้จบ เราจึงต้องกำหนด timeout ว่าให้รันได้ไม่เกินกี่วินาที ถ้าโปรแกรมรันนานเกินไป โปรแกรม grader จะต้องหยุดการทำงาน (End Process) ของโปรแกรมที่ถูกตรวจ</p>
<p>ปรากฏว่าผมไปค้นๆ ในเน็ตก็ไม่เจอตัวอย่างโปรแกรม python ที่สามารถ รันโปรแกรมอื่น แล้วกำหนด timeout แบบง่ายๆ เลย ผมก็เลยพยายามเขียนเอง <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  ได้โค้ดมาดังนี้ (ใช้ thread และ subprocess)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">time</span> <span style="color: #ff7700;font-weight:bold;">import</span> sleep
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">threading</span> <span style="color: #ff7700;font-weight:bold;">import</span> Thread
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> process<span style="color: black;">&#40;</span>Thread<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># written by Natt Piyapramote &lt;nattster at google mail&gt;</span>
    <span style="color: #808080; font-style: italic;"># requires: Python 2.6</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, filename, input_txt=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        Thread.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">filename</span> = filename
        <span style="color: #008000;">self</span>.<span style="color: black;">input_txt</span> = input_txt
        <span style="color: #008000;">self</span>.<span style="color: black;">status</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">output</span> = <span style="color: #483d8b;">''</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">process</span> = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">filename</span>,
                                   stdin=<span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span>, stdout=<span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">output</span>, <span style="color: #008000;">self</span>.<span style="color: black;">err</span> = <span style="color: #008000;">self</span>.<span style="color: black;">process</span>.<span style="color: black;">communicate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">input_txt</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">status</span> = <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> run_process<span style="color: black;">&#40;</span>filename, input_txt=<span style="color: #008000;">None</span>, timeout=<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;run a process with timeout&quot;</span>
&nbsp;
    p = process<span style="color: black;">&#40;</span>filename, input_txt<span style="color: black;">&#41;</span>
    p.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">join</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> p.<span style="color: black;">status</span> == <span style="color: #ff4500;">0</span>:   <span style="color: #808080; font-style: italic;"># process still running?</span>
        p.<span style="color: black;">process</span>.<span style="color: black;">terminate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">while</span> p.<span style="color: black;">isAlive</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            sleep<span style="color: black;">&#40;</span><span style="color: #ff4500;">0.1</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'killing process...'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> p.<span style="color: black;">output</span></pre></div></div>

<p>ตัวอย่างการใช้งานฟังก์ชันนี้ก็</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">run_process<span style="color: black;">&#40;</span><span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>windows<span style="color: #000099; font-weight: bold;">\\</span>notepad.exe'</span>, timeout=<span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span></pre></div></div>

<p>ฟังก์ชัน run_process จะไปเรียกโปรแกรม notepad.exe ให้ทำงาน (ซึ่ง notepad จะรันไปเรื่อยๆ ไม่ปิดตัวเอง) ดังนั้นฟังก์ชัน run_process จะหยุดการทำงานของ notepad ภายในเวลา 4 วินาที</p>
<p>นอกจากนี้ถ้าเรารันโปรแกรมที่เป็น Console Application เราสามารถกำหนด Input ให้กับ Standard Input (stdin) และอ่านค่าจาก Standard Output (stdout) ของโปรแกรมที่รันได้ด้วย (กำหนด Input ให้ตัวแปร input_txt แล้วฟังก์ชันจะคืนค่าข้อความจาก stdout)</p>
<p>อ้อ&#8230; ฟังก์ชันนี้ต้องใช้ Python 2.6 นะครับ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2009/01/python-run-subprocess-with-timeout/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>อ่านไฟล์ใน python อย่างรวดเร็วและมีประสิทธิภาพ</title>
		<link>http://nattster.siamdev.net/2009/01/reading-file-efficiently-in-python/</link>
		<comments>http://nattster.siamdev.net/2009/01/reading-file-efficiently-in-python/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 16:41:44 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=149</guid>
		<description><![CDATA[ก่อนหน้านี้นิสัยไม่ดี ชอบเขียนโปรแกรมอ่านไฟล์ประมาณนี้ lines = open&#40;'file.txt', 'r'&#41;.read&#40;&#41;.split&#40;'\n'&#41; for line in lines: # do something คำสั่ง read() แบบไม่กำหนด parameter จะอ่านไฟล์ทั้งหมดเข้ามาไว้ในหน่วยความจำ ถ้าไฟล์มีขนาดเล็ก ก็คงไม่มีปัญหาอะไร แต่เมื่อคืนเขียนโปรแกรมตัดคำไฟล์ใหญ่ประมาณ 64mb ปรากฏว่าโปรแกรมทำงานช้าลงมาก (จากไฟล์เล็กๆ ~7000 คำ/วินาที พอเจอไฟล์ใหญ่ๆเหลือ ~700 คำ/วินาที) พออ่าน Python Doc แล้วเปลี่ยนวิธีเขียนโปรแกรมอ่านไฟล์เป็นแบบนี้แทน (ซึ่งมีประสิทธิภาพมากกว่า เพราะค่อยๆ อ่านทีละบรรทัด) f = open&#40;'file.txt', 'r'&#41; for line in f: # do something f.close&#40;&#41; ปรากฏว่า ไฟล์จะใหญ่แค่ไหน โปรแกรมก็ทำงานที่ความเร็ว ~7000 คำ/วินาที ปล. มาเขียนบล็อกไว้เผื่อคนอื่นจะเจอปัญหาโง่ๆ [...]]]></description>
			<content:encoded><![CDATA[<p>ก่อนหน้านี้นิสัยไม่ดี ชอบเขียนโปรแกรมอ่านไฟล์ประมาณนี้</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">lines = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'file.txt'</span>, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> lines:
    <span style="color: #808080; font-style: italic;"># do something</span></pre></div></div>

<p>คำสั่ง read() แบบไม่กำหนด parameter จะอ่านไฟล์ทั้งหมดเข้ามาไว้ในหน่วยความจำ ถ้าไฟล์มีขนาดเล็ก ก็คงไม่มีปัญหาอะไร แต่เมื่อคืนเขียนโปรแกรมตัดคำไฟล์ใหญ่ประมาณ 64mb ปรากฏว่าโปรแกรมทำงานช้าลงมาก (จากไฟล์เล็กๆ ~7000 คำ/วินาที พอเจอไฟล์ใหญ่ๆเหลือ ~700 คำ/วินาที)</p>
<p>พออ่าน Python Doc แล้วเปลี่ยนวิธีเขียนโปรแกรมอ่านไฟล์เป็นแบบนี้แทน (ซึ่งมีประสิทธิภาพมากกว่า เพราะค่อยๆ อ่านทีละบรรทัด)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'file.txt'</span>, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> f:
    <span style="color: #808080; font-style: italic;"># do something</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>ปรากฏว่า ไฟล์จะใหญ่แค่ไหน โปรแกรมก็ทำงานที่ความเร็ว ~7000 คำ/วินาที <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
ปล. มาเขียนบล็อกไว้เผื่อคนอื่นจะเจอปัญหาโง่ๆ แบบนี้ T_T (หรือไม่เค้าก็คงจะเขียนกันแบบล่างซะส่วนใหญ่ล่ะมั้ง)<br />
ปล2. วิธีอ่านไฟล์แบบล่าง มีปัญหาคือ ถ้าโปรแกรมเราจำเป็นต้องกระโดดไปอ่านข้อความที่บรรทัดนู้นที บรรทัดนี้ทีก็คงจะทำไม่ได้ครับ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2009/01/reading-file-efficiently-in-python/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>วนลูป แล้วลบ &#8220;ของ&#8221; ออกจาก list</title>
		<link>http://nattster.siamdev.net/2008/10/iterate-and-remove-item-from-list/</link>
		<comments>http://nattster.siamdev.net/2008/10/iterate-and-remove-item-from-list/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 17:42:12 +0000</pubDate>
		<dc:creator>nattster</dc:creator>
				<category><![CDATA[คอมพิวเตอร์จ๋า]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[iteration]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://nattster.siamdev.net/?p=107</guid>
		<description><![CDATA[คุณเคยต้องเขียนโปรแกรมที่วนลูปบน list แล้วลบ &#8220;ของ (object)&#8221; ออกจาก list นั้นหรือไม่? ลองยกตัวอย่างโปรแกรมง่ายๆ สมมติให้ list A เก็บเลขจำนวนเต็ม แล้วคุณต้องการลบเลขที่หารสามลงตัว ออกจาก list A โค้ดของคุณก็อาจจะเป็น Python C# A = &#91;1, 2, 3, 6, 7, 9, 12&#93; for x in A: if x % 3 == 0: A.remove&#40;x&#41; List&#60;int&#62; A = new List&#60;int&#62;&#40;new int&#91;&#93;&#123;1, 2, 3, 6, 7, 9, 12&#125;&#41;; foreach&#40;int x in [...]]]></description>
			<content:encoded><![CDATA[<p>คุณเคยต้องเขียนโปรแกรมที่วนลูปบน list แล้วลบ &#8220;ของ (object)&#8221; ออกจาก list นั้นหรือไม่? ลองยกตัวอย่างโปรแกรมง่ายๆ สมมติให้ list A เก็บเลขจำนวนเต็ม แล้วคุณต้องการลบเลขที่<strong>หารสามลงตัว</strong> ออกจาก list A โค้ดของคุณก็อาจจะเป็น</p>
<table border="0" width="100%">
<tbody>
<tr>
<th>Python</th>
<th>C#</th>
</tr>
<tr>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">6</span>, <span style="color: #ff4500;">7</span>, <span style="color: #ff4500;">9</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> A:
    <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span> == <span style="color: #ff4500;">0</span>:
        A.<span style="color: black;">remove</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span></pre></div></div>

</td>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span> A <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#123;</span><span style="color: #FF0000;">1</span>, <span style="color: #FF0000;">2</span>, <span style="color: #FF0000;">3</span>, <span style="color: #FF0000;">6</span>, <span style="color: #FF0000;">7</span>, <span style="color: #FF0000;">9</span>, <span style="color: #FF0000;">12</span><span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">foreach</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> x <span style="color: #0600FF; font-weight: bold;">in</span> A<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #008000;">&#40;</span>x <span style="color: #008000;">%</span> <span style="color: #FF0000;">3</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
        A<span style="color: #008000;">.</span><span style="color: #0000FF;">Remove</span><span style="color: #008000;">&#40;</span>x<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</td>
</tr>
</tbody>
</table>
<p>ในบล็อกนี้ขออนุญาตยกตัวอย่างแค่ 2 ภาษา คือ Python และ C# นะครับ สำหรับฝั่ง C# จะเจอกับ &#8220;Unhandled Exception: System.InvalidOperationException: Collection was modified;&#8221; (เขาบอกว่า เกิดการกระทำที่ไม่ถูกต้อง เนื่องจาก list ถูกแก้ไขระหว่างวนลูป) ส่วนคนใช้ Python จะไม่เจอปัญหาอะไรเวลารันครับ แต่พอลองพิมพ์ A ออกมาดูจะพบว่า</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">6</span>, <span style="color: #ff4500;">7</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#93;</span></pre></div></div>

<p>แงว&#8230; ทำไม 6 กับ 12 ยังโผล่ออกมา? ในเมื่อมันน่าจะ mod 3 ลงตัว&#8230; ในบล็อกนี้เราจะมาดูวิธีแก้ปัญหาที่มักจะเจอบ่อยๆ ปัญหานี้กันครับ</p>
<p><span id="more-107"></span>ปัญหาที่เจอใน Python คือ เลขจำนวนเต็มที่หารสามลงตัว ไม่โดนลบออกไปทุกตัว สาเหตุคือ ในการวนลูปบน list python จะมีตัวชี้ index ของ list สร้างขึ้นมา และในการวนลูปแต่ละรอบ index จะต้องโดนขยับไป 1 เสมอ ดังนั้นเมื่อตัวเลขโดนลบไป ตัวเลขอื่นๆ ที่อยู่ต่อท้ายจะเลื่อนมาแทนที่ตัวที่หายไป แล้วตัวที่เลื่อนมาแทนที่เนี่ยแหละครับ จะโดนข้ามไป (ไม่โดนตรวจสอบ)&#8230;. ถ้างง ลองดูตัวอย่างต่อไปนี้ครับ</p>
<table border="0" cellpadding="2">
<tbody>
<tr>
<td width="40%">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: #ff4500;">1</span> <span style="color: #ff4500;">2</span> <span style="color: #ff4500;">3</span> <span style="color: #ff4500;">6</span> <span style="color: #ff4500;">7</span> <span style="color: #ff4500;">9</span> <span style="color: #ff4500;">12</span></pre></div></div>

</td>
<td>พิจารณา A[0] คือ 1 หารสาม ไม่ลงตัว</td>
</tr>
<tr>
<td>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: #ff4500;">1</span> <span style="color: #ff4500;">2</span> <span style="color: #ff4500;">3</span> <span style="color: #ff4500;">6</span> <span style="color: #ff4500;">7</span> <span style="color: #ff4500;">9</span> <span style="color: #ff4500;">12</span></pre></div></div>

</td>
<td>พิจารณา A[1] คือ 2 หารสาม ไม่ลงตัว</td>
</tr>
<tr>
<td>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: #ff4500;">1</span> <span style="color: #ff4500;">2</span> <span style="color: #ff4500;">3</span> <span style="color: #ff4500;">6</span> <span style="color: #ff4500;">7</span> <span style="color: #ff4500;">9</span> <span style="color: #ff4500;">12</span></pre></div></div>

</td>
<td>พิจารณา A[2] คือ 3 หารสามลงตัว ลบทิ้ง!</td>
</tr>
<tr>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">A = <span style="color: #ff4500;">1</span> <span style="color: #ff4500;">2</span> <span style="color: #ff4500;">6</span> <span style="color: #ff4500;">7</span> <span style="color: #ff4500;">9</span> <span style="color: #ff4500;">12</span></pre></div></div>

</td>
<td>list A กลายเป็นแบบนี้ จะเห็นว่า 6 เลื่อนมาอยู่ที่ A[2] แต่ python ก็ยังเลื่อน index ไปหนึ่งช่อง ไปพิจารณา A[3] เลย ทำให้เลข 6 โดนข้ามไป<br />
&#8230;</td>
</tr>
</tbody>
</table>
<p>จะเห็นว่ามีกรณีแบบนี้เกิดขึ้นได้ใน python และคนเขียนโปรแกรมก็ไม่รู้ว่าเกิดปัญหาขึ้นเลย (นอกจากมาดูผลลัพธ์) ดังนั้นใน C# เขาจึงห้ามวนลูปแบบ foreach แล้วแก้ไขข้อมูลใน list (เกิด InvalidOperationException นั่นเอง) ในเมื่อ foreach ใช้ไม่ได้ ขอลักไก่ใช้ for ธรรมดาแทนได้มั้ย? คำตอบคือ ไม่ได้ครับ ถ้าลองเขียนแล้วจะเจอปัญหาเหมือนกับที่เจอใน Python ครับ</p>
<h2>แล้วเราจะแก้ปัญหานี้ยังไงดีหละ?</h2>
<p>แบ่งได้เป็น 3 วิธีที่เจอบ่อยๆ ครับ</p>
<h3>1. สร้าง List อีกอันมาเก็บเฉพาะผลลัพธ์ที่ต้องการ</h3>
<p>วิธีนี้ง่ายๆ ตรงๆ เลยครับ ในเมื่อมี list A แล้วเราต้องการเฉพาะเลขที่หารสามไม่ลงตัว แล้วใช้ list ใหม่เป็นคำตอบ เราก็เขียนโปรแกรมประมาณนี้ได้เลยครับ</p>
<table border="0" width="100%" cellpadding="2">
<tbody>
<tr>
<th width="50%">Python</th>
<th>C#</th>
</tr>
<tr>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">B = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> A:
    <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span> <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #ff4500;">0</span>:
        B.<span style="color: black;">append</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span></pre></div></div>

</td>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">List B <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">foreach</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> x <span style="color: #0600FF; font-weight: bold;">in</span> A<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>x <span style="color: #008000;">%</span> <span style="color: #FF0000;">3</span> <span style="color: #008000;">!=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
	B<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>x<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</td>
</tr>
</tbody>
</table>
<p>อ่าวๆๆแบบนี้ โปรแกรมก็ต้อง copy ตัวเลขทุกตัว ไปใส่ list B แทน ซึ่งมันต้องทำงานช้าแน่ๆ เลย สมมติว่าเราต้องการลบเลขแค่ตัวเดียวใน list A แต่ดันต้อง copy ตัวที่ต้องการเก็บไว้ไปใส่ใน list B ซึ่งเสียเวลาทำงานตั้งนาน (แต่! จะเร็วกว่าวิธีอื่นๆ ถ้ามีตัวเลขที่ต้องโดนลบเยอะๆ ครับ)</p>
<p>งั้นไปดูวิธีที่สองดีกว่า</p>
<h3>2. วนลูปในตัวก๊อบปี้ของ List</h3>
<p>วิธีนี้คือ สร้างตัวก๊อบปี้ของ List (เอาตัวเลขทุกตัว) มาเลยครับ เอามาใช้วนลูป แล้วเวลาลบข้อมูลก็ลบใน list ของจริง ผลลัพธ์ก็จะเก็บอยู่ใน list A ตามปกติ</p>
<table border="0" width="100%" cellpadding="2">
<tbody>
<tr>
<th width="50%">Python</th>
<th>C#</th>
</tr>
<tr>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> A<span style="color: black;">&#91;</span>:<span style="color: black;">&#93;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span> == <span style="color: #ff4500;">0</span>:
        A.<span style="color: black;">remove</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span></pre></div></div>

</td>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">foreach</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> x <span style="color: #0600FF; font-weight: bold;">in</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>A<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>x <span style="color: #008000;">%</span> <span style="color: #FF0000;">3</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
	A<span style="color: #008000;">.</span><span style="color: #0000FF;">Remove</span><span style="color: #008000;">&#40;</span>x<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</td>
</tr>
<tr>
<td><strong>อธิบายเพิ่มเติม:</strong>A[:] คือการสร้างตัวก๊อบปี้ของ list A ครับ</td>
<td><strong>อธิบายเพิ่มเติม:</strong>new List(A) คือการสร้างตัวก๊อบปี้ของ list A ครับ</td>
</tr>
</tbody>
</table>
<p>หลายๆ คนคงจะเห็นว่า มันก็คล้ายๆ กับวิธีที่ 1 แหละน๊า&#8230; แค่สร้างตัวก๊อบปี้ไว้วนลูป ต้องเสียเวลาสร้างตัวก๊อบปี้เหมือนกันไม่ใช่เรอะ?&#8230; ฮึ่ม! งั้นลองไปดูวิธีที่ 3 กันครับ</p>
<h3><strong>3. วนลูปถอยหลัง</strong></h3>
<p>ในเมื่อวนลูปจากหน้าไปหลัง (0 ไปจนถึงขนาดของ list) จะมีปัญหาเพราะว่า ตัวเลขใน list จะเลื่อนมาแทนที่ตัวที่ถูกลบ ดังนั้นเราแก้ปัญหาโดย<strong>วนลูปถอยหลัง</strong> แทนครับ นั่นก็คือ วนลูปจากขนาดของ list มาจนถึง 0 นั่นเอง</p>
<table border="0" width="100%" cellpadding="2">
<tbody>
<tr>
<th width="50%">Python</th>
<th>C#</th>
</tr>
<tr>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>A<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">3</span> == <span style="color: #ff4500;">0</span>:
        <span style="color: #ff7700;font-weight:bold;">del</span> A<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span></pre></div></div>

</td>
<td valign="top">

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">for</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> A<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i<span style="color: #008000;">--</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>A<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #008000;">%</span> <span style="color: #FF0000;">3</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
	A<span style="color: #008000;">.</span><span style="color: #0000FF;">RemoveAt</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</td>
</tr>
</tbody>
</table>
<p>จากตัวอย่างโค้ดจะเห็นว่าเราใช้ del A[i] และ A.RemoveAt(i) เพื่อลบตัวเลข <strong>ที่ตำแหน่งใดๆ</strong> แทนที่จะใช้ Remove ที่ใช้ลบ<strong>ค่าใดๆ</strong> จะเห็นว่าวิธีที่สามนั้นน่าจะทำงานได้เร็วกว่าวิธีที่ 1 และ 2 เพราะไม่ต้องสร้างตัวก๊อบปี้ของ list นั่นเอง</p>
<h2>สรุป</h2>
<p>จากบล็อกนี้เราได้เรียนรู้วิธีแก้ปัญหาที่เกิดขึ้นจากการวนลูป แล้วลบ &#8220;ของ&#8221; ออกจาก list โดยแบ่งออกเป็น 3 วิธีที่เจอบ่อยๆ ซึ่งแต่ละวิธีก็มีประสิทธิภาพแตกต่างกันไปขึ้นกับการนำไปใช้ และความแตกต่างของแต่ละภาษา ใครชอบใครถนัดวิธีไหนก็เลือกไปใช้ตามสะดวก <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>ส่วนตั๊วส่วนตัวจากคนเขียน</h2>
<p>ปล. สาเหตุที่มานั่งเขียน blog นี้เพราะผมเขียนโปรแกรมไปแล้วก็เจอ bug&#8230; คือ &#8220;ของ&#8221; ใน list มันโดนลบออกไปไม่หมด (แต่ python ไม่ยอมเตือนเหมือน C# หง่ะ!!) ก็เลยนั่งหา bug จนมาเจอ&#8230; เอาเป็นว่า เพื่อนๆ คนอื่นที่อ่านมาเจอบล็อกนี้แล้ว คงไม่พลาดแบบผมละกันครับ</p>
<p>ปล2. เพิ่งรู้ว่าใช้ reversed() แล้วโค้ดสวยกว่าเดิมเยอะเลย ปกติเวลาต้องการวนลูปจากมากไปน้อย (9 ถึง 0) ก็เขียนโค้ดน่าเกลียดๆ แบบนี้</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">9</span>, -<span style="color: #ff4500;">1</span>, -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> i</pre></div></div>

<p>พอเขียนบล็อกนี้แล้วเพิ่งรู้ว่าเขียนเป็น</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">9</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> i</pre></div></div>

<p>สวยกว่าเยอะเลย <img src='http://nattster.siamdev.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>ปล3. ใครอยากให้เขียนบล็อก แล้วยกตัวอย่างภาษาอื่นๆ นอกจาก Python และ C# ช่วยทิ้งคอมเม็นท์ไว้ด้วยครับ<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://nattster.siamdev.net/2008/10/iterate-and-remove-item-from-list/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

