<?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>Codebreaker</title>
	<atom:link href="http://blog.sumin.us/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.sumin.us</link>
	<description>2bc08752a0894eb2c7afb345286e391d</description>
	<lastBuildDate>Mon, 08 Mar 2010 16:03:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Steve Jobs&#8217; 2005 Stanford Commencement Address</title>
		<link>http://blog.sumin.us/archives/1247</link>
		<comments>http://blog.sumin.us/archives/1247#comments</comments>
		<pubDate>Mon, 08 Mar 2010 13:39:26 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[2005]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Stanford]]></category>
		<category><![CDATA[Steve Jobs]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1247</guid>
		<description><![CDATA[

I think this is a great speech. I hope one day I become another person who can say those thing in front of people. In the speech, Steve Jobs gave me some clues that lead me to an answer that I&#8217;ve been looking for a long time. Jobs said,


  Your time is limited, so [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/Hd_ptbiPoXM&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Hd_ptbiPoXM&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>

<p>I think this is a great speech. I hope one day I become another person who can say those thing in front of people. In the speech, Steve Jobs gave me some clues that lead me to an answer that I&#8217;ve been looking for a long time. Jobs said,</p>

<blockquote>
  <p>Your time is limited, so don&#8217;t waste it living someone else&#8217;s life. Don&#8217;t be trapped by dogma which is living with the results of other people&#8217;s thinking. Don&#8217;t let the noise of others&#8217; opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.</p>
</blockquote>

<p>Even though the statement he made was highly abstract and conceptual, it forced me to re-think about everything I was doing and I have been doing. Ever since I decided to study computer science, I thought I already knew what I want to do. But there were too much of noise from others, temptations and uncertainties. Computer science is indeed a broad subject and it doesn&#8217;t define me. It is just one of things I am interested in.</p>

<p>I don&#8217;t think anyone else can answer to this question for me; what do I really want to become? If someone else answers to the question, it&#8217;s probably not what I truly want to become. Thus I shall be the one who ultimately answers to the question, and hopefully not too late.</p>
<!-- AdSense Now! V1.83 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="text-align:center;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-2353453386862167";
/* 468x60, created 10/26/09 */
google_ad_slot = "1252542387";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1247/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem #20</title>
		<link>http://blog.sumin.us/archives/1244</link>
		<comments>http://blog.sumin.us/archives/1244#comments</comments>
		<pubDate>Sun, 07 Mar 2010 12:27:21 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[Project Euler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1244</guid>
		<description><![CDATA[Problem #20 is to find the sum of the digits in the number 100!

This can be easily solved with Python as the math package comes with factorial function.

from math import factorial
reduce(lambda x, y: int(x)+int(y), str(factorial(100)))






]]></description>
			<content:encoded><![CDATA[<p><a href="http://projecteuler.net/index.php?section=problems&amp;id=20">Problem #20</a> is to find the sum of the digits in the number 100!</p>

<p>This can be easily solved with Python as the <code>math</code> package comes with <code>factorial</code> function.</p>

<pre><code>from math import factorial
reduce(lambda x, y: int(x)+int(y), str(factorial(100)))
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1244/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem #8</title>
		<link>http://blog.sumin.us/archives/1241</link>
		<comments>http://blog.sumin.us/archives/1241#comments</comments>
		<pubDate>Fri, 05 Mar 2010 10:22:56 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[amusement]]></category>
		<category><![CDATA[general]]></category>
		<category><![CDATA[Project Euler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1241</guid>
		<description><![CDATA[A friend of mine, Leon, told me about the Project Euler. One of the problems is to find the greatest product of five consecutive digits in the 1000-digit number.

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450


Here&#8217;s my one-line Python solution. l is a string that contains all 1000 digits above.

max(map(lambda a,b,c,d,e: int(a)*int(b)*int(c)*int(d)*int(e), l[:-4], l[1:-3], l[2:-2], l[3:-1], l[4:]))


Python for the win!
]]></description>
			<content:encoded><![CDATA[<p>A friend of mine, Leon, told me about the <a href="http://projecteuler.net">Project Euler</a>. <a href="http://projecteuler.net/index.php?section=problems&amp;id=8">One of the problems</a> is to find the greatest product of five consecutive digits in the 1000-digit number.</p>

<pre><code>73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
</code></pre>

<p>Here&#8217;s my one-line Python solution. <code>l</code> is a string that contains all 1000 digits above.</p>

<pre><code>max(map(lambda a,b,c,d,e: int(a)*int(b)*int(c)*int(d)*int(e), l[:-4], l[1:-3], l[2:-2], l[3:-1], l[4:]))
</code></pre>

<p>Python for the win!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1241/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Ternary Operator</title>
		<link>http://blog.sumin.us/archives/1236</link>
		<comments>http://blog.sumin.us/archives/1236#comments</comments>
		<pubDate>Mon, 01 Mar 2010 20:08:24 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1236</guid>
		<description><![CDATA[I&#8217;ve been using a tuple as a substitution of a ternary operator in Python. Even though it is not exactly a ternary operator and has some drawbacks, but it works fine in most cases.

w = (u, v)[x &#60; y]


When x &#60; y is true, the whole expression of the tuple, (u, v)[x &#60; y], will [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using a tuple as a substitution of a ternary operator in Python. Even though it is not exactly a ternary operator and has some drawbacks, but it works fine in most cases.</p>

<pre><code>w = (u, v)[x &lt; y]
</code></pre>

<p>When <code>x &lt; y</code> is true, the whole expression of the tuple, <code>(u, v)[x &lt; y]</code>, will be evaluated as <code>v</code> because true means 1 here. Likewise, false will cause the tuple expression to be evaluated as <code>u</code>.</p>

<p>I had another trick to use with lambda functions.</p>

<pre><code>lambda w: x &lt; y and v or u
</code></pre>

<p>This might be a little less obvious to see what&#8217;s going on. When <code>x &lt; y</code> is false, the following part, <code>and v</code>, will not be evaluated due to <a href="http://en.wikipedia.org/wiki/Short-circuit_evaluation">short-circuit evaluation</a>, and it will jump to the next part, <code>or u</code>. Thus, this whole expression is to be evaluated as <code>u</code>. Similarly, when <code>x &lt; y</code> is true, <code>and v</code> part has to be evaluated so it the whole expression will be evaluated as <code>v</code>.</p>

<p>However, as acute readers might already noticed, this trick has a major drawback. When <code>v</code> is a <em>falsy</em> value such as <code>0</code>, <code>False</code> or <code>None</code>, the whole expression will be evaluated as <code>u</code> regardless of the result of <code>x &lt; y</code>. So, one should refrain from using this trick unless it is impossible for <code>v</code> to be a falsy value.</p>

<p>Last Saturday, Cody told me that there is a ternary operator equivalent in Python.</p>

<pre><code>w = v if x &lt; y else u
</code></pre>

<p>Strictly speaking, it is not a ternary <em>operator</em>, rather an expression. But, in my opinion, it is more intuitive thus it makes it easier to maintain the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1236/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>한자-한글 변환</title>
		<link>http://blog.sumin.us/archives/1230</link>
		<comments>http://blog.sumin.us/archives/1230#comments</comments>
		<pubDate>Sun, 14 Feb 2010 10:06:22 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[한글]]></category>
		<category><![CDATA[한자]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1230</guid>
		<description><![CDATA[오랜만의 한국어 포스팅이다.

나는 어렸을 때 한자 공부를 열심히 하지 않아서 그런지, 이런 글을 보면 무언가 거부감이 든다. 한자와 한글의 병용을 주장하는 글을 한자 혼용으로 작성해놓은 이유는 무엇인가.

본문에 따르자면 한자를 배워야 하는 이유를 다음의 몇가지로 요약할 수 있다.


성명의 한자 표기를 통해 자기의 근본을 알고 자기 정체성을 확립한다.
어휘력을 풍부하게 한다.
단어의 뜻을 명확하게 알 수 있다.


먼저, 자기의 성과 [...]]]></description>
			<content:encoded><![CDATA[<p>오랜만의 한국어 포스팅이다.</p>

<p>나는 어렸을 때 한자 공부를 열심히 하지 않아서 그런지, <a href="http://www.hanja-edu.com/bbs/view.php?id=magazine_article&amp;no=368">이런</a> 글을 보면 무언가 거부감이 든다. 한자와 한글의 병용을 주장하는 글을 한자 혼용으로 작성해놓은 이유는 무엇인가.</p>

<p>본문에 따르자면 한자를 배워야 하는 이유를 다음의 몇가지로 요약할 수 있다.</p>

<ol>
<li>성명의 한자 표기를 통해 자기의 근본을 알고 자기 정체성을 확립한다.</li>
<li>어휘력을 풍부하게 한다.</li>
<li>단어의 뜻을 명확하게 알 수 있다.</li>
</ol>

<p>먼저, 자기의 성과 이름을 한자로 쓸 줄 알고 자기의 근본을 알고 자기정체성을 확립하는 것과 일상 생활에서 한자를 병용하는것은 별 관계가 없어보인다. 또, 흔한 경우는 아니지만, 한글 전용으로 인해 특정 단어의 의미가 명확하지 않은 경우가 있을수도 있는데, 이런 경우에 한해서만 괄호 안에 대응되는 한자를 넣어주는 한자 병용으로 문제를 해결할 수 있다. 대부분의 경우에 한글 전용으로도 의미가 확실히 전달되는데에도 불구하고 굳이 한자를 쓰는것은 대단한 자원의 낭비라고 생각된다.</p>

<p>본문 중에 다음과 같은 내용이 있다.</p>

<blockquote>
  <p>例를 들어 여기 흔히 쓰이는 정신 나간 사람이라고 할 때 ‘井神, 定身, 廷臣, 精神, 挺身, 正信, 貞臣, 淨神, 正身, 情神, 鼎臣’ 등이 있는데 이 중 어느 정신인지 漢字를 모르면 구분이 잘 안 된다.</p>
</blockquote>

<p>주장하고자 하는 바가 무엇인지 대략 짐작이 가지만, 예를 조금 잘못 선택한것 같다. 위의 문맥에서 쓰인 &#8216;정신&#8217;이 어떤 뜻의 정신인지 모르면 정말로 정신 나간 사람이 아닐까 한다.</p>

<p>이것 이외에도 적절하지 않은 뒷받침 내용이나, 출처나 사실 여부를 알 수 없는 서술문, 논리적 오류가 보이지만, 이 글을 쓰는 목적이 위의 글을 비판하기 위함이 아니므로 본론으로 넘어가도록 하겠다.</p>

<p>오늘 이 글을 쓰는 목적은 <a href="http://labs.sumin.us/hanja">한자-한글 변환기</a>를 공개하는 것이다. 이것 덕분에 위의 한자 혼용 글도 읽고 이해할 수 있었다.</p>

<p>일단, 약 3만개의 한자-한글 매핑 데이터를 <a href="http://kore.wikia.com/wiki/사용자:Masoris/hani_converter.js">여기</a>서 얻어왔다. 이것을 파이썬의 사전(dictionary) 형식으로 표현하고, 변환할 문자열에서 한 글자씩 한자에서 한글로 변환하는 방식이다. 핵심 기능을 하는 코드는 다음의 한 줄이 전부이고, 나머지는 사용자의 입력을 받고 결과물을 보여주기 위한 코드이다.</p>

<pre><code>map(lambda x: x in dict and dict[x] or x, post['query'])
</code></pre>

<p><code>map</code> 함수가 어떤 기능을 하는 것인지 모르겠으면 <a href="http://docs.python.org/library/functions.html#map">이 문서</a>를 읽어보길 바란다. <code>map</code>, <code>reduce</code>, <code>filter</code> 과 같은 <a href="http://en.wikipedia.org/wiki/Higher-order_function">higher-order function</a> 들을 잘 쓰면 프로그램을 간결하면서도 효과적으로 작성할 수 있다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1230/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Programming Contest: 4-function Calculator</title>
		<link>http://blog.sumin.us/archives/1222</link>
		<comments>http://blog.sumin.us/archives/1222#comments</comments>
		<pubDate>Fri, 05 Feb 2010 06:34:51 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[pymt]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1222</guid>
		<description><![CDATA[Today&#8217;s programming contest, sponsored by Jude Nelson, was to make a 4-function calculator using PyMT. There were some extra credits for additional features such as support for trigonometric functions, parenthesis for changing orders of operations, and so on.

Even though I was the winner (thanks to Google), I admit I wrote an embarrasingly low quality code, [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s programming contest, sponsored by Jude Nelson, was to make a 4-function calculator using PyMT. There were some extra credits for additional features such as support for trigonometric functions, parenthesis for changing orders of operations, and so on.</p>

<p>Even though I was the winner (thanks to Google), I admit I wrote an embarrasingly low quality code, but I think I have legitimate excuses; I&#8217;ve never dealt with PyMT until few hours ago, and we had a very tight time constraint.</p>

<p>So, here I&#8217;m posting the full source code at the request of Charles and a couple more people.</p>

<pre><code>import urllib, urllib2, re
from pymt import *

# Google search would give me a 403 error so I had to "pretend" to be a real web browser.
useragent = 'Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6'

# This is how you get things done.
url = 'http://www.google.com/search?'

m = MTWidget()

button0 = MTButton(label='0', pos=(0, 0), size=(90, 90))
buttonpr = MTButton(label='.', pos=(100,0), size=(90, 90))
buttonok = MTButton(label='=', pos=(200,0), size=(90, 90))

button1 = MTButton(label='1', pos=(0,100), size=(90, 90))
button2 = MTButton(label='2', pos=(100,100), size=(90, 90))
button3 = MTButton(label='3', pos=(200,100), size=(90, 90))

button4 = MTButton(label='4', pos=(0,200), size=(90, 90))
button5 = MTButton(label='5', pos=(100,200), size=(90, 90))
button6 = MTButton(label='6', pos=(200,200), size=(90, 90))

button7 = MTButton(label='7', pos=(0,300), size=(90, 90))
button8 = MTButton(label='8', pos=(100,300), size=(90, 90))
button9 = MTButton(label='9', pos=(200,300), size=(90, 90))

m.add_widget(button0)
m.add_widget(buttonpr)
m.add_widget(buttonok)
m.add_widget(button1)
m.add_widget(button2)
m.add_widget(button3)
m.add_widget(button4)
m.add_widget(button5)
m.add_widget(button6)
m.add_widget(button7)
m.add_widget(button8)
m.add_widget(button9)

buttonlp = MTButton(label='(', pos=(400,0), size=(90, 90))
buttonrp = MTButton(label=')', pos=(500,0), size=(90, 90))

m.add_widget(buttonlp)
m.add_widget(buttonrp)

buttonp = MTButton(label='+', pos=(300,300), size=(90, 90))
buttons = MTButton(label='-', pos=(300,200), size=(90, 90))
buttonm = MTButton(label='*', pos=(300,100), size=(90, 90))
buttond = MTButton(label='/', pos=(300,0), size=(90, 90))

m.add_widget(buttonp)
m.add_widget(buttons)
m.add_widget(buttonm)
m.add_widget(buttond)

buttonbs = MTButton(label='&lt;-', pos=(400,100), size=(90, 90))
buttoncl = MTButton(label='CL', pos=(400,200), size=(90, 90))

m.add_widget(buttonbs)
m.add_widget(buttoncl)

buttonsin = MTButton(label='sin', pos=(500,300), size=(90, 90))
buttoncos = MTButton(label='cos', pos=(500,200), size=(90, 90))
buttontan = MTButton(label='tan', pos=(500,100), size=(90, 90))

m.add_widget(buttonsin)
m.add_widget(buttoncos)
m.add_widget(buttontan)

buttonhex = MTButton(label='0x', pos=(600,0), size=(90, 90))
buttonbin = MTButton(label='0b', pos=(600,100), size=(90, 90))

m.add_widget(buttonhex)
m.add_widget(buttonbin)

inputl = MTLabel(label='', pos=(0, 400), size=(90, 300))
m.add_widget(inputl)

#@button0.event
#def on_press(*largs):
#   print 'on_press()', button0.state, largs

@button0.event
def on_release(*largs):
    inputl.label += '0'

@button1.event
def on_release(*largs):
    inputl.label += '1'

@button2.event
def on_release(*largs):
    inputl.label += '2'

@button3.event
def on_release(*largs):
    inputl.label += '3'

@button4.event
def on_release(*largs):
    inputl.label += '4'

@button5.event
def on_release(*largs):
    inputl.label += '5'

@button6.event
def on_release(*largs):
    inputl.label += '6'

@button7.event
def on_release(*largs):
    inputl.label += '7'

@button8.event
def on_release(*largs):
    inputl.label += '8'

@button9.event
def on_release(*largs):
    inputl.label += '9'

@buttonlp.event
def on_release(*largs):
    inputl.label += '('

@buttonrp.event
def on_release(*largs):
    inputl.label += ')'

@buttonp.event
def on_release(*largs):
    inputl.label += '+'

@buttons.event
def on_release(*largs):
    inputl.label += '-'

@buttonm.event
def on_release(*largs):
    inputl.label += '*'

@buttond.event
def on_release(*largs):
    inputl.label += '/'

@buttonpr.event
def on_release(*largs):
    inputl.label += '.'

@buttonbs.event
def on_release(*largs):
    inputl.label = inputl.label[:-1]

@buttoncl.event
def on_release(*largs):
    inputl.label = ''

@buttonsin.event
def on_release(*largs):
    inputl.label += 'sin('

@buttoncos.event
def on_release(*largs):
    inputl.label += 'cos('

@buttontan.event
def on_release(*largs):
    inputl.label += 'tan('

@buttonhex.event
def on_release(*largs):
    inputl.label += '0x'

@buttonbin.event
def on_release(*largs):
    inputl.label += '0b'

@buttonok.event
def on_release(*largs):
    inputl.label = get_result(inputl.label)

def get_result(query):
    headers = {'User-Agent':useragent}
    req = urllib2.Request(url + urllib.urlencode({'q':query}), None, headers)
    r = urllib2.urlopen(req)
    result = r.read()

    m1 = re.search('&lt;td nowrap &gt;&lt;h2 class=r style="font-size:138%"&gt;&lt;b&gt;', result)
    if m1 is None:
        return 'Invalid expression'

    m2 = re.search('&lt;/b&gt;', result[m1.end():])

    return result[m1.end():(m1.end()+m2.start())]


runTouchApp(m)
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1222/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Languages of the Year 2009</title>
		<link>http://blog.sumin.us/archives/1200</link>
		<comments>http://blog.sumin.us/archives/1200#comments</comments>
		<pubDate>Wed, 23 Dec 2009 00:42:44 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[prolog]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1200</guid>
		<description><![CDATA[It&#8217;s almost the end of the year 2009. This year is special because I&#8217;ve never dealt with so many languages in a year. Objective C, Python, Java, C++, PHP, JavaScript, Haskell, Prolog, Ruby, C#, and probably more. Some of them were for work, some for school, and others were for my personal projects. I have [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost the end of the year 2009. This year is special because I&#8217;ve never dealt with so many languages in a year. Objective C, Python, Java, C++, PHP, JavaScript, Haskell, Prolog, Ruby, C#, and probably more. Some of them were for work, some for school, and others were for my personal projects. I have plenty of stories for each language, but I&#8217;ll try to keep them brief.</p>

<h3>Objective C</h3>

<p><a href="http://cqube.mobi">CQube</a> iPhone edition was released back in March, and as you know Objective C is the language you use for iPhone application development. Objective C is a strict superset of C, so it didn&#8217;t take too much effort to learn. Rather, I spent most of time to learn the Cocoa framework. All those magic keywords like <code>@property</code>, <code>@synthesize</code>, and <code>@dynamic</code> were nice to have.</p>

<h3>Python</h3>

<p>I love Python. I used Python for many different things; from disposable command line utilities to implementation of Apple Push Notification service. I also used this language to conduct a <em>classified operation</em>. After I learned Haskell, which is what I&#8217;m going to talk about in a minute, I started enjoying use of higher order functions such as <code>map</code>, <code>reduce</code>, <code>filter</code>, and so on.</p>

<h3>Java</h3>

<p>I also use Java a lot. I built a Java mobile application at my work. I also built a nearest neighbor search engine, an HTTP based real time communication framework, and a Luca compiler. There are probably more, but these are the ones I remember. There are few things that I really wish to have in Java: automatic getter/setter, operator overriding, and delegate. Could someone give me these as a Christmas gift? ;-)</p>

<h3>C++</h3>

<p>To be honest with you, I&#8217;m kind of scared of this magic language. I would say it&#8217;s quite difficult and takes a considerable amount of practice to use this language properly and effectively. Well, in my compiler class, I had to use either C or C++ to implement a Luca interpreter with indirect threading.</p>

<h3>PHP</h3>

<p>I&#8217;m not a big fan of this language. Ironically, this is probably one of the top three languages that I spent most time with so far. I had a web application development job over the summer. It was a lot of PHP programming. I also had to build server side components at my current work. I wanted to use Python, but apparently not many people know Python. So, I had stick with whatever language that most people can deal with.</p>

<h3>JavaScript</h3>

<p>You would imagine using JavaScript to manipulate the DOM structure of a web page. But, this is not the only case. I used this language to build a Firefox extension (thanks to <a href="http://groups.google.com/group/ua-developers/web/firefox-extension-development-tutorial---part-1">Justin Samuel&#8217;s Firefox extension development tutorial</a>). I can&#8217;t tell you what it is though because it&#8217;s a part of a classified operation.</p>

<h3>Haskell</h3>

<p>Haskell changed a lot of things in my point of view of programming. All the functional programming features and its imperativeness really blew my mind. Basically it made me a better developer in general. Even though I have no intention to use Haskell in production environment, I will be using things I learned from this language.</p>

<h3>Prolog</h3>

<p>Cody Jorgensen:</p>

<blockquote>
  <p>Why can&#8217;t I get an element from the god damn list?</p>
</blockquote>

<h3>Ruby</h3>

<p>It was very joyful to learn Ruby as I already know how to use Python. Ruby is very similar to Python in many different aspects as C# is similar to Java. I see blocks and the yield keyword as a giant lambda function, and I kind of like it. One thing I like from this language over Python is that there&#8217;s <code>end</code> keyword so that you don&#8217;t have to be super careful about indentation. Because of this, there&#8217;s no need to make a new template language in web application framework such as Ruby on Rails, whereas it is necessary in Python based frameworks such as Django. Oh, it&#8217;s also very nice to have built-in regular expression features.</p>

<h3>C&#35;</h3>

<p>We decided to switch from Nokia&#8217;s Symbian to Microsoft Windows Mobile platform at my work. I was hoping the Java code I&#8217;ve been writing works just fine on the Windows Mobile, but few things didn&#8217;t really work out well. So, I decided to re-write the whole application in C#, and I did it over the last weekend. I wouldn&#8217;t be able to make all these happen without Visual Studio&#8217;s great help. Not to mention I didn&#8217;t have to re-write all the server side components.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1200/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding Gram Matrix</title>
		<link>http://blog.sumin.us/archives/1196</link>
		<comments>http://blog.sumin.us/archives/1196#comments</comments>
		<pubDate>Mon, 07 Dec 2009 20:07:37 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[mathematics]]></category>
		<category><![CDATA[linear algebra]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1196</guid>
		<description><![CDATA[Matrix manipulation by hand is often times pain in the neck when it comes to anything bigger than 2 by 2 matrices as it involves a quite amount of arithmetic operations. Well, I&#8217;ve got an Intel Core 2 Duo processor and Python. No reason not to take advantage of them ;-)

Source Code

__author__ = 'Sumin Byeon [...]]]></description>
			<content:encoded><![CDATA[<p>Matrix manipulation by hand is often times pain in the neck when it comes to anything bigger than 2 by 2 matrices as it involves a quite amount of arithmetic operations. Well, I&#8217;ve got an Intel Core 2 Duo processor and Python. No reason not to take advantage of them ;-)</p>

<h3>Source Code</h3>

<pre><code>__author__ = 'Sumin Byeon &lt;sumin@cs.arizona.edu&gt;'

from Numeric import *

# u and v are lists of same lengths
def inner_product(u, v):
    return reduce(int.__add__, map(lambda x: x[0]*x[1], zip(u, v)))

# vs: a list of vectors
def gram_matrix(*vs):
    n = len(vs)
    mx = zeros((n, n))
    for i in range(0, n):
        for j in range(0, n):
            mx[i,j] = inner_product(vs[i], vs[j])
    return mx
</code></pre>

<h3>Result</h3>

<pre><code>&gt;&gt;&gt; gram_matrix([1,0,0,1], [-2,1,0,0], [-1,0,-1,0], [0,2,-3,0])
[[ 2 -2 -1  0]
 [-2  5  2  2]
 [-1  2  2  3]
 [ 0  2  3 13]]
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1196/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Halloween Prank Was Successful</title>
		<link>http://blog.sumin.us/archives/1185</link>
		<comments>http://blog.sumin.us/archives/1185#comments</comments>
		<pubDate>Sun, 01 Nov 2009 05:58:44 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[amusement]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1185</guid>
		<description><![CDATA[The Halloween prank I planned and executed was very successful. It worked for all three of my roommates XD





When you open the cabinet, the cute little spider sitting on the plates comes out and scares people out.



You don&#8217;t normally expect to see this kind of thing when you open your fridge, right?
]]></description>
			<content:encoded><![CDATA[<p>The Halloween prank I planned and executed was very successful. It worked for all three of my roommates XD</p>

<p><a href="/wp-content/uploads/2009/10/DSC_7229.jpg"><img src="/wp-content/uploads/2009/10/DSC_7229.jpg" alt="DSC_7229" title="DSC_7229" width="480" height="320" class="aligncenter size-full wp-image-1182" /></a></p>

<p><a href="/wp-content/uploads/2009/10/DSC_7233.jpg"><img src="/wp-content/uploads/2009/10/DSC_7233.jpg" alt="DSC_7233" title="DSC_7233" width="480" height="320" class="aligncenter size-full wp-image-1183" /></a></p>

<p>When you open the cabinet, the cute little spider sitting on the plates comes out and scares people out.</p>

<p><a href="/wp-content/uploads/2009/10/DSC_7235.jpg"><img src="/wp-content/uploads/2009/10/DSC_7235.jpg" alt="DSC_7235" title="DSC_7235" width="480" height="320" class="aligncenter size-full wp-image-1184" /></a></p>

<p>You don&#8217;t normally expect to see this kind of thing when you open your fridge, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1185/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Permutation Generation</title>
		<link>http://blog.sumin.us/archives/1119</link>
		<comments>http://blog.sumin.us/archives/1119#comments</comments>
		<pubDate>Wed, 30 Sep 2009 09:15:45 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[recursion]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1119</guid>
		<description><![CDATA[Someone asked me how to generate all possible permutations out of a given set and I thought it was kind of interesting to think about it. I was able to come up with a general solution pretty easily (thanks to all the algorithm and math classes I took!) and I would like to share it [...]]]></description>
			<content:encoded><![CDATA[<p>Someone asked me how to generate all possible permutations out of a given set and I thought it was kind of interesting to think about it. I was able to come up with a general solution pretty easily (thanks to all the algorithm and math classes I took!) and I would like to share it with everyone.</p>

<h3>Recursive solution</h3>

<p>For a given set, <em>S</em>,</p>

<p><img src="http://blog.sumin.us/wp-content/cache/tex_5f3effd07c21e2e9a6d5f592fa0455c3.png" align="absmiddle" class="tex" alt="p(S) = 
\begin{cases} 
  \{\emptyset\},  &#038; \mbox{if } S = \emptyset \\
  \{\{s_1\} + p(S - \{s_1\}), \{s_2\} + p(S - \{s_2\}), ..., \\
    \mbox{  } \{s_n\} + p(S - \{s_n\}) \}, &#038; \mbox{otherwise}
\end{cases}" /></p>

<p>whereas <code>+</code> and <code>-</code> signs denote set addition and set subtraction respectively.</p>

<h3>Python implementation</h3>

<pre><code>def permutation(set):
        if set == []:
                return [[]]
        else:
                r = []
                for i in xrange(0, len(set)):
                        for p in permutation(set[0:i] + set[i+1:]):
                                r.append([set[i]] + p)
                return r
</code></pre>

<h3>Results</h3>

<pre><code>&gt;&gt;&gt; print permutation([1, 2, 3])
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
</code></pre>

<p>I wouldn&#8217;t say this particular implementation is <em>the most efficient</em> one, but at least we know it works with up to a certain size of set. Sadly, we all have machines with a finite size of memory, our machine will produce stack overflow if your set is too big.</p>

<p>I think languages like Haskell would work very efficiently with this kind of recursive solution due to its beautiful features like lazy evaluation, tail recursion, etc. Please feel free to share your solution or implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1119/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mounting Remote Filesystem over SSH</title>
		<link>http://blog.sumin.us/archives/1179</link>
		<comments>http://blog.sumin.us/archives/1179#comments</comments>
		<pubDate>Wed, 23 Sep 2009 04:29:51 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[sshfs]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1179</guid>
		<description><![CDATA[I&#8217;ve been using this shell script for a long time and it works pretty well unless I have really slow network connection. When I upgraded to Snow Leopard from Leopard, the installer got rid of all files under /Volumes directory where this script was located. I probably should&#8217;ve put the file under /usr/bin. So I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using this shell script for a long time and it works pretty well unless I have really slow network connection. When I upgraded to Snow Leopard from Leopard, the installer got rid of all files under <code>/Volumes</code> directory where this script was located. I probably should&#8217;ve put the file under <code>/usr/bin</code>. So I&#8217;m posting this as a backup just in case I lose the file again, but please feel free to use it if you have <code>sshfs</code> installed on your system.</p>

<pre><code>#!/bin/sh
# @author Sumin Byeon

URI=user@dev.sumin.us
MOUNTPOINT=/Volumes/dev.sumin.us
OPTIONS="reconnect,follow_symlinks"

if [ ! -d $MOUNTPOINT ]; then
    mkdir $MOUNTPOINT
fi

sshfs -o $OPTIONS $URI: $MOUNTPOINT
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1179/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Future Project: OpenOffice for Mac</title>
		<link>http://blog.sumin.us/archives/1153</link>
		<comments>http://blog.sumin.us/archives/1153#comments</comments>
		<pubDate>Sat, 12 Sep 2009 09:34:16 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[openoffice]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1153</guid>
		<description><![CDATA[Thoughts

Mac applications in general have been maintaining a pretty good consistency in terms of user interface/experience. In case of Windows or Linux applications, it is not a big of deal to be inconsistent because either there is no concrete guideline that states how applications should look and how they behave, or no one really cares [...]]]></description>
			<content:encoded><![CDATA[<h3>Thoughts</h3>

<p>Mac applications in general have been maintaining a pretty good consistency in terms of user interface/experience. In case of Windows or Linux applications, it is not a big of deal to be inconsistent because either there is no concrete guideline that states how applications should look and how they behave, or no one really cares what the guideline suggests. However, in case of Mac applications, it really makes your application distinguishable, usually in a bad way, if you don&#8217;t follow the guide line. Our popular example would be the <a href="http://www.openoffice.org">OpenOffice</a> application suite.</p>

<h3>OpenOffice Writer</h3>

<p><a href="/wp-content/uploads/2009/10/Screen-shot-2009-10-12-at-2.14.04-AM.png"><img src="/wp-content/uploads/2009/10/Screen-shot-2009-10-12-at-2.14.04-AM-400x276.png" alt="Screen shot 2009-10-12 at 2.14.04 AM" title="Screen shot 2009-10-12 at 2.14.04 AM" width="400" height="276" class="aligncenter size-medium wp-image-1155" /></a></p>

<p>I have no doubt that OpenOffice is a great application and I use it on my Linux workstation, but let&#8217;s face it. It&#8217;s ugly.</p>

<h3>Apple iWork Pages</h3>

<p><a href="/wp-content/uploads/2009/10/Screen-shot-2009-10-12-at-2.09.49-AM.png"><img src="/wp-content/uploads/2009/10/Screen-shot-2009-10-12-at-2.09.49-AM-382x400.png" alt="Screen shot 2009-10-12 at 2.09.49 AM" title="Screen shot 2009-10-12 at 2.09.49 AM" width="382" height="400" class="aligncenter size-medium wp-image-1154" /></a></p>

<p>Yup. I actually paid for this ;-)</p>

<h3>What I Want To Do</h3>

<p>So, what I want to do is to make a decent user interface for OpenOffice, using the Cocoa framework, to give it a consistent look and feel and common behaviors provided by the Cocoa framework so that it looks like a typical Mac application.</p>

<p>It&#8217;s going to be a lot of work even though significant amount of code base of the OpenOffice remains unchanged. If you have skills and time, please jump in to this. I won&#8217;t mind for you to <em>steal</em> my idea. I would love to see what comes out.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1153/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dumbass of the Year Award</title>
		<link>http://blog.sumin.us/archives/1114</link>
		<comments>http://blog.sumin.us/archives/1114#comments</comments>
		<pubDate>Sun, 30 Aug 2009 06:40:01 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[amusement]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/?p=1114</guid>
		<description><![CDATA[
]]></description>
			<content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/IMG00276.jpg"><img class="aligncenter size-full wp-image-1115" title="IMG00276" src="/wp-content/uploads/2009/08/IMG00276.jpg" alt="IMG00276" width="480" height="360" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1114/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Apple Push Notification</title>
		<link>http://blog.sumin.us/archives/1112</link>
		<comments>http://blog.sumin.us/archives/1112#comments</comments>
		<pubDate>Sun, 16 Aug 2009 06:10:22 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[push notification]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/archives/1112</guid>
		<description><![CDATA[I was able to setup my server and mobile device (iPhone and iPod touch) to make the push notification service working. I had to send a binary data packet over SSL/TSL connection and the APNs doesn&#8217;t even tell me anything back, so it was very difficult to debug the system. So if you need someone [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1111" class="wp-caption aligncenter" style="width: 330px"><a href="/wp-content/uploads/2009/08/Screenshot-2009.08.15-11.40.07.png"><img src="http://blog.sumin.us/wp-content/uploads/2009/08/Screenshot-2009.08.15-11.40.07.png" alt="Push Test" title="Screenshot 2009.08.15 11.40.07" width="320" height="480" class="size-full wp-image-1111" /></a><p class="wp-caption-text">Push Test</p></div>

<p>I was able to setup my server and mobile device (iPhone and iPod touch) to make the push notification service working. I had to send a binary data packet over SSL/TSL connection and the APNs doesn&#8217;t even tell me anything back, so it was very difficult to debug the system. So if you need someone to setup the push notification, you can contact me.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1112/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSH Tunneling for Secure Connection to Remote MySQL Server</title>
		<link>http://blog.sumin.us/archives/1109</link>
		<comments>http://blog.sumin.us/archives/1109#comments</comments>
		<pubDate>Wed, 12 Aug 2009 10:19:00 +0000</pubDate>
		<dc:creator>Sumin</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://blog.sumin.us/archives/1109</guid>
		<description><![CDATA[Introduction

Database is one of the must-have items for today&#8217;s web application projects. I believe there are plenty of project teams who use MySQL, and I&#8217;m one of them. During the development process, there might be a case where the team members want to share a single database instance rather than keeping separate copies for each [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>

<p>Database is one of the <em>must-have</em> items for today&#8217;s web application projects. I believe there are plenty of project teams who use MySQL, and I&#8217;m one of them. During the development process, there might be a case where the team members want to share a single database instance rather than keeping separate copies for each of members. However, in this case, security becomes our primary concern as MySQL does not provide a secure connection to remote clients.</p>

<p>(Still working on this part…)</p>

<p>In my opinion, SSH is such an awesome protocol. I can access to any remote computers from anywhere in this world, securely transfer files, and so on and so forth. In this article, I&#8217;ll make a brief explanation on how to setup a SSH tunneling for secure connection to a remote MySQL server.</p>

<p>If you&#8217;re not sure what &#8216;tunneling&#8217; means, you might want to refer <a href="http://en.wikipedia.org/wiki/Tunneling_protocol">this article</a>.</p>

<h3>HOW-TO</h3>

<pre><code>ssh -L $LOCAL_PORT:localhost:3306 $REMOTE_SERVER
mysql -u $USER -p -h 127.0.0.1
</code></pre>

<h3>Example</h3>

<pre><code>ssh -L 3306:localhost:3306 db.sumin.us
</code></pre>

<p>Then now I can connect to</p>

<pre><code>mysql -u sumin -p -h 127.0.0.1
</code></pre>

<h3>No localhost, but 127.0.0.1</h3>

<p>If you tried to connect to <code>localhost</code>, then you probably got this kind of message.</p>

<pre><code>ERROR 2002 (HY000): Can't connect to local MySQL server through socket
'/opt/local/var/run/mysql5/mysqld.sock' (2)
</code></pre>

<p>My perception is that when you connect to <code>localhost</code> then the MySQL client tries to establish an inter process communication through <code>mysql.sock</code> file.</p>

<h3>Further Applications</h3>

<p>You can use SSH tunneling for pretty much anything you want. AFP, SMB, or FTP. You name it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sumin.us/archives/1109/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
