<?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>Cholwich's blog &#187; programming</title>
	<atom:link href="http://cholwich.org/wordpress/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://cholwich.org/wordpress</link>
	<description>Just another blog of mine</description>
	<lastBuildDate>Fri, 09 Jul 2010 09:11:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>กรอกคะแนน</title>
		<link>http://cholwich.org/wordpress/2010/07/09/%e0%b8%81%e0%b8%a3%e0%b8%ad%e0%b8%81%e0%b8%84%e0%b8%b0%e0%b9%81%e0%b8%99%e0%b8%99/</link>
		<comments>http://cholwich.org/wordpress/2010/07/09/%e0%b8%81%e0%b8%a3%e0%b8%ad%e0%b8%81%e0%b8%84%e0%b8%b0%e0%b9%81%e0%b8%99%e0%b8%99/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 09:11:23 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[teaching]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[score]]></category>
		<category><![CDATA[teaching. programming]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=404</guid>
		<description><![CDATA[ผมรู้สึกว่าการกรอกคะแนนนักศึกษาเป็นเรื่องยุ่งยาก โดยเฉพาะคะแนนการบ้านกับควิซ ที่เก็บมาแบบไม่ได้เรียงตามลำดับรหัสนักศึกษา ไม่รู้ว่าอาจารย์คนอื่นเขาทำกันยังไง (โดยเฉพาะวิชาที่สอนกัน 200-300 คน) เดิมผมมักจะเอากระดาษมาเรียงตามรหัสนักศึกษา แล้วค่อยไล่กรอกลง spreadsheet แต่มันก็ยุ่งยาก ขี้เกียจอีก ความขี้เกียจนี้ส่งผลให้ผมไม่ค่อยได้คืนควิชหรือการบ้านกลับให้นักศึกษา แล้วก็จะมาหัวหมุนเอาตอนปลายเทอม เพราะต้องกรอกทุกอย่างให้เสร็จก่อนจะตัดเกรด วันก่อนก็เลยเขียนโปรแกรมเล็กๆ เอาไว้กรอกคะแนนควิซโดยเฉพาะ ฟีเจอร์หลักๆ ที่ต้องการก็คือ อยากใส่แค่รหัสนักศึกษาบางส่วน (3-4 ตัวก็พอ) ถ้าไม่ซ้ำก็กรอกคะแนนไปได้เลย ถ้าซ้ำก็แสดงตัวเลือกให้หน่อย แล้วค่อยกรอกคะแนน ตอนแรกก็อยากจะทำเป็น GUI สวยงาม มี textbox ให้กรอกรหัส แล้วจะแสดงตัวเลือกเหมือนพวก autocomplete อะไรทำนองนั้น แต่ก็ดูยุ่งยาก ขี้เกียจอีก (จะเห็นว่าขี้เกียจกันทุกขั้นตอน) แต่สุดท้ายเลยได้โปรแกรม python แบบ command-line มาอันหนึ่ง รับข้อมูลเป็น text file มีแต่รหัสนักศึกษา ใช้ regular expression สำหรับเทียบรหัสกรอกเข้ามา แล้วก็ให้เลือกได้ ถ้ามีรหัสตรงหลายอัน จากนั้นก็กรอกคะแนนลงไปได้ เรียบร้อย ใช้ได้ดี ตามข้างล่างนี้ [...]]]></description>
			<content:encoded><![CDATA[<p>ผมรู้สึกว่าการกรอกคะแนนนักศึกษาเป็นเรื่องยุ่งยาก โดยเฉพาะคะแนนการบ้านกับควิซ ที่เก็บมาแบบไม่ได้เรียงตามลำดับรหัสนักศึกษา ไม่รู้ว่าอาจารย์คนอื่นเขาทำกันยังไง (โดยเฉพาะวิชาที่สอนกัน 200-300 คน) เดิมผมมักจะเอากระดาษมาเรียงตามรหัสนักศึกษา แล้วค่อยไล่กรอกลง spreadsheet แต่มันก็ยุ่งยาก <strong>ขี้เกียจ</strong>อีก</p>
<p>ความ<strong>ขี้เกียจ</strong>นี้ส่งผลให้ผมไม่ค่อยได้คืนควิชหรือการบ้านกลับให้นักศึกษา แล้วก็จะมาหัวหมุนเอาตอนปลายเทอม เพราะต้องกรอกทุกอย่างให้เสร็จก่อนจะตัดเกรด</p>
<p>วันก่อนก็เลยเขียนโปรแกรมเล็กๆ เอาไว้กรอกคะแนนควิซโดยเฉพาะ ฟีเจอร์หลักๆ ที่ต้องการก็คือ อยากใส่แค่รหัสนักศึกษาบางส่วน (3-4 ตัวก็พอ) ถ้าไม่ซ้ำก็กรอกคะแนนไปได้เลย ถ้าซ้ำก็แสดงตัวเลือกให้หน่อย แล้วค่อยกรอกคะแนน ตอนแรกก็อยากจะทำเป็น GUI สวยงาม มี textbox ให้กรอกรหัส แล้วจะแสดงตัวเลือกเหมือนพวก autocomplete อะไรทำนองนั้น แต่ก็ดูยุ่งยาก <strong>ขี้เกียจ</strong>อีก (จะเห็นว่าขี้เกียจกันทุกขั้นตอน) แต่สุดท้ายเลยได้โปรแกรม python แบบ command-line มาอันหนึ่ง รับข้อมูลเป็น text file มีแต่รหัสนักศึกษา ใช้ regular expression สำหรับเทียบรหัสกรอกเข้ามา แล้วก็ให้เลือกได้ ถ้ามีรหัสตรงหลายอัน จากนั้นก็กรอกคะแนนลงไปได้ เรียบร้อย ใช้ได้ดี ตามข้างล่างนี้ (แต่ไม่รับประกันความผิดพลาดถ้าจะเอาไปใช้ เพราะ<strong>ขี้เกียจ</strong>เช็ค input error บางกรณีอีก) โปรดลองใช้กันได้ตามอัตภาพ <img src='http://cholwich.org/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
<span id="more-404"></span></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;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Student:
	<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>,line<span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">line</span> = line.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		l = <span style="color: #008000;">self</span>.<span style="color: black;">line</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = l<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">score</span> = -<span style="color: #ff4500;">1.0</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__str__</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>.<span style="color: #008000;">id</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> saveData<span style="color: black;">&#40;</span>fname,students<span style="color: black;">&#41;</span>:
	f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>fname, <span style="color: #483d8b;">'w'</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> students:
		score = <span style="color: #ff4500;">0</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> i.<span style="color: black;">score</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
			score = i.<span style="color: black;">score</span>
		i.<span style="color: black;">line</span> += <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\t</span>{0}'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>score<span style="color: black;">&#41;</span>
		f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i.<span style="color: black;">line</span><span style="color: black;">&#41;</span>
		f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
	f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> inputUntilMatched<span style="color: black;">&#40;</span>prompt, pattern<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
		s = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span>prompt<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>pattern, s<span style="color: black;">&#41;</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> s
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">1</span>:
	fname = <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><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;">else</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Unknown data file.&quot;</span>
	quit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>fname, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
students = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> f:
	s = Student<span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span>
	students.<span style="color: black;">append</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> students:
	<span style="color: #ff7700;font-weight:bold;">print</span> i
&nbsp;
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
	<span style="color: #dc143c;">cmd</span> = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&gt; '</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">cmd</span>==<span style="color: #483d8b;">'save'</span>:
		saveData<span style="color: black;">&#40;</span>fname, students<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">break</span>
	<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span>==<span style="color: #483d8b;">'quit'</span>:
		<span style="color: #ff7700;font-weight:bold;">break</span>
	pat = <span style="color: #483d8b;">&quot;.*&quot;</span>+<span style="color: #dc143c;">cmd</span>+<span style="color: #483d8b;">&quot;.*&quot;</span>
&nbsp;
	matched = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> s <span style="color: #ff7700;font-weight:bold;">in</span> students:
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>pat, s.<span style="color: #008000;">id</span><span style="color: black;">&#41;</span>:
			matched.<span style="color: black;">append</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
			<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;({0}) {1}&quot;</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>matched<span style="color: black;">&#41;</span>,s<span style="color: black;">&#41;</span>
	count = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>matched<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> count==<span style="color: #ff4500;">0</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Not found&quot;</span>
	<span style="color: #ff7700;font-weight:bold;">else</span>:
		<span style="color: #ff7700;font-weight:bold;">while</span> count<span style="color: #66cc66;">&gt;</span><span style="color: #ff4500;">1</span>:
			schoice = inputUntilMatched<span style="color: black;">&#40;</span><span style="color: #483d8b;">'choice&gt; '</span>, <span style="color: #483d8b;">'[0-9]+'</span><span style="color: black;">&#41;</span>
			choice = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>schoice<span style="color: black;">&#41;</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> choice <span style="color: #66cc66;">&lt;</span>= count:
				student = matched<span style="color: black;">&#91;</span>choice-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
				<span style="color: #ff7700;font-weight:bold;">break</span>
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Unknown choice&quot;</span> 
		<span style="color: #ff7700;font-weight:bold;">if</span> count==<span style="color: #ff4500;">1</span>:
			student = matched<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
		sscore = inputUntilMatched<span style="color: black;">&#40;</span><span style="color: #483d8b;">'score&gt; '</span>, <span style="color: #483d8b;">'[0-9.]+'</span><span style="color: black;">&#41;</span>
		score = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>sscore<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> student.<span style="color: black;">score</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
			<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Replaced!!!&quot;</span>
		student.<span style="color: black;">score</span> = score
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Updated {0} to {1}&quot;</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>student.<span style="color: #008000;">id</span>, student.<span style="color: black;">score</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2010/07/09/%e0%b8%81%e0%b8%a3%e0%b8%ad%e0%b8%81%e0%b8%84%e0%b8%b0%e0%b9%81%e0%b8%99%e0%b8%99/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ลองเล่น Go</title>
		<link>http://cholwich.org/wordpress/2009/11/22/%e0%b8%a5%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%a5%e0%b9%88%e0%b8%99-go/</link>
		<comments>http://cholwich.org/wordpress/2009/11/22/%e0%b8%a5%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%a5%e0%b9%88%e0%b8%99-go/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 14:07:27 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[go]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=349</guid>
		<description><![CDATA[ไม่ได้เขียนอะไรใหม่ๆ ที่นี่มาเกือบครึ่งปี เพราะงานยุ่ง แล้วก็ยังเสพติด twitter และ facebook งอมแงมอีกต่างหาก วันนี้มีเวลาว่าง (จริงๆ ก็ไม่ว่างหรอก แต่ขี้เกียจทำงานที่ควรจะทำ) เลยเอา Go Programming Language ที่พัฒนาโดย Google มาลองเล่นดู เนื่องจากผมใช้ Mac OS X ซึ่งเป็นแพลตฟอร์มที่สนับสนุนอยู่แล้ว ก็เลยติดตั้งไม่ยาก แค่มี XCode อยู่ แล้วลง mercurial เพิ่ม ก็สามารถโหลดซอร์สโค้ดคอมไพเลอร์ของ Go มาคอมไพล์เองได้เลย ใช้เวลาคอมไพล์ตัวคอมไพเลอร์สั้นมาก แป๊บเดียวเสร็จ ประทับใจพอสมควร จากนั้นก็เลยลองเขียนโปรแกรมแบบมั่วๆ (เพราะยังงงกับ syntax อยู่) เพื่อแก้ปัญหา N-Queens แบบง่ายๆ (ใช้ backtracking search ด้วย recursive ดื้อๆ เอานี่แหละ) โดยใช้ Go: package main [...]]]></description>
			<content:encoded><![CDATA[<p>ไม่ได้เขียนอะไรใหม่ๆ ที่นี่มาเกือบครึ่งปี เพราะงานยุ่ง แล้วก็ยังเสพติด <a href="http://twitter.com">twitter</a> และ <a href="http://facebook.com">facebook</a> งอมแงมอีกต่างหาก วันนี้มีเวลาว่าง (จริงๆ ก็ไม่ว่างหรอก แต่ขี้เกียจทำงานที่ควรจะทำ) เลยเอา <a href="http://golang.org">Go Programming Language</a> ที่พัฒนาโดย <a href="http://google.com">Google</a> มาลองเล่นดู เนื่องจากผมใช้ Mac OS X ซึ่งเป็นแพลตฟอร์มที่สนับสนุนอยู่แล้ว ก็เลยติดตั้งไม่ยาก แค่มี XCode อยู่ แล้วลง mercurial เพิ่ม ก็สามารถโหลดซอร์สโค้ดคอมไพเลอร์ของ Go มาคอมไพล์เองได้เลย ใช้เวลาคอมไพล์ตัวคอมไพเลอร์สั้นมาก แป๊บเดียวเสร็จ ประทับใจพอสมควร</p>
<p>จากนั้นก็เลยลองเขียนโปรแกรมแบบมั่วๆ (เพราะยังงงกับ syntax อยู่) เพื่อแก้ปัญหา N-Queens แบบง่ายๆ (ใช้ backtracking search ด้วย recursive ดื้อๆ เอานี่แหละ) โดยใช้ Go:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">package main
&nbsp;
import <span style="color: #ff0000;">&quot;fmt&quot;</span>
&nbsp;
var N <span style="color: #993333;">int</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span>
&nbsp;
func nqueens<span style="color: #009900;">&#40;</span>board <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #993333;">int</span><span style="color: #339933;">,</span> filled <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span> <span style="color: #993333;">int</span> <span style="color: #009900;">&#123;</span>
	var attack bool <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> filled <span style="color: #339933;">==</span> N<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span> i<span style="color: #339933;">:=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>N<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#123;</span>
			fmt.<span style="color: #202020;">Printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">,</span> board<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#125;</span>
		fmt.<span style="color: #202020;">Printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span>
	<span style="color: #009900;">&#125;</span>
	filled <span style="color: #339933;">+=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">for</span> i<span style="color: #339933;">:=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>N<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#123;</span>
		board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
		attack <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span> j<span style="color: #339933;">:=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>filled<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span> <span style="color: #009900;">&#123;</span>
			dy <span style="color: #339933;">:=</span> board<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			dx <span style="color: #339933;">:=</span> j <span style="color: #339933;">-</span> filled<span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> 
			<span style="color: #009900;">&#40;</span>dy<span style="color: #339933;">/</span>dx <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">||</span> dy<span style="color: #339933;">/</span>dx <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>dy<span style="color: #339933;">%</span>dx <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				attack <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">break</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>		
		<span style="color: #b1b100;">if</span> <span style="color: #339933;">!</span>attack <span style="color: #009900;">&#123;</span>
			nqueens<span style="color: #009900;">&#40;</span>board<span style="color: #339933;">,</span> filled<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#125;</span>	
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
func main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	var board <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #993333;">int</span> <span style="color: #339933;">=</span> make<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #993333;">int</span><span style="color: #339933;">,</span> N<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	nqueens<span style="color: #009900;">&#40;</span>board<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>ด้วยความอยากรู้ ก็เลยลองเอาโปรแกรมนี้เอามาแปลงเป็นภาษา C แบบตรงๆ บรรทัดต่อบรรทัด</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include&lt;stdio.h&gt;</span>
<span style="color: #339933;">#include&lt;stdlib.h&gt;</span>
&nbsp;
<span style="color: #993333;">const</span> <span style="color: #993333;">int</span> N<span style="color: #339933;">=</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> nqueens<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> <span style="color: #339933;">*</span>board<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> filled<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> i<span style="color: #339933;">,</span>j<span style="color: #339933;">,</span>attack<span style="color: #339933;">,</span>dy<span style="color: #339933;">,</span>dx<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>filled <span style="color: #339933;">==</span> N<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>N<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">,</span> board<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	filled<span style="color: #339933;">++;</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>N<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
		attack <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>filled<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			dy <span style="color: #339933;">=</span> board<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			dx <span style="color: #339933;">=</span> j <span style="color: #339933;">-</span> filled<span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> board<span style="color: #009900;">&#91;</span>filled<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span>
			<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>dy<span style="color: #339933;">/</span>dx <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">||</span> dy<span style="color: #339933;">/</span>dx <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>dy<span style="color: #339933;">%</span>dx <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				attack <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>attack<span style="color: #009900;">&#41;</span>
			nqueens<span style="color: #009900;">&#40;</span>board<span style="color: #339933;">,</span> filled<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> <span style="color: #339933;">*</span>board <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>malloc<span style="color: #009900;">&#40;</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>N<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	nqueens<span style="color: #009900;">&#40;</span>board<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>เสร็จแล้วก็ลองเขียน Python อีกโปรแกรมหนึ่ง</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> nqueens<span style="color: black;">&#40;</span>board, filled<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">global</span> N
	<span style="color: #ff7700;font-weight:bold;">if</span> filled == N-<span style="color: #ff4500;">1</span>:
		<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> board:
			<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%d<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span> <span style="color: #66cc66;">%</span> board<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>,
		<span style="color: #ff7700;font-weight:bold;">print</span>
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
	filled+=<span style="color: #ff4500;">1</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, N<span style="color: black;">&#41;</span>:
		board<span style="color: black;">&#91;</span>filled<span style="color: black;">&#93;</span> = i
		attack = <span style="color: #008000;">False</span>
		<span style="color: #ff7700;font-weight:bold;">for</span> j <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, filled<span style="color: black;">&#41;</span>:
			dy = board<span style="color: black;">&#91;</span>j<span style="color: black;">&#93;</span>-board<span style="color: black;">&#91;</span>filled<span style="color: black;">&#93;</span>
			dx = j - filled
			<span style="color: #ff7700;font-weight:bold;">if</span> board<span style="color: black;">&#91;</span>j<span style="color: black;">&#93;</span> == board<span style="color: black;">&#91;</span>filled<span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>dy/dx == <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">or</span> dy/dx == -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> dy<span style="color: #66cc66;">%</span>dx==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
				attack = <span style="color: #008000;">True</span>
				<span style="color: #ff7700;font-weight:bold;">break</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> attack:
			nqueens<span style="color: black;">&#40;</span>board, filled<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
N=<span style="color: #ff4500;">10</span>
board = <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">*</span>N
nqueens<span style="color: black;">&#40;</span>board, -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></div></div>

<p>ทดลองรัน (ด้วย N=10) แล้วจับเวลาง่ายๆ ด้วย time ก็จะได้ผลเป็น</p>
<table>
<tr>
<th></th>
<th>Go</th>
<th>C</th>
<th>Python</th>
</tr>
<tr>
<th>real</th>
<td>0m0.165s</td>
<td>0m0.041s</td>
<td>0m1.048s</td>
</tr>
<tr>
<th>user</th>
<td>0m0.116s</td>
<td>0m0.029s</td>
<td>0m1.028s</td>
</tr>
<tr>
<th>sys</th>
<td>0m0.040s</td>
<td>0m0.002s</td>
<td>0m0.015s</td>
</tr>
</table>
<p>ประสิทธิภาพแบบคร่าวๆ ก็ถือว่าใช้ได้ทีเดียว ไม่ได้แย่กว่า C นัก แต่ไม่รู้ว่าผมชินกับภาษา C มากเกินไปหรือเปล่า ทำให้ผมรู้สึกแปลกๆ งงๆ กับ syntax ของ Go มันดูไม่ค่อยสวยงามยังไงไม่รู้ บอกไม่ถูก เหมือนแค่เอา C มาตัดบางส่วนออก เพราะกลัวจะพิมพ์เยอะเกินไป มันเลยดูขัดๆ อีกอย่าง Go ก็ไม่ได้เขียนสั้นๆ ง่ายๆ ได้เหมือน Python ผมว่าโครงสร้าง syntax ของ C กับ Python สวยงามกว่าเยอะ แต่ผมก็ยังไม่ลอง concurrent programming ที่เป็นจุดขายของ Go เหมือนกัน เอาไว้หนีงานมาลองใหม่คราวหน้าละกัน</p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2009/11/22/%e0%b8%a5%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%a5%e0%b9%88%e0%b8%99-go/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mail Merge ด้วย Python</title>
		<link>http://cholwich.org/wordpress/2009/04/22/mail-merge-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-python/</link>
		<comments>http://cholwich.org/wordpress/2009/04/22/mail-merge-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-python/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 12:03:22 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=286</guid>
		<description><![CDATA[หลังจากถูกถล่มด้วยงานต่างๆ ทำให้ไม่ได้มาเขียนสองเดือนกว่าๆ พอดีช่วงนี้ช่วยจัดงาน PAKDD2009 อยู่ และมีงานที่เกี่ยวข้องที่ต้องใช้สคริปต์ เลยเอามาจดไว้ที่นี่หน่อยกันลืม เรื่องของเรื่องก็คือผมต้องการส่งอีเมลไปยังคนหลายๆ คน โดยมีเนื้อหาที่แตกต่างกันเล็กน้อย ผมเลยเริ่มจากเปิด OpenOffice.org Spreadsheet ขึ้นมาเขียนข้อมูลต่างๆ ที่ต้องการแปะลงไปในจดหมาย แล้วเก็บเป็นไฟล์ CSV (Comma-Separated Value) ที่เป็นสำหรับเก็บข้อมูลแบบง่ายที่สุด แต่ละบรรทัดแทนข้อมูลแต่ละเรคอร์ด และใช้เครื่องหมาย &#8220;,&#8221; คั่นระหว่างข้อมูลแต่ละฟิลด์ จากนั้นก็เขียนสคริปต์ Python เพื่ออ่านข้อมูลจากไฟล์ CSV ที่ทำไว้ เอาไปแปะในเทมเพลตที่เตรียมไว้ โดย Python จะมีคลาสสำหรับอ่านเขียนไฟล์ CSV เป็นคลาสมาตรฐานอยู่แล้ว ก็เลยสามารถทำงานได้สะดวกมาก วิธีใช้คลาส csv เพื่ออ่านข้อมูล จะทำอย่างนี้ import csv data = csv.reader&#40;open&#40;'myfile.csv'&#41;, delimiter=',', quotechar='&#34;'&#41; for row in data: print row&#91;0&#93; csv.reader เป็นคลาสสำหรับจัดการอ่านข้อมูลแบบ [...]]]></description>
			<content:encoded><![CDATA[<p>หลังจากถูกถล่มด้วยงานต่างๆ ทำให้ไม่ได้มาเขียนสองเดือนกว่าๆ พอดีช่วงนี้ช่วยจัดงาน <a href="http://www.pakdd2009.org">PAKDD2009</a> อยู่ และมีงานที่เกี่ยวข้องที่ต้องใช้สคริปต์ เลยเอามาจดไว้ที่นี่หน่อยกันลืม</p>
<p>เรื่องของเรื่องก็คือผมต้องการส่งอีเมลไปยังคนหลายๆ คน โดยมีเนื้อหาที่แตกต่างกันเล็กน้อย ผมเลยเริ่มจากเปิด OpenOffice.org Spreadsheet ขึ้นมาเขียนข้อมูลต่างๆ ที่ต้องการแปะลงไปในจดหมาย แล้วเก็บเป็นไฟล์ CSV (Comma-Separated Value) ที่เป็นสำหรับเก็บข้อมูลแบบง่ายที่สุด แต่ละบรรทัดแทนข้อมูลแต่ละเรคอร์ด และใช้เครื่องหมาย &#8220;,&#8221; คั่นระหว่างข้อมูลแต่ละฟิลด์ จากนั้นก็เขียนสคริปต์ Python เพื่ออ่านข้อมูลจากไฟล์ CSV ที่ทำไว้ เอาไปแปะในเทมเพลตที่เตรียมไว้ โดย Python จะมีคลาสสำหรับอ่านเขียนไฟล์ CSV เป็นคลาสมาตรฐานอยู่แล้ว ก็เลยสามารถทำงานได้สะดวกมาก</p>
<p>วิธีใช้คลาส csv เพื่ออ่านข้อมูล จะทำอย่างนี้</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;">csv</span>
data = <span style="color: #dc143c;">csv</span>.<span style="color: black;">reader</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myfile.csv'</span><span style="color: black;">&#41;</span>, delimiter=<span style="color: #483d8b;">','</span>, quotechar=<span style="color: #483d8b;">'&quot;'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> data:
	<span style="color: #ff7700;font-weight:bold;">print</span> row<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span></pre></div></div>

<p>csv.reader เป็นคลาสสำหรับจัดการอ่านข้อมูลแบบ CSV รับอาร์กิวเมนต์เป็นไฟล์ เครื่องหมายที่ใช้คั่นระหว่างฟิลด์ และเครื่องหมายที่ใช้เป็น quote ครอบข้อมูลแต่ละฟิลด์ เมื่อสร้างออพเจคต์ของ csv.reader ขึ้นมาแล้ว ก็สามารถวนรอบเพื่ออ่านไฟล์ขึ้นมาทีละเรคอร์ดได้เลย โดยข้อมูลที่อ่านขึ้นมาจะเก็บไว้ในรูปอาเรย์ อย่างกรณีนี้ row[0] ก็คือข้อมูลในฟิลด์แรกสุด</p>
<p>หลังจากนี้เราก็ต้องเตรียมเทมเพลต ซึ่งก็คือกำหนดตัวแปรสตริงเท่านั้นเอง เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">template = <span style="color: #483d8b;">&quot;&quot;&quot;
Dear {r[0]},
&nbsp;
I would like to send you the following information:
&nbsp;
{r[1]}
&nbsp;
Best Regards,
Cholwich
&quot;&quot;&quot;</span></pre></div></div>

<p>จะเห็นว่าสตริงนี้มีสัญลักษณ์พิเศษ ระบุข้อมูลที่เราต้องการจะเอาไปแทรก {r[0]} หมายถึงสมาชิกตัวแรกของตัวแปร r ที่ส่งมาเป็นพารามิเตอร์ อันนี้เป็นฟีเจอร์ String Formatting ของ Python อยู่แล้ว เมื่อกำหนดเทมเพลตเสร็จ สั่งให้ Python แทรกข้อมูลโดย</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">output = template.<span style="color: black;">format</span><span style="color: black;">&#40;</span>r=row<span style="color: black;">&#41;</span></pre></div></div>

<p>จะได้ผลลัพธ์ที่ผสานข้อมูลเข้าไปแล้ว เป็นสตริงเก็บไว้ที่ตัวแปรชื่อ output จากนั้นผมก็สามารถเอาไปส่งเมล์ หรือเอาไปเขียนลงไฟล์เก็บไว้ได้ พอเอาทั้งหมดมารวมกันก็จะได้</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;">csv</span>
&nbsp;
template = <span style="color: #483d8b;">&quot;&quot;&quot;
Dear {r[0]},
&nbsp;
I would like to send you the following information:
&nbsp;
{r[1]}
&nbsp;
Best Regards,
Cholwich.
&quot;&quot;&quot;</span>
data = <span style="color: #dc143c;">csv</span>.<span style="color: black;">reader</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myfile.csv'</span><span style="color: black;">&#41;</span>, delimiter=<span style="color: #483d8b;">','</span>, quotechar=<span style="color: #483d8b;">'&quot;'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> data:
	output = template.<span style="color: black;">format</span><span style="color: black;">&#40;</span>r=row<span style="color: black;">&#41;</span>
	f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>row<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
	f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>output<span style="color: black;">&#41;</span>
	f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>สุดท้ายก็จะได้สคริปต์ง่ายๆ สำหรับทำ mail merge ที่ได้ output เป็นไฟล์แยกกัน โดยระบุชื่อไฟล์ไว้ที่ row[2]</p>
<p>อ้างอิง:</p>
<ol>
<li><a href="http://docs.python.org/whatsnew/2.6.html#pep-3101-advanced-string-formatting">PEP 3103: Advanced String Formatting</a></li>
<li><a href="http://docs.python.org/library/csv.html">Python csv &mdash; CSV File Reading and Writing</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2009/04/22/mail-merge-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Student Randomizer</title>
		<link>http://cholwich.org/wordpress/2008/12/02/student-randomizer/</link>
		<comments>http://cholwich.org/wordpress/2008/12/02/student-randomizer/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 16:31:20 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[teaching]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=141</guid>
		<description><![CDATA[ด้วยความที่อยากให้นักศึกษามีส่วนร่วมในการเรียนมากขึ้น เทอมนี้เลยพยายามเรียกนักศึกษาให้ช่วยตอบคำถาม หรือออกมาทำอะไรเล่นหน้าห้อง อย่างน้อยจะได้หลับกันน้อยลง หรือพยายามทำแบบฝึกหัดที่ให้ในห้องเรียนบ้าง แต่จะให้เลือกชื่อก็จำชื่อนักศึกษาทั้งหมดไม่ได้ แถมอาจจะเรียกบางคนซ้ำ หรือไม่ได้เรียกบางคนเลย เมื่อวานพอมีเวลาว่างอยู่บ้าง เลยนั่งเขียนโปรแกรม Java เล็กๆ ขึ้นมาหนึ่งตัว เอาไว้สำหรับสุ่มชื่อนักศึกษาในชั้นเรียน ตอนแรกก็กะจะทำเป็นโปรแกรมง่ายๆ คือแค่เปิดไฟล์อ่านชื่อนักศึกษามา แล้วก็แค่สุ่ม แต่ถ้าทำอย่างนั้นก็มีโอกาสที่บางคนจะโดนซ้ำ หรือสุ่มไม่ทั่วถึง เพื่อเผื่อแผ่ให้ทุกคนถูกเรียกกันอย่างทั่วถึง เลยปรับการสุ่มนิดหน่อย โดยเก็บจำนวนครั้งที่นักศึกษาแต่ละคนถูกเรียกไว้ ถ้าโดนเรียกแล้วหนึ่งครั้ง ก็จะกำหนดโอกาสที่จะถูกสุ่มขึ้นมาอีกให้เป็น 1/2 ของเพื่อนที่ยังไม่เคยโดนเรียก ถ้าโดนสองครั้งก็จะลดไปอีกให้เหลือ 1/4 ของเพื่อนๆ คือให้เป็น 1/(2^n) เมื่อ n เป็นจำนวนครั้งที่ถูกเรียก เสร็จแล้วก็มานึกอีกว่าบางคนอาจจะโดนเรียกแล้วไม่อยู่ อย่ากระนั้นเลยจะต้องเก็บข้อมูลไว้หน่อยว่าคนนี้โดดเรียน เลยทำปุ่มให้กดได้ด้วยว่าโดดไปแล้วกี่ครั้ง (ไม่รู้เก็บไว้ทำไมเหมือนกัน) สุดท้ายได้โปรแกรมออกมาหน้าตาแบบนี้ ถ้าใครสนใจลองโหลดไปเล่นได้ที่นี่ วิธีใช้ก็คือเตรียม text file ใส่ชื่อนักศึกษาบรรทัดละคน เขียน ID ก่อน แล้วค่อยตามด้วยชื่อ คั่นด้วย TAB อาจจะใส่จำนวนครั้งที่เรียกนักศึกษาไปแล้วด้วยก็ได้ คั่นด้วย TAB เหมือนกัน ส่วนโค้ด [...]]]></description>
			<content:encoded><![CDATA[<p>ด้วยความที่อยากให้นักศึกษามีส่วนร่วมในการเรียนมากขึ้น เทอมนี้เลยพยายามเรียกนักศึกษาให้ช่วยตอบคำถาม หรือออกมาทำอะไรเล่นหน้าห้อง อย่างน้อยจะได้หลับกันน้อยลง หรือพยายามทำแบบฝึกหัดที่ให้ในห้องเรียนบ้าง แต่จะให้เลือกชื่อก็จำชื่อนักศึกษาทั้งหมดไม่ได้ แถมอาจจะเรียกบางคนซ้ำ หรือไม่ได้เรียกบางคนเลย เมื่อวานพอมีเวลาว่างอยู่บ้าง เลยนั่งเขียนโปรแกรม Java เล็กๆ ขึ้นมาหนึ่งตัว เอาไว้สำหรับสุ่มชื่อนักศึกษาในชั้นเรียน ตอนแรกก็กะจะทำเป็นโปรแกรมง่ายๆ คือแค่เปิดไฟล์อ่านชื่อนักศึกษามา แล้วก็แค่สุ่ม แต่ถ้าทำอย่างนั้นก็มีโอกาสที่บางคนจะโดนซ้ำ หรือสุ่มไม่ทั่วถึง</p>
<p>เพื่อเผื่อแผ่ให้ทุกคนถูกเรียกกันอย่างทั่วถึง เลยปรับการสุ่มนิดหน่อย โดยเก็บจำนวนครั้งที่นักศึกษาแต่ละคนถูกเรียกไว้ ถ้าโดนเรียกแล้วหนึ่งครั้ง ก็จะกำหนดโอกาสที่จะถูกสุ่มขึ้นมาอีกให้เป็น 1/2 ของเพื่อนที่ยังไม่เคยโดนเรียก ถ้าโดนสองครั้งก็จะลดไปอีกให้เหลือ 1/4 ของเพื่อนๆ คือให้เป็น 1/(2^n) เมื่อ n เป็นจำนวนครั้งที่ถูกเรียก เสร็จแล้วก็มานึกอีกว่าบางคนอาจจะโดนเรียกแล้วไม่อยู่ อย่ากระนั้นเลยจะต้องเก็บข้อมูลไว้หน่อยว่าคนนี้โดดเรียน เลยทำปุ่มให้กดได้ด้วยว่าโดดไปแล้วกี่ครั้ง (ไม่รู้เก็บไว้ทำไมเหมือนกัน)</p>
<p>สุดท้ายได้โปรแกรมออกมาหน้าตาแบบนี้</p>
<p><a href="http://cholwich.org/wordpress/wp-content/uploads/2008/12/stdrnd.png"><img class="aligncenter size-medium wp-image-142" title="Student Randomizer" src="http://cholwich.org/wordpress/wp-content/uploads/2008/12/stdrnd-300x112.png" alt="" width="300" height="112" /></a></p>
<p>ถ้าใครสนใจลองโหลดไปเล่นได้<a href="http://cholwich.org/programs/StudentRandomizer.jar">ที่นี่</a> วิธีใช้ก็คือเตรียม text file ใส่ชื่อนักศึกษาบรรทัดละคน เขียน ID ก่อน แล้วค่อยตามด้วยชื่อ คั่นด้วย TAB อาจจะใส่จำนวนครั้งที่เรียกนักศึกษาไปแล้วด้วยก็ได้ คั่นด้วย TAB เหมือนกัน</p>
<p>ส่วนโค้ด ถ้าใครอยากได้ก็ขอมาล่ะกันครับ มันค่อนข้างเละเทะ ไม่อยากเผย อายครับ <img src='http://cholwich.org/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  ถ้ามีเวลาบ้าอีก ก็อาจจะเพิ่มฟีเจอร์อื่นๆ ไปด้วย</p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2008/12/02/student-randomizer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Screen, NoHUP, SIGHUP</title>
		<link>http://cholwich.org/wordpress/2008/08/07/screen-nohup-sighup/</link>
		<comments>http://cholwich.org/wordpress/2008/08/07/screen-nohup-sighup/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 13:47:35 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nohup]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[sighup]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=112</guid>
		<description><![CDATA[ในระบบเชลล์ของยูนิกซ์เวลาที่เราต้องการจะสั่งให้โปรแกรมทำงานแบบแบ็คกราวน์ จะทำโดยเรียกโปรแกรมนั้นพร้อมกับระบุเครื่องหมาย &#38; ต่อท้าย เช่น $ firefox &#38; แต่เราจะพบปัญหาเวลาที่ต้องการให้โปรแกรมที่สั่งให้ทำงานแบบแบ็คกราวน์นั้นทำงานต่อไปแม้ว่าเราจะออกจากระบบไปแล้ว เนื่องจากเวลาเราออกจากระบบ (logout) จะมีการส่งสัญญาณ SIGHUP (hangup) ไปยังโปรเซสทั้งหมดของเราที่กำลังทำงานอยู่ ซึ่งพฤติกรรมโดยปกติของโปรเซสเมื่อได้รับสัญญาณก็คือ หยุดการทำงานแบบไม่ปกติ (abnormal termination) จึงทำให้โปรแกรมที่เราหมายมั่นปั้นมือว่าจะให้ทำงานไปตลอดคืนนี้ หยุดทำงานไปโดยไม่รู้ตัว (กว่าจะรู้อีกทีก็อาจจะเช้าแล้ว ต้องเสียเวลารออีก) วิธีการแก้ปัญหานี้มีหลายวิธี วิธีที่ยุ่งยากหน่อยก็คือแก้โปรแกรมโดยเรียกใช้ system call เพื่อดัก SIGHUP ไว้ โปรแกรมของเราจะได้ไม่ทำตามพฤติกรรมปกติซึ่งก็ดูจะยุ่งยากไปหน่อย และไม่สามารถใช้กับโปรแกรมที่ไม่เปิดเผยโค้ดได้ อีกวิธีหนึ่งก็คือการใช้โปรแกรม nohup ซึ่งจะทำตัวเป็นเหมือนเชลล์ห่อโปรแกรมของเราไว้อีกชั้นหนึ่ง โดยจะดักสัญญาณ SIGHUP ไว้ ทำให้โปรแกรมทำงานต่อไปหลังจากออกจากระบบ เช่น $ nohup myprogram &#38; แต่ข้อเสียของโปรแกรม nohup ก็คือแม้ว่าเราจะกลับเข้ามาในระบบใหม่ เราก็จะไม่สามารถติดต่อหรือดูผลการทำงานของโปรแกรมได้ ผลลัพธ์ทั้งหมดจะต้องเก็บลงไฟล์ไว้ก่อนเท่านั้น ทำให้ไม่สะดวกเท่าที่ควร screen เป็นโปรแกรมบนยูนิกซ์อีกโปรแกรมหนึ่งที่ช่วยอำนวยความสะดวกในการรันโปรแกรมแบบนี้ $ screen myprogram [...]]]></description>
			<content:encoded><![CDATA[<p>ในระบบเชลล์ของยูนิกซ์เวลาที่เราต้องการจะสั่งให้โปรแกรมทำงานแบบแบ็คกราวน์ จะทำโดยเรียกโปรแกรมนั้นพร้อมกับระบุเครื่องหมาย &amp;<br />
ต่อท้าย เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ firefox <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>แต่เราจะพบปัญหาเวลาที่ต้องการให้โปรแกรมที่สั่งให้ทำงานแบบแบ็คกราวน์นั้นทำงานต่อไปแม้ว่าเราจะออกจากระบบไปแล้ว เนื่องจากเวลาเราออกจากระบบ (logout) จะมีการส่งสัญญาณ SIGHUP (hangup) ไปยังโปรเซสทั้งหมดของเราที่กำลังทำงานอยู่ ซึ่งพฤติกรรมโดยปกติของโปรเซสเมื่อได้รับสัญญาณก็คือ หยุดการทำงานแบบไม่ปกติ (abnormal termination) จึงทำให้โปรแกรมที่เราหมายมั่นปั้นมือว่าจะให้ทำงานไปตลอดคืนนี้ หยุดทำงานไปโดยไม่รู้ตัว (กว่าจะรู้อีกทีก็อาจจะเช้าแล้ว ต้องเสียเวลารออีก) </p>
<p>วิธีการแก้ปัญหานี้มีหลายวิธี วิธีที่ยุ่งยากหน่อยก็คือแก้โปรแกรมโดยเรียกใช้ system call เพื่อดัก SIGHUP ไว้ โปรแกรมของเราจะได้ไม่ทำตามพฤติกรรมปกติซึ่งก็ดูจะยุ่งยากไปหน่อย และไม่สามารถใช้กับโปรแกรมที่ไม่เปิดเผยโค้ดได้ อีกวิธีหนึ่งก็คือการใช้โปรแกรม nohup ซึ่งจะทำตัวเป็นเหมือนเชลล์ห่อโปรแกรมของเราไว้อีกชั้นหนึ่ง โดยจะดักสัญญาณ SIGHUP ไว้ ทำให้โปรแกรมทำงานต่อไปหลังจากออกจากระบบ เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nohup</span> myprogram <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>แต่ข้อเสียของโปรแกรม nohup ก็คือแม้ว่าเราจะกลับเข้ามาในระบบใหม่ เราก็จะไม่สามารถติดต่อหรือดูผลการทำงานของโปรแกรมได้ ผลลัพธ์ทั้งหมดจะต้องเก็บลงไฟล์ไว้ก่อนเท่านั้น ทำให้ไม่สะดวกเท่าที่ควร</p>
<p>screen เป็นโปรแกรมบนยูนิกซ์อีกโปรแกรมหนึ่งที่ช่วยอำนวยความสะดวกในการรันโปรแกรมแบบนี้</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">screen</span> myprogram</pre></div></div>

<p>screen จะทำงานคล้าย nohup เพียงแต่ว่าเมื่อเริ่มทำงาน screen จะทำให้ดูเหมือนว่าโปรแกรมของเราทำงานเป็นแบบฟอร์กราวน์ตามปกติทั่วไป เราสามารถสั่งให้ทำงานเบื้องหลังได้ โดยกด CTRL-A CTRL-D ต่อกัน โปรแกรมก็จะไม่เชื่อมต่อกับเทอร์มินัล แต่จะทำงานในแบบแบ็คกราวน์ แต่เราสามารถกำหนดให้ screen เรียกโปรแกรมของเราที่ทำงานอยู่ให้กลับมาอยู่เบื้องหน้าอีกครั้งได้ แม้ว่าเราจะออกจากระบบไป และกลับมาใหม่แล้วก็ตาม</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-r</span></pre></div></div>

<p>ในกรณีที่เรียกใช้ screen พร้อมกันหลายๆ โปรเซส ก็อาจจะต้องระบุรหัสโปรเซสที่ต้องการเรียกกลับมาบนเทอร์มินัล โดยอาจจะใช้ออปชัน -ls เพื่อแสดงโปรเซสของ screen ทั้งหมดก็ได้ นอกจากนี้ screen ยังมีออปชันให้เกิดสิ่งที่เป็นผลลัพธ์ทั้งหมดลงไฟล์ไว้ให้ด้วยก็ได้ ทำให้สะดวกในการเรียกดูผลลัพธ์ภายหลัง ผมเองก็ต้องพึ่งโปรแกรม screen เยอะเลยทีเดียวกว่าจะเรียนจบมาได้</p>
<p>รายละเอียดเพิ่มเติม: <a href="http://www.gnu.org/software/screen/">http://www.gnu.org/software/screen/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2008/08/07/screen-nohup-sighup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby กับ Prolog</title>
		<link>http://cholwich.org/wordpress/2008/04/10/ruby-%e0%b8%81%e0%b8%b1%e0%b8%9a-prolog/</link>
		<comments>http://cholwich.org/wordpress/2008/04/10/ruby-%e0%b8%81%e0%b8%b1%e0%b8%9a-prolog/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 13:07:34 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[prolog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=52</guid>
		<description><![CDATA[ช่วงนี้ได้อ่านหนังสือ &#8220;The Ruby Programming Language&#8221; ทำให้มีโอกาสได้รู้เทคนิค หรือฟีเจอร์ของภาษา Ruby หลายอย่าง แม้ว่าจะใช้ Ruby มาตั้งแต่สมัยอยู่ญี่ปุ่น แต่ยังไม่เคยมีโอกาสอ่านหนังสือจริงๆ จังๆ ส่วนใหญ่ก็ใช้ไปแบบงูๆ ปลาๆ เหตุผลเดียวที่ใช้ก็คือรู้สึกว่า syntax ค่อนข้างคงที่ไม่กำกวม แถมยังเป็น OOP ทำให้ง่ายต่อการทำงานบางอย่าง วันนี้เพิ่งอ่านเจอว่าเราสามารถเขียน method ที่รับอาร์กิวเมนต์จำนวนไม่คงที่ได้ โดยใช้วิธีการกำหนดพารามิเตอร์เพิ่มหนึ่งตัว นอกเหนือจากพารามิเตอร์ปกติ และให้ใส่เครื่องหมาย * ไว้ข้างหน้าพารามิเตอร์ตัวนั้น เช่น def min&#40;first, *rest&#41; min=first rest.each &#123;&#124;x&#124; min=x if x&#60;min&#125; return min end method นี้จะหาค่าต่ำที่สุดของอาร์กิวเมนต์ทั้งหมดที่รับมา เช่น &#62;&#62; min&#40;4,2,1,5&#41; =&#62; 1 โดย first เป็นพารามิเตอร์หลัก หมายความว่าจะต้องรับข้อมูลมาอย่างน้อยหนึ่งตัว ส่วน [...]]]></description>
			<content:encoded><![CDATA[<p>ช่วงนี้ได้อ่านหนังสือ &#8220;The Ruby Programming Language&#8221; ทำให้มีโอกาสได้รู้เทคนิค หรือฟีเจอร์ของภาษา Ruby หลายอย่าง แม้ว่าจะใช้ Ruby มาตั้งแต่สมัยอยู่ญี่ปุ่น แต่ยังไม่เคยมีโอกาสอ่านหนังสือจริงๆ จังๆ ส่วนใหญ่ก็ใช้ไปแบบงูๆ ปลาๆ เหตุผลเดียวที่ใช้ก็คือรู้สึกว่า syntax ค่อนข้างคงที่ไม่กำกวม แถมยังเป็น OOP ทำให้ง่ายต่อการทำงานบางอย่าง วันนี้เพิ่งอ่านเจอว่าเราสามารถเขียน method ที่รับอาร์กิวเมนต์จำนวนไม่คงที่ได้ โดยใช้วิธีการกำหนดพารามิเตอร์เพิ่มหนึ่งตัว นอกเหนือจากพารามิเตอร์ปกติ และให้ใส่เครื่องหมาย <code>*</code> ไว้ข้างหน้าพารามิเตอร์ตัวนั้น เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> min<span style="color:#006600; font-weight:bold;">&#40;</span>first, <span style="color:#006600; font-weight:bold;">*</span>rest<span style="color:#006600; font-weight:bold;">&#41;</span> 
  min=first
  rest.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>x<span style="color:#006600; font-weight:bold;">|</span> min=x <span style="color:#9966CC; font-weight:bold;">if</span> x<span style="color:#006600; font-weight:bold;">&lt;</span>min<span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> min
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>method นี้จะหาค่าต่ำที่สุดของอาร์กิวเมนต์ทั้งหมดที่รับมา เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> min<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">4</span>,<span style="color:#006666;">2</span>,<span style="color:#006666;">1</span>,<span style="color:#006666;">5</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1</span></pre></div></div>

<p>โดย first เป็นพารามิเตอร์หลัก หมายความว่าจะต้องรับข้อมูลมาอย่างน้อยหนึ่งตัว ส่วน rest เป็นพารามิเตอร์สำหรับค่าอื่นๆ ที่เหลือ ในที่นี้เมื่ออ้างถึง rest จะเป็นอะเรย์เก็บค่าต่างๆ ที่ได้รับมา ดังนั้นจึงสามารถใช้ rest.each ในการอ้างถึงสมาชิกแต่ละตัว แล้วเปรียบเทียบหาค่าต่ำที่สุดได้ </p>
<p>ลองดูฟีเจอร์นี้ของ Ruby แล้ว ก็รู้สึกว่าไม่ต่างจากรูปแบบลิสต์ <code>[head|tail]</code> ของ Prolog คือลิสต์ถูกแบ่งเป็นสองส่วน ได้แก่ ส่วนหัว กับส่วนที่เหลือ (ตรงนี้จะต่างจากภาษา C ที่ใช้วิธีกำหนดทั้งหมดไว้ในอะเรย์ แล้วระบุจำนวนอาร์กิวเมนต์มาให้) เลยอยากจะลองเขียน method reverse สำหรับสลับลำดับข้อมูลในลิสต์เรียงกลับจากลำดับเดิม โดยใช้วิธี recursive แบบ Prolog ดู</p>

<div class="wp_syntax"><div class="code"><pre class="prolog" style="font-family:monospace;">reverse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>
reverse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #008080;">H</span><span style="color: #339933;">|</span><span style="color: #008080;">T</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #008080;">R</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:-</span> reverse<span style="color: #009900;">&#40;</span><span style="color: #008080;">T</span><span style="color: #339933;">,</span><span style="color: #008080;">TR</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> append<span style="color: #009900;">&#40;</span><span style="color: #008080;">T</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #008080;">H</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #008080;">R</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> reverse<span style="color:#006600; font-weight:bold;">&#40;</span>first, <span style="color:#006600; font-weight:bold;">*</span>rest<span style="color:#006600; font-weight:bold;">&#41;</span> 
  <span style="color:#9966CC; font-weight:bold;">if</span> rest.<span style="color:#9900CC;">empty</span>?
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#006600; font-weight:bold;">&#91;</span>first<span style="color:#006600; font-weight:bold;">&#93;</span> 
  <span style="color:#9966CC; font-weight:bold;">else</span> 
    <span style="color:#0000FF; font-weight:bold;">return</span> reverse<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>rest<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> first
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>ลองเทียบกันดูในแง่ความหมาย จะเห็นว่่าเหมือนกันเป๊ะๆ แถมยังใช้เครื่องหมายคล้ายๆ กันอีก จุดที่แตกต่างที่สุดก็เห็นจะอยู่ที่ลักษณะของ reverse ใน Ruby เป็นฟังก์ชันมีการส่งค่ากลับ ส่วน reverse ของ Prolog เป็น predicate แสดงความสัมพันธ์ระหว่าง list สองอัน </p>
<p>เป็นอันสิ้นสุดการทดลองของวันนี้แต่เพียงเท่านี้ </p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2008/04/10/ruby-%e0%b8%81%e0%b8%b1%e0%b8%9a-prolog/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Grails</title>
		<link>http://cholwich.org/wordpress/2007/12/07/grails/</link>
		<comments>http://cholwich.org/wordpress/2007/12/07/grails/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 08:24:58 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/2007/12/07/grails/</guid>
		<description><![CDATA[วันก่อนเห็นบลอคของอาทเขียนเรื่องเกี่ยวกับ Netbeans 6.0 กับ Grails เลยลองไปนั่งอ่านดู Grails ก็เป็นกรอบสำหรับพัฒนาเว็บแอพพลิเคชันที่อิงมาจาก Ruby on Rails แต่ใช้ภาษา Groovy เป็นหลัก และทำงานบน Java Virtual Machine ลองอ่านหนังสือแนะนำการพัฒนาเว็บโดยใช้ Grails ดูแล้ว ก็ไม่ต่างจาก RoR  หรือกรอบงานแบบเดียวกัน เช่น CakePHP แต่จุดเด่นของ Grails น่าจะอยู่ที่การใช้ JVM ให้สามารถใช้เครื่องมือ รวมทั้งไลบรารีต่างๆ ที่สร้างสำหรับ Java EE ได้เลย มีเครื่องมือให้ใช้เยอะพอดู น่าลองใช้ ที่ดูๆ อยู่เนื่องจากปี (การศึกษา) ที่แล้วพัฒนาระบบเก็บข้อมูลภายในสำหรับสถาบันฯ ด้วย CakePHP เว็บที่ทำขึ้นยังค่อนข้างสกปรกอยู่ ปีนี้อาจจะต้องปรับปรุงหรือพัฒนาเพิ่มเติม ถ้าเปลี่ยนมาใช้ Grails แล้วสะดวกขึ้น หรือสามารถหาคนมาช่วยพัฒนาแทนได้ ไม่จำเป็นต้องทำเองทั้งหมด ก็น่าสนใจ ดูคร่าวๆ แล้ว เห็นว่า [...]]]></description>
			<content:encoded><![CDATA[<p>วันก่อนเห็น<a href="http://bact.blogspot.com/2007/12/netbeans-60-groovy-plug-in.html">บลอคของอาท</a>เขียนเรื่องเกี่ยวกับ <a href="http://www.netbeans.org">Netbeans 6.0</a> กับ <a href="http://grails.codehaus.org/">Grails</a> เลยลองไปนั่งอ่านดู Grails ก็เป็นกรอบสำหรับพัฒนาเว็บแอพพลิเคชันที่อิงมาจาก <a href="http://www.rubyonrails.org">Ruby on Rails</a> แต่ใช้ภาษา Groovy เป็นหลัก และทำงานบน Java Virtual Machine ลองอ่านหนังสือแนะนำการพัฒนาเว็บโดยใช้ Grails ดูแล้ว ก็ไม่ต่างจาก RoR  หรือกรอบงานแบบเดียวกัน เช่น CakePHP แต่จุดเด่นของ Grails น่าจะอยู่ที่การใช้ JVM ให้สามารถใช้เครื่องมือ รวมทั้งไลบรารีต่างๆ ที่สร้างสำหรับ Java EE ได้เลย มีเครื่องมือให้ใช้เยอะพอดู น่าลองใช้ ที่ดูๆ อยู่เนื่องจากปี (การศึกษา) ที่แล้วพัฒนาระบบเก็บข้อมูลภายในสำหรับสถาบันฯ ด้วย CakePHP เว็บที่ทำขึ้นยังค่อนข้างสกปรกอยู่ ปีนี้อาจจะต้องปรับปรุงหรือพัฒนาเพิ่มเติม</p>
<p>ถ้าเปลี่ยนมาใช้ Grails แล้วสะดวกขึ้น หรือสามารถหาคนมาช่วยพัฒนาแทนได้ ไม่จำเป็นต้องทำเองทั้งหมด ก็น่าสนใจ ดูคร่าวๆ แล้ว เห็นว่า Grails มีโครงสร้างต่างๆ ที่ดีกว่า CakePHP เยอะ เพราะจุดขายของกรอบงานแบบนี้ คือ วิธีการที่เรียกว่า scaffolding ซึ่งทำให้สามารถสร้างเว็บเพื่อทำ CRUD (Create-Retrieve-Update-Delete) ได้ง่ายๆ แต่ก็เป็นปัญหาด้วยส่วนหนึ่ง เนื่องจากอาจจะไม่ได้ออกแบบมาให้ปรับแต่งได้ตามความต้องการของระบบ สุดท้ายเวลาต้องการอะไรเพิ่มเติมก็ต้องมาหาวิธีปรับแต่งเอง หรือเขียนเองทั้งหมด อย่าง RoR ก็ต้องมี StreamLine หรือ ActiveScaffold ออกมาเพื่อช่วยให้ทำงานได้ง่ายขึ้น ซึ่งส่วนนี้ดูเหมือนจะเป็นจุดเด่นของ Grails</p>
<p>อย่างไรก็ดี ปัญหาที่สำคัญของการใช้กรอบงานแบบนี้ คือ แนวความคิดในการพัฒนาโปรแกรมของนักพัฒนา ที่จะต้องก้าวข้ามเข้ามาอยู่ในกรอบ Object Oriented และ Model-View-Controller ผมรู้สึกว่านักศึกษาที่สอนอยู่ส่วนใหญ่ยังไม่สามารถข้ามมาได้ ส่วนใหญ่ยังติดอยู่กับ structured programming หวังว่าปีหน้าถ้าเปลี่ยนแนวคิดการพัฒนาโปรแกรมใหม่ ตั้งแต่วิชาแรกที่เริ่มเรียน เขาน่าจะเข้าใจได้ง่ายขึ้น</p>
<p>สุดท้ายจดลิงก์ไว้กันลืม</p>
<ul>
<li><a href="http://www.infoq.com/minibooks/grails">Getting Started with Grails</a> เป็น e-book แจกฟรี เขียนเข้าใจง่ายมาก</li>
</ul>
<ul></ul>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2007/12/07/grails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>เขียนโปรแกรม</title>
		<link>http://cholwich.org/wordpress/2007/07/13/%e0%b9%80%e0%b8%82%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b9%82%e0%b8%9b%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b8%a3%e0%b8%a1/</link>
		<comments>http://cholwich.org/wordpress/2007/07/13/%e0%b9%80%e0%b8%82%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b9%82%e0%b8%9b%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b8%a3%e0%b8%a1/#comments</comments>
		<pubDate>Fri, 13 Jul 2007 03:47:31 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[quote]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/2007/07/13/%e0%b9%80%e0%b8%82%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b9%82%e0%b8%9b%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b8%a3%e0%b8%a1/</guid>
		<description><![CDATA[วันนี้อ่านหนังสือใหม่ &#8220;Beautiful Code&#8221; ซึ่งเป็นหนังสือรวมบทความเกี่ยวกันการเขียนโปรแกรม โดยนักวิทยาศาสตร์ และนักพัฒนาโปรแกรมคอมพิวเตอร์ชั้นนำของโลก เลยไปเจอ quote โดนใจในตอนท้ายบทที่ 3 I believe that computer programming is a practical skill, and I agree with Pólya that we &#8220;acquire any practical skill by imitation and practice.&#8221; Programmers who long to write beautiful code should therefore read beautiful programs and imitate the techniques they learn as they write [...]]]></description>
			<content:encoded><![CDATA[<p>วันนี้อ่านหนังสือใหม่ &#8220;Beautiful Code&#8221; ซึ่งเป็นหนังสือรวมบทความเกี่ยวกันการเขียนโปรแกรม โดยนักวิทยาศาสตร์ และนักพัฒนาโปรแกรมคอมพิวเตอร์ชั้นนำของโลก เลยไปเจอ quote โดนใจในตอนท้ายบทที่ 3</p>
<blockquote><p>I believe that computer programming is a practical skill, and I agree with Pólya that we &#8220;acquire any practical skill by imitation and practice.&#8221; Programmers who long to write beautiful code should therefore read beautiful programs and imitate the techniques they learn as they write their own programs.<br />
- Jon Bentley, &#8220;The Most Beautiful Code I Never Wrote&#8221; in &#8220;Beautiful Code&#8221;</p></blockquote>
<p>เข้ากันสถานการณ์ที่กำลังสอนวิชาพื้นฐานให้กับนักศึกษาปีหนึ่งเลย ตอนนี้ก็พยายามย้ำเสมอๆ ว่า Programming เป็นทักษะ ที่ต้องอาศัยการฝึกฝน ไม่ใช่จำรูปแบบคำสั่งได้ แล้วจะเขียนได้ เพราะพยายามกระตุ้นให้คิดให้ทำโจทย์ในห้องเรียน แต่ก็ยังไม่ค่อยประสบความสำเร็จเท่าที่ควร สุดท้ายเลยกลายเป็นอธิบายวิธีทำโจทย์ หรือวิธีคิด วิธีเขียน อยู่ฝ่ายเดียว แต่มองอีกแง่หนึ่งก็อาจจะเป็นการเพิ่มประสบการณ์ให้นักศึกษาก็ได้ ถ้าได้ลองเอาวิธีที่สอนไป ไปคิด ไปลองเล่นเองบ้าง</p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2007/07/13/%e0%b9%80%e0%b8%82%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b9%82%e0%b8%9b%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b8%a3%e0%b8%a1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActiveScaffold</title>
		<link>http://cholwich.org/wordpress/2007/06/28/activescaffold/</link>
		<comments>http://cholwich.org/wordpress/2007/06/28/activescaffold/#comments</comments>
		<pubDate>Wed, 27 Jun 2007 23:46:13 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/2007/06/28/activescaffold/</guid>
		<description><![CDATA[วันก่อนลองค้นไปค้นมา เจอ ActiveScaffold ซึ่งเป็น plugin สำหรับ Ruby on Rails ซึ่งสนับสนุน Ajax และสามารถปรับแต่งวิธีการแสดงผลต่างๆ ของ Scaffold ได้ง่ายๆ เลยกำลังคิดว่าจะเอามาใช้กับระบบที่กำลังทำอยู่]]></description>
			<content:encoded><![CDATA[<p>วันก่อนลองค้นไปค้นมา เจอ <a href="http://www.activescaffold.org">ActiveScaffold</a> ซึ่งเป็น plugin สำหรับ Ruby on Rails  ซึ่งสนับสนุน Ajax และสามารถปรับแต่งวิธีการแสดงผลต่างๆ ของ Scaffold ได้ง่ายๆ เลยกำลังคิดว่าจะเอามาใช้กับระบบที่กำลังทำอยู่ </p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2007/06/28/activescaffold/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>qsort@stdlib</title>
		<link>http://cholwich.org/wordpress/2007/06/05/qsortstdlib/</link>
		<comments>http://cholwich.org/wordpress/2007/06/05/qsortstdlib/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 07:50:03 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[qsort]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/2007/06/05/qsortstdlib/</guid>
		<description><![CDATA[ในไลบรารีมาตรฐานของภาษาซี มีฟังก์ชันสำหรับจัดการข้อมูลที่สำคัญอยู่ 2 ฟังก์ชัน คือ bsearch สำหรับการค้นหาข้อมูลแบบ binary search และ qsort สำหรับเรียงลำดับข้อมูลโดยใช้อัลกอริทึม quick sort โดยปกตินักศึกษาส่วนใหญ่มักจะไม่ใช้ เพราะมันดูเหมือนจะยุ่งยากซับซ้อน โดยเฉพาะเรื่องเกี่ยวกับ pointer วันนี้ต้องเขียนโปรแกรมเพื่อเรียงลำดับสายอักขระ เลยเอามาเขียนอธิบายวิธีการใช้ไว้หน่อย เผื่อจะเป็นประโยชน์ต่อตัวเอง และคนที่ผ่านมาเห็น void qsort&#40;void *base, size_t nmemb, size_t size, int&#40;*compar&#41;&#40;const void *, const void *&#41;&#41; จาก function prototype จะเห็นว่าฟังก์ชันนี้ต้องการ argument 4 ตัว คือ base เป็น pointer ที่ชี้ไปยังอะเรย์ที่ใช้เก็บข้อมูลทั้งหมด nmemb ใช้ระบุจำนวนสมาชิกของอะเรย์ที่ต้องการเรียงลำดับ size กำหนดขนาดของข้อมูลแต่ละชุด ซึ่งจำเป็นต้องใช้เวลาย้ายข้อมูลสลับตำแหน่งกัน compar เป็น pointer [...]]]></description>
			<content:encoded><![CDATA[<p>ในไลบรารีมาตรฐานของภาษาซี มีฟังก์ชันสำหรับจัดการข้อมูลที่สำคัญอยู่ 2 ฟังก์ชัน คือ bsearch สำหรับการค้นหาข้อมูลแบบ binary search และ qsort สำหรับเรียงลำดับข้อมูลโดยใช้อัลกอริทึม quick sort โดยปกตินักศึกษาส่วนใหญ่มักจะไม่ใช้ เพราะมันดูเหมือนจะยุ่งยากซับซ้อน โดยเฉพาะเรื่องเกี่ยวกับ pointer วันนี้ต้องเขียนโปรแกรมเพื่อเรียงลำดับสายอักขระ เลยเอามาเขียนอธิบายวิธีการใช้ไว้หน่อย เผื่อจะเป็นประโยชน์ต่อตัวเอง และคนที่ผ่านมาเห็น</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> qsort<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>base<span style="color: #339933;">,</span> size_t nmemb<span style="color: #339933;">,</span> size_t size<span style="color: #339933;">,</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>compar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>จาก function prototype จะเห็นว่าฟังก์ชันนี้ต้องการ argument 4 ตัว คือ</p>
<ol>
<li>base เป็น pointer ที่ชี้ไปยังอะเรย์ที่ใช้เก็บข้อมูลทั้งหมด</li>
<li>nmemb ใช้ระบุจำนวนสมาชิกของอะเรย์ที่ต้องการเรียงลำดับ</li>
<li>size กำหนดขนาดของข้อมูลแต่ละชุด ซึ่งจำเป็นต้องใช้เวลาย้ายข้อมูลสลับตำแหน่งกัน</li>
<li>compar เป็น pointer ที่ชี้ไปยังฟังก์ชัน เพื่อเปรียบเทียบสมาชิกแต่ละตัวในอะเรย์ ฟังก์ชันนี้ควรจะให้ค่าน้อยกว่าศูนย์ เท่ากับศูนย์ และมากกว่าศูนย์ เช่นเดียวกับฟังก์ชัน strcmp</li>
</ol>
<p><strong>ตัวอย่าง</strong> ผมต้องการเรียงลำดับสตริง ซึ่งในภาษาซีจะใช้ char * ดังนั้นผมจึงสร้างตัวแปรแบบ char ** เพื่อเป็นอะเรย์สำหรับเก็บ pointer ที่ชี้ไปยังสตริงแต่ละตัว ส่วน nmemb ก็คือจำนวนสมาชิกของอะเรย์ กับ size ก็คือ sizeof(char) หาได้ไม่ยาก ปัญหาหลักอยู่ที่ฟังก์ชันสำหรับเปรียบเทียบข้อมูล ซึ่งจะเห็นว่าเรามีฟังก์ชัน strcmp สำหรับเปรียบเทียบสตริงอยู่แล้ว เพียงแต่ prototype อาจจะไม่เหมือนกัน เลยต้องทำฟังก์ชันขึ้นมาห่อไว้หน่อย</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> compare<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>a<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>pa <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>pb <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> strcmp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>pa<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>pb<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>อ้อ เวลาฟังก์ชัน qsort เรียก compar มาทำงาน จะเรียกโดยส่ง pointer ที่ชี้ไปยังสมาชิก 2 ตัวในอะเรย์ไปให้ ฉะนั้นจึงต้องมา cast ให้เป็น char ** ก่อน แล้วถึงจะไปเรียกใช้ strcmp ได้ ส่วนการเรียกฟังก์ชัน qsort ก็แค่</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">qsort<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> n<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> compare<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>สุดท้ายที่อยากฝากไว้ก็คือ &#8220;don&#8217;t reinvent the wheel&#8221; เราควรจะใช้สิ่งที่มีอยู่แล้วให้เป็นประโยชน์ให้มากที่สุด โดยเฉพาะอย่างยิ่งฟังก์ชันมาตรฐานต่างๆ เพราะฟังก์ชันเหล่านี้ได้รับการพัฒนามายาวนาน ผ่านร้อนผ่านหนาวมาเยอะ น่าจะทำงานได้ดีกว่าการเขียนฟังก์ชันขึ้นมาใช้งานเอง แต่ทั้งนี้ไม่ได้บอกว่าไม่ควรทำเองนะ เพียงแต่พยายามปรับใช้สิ่งต่างๆ ที่มีอยู่ให้ดี เพื่อจะได้มีเวลาไปทำให้สิ่งใหม่ๆ</p>
<p>อ้างอิง: man qsort</p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2007/06/05/qsortstdlib/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
