<?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>한날의 낙서 &#187; 잘난 척 하기</title>
	<atom:link href="http://www.hannal.net/blog/category/%ec%9e%98%eb%82%9c-%ec%b2%99-%ed%95%98%ea%b8%b0/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hannal.net/blog</link>
	<description>가볍거나 혹은 얕은 낙서</description>
	<lastBuildDate>Wed, 27 Jan 2010 14:34:09 +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>온라인 연락처를 하나로 통일하기</title>
		<link>http://www.hannal.net/blog/to_consistent_own_online_contact_address/</link>
		<comments>http://www.hannal.net/blog/to_consistent_own_online_contact_address/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 07:46:44 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[계정]]></category>
		<category><![CDATA[구글]]></category>
		<category><![CDATA[구글앱스]]></category>
		<category><![CDATA[온라인연락처]]></category>
		<category><![CDATA[전자우편]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1905</guid>
		<description><![CDATA[나는 전자우편을 비롯해 주로 쓰는 메신저 주소도 iam 달팽이 hannal.net로 통일해서 쓴다. MSN 메신저, 네이트온, 구글토크 모두 iam 달팽이 hannal.net 이다. 알만한 사람은 이미 알지만, 전자우편 주소로 메신저 주소 모두를 통일하고 싶은 사람이 있을 것 같아서 내 경우를 예로 들어 간단히 소개해본다.
전자우편 주소
난 구글 애플리케이션(혹은 구글 앱스, Google Apps. 이하 구글 앱스)를 이용해 전자우편, 문서 [...]]]></description>
			<content:encoded><![CDATA[<p>나는 전자우편을 비롯해 주로 쓰는 메신저 주소도 iam 달팽이 hannal.net로 통일해서 쓴다. MSN 메신저, 네이트온, 구글토크 모두 iam 달팽이 hannal.net 이다. 알만한 사람은 이미 알지만, 전자우편 주소로 메신저 주소 모두를 통일하고 싶은 사람이 있을 것 같아서 내 경우를 예로 들어 간단히 소개해본다.</p>
<h3>전자우편 주소</h3>
<p>난 <a href="http://www.google.com/apps">구글 애플리케이션</a>(혹은 구글 앱스, Google Apps. 이하 구글 앱스)를 이용해 전자우편, 문서 도구 등을 이용한다. 구글 앱스는 표준형, 기업용, 비영리 기관용으로 나뉘는데, 무료인 표준형도 대체로 큰 불편함 없이 충분하다.</p>
<p>구글 앱스에 개인 인터넷 도메인을 연결하면, 자신의 도메인으로 된 Gmail을 쓸 수 있다. 도메인 설정을 할 때 메일 서버(MX)을 구글 앱스 서버로 지정하면 되는데, 이러한 <a href="http://www.google.com/support/a/bin/answer.py?hlrm=en&amp;answer=33915">구글 앱스에 맞는 MX 레코드 구성</a>은 구글 도움말 센터에서 제공하고 있다.</p>
<p>내 경우엔 hannal.net 에 대해서 구글 메일 서버를 연결했다. 주의할 점은 mail.hannal.net 이 아니라 hannal.net 도메인을 지정한 것인데, mail.hannal.net로 지정하면 전자우편 주소가 계정이름@mail.hannal.net과 같이 된다.</p>
<p>난 iam 이라는 계정을 쓰므로 iam 달팽이 hannal.net이 전자우편 주소이며, 이 주소로 메신저 주소를 설정한다.</p>
<h3>구글 계정 생성</h3>
<p>구글 계정은 Gmail 계정과 다르다. 구글 계정이 Gmail 계정을 포함하고 있다. 보통은 Gmail 계정을 만들면, 해당 Gmail 전자우편 주소로 구글 계정도 함께 만들어지므로 Gmail 계정을 구글 계정으로 쓰는 사람이 많다.</p>
<p>이 말은 구글 계정은 전자우편 주소를 계정 이름으로 쓴다는 뜻이다. Gmail 계정이 아니라 <a href="https://www.google.com/accounts/NewAccount">구글 계정을 만들러 가면</a> 사용할 구글 계정 이름으로 전자우편 주소를 넣으라고 한다. 나는 이곳에 iam 달팽이 hannal.net 을 써넣어서 가입했다. 이러면 내 전자우편 주소를 이름으로 하는 구글 계정을 만들 수 있다.</p>
<p>주의해야 할 점은 이 계정으로 구글에 접속한(Sign in 혹은 Log in) 뒤에 Gmail 서비스를 해당 계정에 연결하지 않아야 하는 것이다. 무심코 Gmail 계정에 가입하면 해당 계정에 지정된 주 전자우편 주소가 Gmail 전자우편 주소로 바뀐다. 예를 들어, hannal.cha 달팽이 gmail.com로 Gmail 계정을 만들면, 이후엔 iam 달팽이 hannal.net 로 만든 구글 계정은 hannal.cha 달팽이 gmail.com 이 되어 버린다.</p>
<p>이를 원상복구하려면 <a href="https://www.google.com/accounts/ManageAccount">구글 계정 관리</a>영역에 가서 Gmail을 제거(탈퇴)하면 된다.</p>
<h3>구글 오피스(이하 구글 닥스)에서 문서 공유 받기</h3>
<p>다른 사람이 구글 닥스에서 작업하고 있는 문서를 내게 공유할 때 해당 문서를 공유하는 주소(Link)를 공유하지 않고, 공유 초대 기능을 이용하면 자동으로 내 도메인이 연결된 구글 앱스에 있는 문서 도구로 공유된다.</p>
<p>예를 들면, “http://docs.google.com/Doc?docid=문서고유문자열”인 구글 닥스 문서에 나를 “공유 초대 기능”으로 공유하면 자동으로  “http://docs.google.com<strong><span style="color: #ff0000;">/a/hannal.net</span></strong>/Doc?docid=문서고유문자열”와 같이 내 구글 앱스용 주소가 추가되어 초대된다.</p>
<h3>MSN(Live) 메신저에 계정 생성</h3>
<p>MSN 메신저는 hotmail.com 이나 live.com 으로 계정을 만들지 않고 자신이 원래 쓰던 전자우편 주소로 계정을 만들 수 있다. 방법은 아주 간단하다. MSN(Live) 메신저를 설치하고 실행하면 접속하는 데 영역과 가입 영역에 나오는데, 거기서 “기존에 쓰던 메일 주소로 가입”할 수 있다(정확한 문구가 이것인지는 기억나지 않는다).</p>
<p>그걸 누르면 웹브라우저가 열리고 가입 안내를 받는데, 다음 안내가 있다.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-1911" style="border: 1px solid black;" title="다른 전자우편 주소로 MSN 메신저 가입하기" src="http://www.hannal.net/blog/wp-content/uploads/2009/09/msn_account_02.png" alt="다른 전자우편 주소로 MSN 메신저 가입하기" width="403" height="264" /></p>
<p>여기서 “기존의 다른 메일 주소 사용하기”를 누르면 사용하는 전자우편 주소(예를 들면, iam 달팽이 hannal.net)로 가입할 수 있다. 가입한 뒤에는 실제로 쓰는 전자우편 주소인지 인증을 해야 한다.</p>
<h3>네이트온에 계정 생성</h3>
<p>네이트온 접속 영역을 보면 계정 이름에 전자우편 주소 부분이 여러 가지가 있다는 걸 알 수 있다. 즉, 자신의 전자우편 주소를 따로 쓸 수 있다는 뜻이다.</p>
<p>하지만, 네이트온에 계정은 “계정이름@nate.com”를 기본으로 한다. 왜냐하면, 네이트온에 계정을 만든다는 것은 <a href="http://www.nate.com">네이트닷컴</a>에 계정을 만드는 것이기 때문이다. 그럼 어떻게 해야 내 전자우편 주소인 iam 달팽이 hannal.net을 네이트온에서 쓸 수 있을까?</p>
<p>바로 네이트에 연계된 다른 서비스 중 전자우편 주소를 계정 이름으로 쓰는 서비스에 가입하는 것이다. 대표 예는 바로 <a href="http://www.cyworld.com">싸이월드</a>이다. 싸이월드는 SK 계열사에 인수합병 되기 전부터 전자우편 주소를 계정 이름으로 쓸 수 있게 해왔다.</p>
<p>이미 가입했어도 괜찮다. 싸이월드에 접속한 뒤에 계정 이름, 즉 전자우편 주소를 원하는 주소(예를 들면 iam 달팽이 hannal.net)로 바꾸면 된다. 바꾸면 해당 전자우편 주소로 주소 혹인 인증 편지가 오며, 이 편지에 나온 내용을 따라 주소를 인증하면 이후부터는 싸이월드 계정이 바꾼 전자우편 주소가 된다.</p>
<p>이 싸이월드 계정 이름을 네이트온에서 쓰면 된다.</p>
<h3>구글 토크</h3>
<p>구글 토크는 단순하다. 구글 앱스에서</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-1910" style="border: 1px solid black;" title="activated_gtalk_on_google-apps" src="http://www.hannal.net/blog/wp-content/uploads/2009/09/activated_gtalk_on_google-apps.png" alt="구글 앱스에서 활성화된 Google talk" width="331" height="70" /></p>
<p>이렇게 Chat 서비스를 활성화한 뒤, 자신의 전자우편 주소(예를 들면, iam 달팽이 hannal.net)와 비밀번호로 접속하면 된다.</p>
<p>앞서 만든 동일한 주소를 갖는 구글 계정과 헷갈릴 수 있는데, 이 구글 계정으로 접속하는 건 아니다. 구글 토크가 실제로 쓰는 계정은 구글 계정이 아니라 Gmail 계정이기 때문이다. 이를 확인해볼 수 있는 방법은 구글 계정 비밀번호와 구글 앱스에서 쓰는 전자우편 계정 비밀번호를 다르게 한 뒤 접속을 시도하는 것이다. 구글 토크 이용자 이름은 똑같은 전자우편 주소이지만(내 경우는 iam 달팽이 hannal.net) 구글 계정 비밀번호로는 접속이 되지 않고, 구글 앱스에서 쓰는 전자우편 주소로 접속이 된다.</p>
<p>물론, 구글 계정에 Gmail 계정을 연결해놔도 구글 앱스 주소로 접속된다. 즉, 구글 계정(통합)이 아니라 구글에서 제공하는 서비스 개별 계정을 쓴다는 것이며, 그 계정이 Gmail이라는 뜻이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/to_consistent_own_online_contact_address/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>프로그래밍 언어 답사기</title>
		<link>http://www.hannal.net/blog/programming_languages_ive_used/</link>
		<comments>http://www.hannal.net/blog/programming_languages_ive_used/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 02:01:05 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[언어]]></category>
		<category><![CDATA[추억]]></category>
		<category><![CDATA[프로그래밍]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1842</guid>
		<description><![CDATA[차니님께서 쓰신 프로그래밍 언어 답사기 글을 보니 재밌어 보여서 나도 간단히 정리해본다.
처음 접한 언어는 GW-Basic이다. 둔촌 국민학교(초등학교) 다닐 때 가끔씩 컴퓨터 수업을 받았는데 그때 GW-Basic으로 더하기 빼기를 짜는 것이었다. 이후 친구가 다니는 컴퓨터 학원에 놀러가거나 좀 사는 동네 친구 집에 놀러가면 늘 접하는 레퍼토리 중 하나여서 징하게 보긴 했지만, 계산기 만드는 것에서 벗어나질 못했다. 아마도 [...]]]></description>
			<content:encoded><![CDATA[<p>차니님께서 쓰신 <a href="http://channy.tistory.com/373">프로그래밍 언어 답사기</a> 글을 보니 재밌어 보여서 나도 간단히 정리해본다.</p>
<p>처음 접한 언어는 GW-Basic이다. 둔촌 국민학교(초등학교) 다닐 때 가끔씩 컴퓨터 수업을 받았는데 그때 GW-Basic으로 더하기 빼기를 짜는 것이었다. 이후 친구가 다니는 컴퓨터 학원에 놀러가거나 좀 사는 동네 친구 집에 놀러가면 늘 접하는 레퍼토리 중 하나여서 징하게 보긴 했지만, 계산기 만드는 것에서 벗어나질 못했다. 아마도 1989년도였던 것 같다.</p>
<p>이후 내 컴퓨터가 생길 때까지는 프로그래밍 언어를 접할 일은 없었다. 성적이 오르면 컴퓨터를 사주신다고 부모님께서 약속하셔서 열심히 공부하여 1994년에 컴퓨터를 샀는데, 이때 접한 프로그래밍 언어가 C, 어셈블리였다.</p>
<p>C언어는 서점에 갔다가 무심코 집어들어서 공부했는데 포인터에서 막혀서 1차 포기. 어셈블리어는 한 달 용돈이 2만원쯤 하던 당시에 힘들게 돈을 모아 산 정품 게임인 YS 2 special 때문에 특수 목적으로 쓰기 위해 익혔다. 키 디스크(key disk)라고 해서 정품인지 판가름하는 역할을 하는 1번 디스켓이 망가져서 정품 이용자인데도 게임을 할 수 없는 상황에 처했다. 당시엔 그런 원인조차 몰랐지만 알음알음 정보를 수집해서 저러한 원인이라는 걸 알게 됐고, 저러한 정품 인증 방식을 우회할 수 있는 행위(cracking)도 있다는 걸 알았다. 그래서, soft ice 등 여러 도구를 이용하여 크랙을 어설프게나마 만들었는데, 며칠 뒤 친구가 크랙 파일(그 유명한 ys2.com 파일)을 구해다 줘서 좌절했었다.</p>
<p>그 다음에 접한 언어는 Perl이다. 1996년일텐데 당시에 KT(구 한국통신)에서 운영하던 co-lan으로 인터넷을 정액제로 쓰고 telnet 으로 나우누리와 하이텔에 접속하기 위해 kornet 에 가입했다. 이때 처음으로 유닉스를 접했고, 사부의 도움을 받아 vi, screen, telnet 등 유닉스를 쓰는 데 필요한 각종 기초를 익히고 더불어 perl 도 익혔다.</p>
<p>하지만, 정규표현식에 좌절하여 잊고 지내다가 다시 perl 을 쓰기 시작했으니 바로 Crazy Web Board 3.01 때문이었다. 당시에 CWB 3.01 은 c언어로 만들어졌고 소스도 배포됐었다. 이걸 입맛에 맞게 고치려니 c 프로그래밍을 해야했는데, c언어로 문자열을 처리하려니 죽을 맛이었다. 그러다 perl로 만들어진 몇 몇 웹 게시판을 접했고, 강력하고 쉬운 문자열 처리에 감동해서 이런 저런 소스를 구해다 개조하며(copy/paste질) 놀았다. yChat로 유명하신 윤석범님 소스를 많이 참조했었다.</p>
<p>HTML는 1996년에 익혔는데 아마 HTML 3이었던 것 같다. 메모장으로 깨작댄 html 문서 파일이 웹 브라우저에서 보이니(넷스케이프 2를 주로 썼다) 그렇게 신기할 수가 없더라. 그래도 딱히 쓸 일은 없었는데, 일본 만화영화 덕후였던 친구에게 O.S.T mp3 파일을 나우누리에서 내려받아 당시에 계정 용량 제한이 없었던 대구넷(home.daegu.net)에 올려서 공유할 때엔 참 편했다.</p>
<p>1997년쯤에 Java를 접했던 것 같다. 1.5였던가? 근데 프로그래밍을 제대로 공부한 적 없이 필요한 부분만 익힌 나로서는 Java에서 말하는 개념을 이해하기 너무 어려웠다. 무엇보다 내 컴퓨터에서 Java는 <strong>너무</strong> 느렸다. 이때부터 Java는 느리고 무겁고 뚱뚱하다는 편견이 생겨서 지금까지도 나와 친하지 않다. 지금도 좋아하지 않는다.</p>
<p>1997년엔 C++을 접했는데, C++이라고 하기 좀 애매한 것이 Visual C(2였던가 6이었던가?)와 DirectX SDK 3을 접한 것이었다. 내 사부는 나를 프로그래머로 만들 생각이었는지 시나리오나 쓰고, 그래픽(도트, 픽셀) 디자인을 많이 하고 가끔 Scream Tracker로 음악 장난이나 치던 나한테 Win32API와 DirectX 를 공부하라고 압박하기 시작했다. 하지만, 난 프로그래밍 자체에 별 관심도, 애착도 없었기에 Windows Message 체계만 이해하고 관뒀다.</p>
<p>나중에(2003년) 어머니께 일기장 프로그램을 만들어 드리려고 MFC를 접하느라 다시 C++을 들여다보긴 했지만, 역시나 C++도 내 취향이 아니었다.</p>
<p>1999년엔 PHP 3를 만났다. yChat를 만드신 윤석범님께서 PHP를 소개하시기도 했고, 마침 회사에서 내가 할 일이 생겼기에 호기심에 쓴 것이다. 무엇보다 text 파일을 일일이 fopen 하고 fread 하던 perl 을 쓰다가 php에 있는 include 문을 보니 아주 감격스러웠다. include &#8216;head.html&#8217;; 과 include &#8216;tail.html&#8217; 을 할 때 그 짜릿함이란.</p>
<p>당시에 회사에서 내가 맡은 일을 생각해보면 참 신기하다. 회사에선 개발 중인 게임(드로이얀 2)을 베타 테스팅을 할 사람을 인터넷으로 접수 받는 걸 만들고 싶어했으나 회사엔 그런 걸 할 사람이 없었다. 그래서 회사 막내이자 어설프게나마 cgi를 접해본 내가 이 일을 맡게 됐다. 인터넷에서 이름과 주소 등을 입력받으면 이걸 DB에 넣고, DB에 넣은 자료를 csv 파일로 저장한 후 이 파일을 엑셀에서 열어서 출력한다. 그리고, 그걸 오려서 게임 CD가 들어있는 봉투에 붙이는 흐름이다.</p>
<p>처음 php를 접한 탓에 <a href="http://www.lovesera.com/tt">정진호</a>님이 공개하신 웹게시판 소스 파일과 phpschool.com 에 있던 여러 소스를 읽고 또 읽으며 3일만에 겨우 만들어냈다. 이때 처음으로 mysql을 깔아봤다. ^^ (그러고보니 당시에 회사 홈페이지에서 쓰던 게시판이 NeoBBS였던 것 같다)</p>
<p>이후 php를 많이 썼다. 4.1판이 나올 때까지 주 script로 썼다. 2002년에 용돈벌이 하려고 ASP 외주를 받아서 ASP를 익히긴 했지만 내 취향은 아니어서 그 이후 쓰진 않았다.</p>
<p>python은 우연히 2001년에 접했다. 1.x판이었던 것 같다. 정작 나는 파이썬을 쓰지도 좋아하지도 않았고, 게임 프로그래머 친구인 <a href="http://myevan.net">myevan</a>에게 써보라며 소개를 해준 뒤로 신경을 안 썼다. 분명 재밌고 흥미로운 언어이긴 한데, 쓰임새가 잘 와닿지 않았고 어떤 이유에서인지 내가 관리하던 FreeBSD 서버에서 파이썬을 깔기 위해 컴파일 할 때 오류가 나며 깔리질 않았다.</p>
<p>Javascript를 다시 보기 시작하며 쓰기 시작한 건 2006년부터이다. php를 갖고 놀다 벗이 된 인터넷 인연인 <a href="http://www.blogmeme.com">꺼칠이</a>님이 <a href="http://www.prototypejs.org">prototype javascript framework</a> 을 소개해주셨기 때문이다. php로 include문을 처음 썼을 때 느꼈던 희열감을 $ 함수로 느꼈다. 나와 비슷한 분들 많을 것 같다. 1.4.0판 문서를 기준으로 번역한 <a href="http://openframework.or.kr/framework_reference/prototype_js/1.4.0/prototype.js.html">prototype.js를 위한 개발자 노트</a>라는 문서에서 많은 도움을 받았다. 그러다 TNC에서 기초부터 다시 공부를 했다. 같이 공부를 하던 때, <a href="http://egoing.net">egoing</a>님에게서 많은 자극을 받았다. 별 이유없이 무작정 이 사람보다 잘 하겠다고 목표를 정했는데, 여러 사람들이 알다시피 egoing님 실력과 능력이 좋아서 따라잡으려면 공부를 많이 해야했다.</p>
<p>파이썬을 지금처럼 좋아하고 자주 쓰게 된 건 2007년에 접한 django 가 계기였다. 그 이후 나는 주욱 파이썬을 애용하고 있다. 능숙하진 않지만, 어지간한 건 뚝딱 만들 자신은 있다. “잘” 만드는 게 아니라 “뚝딱” 만든다는 데 주의. <img src='http://www.hannal.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>2008년에 Ruby를 만졌는데 Rails 를 쓰려 했기 때문이다. <a href="http://www.acornpub.co.kr">에이콘 출판사</a>로부터 선물받은 <a href="http://blog.daesan.com">황대산</a>님의 “웹 개발 2.0 루비 온 레일스” 책으로 공부를 했는데, 판오름수준(version)이 책에 있는 것과 당시 배포 중이던 것이 달라서 조금 헤맸던 기억이 난다. 루비 역시 딱히 내 취향은 아니어서 지금까지 관심을 끄고 있다.</p>
<p>마지막으로 올해 초에 C#을 공부했다. 2007~8년에 잠깐 같이 일한 적 있는 <a href="http://epicure.graffity.net/">최승준</a>님께서 C#과 xna를 이용해서 멋진 미디어 아트 작품을 만드셔서 C#과 xna에 호감을 갖고 있었던 터라 잠깐 회사 일이 한가한 틈을 타서 후다닥 익혔다. 많은 부분 Java와 비슷하다는데 이상하게도 C#은 금방 마음에 들었다.</p>
<p>실은 올해 봄에 iPhone OS 기반 프로그래밍 유행이 돌기 시작할 때쯤 Objective C를 잠깐 공부했는데 내 입맛에 맞지도 않고 게으름 피우느라 제대로 익히질 않았다. 이런 식으로 접한 언어로 Cobol, Ruby이 있다.</p>
<p>&#8230;</p>
<p>프로그래밍 자체를 즐긴다기 보다는 <a href="http://www.hannal.net/think/programming_for_designing_to_me/">생각을 눈에 보이게 드러내는 과정을 좋아해서 프로그래밍을 한다</a>. 그래서 프로그래밍 능력을 키우는 일 대신 이런 저런 연장을 만지는 데 만족한다. 제대로 할 줄 아는 프로그래밍 언어 없이 잡다하게 맛만 보기만 한다. 그래서 “할 줄 아는 프로그래밍 언어”라고 글 제목을 짓지 않고, 차니님 글 제목처럼 “답사”에 의의를 뒀다. 아마 앞으로도 그럴 것이다.</p>
<p>그래도 호기심은 왕성해서 앞으로 답사할 언어가 조금씩 늘어날 것 같긴 하다. 기획을 할 때 <strong>논리</strong>를 따지거나 이끌어내기엔 막연한 경우가 있다. 그럴 때 프로그래밍 작업 도구로 풀어쓰면 한결 쉽게 정리가 되는데, 그런 과정에 도움이 되는 언어를 언제 어떻게 만날지 모를 일이기 때문이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/programming_languages_ive_used/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Google App Engine의 모델에 있는 get_or_insert 메서드 사용할 때 주의점</title>
		<link>http://www.hannal.net/blog/about_key_name_of_get_or_insert-method_of_gae/</link>
		<comments>http://www.hannal.net/blog/about_key_name_of_get_or_insert-method_of_gae/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 05:43:30 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[get_or_insert]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[구글]]></category>
		<category><![CDATA[구글앱엔진]]></category>
		<category><![CDATA[모델]]></category>
		<category><![CDATA[파이썬]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1794</guid>
		<description><![CDATA[Google App Engine 에서 제공하는 파이썬(python) SDK로 개발을 할 때, Datastore API를 이용하여 DB를 모델링하고 자료를 넣을 겁니다. 이 중 get_or_insert 라는 유용한 클래스 메서드가 있는데, 지정한 값이 있으면 DB에서 그 자료를 가져오고, 없으면 DB에 그 자료를 집어넣습니다.
이렇게 쓰면 됩니다.
모델.get_or_insert(키, 값들)
Hannal 이라는 모델을 예로 들지요.
class Hannal(db.Model):
	name = db.StringProperty(required=True)

name이라는 프로퍼티만 있는 클래스이지요. 이 모델에 자료를 하나 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/appengine/">Google App Engine</a> 에서 제공하는 파이썬(python) SDK로 개발을 할 때, Datastore API를 이용하여 DB를 모델링하고 자료를 넣을 겁니다. 이 중 <a href="http://code.google.com/intl/en/appengine/docs/python/datastore/modelclass.html#Model_get_or_insert">get_or_insert</a> 라는 유용한 클래스 메서드가 있는데, 지정한 값이 있으면 DB에서 그 자료를 가져오고, 없으면 DB에 그 자료를 집어넣습니다.</p>
<p>이렇게 쓰면 됩니다.</p>
<blockquote><p>모델.get_or_insert(키, 값들)</p></blockquote>
<p>Hannal 이라는 모델을 예로 들지요.</p>
<blockquote><pre>class Hannal(db.Model):
	name = db.StringProperty(required=True)</pre>
</blockquote>
<p>name이라는 프로퍼티만 있는 클래스이지요. 이 모델에 자료를 하나 넣어보지요.</p>
<blockquote><p>Hannal.get_or_insert(&#8216;key_0000001&#8242;, name=u&#8217;Hannal Cha&#8217;)</p></blockquote>
<p>이러면 key_0000001 를 키(id)로 갖는 자료를 찾아보고 있으면 그걸 가져오고 없으면, key_0000001를 키로 하고 name 은 u&#8217;Hannal Cha&#8217;인 자료를 집어넣습니다.</p>
<p>주의할 점은 바로 이 키인데요. 이 키 문자열 맨 앞이 숫자로 시작하면 <strong>Names may not begin with a digit</strong> 라는 오류가 납니다. 키 자료형이 문자형이어도 마찬가지입니다. 자료형을 따지는 게 아니라 키 문자열의 맨 앞 문자가 숫자인지를 따집니다.</p>
<p>유레카! 를 외칠만큼 위대한 발견을 한 건 아닙니다. 오류 내용에서도 비록 영문이긴 하지만 숫자(digit)으로 시작하면 안 된다고 알려주니까요. 다만, 보통은 키라 하면 일련번호 id로 관리하기 때문에, 그리고 저처럼 초보들은 눈에 익지 않은 오류가 나면 겁부터 먹기 때문에 종종 당할 듯 해서 적어둡니다. 저는 친절하거든요.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/about_key_name_of_get_or_insert-method_of_gae/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>소인배의 반대말은 대인배?</title>
		<link>http://www.hannal.net/blog/a_lesser_man_and_a_greater_man/</link>
		<comments>http://www.hannal.net/blog/a_lesser_man_and_a_greater_man/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 14:19:13 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[대인]]></category>
		<category><![CDATA[대인배]]></category>
		<category><![CDATA[소인배]]></category>
		<category><![CDATA[우리말]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1674</guid>
		<description><![CDATA[대인배는 최근 몇 년 사이에 생긴 신조어이다. 원래 없던 말이다. 그렇다고 소인배의 반대말이 없던 것은 아니다. 다만, 소인배의 반대말은 대인배가 아니라 대인 혹은 군자일 뿐이다.
소인배에 붙은 배(輩)는 무리를 뜻한다. 무리를 뜻하는 또다른 말인 군(群)과 달리 무리를 얕잡아 부르는 표현이다. 이를테면 패거리, 소굴과 비슷한 말느낌을 지녔다. 그래서 이 글자는 폭력배, 모리배, 무뢰배, 망국배처럼 다소 좋지 않은 뜻을 [...]]]></description>
			<content:encoded><![CDATA[<p>대인배는 최근 몇 년 사이에 생긴 신조어이다. 원래 없던 말이다. 그렇다고 소인배의 반대말이 없던 것은 아니다. 다만, 소인배의 반대말은 대인배가 아니라 대인 혹은 군자일 뿐이다.</p>
<p>소인배에 붙은 배(輩)는 무리를 뜻한다. 무리를 뜻하는 또다른 말인 군(群)과 달리 무리를 얕잡아 부르는 표현이다. 이를테면 패거리, 소굴과 비슷한 말느낌을 지녔다. 그래서 이 글자는 폭력배, 모리배, 무뢰배, 망국배처럼 다소 좋지 않은 뜻을 가진 낱말에 붙는다. (물론, 모든 경우에 그런 건 아니다. 선배나 동년배에도 같은 글자를 쓰기도 한다)</p>
<p>정리하면, 대인배는 대인과 -배(輩)라는 서로 어울리지 않는 낱말을 합쳐 부르는 것이다. 마치 “그분은 정말로 훌륭한 새끼입니다”라고 하는 것과 같다.</p>
<p>하지만, 대인배라는 말이 생긴 유래를 보면 단순히 대인이나 군자를 뜻한다고 보기는 어렵다. 대인이라는 뜻은 있으나 존경이나 존중하는 마음을 품는다기보다는 단순히 웃고 즐기는 상황을 담는 과정에서 소인배의 말느낌(어감)을 살리면서 반대 개념을 갖게 만든 말이기 때문이다.</p>
<p>그러므로 소인배의 반대말이 대인 혹은 군자라는 말임을 명확히 알고 있으며, 대인을 나타내는 말로써 쓰는게 아니라 대인배라는 낱말을 쓰는 상황이라서 대인배라는 말을 쓰는 것이라면 유행처럼 새로이 생겨난 대인배라는 낱말 자체를 굳이 부정할 필요는 없다고 생각한다. 단지, 제대로 알고 쓰자는 의견이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/a_lesser_man_and_a_greater_man/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>싱크대 배수구 막힘 문제</title>
		<link>http://www.hannal.net/blog/a_problem_that_be_blocked_a_waterway_of_sink/</link>
		<comments>http://www.hannal.net/blog/a_problem_that_be_blocked_a_waterway_of_sink/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 04:50:37 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[배수구]]></category>
		<category><![CDATA[설거지대]]></category>
		<category><![CDATA[싱크대]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1609</guid>
		<description><![CDATA[얼마 전에 설거지대(싱크대)에 연결된 배수구가 막힌 적이 있다. 큼직한 덩어리를 배수구로 버리지 않았는데 막힌 걸 보니 분해용액으로 뚫을 수 있겠다 생각했다. 하지만, 1리터짜리 분해용액을 두 통이나 썼는데도 별 효과가 없었다. 며칠 고생한 끝에 마침내 뚫었고, 뚫으려고 이리 저리 고생하고 고민하여 얻은 교훈과 경험을 공유해본다.
1. 왜 막히는가?
이유는 단순하다. 배수구나 배수관을 막는 무언가를 버렸기 때문이다. 배수구는 보기와는 [...]]]></description>
			<content:encoded><![CDATA[<p>얼마 전에 설거지대(싱크대)에 연결된 배수구가 막힌 적이 있다. 큼직한 덩어리를 배수구로 버리지 않았는데 막힌 걸 보니 분해용액으로 뚫을 수 있겠다 생각했다. 하지만, 1리터짜리 분해용액을 두 통이나 썼는데도 별 효과가 없었다. 며칠 고생한 끝에 마침내 뚫었고, 뚫으려고 이리 저리 고생하고 고민하여 얻은 교훈과 경험을 공유해본다.</p>
<h3>1. 왜 막히는가?</h3>
<p>이유는 단순하다. 배수구나 배수관을 막는 무언가를 버렸기 때문이다. 배수구는 보기와는 달리 음식물을 떠내려 보내기엔 좁다. 그래서 남은 밥이나 반찬을 버리면 금방 막힌다.</p>
<p>배수구를 막을만한 것을 버리지 않았는데도 막히는 경우도 있다. 한 번에 큼직한 걸 버리지 않아도 막힐 수 있다. 주로 <strong>기름(지방)이 원인</strong>이다. 라면을 끓여먹으면 기름이 둥둥 떠다니든데 이런 기름을 버리면 배수관에 조금씩 붙어 단단해진다. 마치 포화 지방이 핏줄(혈관)에 쌓여 큰 문제를 일으키듯이, 이런 기름도 서서히 쌓여 배수관을 좁히는 것이다. 그래서 예전에는 잘 내려가던 음식물 찌꺼기, 예를 들면 조각난 대파나 밥알이 어느 순간 턱 막히는 것이다.</p>
<h3>2. 예방하기</h3>
<p>큰 덩어리를 배수구로 버리지 않는 건 평소에 조금만 신경쓰면 충분히 예방할 수 있다. 배수구 걸림망을 사다 꽂기만 해도 이런 문제는 거의 일어나지 않는다.</p>
<p>배수관에 조금씩 찌꺼기가 쌓이는 건 좀 더 신경을 써야 한다. 기름기가 많은 그릇이나 냄비를 설거지 할 때에 이 기름이 배수관에 쌓이지 않게 따뜻한 물로 설거지를 하는 게 좋다. 설거지를 마친 후 뜨거운 물을 부어주면 더 좋다. 차가운 물로 설거지를 하면 기름이 빨리 굳기 때문이다.</p>
<h3>3. 뚫기</h3>
<p>기름으로 배수관이 좁아졌다가 막힌 경우엔 분해용액으로 뚫을 수 있다. 1리터짜리가 약 3,000원쯤 하는데, 이걸 사다 붓으면 분해용액이 찌꺼기를 녹인다. 30~60분 후에 뜨거운 물을 부으면 어지간해서는 뚫린다. 안 뚫리면 붓고 6~8시간 정도 기다렸다가 다시 하면 된다.</p>
<p>그러나, 섬유소는 잘 녹지 않는다. 기름때가 쌓여 배수관이 좁아진 상태에서 채소나 과일을 많이(사람 눈으로 보기엔 분명 적은 양이지만) 버리면 이것들이 층층히 쌓인다. 이때엔 분해용액을 아무리 써도 좀처럼 뚫리지 않는다. 부엌이나 방안에 독한 알카리액 냄새만 풍길 뿐이다.</p>
<p>이럴 때엔 직접 뚫어야 한다. 그런데 세면대나 변기와 달리 설거지대는 막힌 배수구나 배수관을 뚫기가 쉽지 않다. 변기나 세면대처럼 배수구가 한 곳이면 그곳을 배수구 소통기로 막고 압력을 가하면 대체로 금방 뚫을 수 있다. 그러나 설거지대엔 설거지하면서 넘치거나 차오르는 물을 빼주는 작은 배수구가 설거지대 안쪽 옆에 있어서 배수구 소통기(일명 뚫어뻥)를 쓸 수 없기 때문이다.</p>
<p>이 상황에 좌절하여 뚫기를 포기하고 전문가를 불러 해결한다. 보통 3~5만원이라고 한다. 물론 바닥을 드러내야 할 만큼 대형 공사를 해야 하는 경우엔 돈이 왕창 깨진다. 이건 우리가 어찌하기 어렵다. 하지만, 3~5만원으로 해결되는 일은 우리도 충분히 할 수 있다.</p>
<p>먼저 뚫을 도구가 있어야 한다. 크게 두 가지를 들 수 있다.</p>
<ul>
<li>배수구 관통기 : 철물점에서 약 1만원으로 살 수 있다.</li>
<li>쇠 옷걸이 : 쇠를 구부려 만든 옷걸이이며, 보통은 세탁소에서 옷을 맡기면 얻는다.</li>
</ul>
<p>배수구 관통기나 쇠 옷걸이나 원리는 같다. 그러니 쇠 옷걸이가 있으면 이걸 써도 괜찮다. 옷걸이를 편 뒤 고리를 꽈악 눌러 갈고리처럼 하면 좋다. 옷걸이를 다 펴면 약 1m 정도 된다. 만약 설거지대에 연결된 배수관이 U자 모양으로 휜 쇠붙이라면 배수구 관통기를 사야 한다. 이 관통기에 들어가 있는 관통쇠는 휘기 때문이다.</p>
<p>도구를 준비했으면 플라스틱 배수관을 설거지대에서 분리해야 한다. 이미 막혀서 물이 내려가지 않은 경우라면 배수관에 물이 고여있으므로 세수대야나 큰 냄비를 준비해 쏟아질 물을 받아야 한다.</p>
<p>이제 이 도구로 배수구와 배수구를 열심히 쑤신다. 최대한 깊이 쑤신다. 옷걸이를 개조해서 쓰는 경우 옷걸이를 놓치지 않게 주의한다. 오랫동안 땀나게 쑤실 필요는 없다. 한 열 댓 번 정도 쑤시면 된다. 물을 부어 흘러내려가는지 확인한다. 안 내려가면 더 쑤셔서 물이 내려갈 때까지 쑤신다.</p>
<p>물이 빠지면 배수관을 설거지대에 연결한다. 혹시 모르니 분해용액을 써서 남은 기름때를 녹여보낸다.</p>
<p>만약, 큰 덩어리를 넣어서 막힌 경우라면 딱히 답이 없다. 되도록 그 덩어리를 끄집어내보고, 안 되면 최대한 쑤시고 녹여야 한다. 그래도 안 되면 전문가를 불러 자신이 벌인 무신경한 실수에 대해 큰 돈으로 대가를 치르라.</p>
<h3>4. 주의할 점</h3>
<p>분해용액을 너무 많이 자주 쓰면 안 좋다. 플라스틱 배수관이 상하기 때문이다. 물론, 배수관으로 쓰는 플라스틱은 산성과 알카리성에 강한 성질이 있고, 분해용액 자체가 플라스틱을 바로 녹일만큼 독하지도 않다. 그렇게 독하다면 분해용액은 유리병이나 캔에 담아 팔았을 것이다. 그래도 너무 남용하는 건 좋지 않다.</p>
<p>이사를 간 경우도 주의해야 한다. 새로 지어서 자신이 첫 입주자라면 모를까, 그게 아니라면 전에 살던 사람이 있다. 만약 그 사람이 개념없이 음식물 쓰레기나 기름을 마구 버렸는데 당신이 입주하자 막힐 수도 있다. 뒤집어 쓰는 것이다. 그러므로 새로 이사왔다고 긴장을 풀고 설거지에 임한다면 나처럼 며칠을 분해용액 냄세(락스 냄새와 같다)에 시달릴 것이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/a_problem_that_be_blocked_a_waterway_of_sink/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>전자우편 쓰기 도움말</title>
		<link>http://www.hannal.net/blog/about_writing_an_email/</link>
		<comments>http://www.hannal.net/blog/about_writing_an_email/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 04:01:39 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[도움말]]></category>
		<category><![CDATA[전자우편]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1448</guid>
		<description><![CDATA[들어가며
예전엔 그다지 신경쓰지 않았는데, 전자우편(email, 이메일)을 메신저 수준으로 쓰면서, 아니, 지금은 메신저보다 전자우편에 더 비중을 두다보니 전자우편을 보낼 때 여러 가지를 신경 쓴다. 틀(양식)이나 수신할 사람 지정 등이 그렇다.
예전에 다니던 회사에서 신청자에 한해 매달 사내 직원 교육을 했었는데, 한 번은 주제가 비즈니스 이메일(업무 전자우편)이었다. 그때 들었던 내용나 인터넷을 통해 이리 저리 접한 자료, 그리고 내 [...]]]></description>
			<content:encoded><![CDATA[<h3>들어가며</h3>
<p>예전엔 그다지 신경쓰지 않았는데, 전자우편(email, 이메일)을 메신저 수준으로 쓰면서, 아니, 지금은 메신저보다 전자우편에 더 비중을 두다보니 전자우편을 보낼 때 여러 가지를 신경 쓴다. 틀(양식)이나 수신할 사람 지정 등이 그렇다.</p>
<p>예전에 다니던 회사에서 신청자에 한해 매달 사내 직원 교육을 했었는데, 한 번은 주제가 비즈니스 이메일(업무 전자우편)이었다. 그때 들었던 내용나 인터넷을 통해 이리 저리 접한 자료, 그리고 내 경험을 정리해서 공유해본다.</p>
<h3>제목</h3>
<p>종이 편지와 다른 점 중 하나는 바로 제목이다. 종이 편지를 쓸 때는 대체로 제목을 쓰지 않지만, 전자우편은 기본 항목이나 마찬가지이다.</p>
<p>전자우편 제목은 내용에 대한 주제여야 한다. 대체로 제목에 인사말을 넣는 실수가 많다. “안녕하세요, 누구님. 한날이라고 합니다” 라고 쓰는 것이다. 전자우편 보내는 목적이 인사나 안부를 묻는 것이라면 상관없지만, 그게 아니라면 제목엔 전자우편을 보내는 목적(주제)을 담아야 한다. 예의 없어 보이는 것 같아서 제목부터 공손히 인사하려는 애틋한 마음을 이해 못하는 바 아니나, 이런 전자우편은 “안녕하세요. 좋은 투자 정보가 있어 연락 드립니다”라는 제목으로 날아오는 광고 전자우편(스팸 메일) 취급 받기 쉽다.</p>
<h3>본문</h3>
<p>전자우편 본문은 단락 세 개 정도가 적당하다고 한다. 실제로 대다수 전자우편 도구(software)나 웹서비스에서 전자우편을 열어보면 단락 세 개 정도가 한 화면에 잘 보인다. 물론, 한 단락당 문장이 3~5줄이다.</p>
<p>첫 번째 단락은 짧은 인사말과 함께 본론, 즉 전자우편을 보내는 목적(주제)을 쓴다.</p>
<blockquote><p>안녕하세요, XXX님. 한날입니다.</p>
<p>며칠 전에 전화통화로 간단히 얘기 나눴던 책 후원에 대해 보다 자세한 계획서/제안서를 보내 드리며, 간단하게 소개를 해봅니다. <ins datetime="2008-11-01T06:49:59+00:00">검토 후 답장을 바랍니다.</ins><sup><a href="http://www.hannal.net/blog/about_writing_an_email/#comment-60591">참고 1)</a></sup></p></blockquote>
<p>두 번째 단락은 주제에 대한 설명을 쓴다.</p>
<blockquote><p>저는 기술 전문 서적이 아니라면 한 달에 책을 여섯 권 읽습니다. 가끔 다른 일이 생겨 느리게 읽는 경우도 있으니 일주일에 한 권이 안정감 있는 양이며, 서평을 쓰면 주요 온라인 서점에서 추천 서평으로 뽑힙니다. 또한, 매주 토요일에 모여 책을 읽는 독서 모임도 운영하고 있어 후원 효과도 높일 여지가 있습니다.</p></blockquote>
<p>세 번째 단락에선 전자우편을 마무리한다.</p>
<blockquote><p>보다 자세한 내용은 첨부한 문서에 있습니다. 그럼 답장을 부탁하며, 좋은 하루 보내세요.</p></blockquote>
<p>상황을 가상으로 만든데다 다소 딱딱한 내용이라서 어색하기 그지없다. -_-;</p>
<p>이런 구조가 정답은 아니다. 전자우편은 종이편지보다 소통/교류 빈도가 높기 때문에, 더 간단하게 쓸 수도 있다. 더욱이 잘 받았다는 식으로 확인 통보를 하는 것이라면 한 문장으로도 본문을 쓸 수 있다. 심지어 제목에 할 말을 다 썼으니 본문은 쓰지 않는, 일명 “냉무(내용없음)” 신공을 발휘하기도 한다. 같은 조직 안에서 소통 효율이 중시될 때 보통 그렇다.</p>
<p>다만, 중요한 것은 본론이나 목적, 주제를 앞에(위에) 쓰느 게 좋다는 건 변치 않는다.</p>
<h3>본문 글꼴</h3>
<p>본문 글꼴은 컴퓨터 모니터에서 깔끔하게 보이는 것이 좋다. 가장 흔히 쓰이는 글꼴은 굴림체이며, 영문 전자우편이라면 Arial 이나 Sans serif 를 많이 쓴다고 한다. 크기는 10~12 픽셀이/포인트를 권장하는데, 전자우편 도구나 서비스마다 단위가 다르다. 그냥 마음 편하게 전자우편 서비스나 도구에서 기본으로 제공하는 글씨 크기라고 보면 된다.</p>
<p>가끔 필기체 느낌이 나거나 바탕체, 궁서체 같은 글꼴을 쓰는 사람이 있는데, 이런 글꼴들은 컴퓨터 모니터에서 읽기 안좋으므로 안쓰는 게 낫다. 물론, 종이로 인쇄해보면 괜찮은 글꼴이지만, 사람들 대다수는 전자우편을 일일이 종이로 인쇄해서 읽지 않는다.</p>
<p>영문 전자우편을 쓸 때 주의해야 할 점은 강조 표시이다.</p>
<ul>
<li>굵게 표시</li>
<li>색깔(보통은 빨간색)</li>
<li>대문자</li>
</ul>
<p>영문에서 강조를 할 때는 위와 같은 방법으로 쓴다. 근데 말을 아주 강조한답시고 위 세 개 중 몇 개를 조합하는 경우가 있는데, 영문권 사람들이 이런 강조 표시를 보면 “아, 대단히 중요한가 보구나”라고 생각하기 보다는 “뭐, 이런 무례한 사람이 있담? 어디다 대고 고함질이야” 라고 생각한다고 한다. 귀에다 “중요한 말이니까 귀 열고 내 말 좀 처들으라고!!!!!!!!!!!!!” 라고 외치는 것과 같다고 한다. 그러니 위 세 개 중 하나만으로 강조하는 것이 좋다.</p>
<h3>수신자, 참조, 숨은참조</h3>
<p>의외로 수신자(TO), 참조(CC), 숨은참조(BCC)를 잘 모르는 사람이 많다.</p>
<p>수신자(to)는 이름 그대로 내가 전자우편을 보내려는 대상, 즉 꼭 읽어야 하는 사람이다.</p>
<p>참조(CC : Carbon Copy)는 전자우편을 참조해서 받을 대상이다.</p>
<p>숨은참조(BCC : Blind Carbon Copy)는 참조자로 전자우편을 받되, 수신자와 참조자들은 알 수 없게 감추는 것이다.</p>
<p>예를 들어 총무팀 중 사무용품 구매 담당자에게 사무용품 구매를 물어본다고 하자. 이 경우, 수신자는 구매 담당자이다. 그리고 총무팀 팀장도 이 사실을 알아야 한다면 참조자로 넣는다. 총무팀장에게 물어보는 것이라면 그도 수신자로 넣어야겠지만, 그게 아니라면 참조자로 넣는다. 그런데 구매 담당자와 총무팀장이 자꾸 내 전자우편을 못본 척 무시하기 일쑤이다. 그래서 우리 팀장이 이 상황을 몰래 지켜볼 수 있게 하고 싶다면, 우리 팀장을 숨은참조(BCC)에 넣는다. 보낸이와 수신자와 참조자는 받은 전자우편 내용에 그 전자우편을 받는 사람들이 나타나지만, 숨은참조자는 이들에게 나타나지 않는다.</p>
<p>예전에 공동구매를 진행한 적이 있는데, 공동구매 참여자들은 무슨 이유에서인지 자신을 드러내지 않기를 바랐다. 그래서 공동구매 공지 전자우편을 보낼 때 수신자는 나 자신으로 하고, 공동구매 참여자들은 전부 숨은참조로 해서 보냈다. 이러면 전자우편 받는 사람은 나만 나타나기 때문에 익명이 보장된다. <small>(뭐 이상한 걸 공동구매한 것도 아니었다. -_-; )</small></p>
<h3>답장과 전체답장, 전달</h3>
<p>답장은 전자우편을 보낸 사람에게만 답장 전자우편을 보내는 것이다. 전체답장은 해당 전자우편을 받는 모든 사람, 그러니까 수신자(to), 참조자(CC) 모두에게 답장을 하는 것이다. 숨은참조자는 받지 않는다.</p>
<p>답장을 하면 대체로 제목 글머리에 Re 라는 낱말이 붙는다. Re: 나 [Re:] 이런 식이다.<del datetime="2008-11-06T03:44:18+00:00">인데, 이는 Reply 를 줄인 말로써</del><ins datetime="2008-11-06T03:44:18+00:00">Reply 줄임말로 알려져 있는데 실제로는 그렇지 않다고 한다</ins><sup><a href="http://www.hannal.net/blog/about_writing_an_email/#comment-60745">참고 1)</a></sup>. 보통은 전자우편 답장을 나타내는 관례로 쓴다.</p>
<p>업무로 전자우편을 주고 받을 때는 대체로 “전체답장”을 누를 때가 많다. 그래서 수신자와 참조자가 명확하게 드러나지 않아서 받는 사람은 자신한테 보낸 것인지, 참조하라고 보낸 것인지 혼란을 줄 수 있다. 어떤 사람은 자신을 수신자로 넣은 전자우편 위주로 읽기도 하는데, 무심코 전체답장을 눌러서 전자우편을 받아야 할 사람이 읽지 않고 놓치는 경우가 생기기도 한다<small>(실제 겪은 일이다)</small>. 그러므로 전체답장으로 전자우편을 보낼 때 수신자와 참조자를 구분해주는 것이 좋다.</p>
<p>하지만 사람들 대부분은 수신자와 참조자를 구분하지 않고, 그냥 “전체답장” 단추를 눌러 전자우편을 보낸다. 사실 나도 그렇다. 그러므로 전자우편 본문에 수신자와 참조자를 따로 언급해주면 좋다.</p>
<ul>
<li>필독 : 한날, 개똥이</li>
<li>참조 : 아니마</li>
</ul>
<p>이런 식으로 말이다.</p>
<p>전달(Forward)은 말 그대로 보냈거나 받은 전자우편을 다른 이에게 그대로 전달(Forward)하는 것이다. 전달하는 전자우편은 그 본문이 인용문처럼 들어가며, 글머리엔 Fwd: 라는 낱말이 들어간다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/about_writing_an_email/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>django 와 jquery 를 이용한 개발 환경</title>
		<link>http://www.hannal.net/blog/dev_enviroment_with_django_n_jquery/</link>
		<comments>http://www.hannal.net/blog/dev_enviroment_with_django_n_jquery/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 08:54:26 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[웹프로그래밍]]></category>
		<category><![CDATA[파이썬]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1263</guid>
		<description><![CDATA[요즘 취미삼아 장난감을 만들고 있다. 이번 주 안에 끝내려는 건 책 장난감이다. 좀 더 거창한 장난감, 그러니까 서비스였는데 역량과 준비 부족을 느끼며 장난감으로 격하(?)시켰다. 필통이라는 훌륭한 방향성을 가진 서비스에서 제공하는 책읽기 서비스와 좀 비슷하다. 책을 읽으며 쌓는 적바림들을 컴퓨터로 관리하려고 시작한 이 기획을 어느 덧 3년 동안 묵혀왔는데, 이제는 도저히 참을 수 없는 상황에 이르러서 [...]]]></description>
			<content:encoded><![CDATA[<p>요즘 취미삼아 장난감을 만들고 있다. 이번 주 안에 끝내려는 건 책 장난감이다. 좀 더 거창한 장난감, 그러니까 서비스였는데 역량과 준비 부족을 느끼며 장난감으로 격하(?)시켰다. <a href="http://www.filltong.net">필통</a>이라는 훌륭한 방향성을 가진 서비스에서 제공하는 <a href="http://book.filltong.net/">책읽기</a> 서비스와 좀 비슷하다. <a href="http://www.hannal.net/blog/a_method_how_i_read_a_book/">책을 읽으며 쌓는 적바림</a>들을 컴퓨터로 관리하려고 시작한 이 기획을 어느 덧 3년 동안 묵혀왔는데, 이제는 도저히 참을 수 없는 상황에 이르러서 칼을 빼어든 것이다(칼 뺀지 반 년 돼간다&#8230;).</p>
<p>이미 비슷한 서비스가 있는데 굳이 직접 만들어서 고생할 필요 있나 생각이 들기도 하지만, <strong>내 기획</strong>을 또 한 해 넘겨 묵히며 죽일 순 없다는 오기도 들어서 만들지 않을 수가 없더라. 지향점이 저 서비스와 다른 점도 큰 이유이다. 내가 만들고자 하는 건 “책 많이 읽는 도서관 사서 같은 서비스”이기 때문이다.</p>
<p>어쨌든 만들고 있다. 작동 환경은 웹이다. 파이썬용 웹 프레임워크인 <a href="http://www.djangoproject.com">django</a> 로 뒷단(back-end)을 만들고 있으며, XHTML 1.0과 CSS, 그리고 javascript 로 앞단(front-end)을 만들고 있다. 일부 있어보이는 조작 체계(Rich Interface ? 하하)는 javascript 로 처리하는데 이를 <a href="http://www.jquery.com">jQuery</a>에 맡겼다. 책 정보는 <a href="http://blog.aladdin.co.kr/ttb/category/16526940?communitytype=MyPaper">Aladdin (알라딘)에서 제공하는 검색 Open API</a>를 이용하고 있다.</p>
<h3>파이썬과 django</h3>
<p>django 는 아직도 우리나라에 쓰는 사람이 많지 않다. 관련 자료도 적다. 얼마 전에 연재를 마친 <a href="http://www.hannal.net/think/01-python_django_lecture/">날로 먹는 Django 웹 프로그래밍 강좌</a>는 여러 모로 많이 부족한데도 이 강좌가 그나마 볼만한 문서처럼 되고 있는 실정이다. ㅜㅜ 물론 영문 자료는 참 많지만, 아무래도 부담이 가는 것은 사실이다.</p>
<p>그런 부담을 걷어내면 django 는 정말 훌륭한 웹 프레임워크이다. 현재 배포 중인 안정판인 0.96은 참 불만스럽지만, 곧 정식 발표되는 1.0은 시험판인 지금 것도 꽤 편하고 강력하다. 더욱이 파이썬이라는 언어가 강력하고 매력 있어서 개발이 참으로 즐겁다.</p>
<p>좋은 점 몇 가지를 꼽으라면 관리자(admin) 기능과 모델(model) 기능, 이용자 인증 모듈, 그리고 꽤 작고 직관성 높은 django 구조를 들 수 있다. 관리자 기능, 이용자 인증 모듈은 내가 무척 좋아하는 기능으로 이 둘 덕분에 개발 기간이 크게 줄어들었다. 관리자 기능은 rails(레일스)에서 scaffold 와 비슷한데 그보다 더 실용성 있고 강력하다. 개발 초기부터 개발 완료 후 운영 과정에까지 쓸 수 있다. 이용자 인증 모듈(기능)은 이용자 추가, 관리, 인증 기능을 따로 만들 필요가 없어 좋다. 이게 의외로 손이 가는 부분이라서 이용자 인증부를 다 만들때까지는 연계되어 돌아가는 다른 부분 개발이 난감할 수 있는데, django 에서 제공하는 이용자 인증부를 쓰면 바로 적용할 수 있다.</p>
<p>파이썬이 갖는 장점 덕에 django 가 더 좋은 점도 있다. 파이썬은 코드 예외성이 무척 적은 언어이다. <a href="http://yong27.biohackers.net/29">파이썬 언어 철학</a> 자체가 문제를 해결하는 방법은 최소화 하기 때문이다. 그래서 파이썬에서는 같은 일을 하는 코드를 짰을 때, 누가 그 코드를 쓰더라도 대체로 비슷하게 생겼다. 쉽고 간결한 코드, 그리고 문법(들여쓰기 같은 문법 강제성은 종종 귀찮음을 일으키곤 하지만) 덕에 개발 자체가 즐겁다. 고작 15kb 로 알라딘에서 책 정보를 가져와서 DB에 저장, 이용자 인증(로그인 등), 책 검색, 책 소유/읽음/관심 여부를 표시하는 기능들을 예외처리(Exception)까지 해서 만들었다. django 에서 제공하는 편리함도 무시할 순 없지만, 파이썬 언어 자체가 가진 특성이 가장 큰 영향을 미쳤다.</p>
<p>누가 짜더라도 대체로 비슷한 코드가 나오는 코드 예외성이 적은점은 인터넷 검색으로 자료를 찾을 때 매우 좋다. 고수가 짠 소스 코드든 아니든 상관없다. 파이썬으로 문제를 해결하는 방법은 거의 비슷하여 초보자가 공부하고 자리잡기 좋다. 성향이나 취향이 이유겠지만, 난 루비스러운 코드를 짜기 위해 정작 루비 언어 철학을(인간 중심 프로그래밍?) 위배하는 코드들이나, 문제를 해결하는 다양한 방법을 언어 철학으로 삼는 펄(perl)의 <a href="http://leonidblog.tistory.com/139">암호같은 코드</a>는 초보자가 공부하기에 썩 좋지 않다고 생각한다.</p>
<p>이렇듯 파이썬과 django는 초보자가 다루기에도 좋고 초기 시연판(prototype)을 만들기에도 아주 좋다. 파이썬이라는 언어가 가진 가볍고 간단함, 그리고 django 가 가진 가벼움과 명료함을 버무리면 장난감 만들기 정말 좋은 환경이 탄생한다. 물론 대형 서비스에서도 쓸 수 있겠지만, 내가 그런 서비스를 직접 개발하진 않으니 무어라 말을 할 순 없다. ^^;</p>
<h3>jQuery</h3>
<p>jQuery는 <a href="http://www.prototypejs.org">prototype javascript framework</a> 못지 않게 많은 인기와 사랑을 받고 있는 Javascript framework 이다. 조금 써보니 정말 강력하고 편해서 꽤 많이 만져온 prototype js 로 돌아가고 싶지 않을 지경이다.</p>
<p>jQuery 장점은 강력한 기능이나 성능을 들 수 있다. 기능은 워낙 많은데다 부족하거나 없는 기능은 확장기능(plug ins) 형태로 보충할 수 있다. 손이 많이 들어가는 귀찮은 작업들을 <a href="http://plugins.jquery.com/">이미 다양한 확장기능으로 만들어 제공하고 있다</a>. 기능이 많으면 덩치가 커서 느리거나 둔하지 않을까 걱정이 될 수도 있지만, jQuery의 많은 부분들이 prototype js 를 성능으로 제치고 있으며, 높은 성능으로 유명한 dojo 나 extjs 와 비교를 해도 크게 뒤처지지 않는다.</p>
<p>뿐만 아니라 jQuery 소스 코드를 보면 주석이 정말 잘 달려 있어서 Javascript 에 깊게 파고 들어 공부할 사람에게도 많은 도움을 준다. 나처럼 의심 많은 사람은 대체 이건 내부에서 어떻게 돌아갈까? 생각을 하며 내부 소스를 들여다 보는데, 친절하게도 코드 대부분에 주석이 달려 있어 조금만 시간을 들이면 흐름을 이해할 수 있다.</p>
<p>일관성 있는 문법도 마음에 든다. prototype js를 보면 어떤 것은 객체여서 생성 할당(instance)을 해야 하고, 어떤 것은 함수라서 바로 실행이 가능하다. 또한, 각 기능부(component)가 별도 객체처럼 나뉘어져 있어서 혹 같은 이름을 쓰는 기능부가 있는 라이브러리를 쓸 경우 충돌을 일으키거나 혹은 이것이 prototype js의 것인지 아닌지 구분하기가 까다롭다. 그에 반해 jQuery 는 jQuery 라는 이름으로 대동단결 되어 있다.</p>
<p>간단히 예를 들자. hannal 이라는 엘레먼트를 마우스로 끌어다 놓을 수 있는 조작(control) 기능을 제공한다고 치자(prototype js 와 jquery 둘다 그런 기능을 제공하는 확장기능을 써야 한다). prototype 은</p>
<blockquote><p>new Draggable(&#8216;hannal&#8217;);</p></blockquote>
<p>이런 식이다. jquery는</p>
<blockquote><p>$(&#8216;#hannal&#8217;).draggable();</p></blockquote>
<p>이렇다. 기능부 쪼개는 장점을 이해 못하는 것은 아니나, 어떤 일을 하려는 대상인 객체(object)를 기준으로 코드를 구현하는 jQuery의 문법이나 코드가 좀 더 일관성 있다.</p>
<p>아쉬운 점은 자료 대다수가 영문이라는 점이다. jquery.com 에서 제공하는 문서들과 예제들이 워낙 잘 되어 있어서 굳이 강좌같은 연재글이 아니더라도 쓰는 데 불편함은 없지만, 기본부터 차근 차근 익히고 싶은 사람에겐 우리말/글 자료가 별로 없는 점은 아쉽다. 하지만 최근에 인사이트 출판사에서 <a href="http://blog.insightbook.co.kr/entry/jQuery-그-맹렬한-추격이-무섭다">jQuery in Action 번역서</a>를 출간해서, 가뭄에 단비를 내려주고 있다. jQuery를 쓰고 싶은데 영어가 부담되던 이라면 꼭 이 책을 사서 접하길 권한다.</p>
<p>두 번째 아쉬운 점은 장점이기도 한데, 상당히 빠른 판올림을 들 수 있다. 빠른 판올림 때문에 예전에 코드가 문제를 일으킬 가능성이 좀 있다. 실 예를 들면, jQuery in Action 원서는 jQuery 1.2.1판을 기준으로 쓰여져 있는데, 1.2.1판에는 jQuery 선택자(selector)에 contains 라는 메소드(method)가 있지만, jQuery 최신판인 1.2.6판에서는 이것이 메소드가 아닌 필터(filter)가 되어 해당 메소드가 존재하지 않는다. <ins datetime="2008-09-02T01:42:40+00:00"><a href="http://www.hannal.net/blog/dev_enviroment_with_django_n_jquery/#comment-58101">하지만 번역서에서는 옮긴이께서 보완하셨다고 한다. 만세~</a></ins></p>
<p>이외 jQuery에 대한 얘기(특히 prototype js와 비교하는 얘기)는 <a href="http://dogfeet.tistory.com/29">내가 Prototype에서 jQuery로 옮긴 이유</a>라는 글을 보길 권한다. jQuery 특징을 잘 나타내고 있다.</p>
<hr />
<p>예전 같으면 정말 손이 많이 가는데다 성능도 보장되지 않아 지레 포기하던 많은 것들을 요즘엔 django 와 jQuery 를 이용해서 아주 편하고 간편하게, 그것도 어느 정도 성능이 보장되는 환경에서 처리하고 있다. 물론 이 둘이 아니더라도 php 나 ruby 언어를 서버 환경으로, 그리고 dojo 나 prototype js 등을 클라이언트 환경으로 하여 성능과 편리함을 취할 수 있다.</p>
<p>이들 모두 개성있는 좋은 도구들이다. 하지만 이런 저런 장난감을 다양한 도구로(php(cakephp), ruby(rails), python(django, turbogears), prototype js, yui, jQuery) 만들어보고 만져본 느낌은 나한텐 역시 django 와 jQuery 가 짱이라는 것이다. ^^</p>
<p>덧쓰기 : 당연한 말이지만 이는 어디까지나 개인 성향과 취향에 따라 다르다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/dev_enviroment_with_django_n_jquery/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>강좌 예고. python + django 로 블로그 만들기.</title>
		<link>http://www.hannal.net/blog/notice_a_lecture_about_django/</link>
		<comments>http://www.hannal.net/blog/notice_a_lecture_about_django/#comments</comments>
		<pubDate>Fri, 23 May 2008 10:19:22 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[강좌]]></category>
		<category><![CDATA[웹 프레임워크]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1180</guid>
		<description><![CDATA[1998년에 c 로 짜여진 웹 게시판(Crazy Web Board) cgi 소스 파일을 처음으로 접한 이후 perl(조금), php(어느 정도), asp(쬐금), 그리고 python(조금) 을 겪어 왔다.
python 은 2001년에 처음 접했다. 하지만 조금만 말실수(syntax error)를 하면 버럭 화를 내는(500 Internal server error) 예민한 성격이어서 곧 떠났다.
다시 python 으로 cgi 프로그래밍 하는 데 관심을 가진 건 유들 유들하고 성격 좋아 [...]]]></description>
			<content:encoded><![CDATA[<p>1998년에 c 로 짜여진 웹 게시판(Crazy Web Board) cgi 소스 파일을 처음으로 접한 이후 perl(조금), php(어느 정도), asp(쬐금), 그리고 python(조금) 을 겪어 왔다.</p>
<p>python 은 2001년에 처음 접했다. 하지만 조금만 말실수(syntax error)를 하면 버럭 화를 내는(500 Internal server error) 예민한 성격이어서 곧 떠났다.</p>
<p>다시 python 으로 cgi 프로그래밍 하는 데 관심을 가진 건 유들 유들하고 성격 좋아 보이는 Rails (RoR 로 유명한 그 처자)를 대산님, 만박님, 코디안님을 통해 알게 된 어느 날이었다. 하지만 Java와 마찬가지로 Ruby라는 처자에 도무지 정이 가지 않았다. 왠지 뚱뚱해 보이는 몸짓도 마음에 들지 않았고, 말하는 것도(문법) 사람 약 올리는 느낌이었다. (마치 문법이 “핵꺼등녀?”, “댁꺼등?” 이라는 말투 같달까)</p>
<p>그래도 Rails의 성격에 자꾸 눈길이 갔다. 그래서 Rails 와 비슷한 성격을 가진 다른 처자들을 찾아 나섰고, php에선 cakephp가, python에선 django 가 비슷한 성격을 가졌다는 정보를 접했다. 발그레 미소 지으며 수줍게 말을 거니 딱히 까탈스럽게 굴지 않고 대답을 해주었다. “hello hannal”(hello world)라고&#8230;</p>
<p>2007년 도쿄市에서 무더운 여름을 나던 난 그렇게 django 처자와 인연을 시작했다.</p>
<hr />
<p>내 취미는 기획이다. 밥벌이 역시 기획이다. 심지어 똥도 기획해서 누곤 한다. 99년부터 2007년 상반기까지는 게임 기획을 해왔고, 그 이후로는 웹 기획을 하고 있다. 그런데 오지랖 넓은 호기심 탓에 이것 저것 많이 건드렸다. 그림을 그리던 때도 있었고 음악을 짜던(?) 때도, 그리고 당장 쌀 살 돈이 없어 급한대로 웹 프로그래밍 외주를 한 적도 있다.</p>
<p>그래도 내 본업은 기획이다. 본업이 아닌 일엔 깊이 파고 들지 않는다. 아니, 그 일에만 파고 들지를 못한다. 얕고 넓게 여러 가지를 접하고 대하며 그러다 보면 자연스레 조금씩 깊어지곤 하지만, 일부로 깊게 파고 들지 않는다. 난 내 분수를 알고 주제를 안다. 그래서 되도록 각 분야 담당자나 전문가에게 까불지 않는다.</p>
<p>강좌 하나 쓰려 한다. 까불지 않는다면서 감히 프로그래밍쪽 강좌를 쓰려 한다. 이름하여 “날로 먹는 Django 웹 프로그래밍”이다.</p>
<p>이 강좌 역시 시건방지게 똥꼬에 주름 접으며 방귀 뽕뽕 낄 계획은 없다. 전문성과 깊이를 담은 지식과 정보를 널리 퍼뜨리는 것이 목적이라기 보다는, 새내기나 웹 기획자들에게 길라잡이 역할만 하려 한다. Django가  Python 이라는 프로그래밍 언어를 기반으로 하는데 Python 을 모른다고 해서 걱정할 필요는 없다. Python 문법 설명도 틈틈히 간단하게 다룰 것이며, 굳이 Python을 모르더라도 흘러가는 논리만 이해하면 어려움 없이 따라 할 수 있다.</p>
<p>아, 물론 사이비가 잘못된 길로 이끌 수도 있는데 그건 각자 알아서 길을 바로 잡아가길 바란다. 그 정도 노력도 없이 어떤 분야를 바르고 깔끔하게 다 얻고자 하는 건 무임승차자 심보이고, 난 무임승차자를 싫어한다. ^^ (농담 반 진담 반)</p>
<p>잠깐, 웹 기획자라고? 어째서 웹 기획자를 대상으로 한다는 것이지?</p>
<p>사람 마다 생각이 다르겠지만, 난 기획자라면 기획을 빼고 다른 분야 중 하나 정도는 할 줄 알아야 한다고 생각한다. 그래픽이든 프로그래밍이든. 그걸로 먹고 살거나 그 분야 담당자/전문가와 맞장을 뜨기 위함도, 뜨내기 개발자 기죽이기 위해서도 아니다. 기획을 할 때엔 많은 경험과 정보가 “기획 삽질”을 줄여 준다. 겪어 본 이들은 알다시피 기획 삽질은 많은 사람들을 고통스럽게 한다. 이 강좌는 웹 기획자도 쉽게 웹 개발을 겪어서 관련 이해도를 높여 다른 분야 사람들을 덜 고통스럽게 하고, 결국 웹 기획자도 행복해지게 하기 위함이다. (그래도 기획자는 게으르고 꼭 핵심 내용 한 두 개쯤 빼먹는 문서나 만들어 대는, 그래서 스토리 보드나마 좀 제대로 만들어 줬으면 좋을 족속에서 벗어나긴 쉽지 않을 것 같다. ^^;)</p>
<hr />
<p>이 강좌는 6월 1일에 시작해서 8월 중순 경에 끝날 예정이다. 1주일에 한 편씩 올릴 예정인데 짧지 않은 이 기간 동안 우리는 간단한 블로그를 만들 것이다. 어딘가에선 5분이나 10분 만에 블로그를 만든다는 걸 보면 이 강좌를 쓰는 한날이라는 사람 수준을 알 만 하다. 어쩔 수 없다. 내가 하수이니 손이 느리며, 이 강좌를 쓰는 나 역시 공부를 하며 강좌를 쓰기 때문에 더 느리다. 그런데도 감히 강좌를 쓸 용기를 갖는 것은 홀아비 마음 헤아릴 줄 아는 과부 같은 마음이라 하겠다.</p>
<p>우리나라에 우리말/글로 쓰여진 python + django 정보가 많지 않아서 아직 널리 알려지지 않았는데, 이 참에 많은 초보자들에게 도움이 되길 바라 본다. 2007년, 열심히 구글링하며 했던 아주 단순한 실수를 다른 사람들이 하지 않기도 바라 본다.</p>
<p>- 2008년 5월 23일, 한날.</p>
<p>	•	저작권 : 이 강좌의 저작권은 한날에게 있으며, 무단 배포를 원하지 않습니다. 어떡해서든 도메인과 블로그를 지켜낼테니 안심하고 강좌를 주소 연결(link)만 하시기 바랍니다. 다른 이유가 있어서는 아니고 중간 중간 틀린 걸 고치거나 내용을 덧쓸 수 있는데, 무단으로 퍼가면 조금이라도 더 부족한 내용을 제가 제어 할 방법이 없습니다.<br />
	•	배포처 : 이 강좌 예고는 이곳에서 하지만, 실제 연재는 <a href="http://www.hannal.net/think/">한날은 생각한다</a>에서 합니다.<br />
	•	연락처 : iam 달팽이 hannal.net 으로 연락을 하시면 되며, 전자우편으로 질문은 받지 않습니다. 질문은 <a href="http://www.hannal.net/think/python_django_questions">python 과 django 에 궁금한 점 물어보고 답하기</a>에 댓글로 남기세요.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/notice_a_lecture_about_django/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>cakephp에서 테이블 필드를 tinyint 로 할 때 주의할 점.</title>
		<link>http://www.hannal.net/blog/issue_about_tinyint_in_cakephp/</link>
		<comments>http://www.hannal.net/blog/issue_about_tinyint_in_cakephp/#comments</comments>
		<pubDate>Fri, 09 May 2008 09:44:13 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1177</guid>
		<description><![CDATA[1. 문제 발생
Cakephp 1.2 시험판(beta)에서 작업을 하다가 특정 필드에 값이 0 아니면 1로만 들어가는 현상이 발생했습니다. 문제가 된 테이블의 필드는 다음과 같습니다.
field_1 tinyint(1) unsigned default 0,
field_2 tinyint(1) unsigned default 0,
위 두 필드엔 1자리 숫자(0~9)를 넣을 것이고, 기본값(default)은 0으로 한 것이지요.
그런데 cakephp에 있는 Model 클래스의 save 메소드로 데이터를 저장하면 field_1 과 field_2 에 넣을 값이 자동으로 [...]]]></description>
			<content:encoded><![CDATA[<h3>1. 문제 발생</h3>
<p>Cakephp 1.2 시험판(beta)에서 작업을 하다가 특정 필드에 값이 0 아니면 1로만 들어가는 현상이 발생했습니다. 문제가 된 테이블의 필드는 다음과 같습니다.</p>
<blockquote><p>field_1 tinyint(1) unsigned default 0,<br />
field_2 tinyint(1) unsigned default 0,</p></blockquote>
<p>위 두 필드엔 1자리 숫자(0~9)를 넣을 것이고, 기본값(default)은 0으로 한 것이지요.</p>
<p>그런데 cakephp에 있는 Model 클래스의 save 메소드로 데이터를 저장하면 field_1 과 field_2 에 넣을 값이 자동으로 1로 바뀌었습니다. 어떤 값을 넣어도 1로 바뀌는 기이한 현상이지요.</p>
<h3>2. 문제 원인</h3>
<p><strong>/cake/libs/model/datasource/dbo_source.php</strong> 에 보면 create 메소드 정의 부분 (function create)에 다음과 같은 부분이 있습니다.</p>
<blockquote><pre>for ($i = 0; $i < $count; $i++) {
	$valueInsert[] = $this->value($values[$i], $model->getColumnType($fields[$i]));
}
</pre>
</blockquote>
<p>이 부분은 데이터를 저장할 테이블의 스키마 정보를 가져 온 뒤, 각 스키마 자료형에 맞춰서 값을 검증하고 만드는 부분입니다. 바로 이 부분이 문제(?)입니다. 이 녀석은 필드 자료형이 tinyint이고 길이가 1 인 경우 (즉, <strong>tinyint(1)</strong>) 이 필드를 Boolean 쓰임새로(true/false) 판정합니다. -_-; 그래서 <strong>1 이상인 값이 들어오면 참으로 간주하여 테이블에 1을 넣은 겁</strong>니다.</p>
<h3>3. 문제 해결</h3>
<p>간단합니다. <strong>테이블 생성할 때 boolean 필드로 쓸 것이 아니라면 tinyint(1)을 쓰지 않으면 됩니다</strong>. tinyint(2) 나 tinyint 라고 쓰면 되지요.</p>
<p>이건 오류(bug)라고 하기도 애매한 것이, <a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html">mysql 에서 테이블 필드를 bool 이나 boolean 으로 지정하면 tinyint(1) 로 바꿔서</a> 이렇게 처리한 듯 합니다. 역시 관련 문서를 정독하지 않고 &#8220;hello world&#8221;부터 찍고 보는 사파 개발 성향이 이번에도 제대로 드러났네요. 히히.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/issue_about_tinyint_in_cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>워드프레스에서 주소 체계 정할 때 조심할 점</title>
		<link>http://www.hannal.net/blog/caution_about_permalink_structure_of_wordpres/</link>
		<comments>http://www.hannal.net/blog/caution_about_permalink_structure_of_wordpres/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 14:38:31 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[워드프레스]]></category>
		<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[permalink]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[낱장주소]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1152</guid>
		<description><![CDATA[1. 문제 발생
워드프레스는 주소 체계를 이용자가 원하는 다양한 형태로 꾸릴 수 있는 기능을 제공한다. 이용자가 글 마다 주소를 만들어서 지정하거나 날짜, 혹은 글 번호 등 다양한 변수를 써서 주소를 꾸릴 수 있다. 한날의 낙서와 한날은 생각한다는 주소 체계를 /%postname%/ 라고 설정하고 글 마다 주소를 정하고 있다. (솔직히 아주 귀찮다. -_-)
이렇게 자유로운 주소 체계 가능하다보니 사람들이 [...]]]></description>
			<content:encoded><![CDATA[<h3>1. 문제 발생</h3>
<p>워드프레스는 주소 체계를 이용자가 원하는 다양한 형태로 꾸릴 수 있는 기능을 제공한다. 이용자가 글 마다 주소를 만들어서 지정하거나 날짜, 혹은 글 번호 등 다양한 변수를 써서 주소를 꾸릴 수 있다. <a href="http://www.hannal.net/blog">한날의 낙서</a>와 <a href="http://www.hannal.net/think">한날은 생각한다</a>는 주소 체계를 /%postname%/ 라고 설정하고 글 마다 주소를 정하고 있다. (솔직히 아주 귀찮다. -_-)</p>
<p>이렇게 자유로운 주소 체계 가능하다보니 사람들이 워드프레스 주소 체계를 정확히 이해하지 않은 상태에서 주소를 만들어 쓰다가 낭패를 겪는 경우가 있다. 예를 들면, 글 주소 체계를 숫자로만 한 경우이다. 이 주소 체계는 글 숫자가 1000 미만인 경우 문제가 없지만 1000 이상이면 문제가 생긴다. 예를 들어보자.</p>
<p>“<a href="http://www.hannal.net/blog/?p=1153&#038;preview=true">이 글은 존재하는 글이지만 접근할 수 없는 글입니다.</a>”라는 글의 낱장 주소는 <a href="http://www.hannal.net/blog/1023">http://www.hannal.net/blog/<strong>1023</strong></a> 이다. 그런데 이 글의 낱장 주소인 http://www.hannal.net/blog/1023로 접근하면 그런 글이 없다고 나온다. 이 글 미리보기 기능 주소인 http://www.hannal.net/blog/?p=1153&#038;preview=true 로 접근해야 글을 볼 수 있다. 왜 이런 일이 생기는 것일까? 워드프레스의 오류(버그)일까?</p>
<h3>2. 문제 원인</h3>
<p>결론부터 말하자면 <strong>오류가 아니다</strong>. 나 조차 워드프레스 구조와 흐름을 꼼꼼히 살펴보지 않았을 때에는 <a href="http://www.hannal.net/blog/something_not_good_of_wordpress/">워드프레스 오류</a>라고 생각했었다. 이 문제는 사실 워드프레스 주소 체계와 기계의 고지식함(?)을 생각하면 아주 당연한 것이며, 따지고보면 이용자 부주의로 생긴 일이다.</p>
<p>워드프레스 주소 종류는 다음과 같이 나뉜다.</p>
<ol>
<li>쪽 글(page) 주소 : /기본주소/쪽주소/</li>
<li>관리자 영역 주소 : /기본주소/wp-admin/</li>
<li><strong>년도/달 단위 주소 : /기본주소/년도/달/</strong></li>
<li>글 갈래 주소 : /기본주소/category/ (혹은 따로 지정 가능)</li>
<li>꼬리표 주소 : /기본주소/tag/ (혹은 따로 지정 가능)</li>
</ol>
<p>이외 몇 가지 규칙이 더 나올 수 있는데 여기선 논외로 치자. 여기서 중요한 것은 바로 세 번째 항목인 “년도/달 단위 주소”이다. 만약 워드프레스를 “도메인/blog/”에 설치했을 경우 년도/달 단위 주소는 “도메인/blog/2008/04” 형태가 된다. 바로 이것이 문제(?)이다. 만약 글 주소 체계를 글 번호로만 하거나 혹은 글 주소 이름으로만 한 뒤 그 주소 이름을 1000 이상 숫자로 하는 경우, 그러니까 “도메인/blog/1000” 이런 식으로 할 경우 “년도/달 단위 주소”와 주소 규칙이 부딪히게 된다.</p>
<p><strong>워드프레스는 기본주소 바로 뒤에 붙는 숫자가 1000 이상인 경우 이 숫자를 년도로 인식</strong>한다.  그러므로 글 주소가 워드프레스를 설치한 기본 주소 바로 뒤에 숫자 1000 이상인 경우 글로 접근하질 않고 1000년으로 접근을 한다. 당연히 1000년에 쓴 글이 없을테니 자료가 없다고 나오는 것이다.</p>
<h3>3. 문제 해결</h3>
<p>해결 방법은 간단하다. 글 주소를 기본 주소 바로 뒤에 숫자로만 붙게 하지 않으면 된다. 아니, 붙게 하더라도 그 숫자가 1000이상이 되지 않게 하면 된다. 혹은, 이 숫자 앞이나 뒤에 다른 문자열을 넣어서 년도와 구분을 해주면 된다.</p>
<p>해결 예제</p>
<ul>
<li>/%post_id%/ => /archives/%post_id%/ , /entry/%post_id%/ , /a/%post_id%/ , 이외 글 주소와 년도/달 단위 주소를 구분 지을 문자열이면 아무거나 무관. (숫자 빼고 -_-; )</li>
<li>혹은 아예 다른 주소 체계</li>
</ul>
<p>굉장히 좋은 방법은 글 주소 구조에 해당 주소가 글 주소라는 걸 알 수 있는 낱말을 집어 넣는 것이다. /entry 라든가 /archives 같은 걸 넣는 것이다. 그렇게 하지 않고 나처럼 /%postname%/ 이렇게 하면 글 주소 이름을 숫자로 하지도 못하고, 그렇다고 글 주소를 한글로 하기도 애매해서 매번 글 주소 이름을 영문으로 짓느라 고생하게 될 것이다. -_-; 워드프레스 2.5에 주소체계 견본으로 /archives/%post_id%/ 가 괜히 있는 것이 아니다.</p>
<p>(굳이 변명을 하자면 난 워드프레스 1.2때부터 썼는데 당시엔 이런 배려가 없었으며, 예쁜주소(fancy url) 기능을 만들어주는 .htaccess 관리 정책도 지금과 완전히 달랐다)</p>
<p>덧쓰기 : 윽, 젠장. 이 글 주소에 wordpress를 오타 쳐서 wordpres 라고 쳤다. -_-</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/caution_about_permalink_structure_of_wordpres/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Google App Engine으로 “안녕하세요, 여러분”  출력하기</title>
		<link>http://www.hannal.net/blog/say_hello-world_on_google-app-engine_service/</link>
		<comments>http://www.hannal.net/blog/say_hello-world_on_google-app-engine_service/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 08:53:04 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[app engine]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[구글]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1144</guid>
		<description><![CDATA[1. 들어가며
며칠 전에 구글에서 Google App Engine이라는 플랫폼을 공개했다. 소식을 접하자 마자 계정 신청을 했는데 오늘 계정이 활성화 됐다는 전자우편이 왔다. Google App Engine에 대해 보다 자세한 우리말 글을 보고 싶다면 likejazz님께서 쓰신 구글 웹 어플리케이션 플랫폼: App Engine 글을 참조 바란다.
2. 가볍게 둘러 본 느낌
난 방금 전에 Google App Engine (이하 GAE)에 예제를 따라 [...]]]></description>
			<content:encoded><![CDATA[<h3>1. 들어가며</h3>
<p>며칠 전에 구글에서 <a href="http://appengine.google.com">Google App Engine</a>이라는 플랫폼을 공개했다. 소식을 접하자 마자 계정 신청을 했는데 오늘 계정이 활성화 됐다는 전자우편이 왔다. Google App Engine에 대해 보다 자세한 우리말 글을 보고 싶다면 likejazz님께서 쓰신 <a href="http://www.likejazz.com/archives/280">구글 웹 어플리케이션 플랫폼: App Engine</a> 글을 참조 바란다.</p>
<h3>2. 가볍게 둘러 본 느낌</h3>
<p>난 방금 전에 Google App Engine (<strong>이하 GAE</strong>)에 예제를 따라 <a href="http://hello-hannal.appspot.com/">Hello world성 문장</a>을 만들어 뿌려봤다. 마침 <a href="http://www.djangoproject.com">Django</a>도 지원하길래 <a href="http://uw.appspot.com/">django를 이용해서 비슷한 일을 해봤다</a>.</p>
<p>이리 저리 둘러 보고</p>
<ul>
<li>이거 정말 짱이다</li>
<li>GAE를 기반으로 하는 서비스가 많아지면 <a href="http://www.passport.com">MS passport</a> 서비스가 실패했던 것과는 달리 Google account(gmail)은 성공할 수 밖에 없다. Open ID보다 더 Open ID스러운 놈이 될 수도 있을 것이다</li>
<li>기획자나 작은 서비스 기업, 혹은 개발자(엔지니어 말고)들은 정말 신나겠다</li>
<li>역시 구글은 무섭다. GAE는 서비스 개발계의 Google Adsense가 될 것이다</li>
</ul>
<p>이와 같은 느낌을 아주 강렬하게 받았다.</p>
<h3>3. 좋은 점</h3>
<p>요즘 개발 인트라넷으로 각광 받고 있는 도구는 <a href="http://trac.edgewall.org/">Trac</a>과 <a href="http://subversion.tigris.org/">Subversion</a>이라고 생각한다. 자료 판숫자(version)나 Wiki를 통한 문서 관리가 편하기 때문이다. 무엇보다 <strong>협업</strong>을 편리하고 안전하게 할 수 있다는 점이 아주 좋다. GAE 역시 이런 점이 잘 되어 있는 걸로 보인다. 잘 되어 있다고 확실하게 말을 하지 못하는 이유는 그런 기능이 보이기는 하지만 아직 제대로 실험을 하지 않았기 때문이고, svn 같은 것도 여전히 따로 필요해 보이기 때문이다.<br />
하지만 소스를 갱신할 때마다 소스 판숫자를 자동으로 올릴 수 있다.</p>
<p>어렵고 골치 아픈 부분은 신경 쓰지 않고 서비스 개발 자체에 집중할 수 있는 환경도 좋은 점이다. 서비스가 잘 되어 확장을 해야 할 때, 개발 초기에 확장성을 고려하지 않으면 큰 고생을 한다. 그래서 개발 초기에 설계에 많은 시간을 들인다. GAE를 쓰면 이런 부분을 신경 쓸 일은 없을 듯 싶다. 서비스 확장을 할 때 Database Server와 Application Server를 주로 확장할텐데 이 두 부분을 GAE가 맡기 때문이다. 서버 뒷단에서 어떻게 분산을 하는지 신경 쓸 것 없이 나는 API로 자료를 꺼내 쓰거나 넣으면 된다.</p>
<p>아직 이용자가 많지 않아서 그런지는 몰라도 GAE 서비스 자체가 빠른 점도 좋다. 값싼 어지간한 웹호스팅 보다 훨씬 낫다. -_-;</p>
<p>SDK도 잘 만들어져 있다. Rails 나 Django가 그러하듯이 GAE SDK도 내장 웹서버가 있어서 GAE에 계정이 없더라도 개발 자체는 진행해 나갈 수 있다. 그리고 이 SDK 기반에서 잘 작동하면 GAE 위에서도 잘 돌아갈 확률이 <strong>높은 편</strong>이다. 왜 “높은 편”이라는 다소 불확실한 말을 썼냐하면, 아직 SDK 완성도가 완전치 않아서 개발 환경(내장 웹서버)에서 잘 작동하는 것이 GAE 안에서는 오류가 나는 경우가 있고, GAE에 소스 코드를 올릴 때 GAE가 소스 파일 일부 내용을 고치는지 개발 환경에서 뜨는 화면과 GAE 위에서 뜨는 화면이 달라지는 경우가 있는 듯 싶다. 대체로 python 경로(path)와 관련된 부분에서 그러한데, GAE에서 제공하는 문서를 보면 어렵지 않게 문제를 피할 수 있다.</p>
<p>이용자 인증 체계도 아주 쉽게 처리할 수 있다. <a href="http://code.google.com/appengine/docs/users/">The Users API 문서</a>를 보면 알겠지만, Google account(Gmail)과 이용자 정보 기능을 연결해놨다. <strong>Google App Engine 을  기반으로 하는 서비스가 많아지면 많아질수록 gmail 계정 하나로 편리하게 서비스에 접근하여 쓸 수 있게 될 것</strong>이다. 이거 어디서 보던 개념 아닌가? 그렇다. 바로 Open ID이다. Open ID는 인증 체계만 덜렁 제공한다면, GAE는 인증 체계와 더불어 Application을 편하게 만드는 환경까지 제공하는 것이다. 정말 기가 막히고 무섭다.</p>
<p>마지막으로 나한테 좋은 점은 (현재) 쓸 수 있는 개발 언어가 python인 점이다. 난 python을 좋아하기 때문이다. <img src='http://www.hannal.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>4. GAE 안쪽 살펴보기</h3>
<p><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_011.jpg" alt="" title="Google App Engine 첫 화면" width="500" height="264" class="alignnone size-full wp-image-1145" /><br />
우선 처음 가면 Application을 만들라고 나온다. 현재는 이용자당 3개를 만들 수 있으며 한 번 만든 Application은 지우거나 ID를 고칠 수 없다.</p>
<p><a href='http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_021.jpg'><img src="http://www.hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_02-300x157.jpg" alt="" title="서비스 로그 영역" width="300" height="157" class="alignnone size-medium wp-image-1146" /></a><br />
Dashboard에는 각 Application(Service) 관련 로그들이 나온다. 서비스 감시 및 현황을 파악할 때 좋을 것이다.</p>
<p>내가 마음에 들어했던 부분은 바로 로그 보기 기능이다. 총 7가지에 로그를 볼 수 있다.</p>
<ul>
<li>debug log line</li>
<li>An info log line</li>
<li>A warning log line</li>
<li>An error log line</li>
<li>A critical log line (most severe)</li>
</ul>
<p><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_031.jpg" alt="" title="각종 로그 내용들" width="500" height="396" class="alignnone size-full wp-image-1147" /></p>
<p>크흑. 정말 기가 막히지 않은가!</p>
<p><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_041.jpg" alt="" title="협업 관리 기능" width="499" height="208" class="alignnone size-full wp-image-1148" /></p>
<p>Google Account를 가진 이용자에 한해서 개발에 참여시킬 수 있다. <a href="http://www.google.com/a">Google apps</a>를 통해 계정을 만든 이용자도 참여가 가능하긴 한데 몇 가지 문제가 있어서 깔끔하게 되지 않는다. gmail.com 계정을 초대하고 참여하는 것이 명랑한 삶을 사는 데 도움이 될 것 같다.</p>
<p>당연히 있을 법한 기능 중 하나는 GAE에 올린 서비스에 도메인을 따로 붙일 수 있는 것이다. 이 기능은 Google apps를 통해야 한다.</p>
<p><a href='http://hannal.net/blog/wp-content/uploads/2008/04/google_apps_setting_021.jpg'><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_apps_setting_021.jpg" alt="" title="관리자 화면에 새 기능이 나오게 하는 설정" width="500" height="111" class="alignnone size-full wp-image-1151" /></a></p>
<p>Google Apps 관리자 화면에 가면 아마 GAE 관련 서비스 추가 항목이 없을 것이다. 그럴 경우 위 그림과 같이 도메인 설정 영역 중 제어판에서 “다음 세대”라는 항목을 적용해야 한다. 그러면</p>
<p><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_apps_setting_011.jpg" alt="" title="Google App Engine에 도메인 연결하기" width="392" height="161" class="alignnone size-full wp-image-1150" /></p>
<p>이와 같은 도메인 연결란이 생긴다. 예를 들면 <a href="http://hello-hannal.appspot.com">http://hello-hannal.appspot.com</a>에 <a href="http://helloworld.hannal.com">http://helloworld.hannal.com</a>을 연결한 것이다.</p>
<h3>5. 실제로 Hello world 찍어보기</h3>
<p>여기서는 GAE에 hello world를 출력하는 과정을 보이는 것이 목적이지 python이나 django 강의를 하는 건 아니다.</p>
<h4>5-1. 어플리케이션 생성</h4>
<p>우선 GAE SDK 디렉토리 안에 GAE에 추가한 Application 디렉토리(폴더)를 하나 만든다. GAE에 만든 Application ID와 꼭 같을 필요는 없다. 근데 여기서는 Django를 이용할 것이므로 django-admin.py 을 이용해 만들기로 하자.</p>
<blockquote><p>django-admin.py startproject uw</p></blockquote>
<p>그러면 <strong>uw</strong>라는 디렉토리가 생기고 django 관련 기본 파일들이 만들어져 있다. 왜 helloworld가 아니라 uw인가하면 별 뜻 없다. hello world가 지겨워서 unlimited world라고 하고 싶었기 때문이다.</p>
<p>이제 <strong>app.yaml</strong> 파일을 uw 디렉토리 안에 만들고 다음 내용을 써넣는다.</p>
<blockquote><pre><code style="font-size: 0.8em; font-family: Arial;">application: uw
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: main.py</code></pre>
</blockquote>
<p>YAML 설정에 대한 자세한 내용은 <a href="http://code.google.com/appengine/docs/configuringanapp.html">Configuring an App 문서</a>를 참조 바란다.</p>
<p>보면 / 로 들어오는 모든 요청을 main.py 이 받게 했다. 이 main.py는 <a href="http://code.google.com/appengine/articles/django.html">Running Django on Google App Engine</a> 문서에 설명이 잘 나와있다. 다만 이 문서대로 하면 settings.py 에서 오류가 발생하는데 settings.py 맨 위에 <strong>import os</strong> 를 써넣으면 된다. 템플릿 경로 지정 문제 때문에 그런 것이다.</p>
<h4>5-2. 화면 만들기</h4>
<p>이번엔 / 로 들어왔을 때 보일 화면을 만들자. 간단하다. 우선 urls.py 에 접근 요청 경로와 이 경로에 연결할 함수를 정의한다.</p>
<blockquote><pre><code style="font-size: 0.8em; font-family: Arial;">urlpatterns = patterns('',
    (r'^$', 'views.root_page'),
    (r'^hannal/$', 'views.goto_hannal'),
)</code></pre>
</blockquote>
<p>난 아무 경로 없이 최상위 경로(/)로 왔을 때 views.root_page 를, /hannal로 왔을 때 views.goto_hannal을 실행하겠다고 했다.</p>
<p>이번엔 views.root_page 를 만들 차례이다. 취향에 따라 views.py 안에 각 함수를 만들어도 되고 views 디렉토리 안에 root_page.py 나 goto_hannal.py 파일을 만들어도 되지만, 난 views.py 안에 각 함수를 만들기로 했다.</p>
<p>urls.py 나 settings.py 파일이 있는 곳에 views.py 를 만든 뒤 다음과 같이 내용을 만든다.</p>
<blockquote><pre><code style="font-size: 0.8em; font-family: Arial;"># -*- coding:utf-8 -*-
from django.http import HttpResponse, HttpResponseRedirect
import django

def root_page(request):
    str = '&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">'
    str += '&lt;html>'
    str += '&lt;head>&lt;title>&lt;/title>&lt;meta http-equiv="content-type" content="text/html; charset=utf-8"/>&lt;/head>'
    str += '&lt;body>'
    str += '&lt;p>안녕하세요, 여러분.  이 화면은 '
    str += '&lt;a href="http://www.djangoproject.com"&gt;Django %s.%s&lt;/a&gt;로 만들었고, '  % (django.VERSION[0],django.VERSION[1])
    str += '&lt;a href="http://appengine.google.com"&gt;Google App Engine&lt;/a&gt;에서 '
    str += '돌리고 있답니다.&lt;/p>'
    str += '&lt;/body>&lt;/html>'

    return HttpResponse(str, mimetype='text/html')

def goto_hannal(request):
    return HttpResponseRedirect('http://www.hannal.net')</code></pre>
</blockquote>
<h4>5-3. 소스 반영 및 확인</h4>
<p><a href='http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_051.jpg'><img src="http://hannal.net/blog/wp-content/uploads/2008/04/google_app_engine_051.jpg" alt="" title="Google app Engine에 소스 갱신하기" width="500" height="327" class="alignnone size-full wp-image-1149" /></a></p>
<p>이제 appcfg.py 를 이용하여 소스를 GAE 서버에 올린다. 처음 실행하면 gmail 계정 인증을 요청하고, 이후엔 .appcfg_cookies 파일을 만들어 인증을 생략한다.</p>
<p>다 올린 뒤 <a href="http://uw.appspot.com">http://uw.appspot.com</a>에 접속하면 화면이 잘 나온다. <a href="http://uw.appspot.com/hannal">http://uw.appspot.com/hannal</a>로 접속하면 http://www.hannal.net 로 이동한다.</p>
<h3>6. 글을 마치며</h3>
<p>기대보다 훨씬 재밌고 끝내주는 서비스, 아니 플랫폼이 등장했다. 시장에 미칠 파급력이 엄청날 것이라고 본다. 기획자도, 소프트웨어 엔지니어가 없거나 경험이 없어 서비스 확장 구조 설계에 어려움을 겪는 작은 팀이나 회사도 모두 매력을 느낄 개발 플랫폼이다.</p>
<p>그나저나 이런 것 나왔으니 <a href="http://www.hannal.net/blog/some_news_for_apr_first_day_2008/">가벼운 말로 꺼낸 django 개발 책</a>을 정말 써야 하는 걸까? ^^</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/say_hello-world_on_google-app-engine_service/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Django 0.97에서 unknown encoding: X-MAC-KOREAN 문제</title>
		<link>http://www.hannal.net/blog/django-097-encoding_error_on_mac/</link>
		<comments>http://www.hannal.net/blog/django-097-encoding_error_on_mac/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 10:10:37 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[오류]]></category>
		<category><![CDATA[인코딩]]></category>
		<category><![CDATA[파이썬]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/?p=1143</guid>
		<description><![CDATA[맥(Mac OS X)에서 Django 0.97 pre1판을 기반으로 개발을 할 때 디버깅 화면이 나오지 않고
unknown encoding: X-MAC-KOREAN
위와 같은 문자열이 들어간 오류 화면이 뜹니다. 저는 맥 언어 환경을 우리말로 했기 때문에 X-MAC-KOREAN 이라고 뜨는 것이죠.
이것은 Django에 있는 tzinfo.py (timezone 정보 관리하는 역할)가 기본 locale 을 가져와서 그럴싸한 문자열을 만들려 하기 때문에 맥 환경에서 발생하는 문제입니다. 이게 0.97 [...]]]></description>
			<content:encoded><![CDATA[<p>맥(Mac OS X)에서 Django 0.97 pre1판을 기반으로 개발을 할 때 디버깅 화면이 나오지 않고</p>
<blockquote><p>unknown encoding: X-MAC-KOREAN</p></blockquote>
<p>위와 같은 문자열이 들어간 오류 화면이 뜹니다. 저는 맥 언어 환경을 우리말로 했기 때문에 X-MAC-KOREAN 이라고 뜨는 것이죠.</p>
<p>이것은 Django에 있는 tzinfo.py (timezone 정보 관리하는 역할)가 기본 locale 을 가져와서 그럴싸한 문자열을 만들려 하기 때문에 맥 환경에서 발생하는 문제입니다. 이게 0.97 언제쯤 고쳐질지는 모르겠으니 일단 아쉬운대로 고쳐서 써봅시다. (음냐. 이러면 svn update 할 때 conflict 뜨는데 그 해결은 알아서 하세요)</p>
<p>대상 소스 파일 : <strong>django/utils/tzinfo.py</strong></p>
<p>위 파일을 열면</p>
<pre>try:
    DEFAULT_ENCODING = locale.getdefaultlocale()[1] or 'ascii'
except:
    # Any problems at all determining the locale and we fallback. See #5846.
    DEFAULT_ENCODING = 'ascii'</pre>
<p>이런 부분이 나옵니다. 소스 파일 안에서 거의 맨 위에 있지요. 여기서 문제가 되는 부분이 바로 try 안에 있는 녀석입니다. 맥에서는 저걸 실행하면 <strong>X-MAC-뭐시기</strong>라고 가져옵니다. 그런 게 없으니 오류가 나는 것이고요. 그 아래에 <strong>DEFAULT_ENCODING = &#8216;utf-8&#8242;</strong>을 넣어주면 오류 안납니다.</p>
<pre>try:
    DEFAULT_ENCODING = locale.getdefaultlocale()[1] or 'ascii'
    <strong>DEFAULT_ENCODING = 'utf-8'</strong>
except:
    # Any problems at all determining the locale and we fallback. See #5846.
    DEFAULT_ENCODING = 'ascii'</pre>
<p>이러면 django의 디버깅 화면이 잘 나옵니다. 찝찝하면 DEFAULT_ENCODING = locale.getdefaultlocale()[1] or &#8216;ascii&#8217; 를 주석으로 하세요.</p>
<p>여기서 교훈 한 마디. 역시 시험판, 특히 미리맛보기판(pre version)은 안쓰는게 정신 건강에 좋다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/django-097-encoding_error_on_mac/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>써 본 웹 프레임워크에 대한 감상. (django, cakephp)</title>
		<link>http://www.hannal.net/blog/blarblar_about_some_web_frameworks-django_cakephp/</link>
		<comments>http://www.hannal.net/blog/blarblar_about_some_web_frameworks-django_cakephp/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 12:09:05 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[프레임워크]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/blarblar_about_some_web_frameworks-django_cakephp/</guid>
		<description><![CDATA[최근에 웹 프레임워크 두 가지를 이래 저래 쓰며 찔러보고 있다. 하나는 Python으로 구현된 Django이고, 또 하나는 PHP로 구현된 Cakephp이다. Django로는 미투데이용 장난감 서비스인 그림자놀이를 만들어서 서비스 중이고, Cakephp로는 회사에서 내가 주도하며 쓰고 있다.
Django를 쓴 기간은 길긴 한데 집에서 취미로 만지며 써서 집중도가 좀 떨어진다. Cakephp는 얼마 안되지만 밥벌이로 만지다보니 아무래도 집중도가 좀 더 높다. 어쨌건 [...]]]></description>
			<content:encoded><![CDATA[<p>최근에 웹 프레임워크 두 가지를 이래 저래 쓰며 찔러보고 있다. 하나는 Python으로 구현된 <a href="http://www.djangoproject.com">Django</a>이고, 또 하나는 PHP로 구현된 <a href="http://www.cakephp.org">Cakephp</a>이다. Django로는 <a href="http://shadow.hannal.com/me2day">미투데이용 장난감 서비스인 그림자놀이</a>를 만들어서 서비스 중이고, Cakephp로는 회사에서 내가 주도하며 쓰고 있다.</p>
<p>Django를 쓴 기간은 길긴 한데 집에서 취미로 만지며 써서 집중도가 좀 떨어진다. Cakephp는 얼마 안되지만 밥벌이로 만지다보니 아무래도 집중도가 좀 더 높다. 어쨌건 이 글을 쓸 만큼 좀 익숙해지고 구조나 흐름을 이해한 상태이다.</p>
<p>두 프레임워크는 RoR이라고도 불리며 인기를 끌고 있는 <a href="http://www.rubyonrails.org/">Rails</a> 프레임워크에 많은 영향을 받았다. 그래서 쓰는 법이나 흐름이 비슷하다. 물론, Rails는 Ruby용, Django는 Python용, Cakephp는 Php용이라서, 언어 특유한 정책이나 철학에 영향을 받아 좀 파고 들다보면 차이가 생길 수 밖에 없다. 그래도 “Hello world” 찍는 방법이나 웹 프로그래밍 할 때 들어가는 잔손질을 많이 줄여주는 방법도 비슷하다.</p>
<hr />
<p>Django는 Python 언어 특성 덕에 참 간결하고 빠르게, 그리고 편하게 적응하며 쓸 수 있다. Rails는 제대로 쓴 적 없이 가벼이 둘러 본 정도라서 비교를 할 순 없지만, Cakephp와 비교하면 정말 쉽고 간편하다. Cakephp도 따로 프레임워크를 쓰지 않고 php로 웹 개발을 하는 것보다 훨씬 편하긴 한데, Django와 비교하면 “왜 이런 것까지 내가 코딩하고 있어야 하지?”라는 생각이 절로 든다.</p>
<p>개발자와 운영자 입장에서 간결하고 편하고 쉽다는 건 무슨 말일까. 사람마다 다른 생각이 있겠지만, 내 생각엔 서비스 중 cgi 문제가 생겼을 때 그 문제를 찾아가 고치거나, 혹은 기능을 추가할 때 어디를 어떻게 건드리면 되는지 금방 찾을 수 있는 것이라 본다. 그런 점에서 Django로 개발을 하다보면 서비스 흐름이나 구조를 이해하고 추적하기 매우 편하다. 아주 큰 서비스를 만든다면야 그 많은 부분을 머리 속에 다 담을 수 없을테니 당연히 추적하는 데 시간이나 노력이 많이 들겠지만, Django는 소스 자체가 간결하고 프레임워크 흐름 자체가 명료해서 그런 개발/운영 비용이 적게 든다고 본다.</p>
<p>Django는 물론, Python 자체가 상당히 빠른 장점도 있다. Python 자체가 선처리저장소(Caching, 캐쉬)와 비슷한 기능을 가진데다(*.py를 실행하고 나면 컴파일 된 *.pyc 을 만드는데 이게 좀 더 실행이 빠르다), Fast-cgi 로 돌리면 정말 반응이 빨라진다. 여기에 Django에 내장된 선처리저장소 기능을 쓰면 응답 화면이 “팍” 뜬다. php도 fast-cgi로 돌려봤지만 Django 속도에 비할 바가 못된다.</p>
<p>내장 웹서버가 있는 점도 큰 장점이다. 굳이 덩치 큰 아파치 웹서버를 띄워 거기서 개발을 할 필요 없이 아주 작고 가벼운 내장 웹서버로 소스를 웹서버에 재적재(reload)하거나 다국어 기능용 문자열 변환 저장소(gettext에서 쓰는 mo 파일)도 그때 그때 반영할 수 있다. fast-cgi 로 개발할 경우 소스를 변경할 때마다 웹서버를 재실행하여 소스를 웹서버에 재적해야 하기 때문에, 이런 내장 웹서버는 개발에 많은 도움을 준다.</p>
<p>문제가 없는 건 아니다. Django 자체는 좋은 편이지만 이걸 개발하고 관리하는 측이 참 아쉽다. <a href="http://www.hannal.net/blog/django_096_to_0961/">하위 판(version) 호환성 유지를 위한 노력도 부족해보이고</a>(무심코 Django를 판올림 하다가는 오류 나서 고생하기 쉽상이다), 기능 갱신도 느린 편이다. 재작년인가 작년 초에 Django 0.9x를 봤는데 아직도 0.96.1 이다.</p>
<p>두 번째 불만은 다중 Database를 지원하지 않는 점이다. Django는 아직 다중 DB 접속을 정식으로 지원하지 않는다. 무슨 말인가 하면, MVC 구조로 예를 들면 각 모델(Model)마다 연결할 DB를 따로 지정할 수 없다는 말이다. Scaling up (확장형 서비스 확대)이라면 모르겠지만, Scaling out(분산형 서비스 확대) 방식을 한다면 Django가 참 불편하다. 물론, 아직 정식판에 적용이 안된 <a href="http://code.djangoproject.com/ticket/1142">다중 DB 접속 기능</a>이 있긴 한데, 저 기능 개발을 시작한 때가 2006년 1월인데도 아직 정식 반영 안된 걸 보면 답답할 따름이다. Django가 판올림하면서 정책을 또 확 뒤엎으면 저 기능을 쓰다 뒤통수 맞을 수 있기 때문이다.</p>
<p>그래서 요즘 <a href="http://www.turbogears.org">Turbogears</a>라는 또 다른 웹 프레임워크에 관심을 두고 있다. Turbogears는 앞서 언급한 Django 장점을 거의 그대로 가진데다, 내가 Django에서 불만스러워 했던 <a href="http://docs.turbogears.org/1.0/SQLAlchemy#multiple-databases">다중 DB 접속 기능도 제공</a>한다. 인터넷 돌아다니다가 <a href="http://www.devchix.com/2007/06/03/python-web-frameworks-are-template-languages-worth-using-or-is-python-enough/">Python Web Frameworks: Are Template Languages Worth using, or is Python enough?</a>라는 글을 공감하며 읽었는데, 이 글에서 권하는 PythonPaste 나 CherryPy 중 CherryPy를 Turbogears에서 채택하고 있어서 더 관심이 가기도 했다.</p>
<p>아직 Turbogears를 써보지 않아 두 프레임워크의 차이점을 세세히 꼽을 순 없지만, Django는 기능들을 자체 개발하여 Django라는 이름으로 제공한다면, Turbogears는 기존에 만들어져 있던 <a href="http://lastmind.net/blog/2006/10/framework-21-rubyonrails-vs-turbogears-part-2.html">모듈들을 Turbogears라는 이름으로 조합한 점</a>이다(표현이 좀 이상한데 주소 연결한 글 참조 바람). 장점이야 각 부문별로 기능이나 성능이 검증된 모듈(module, library)를 쓰고 쉽게 갈아 끼울 수 있다는 점이고, 단점이라면 이게 혹시라도 Turbogears라는 이름으로 일관된 정책으로 잘 묶여 있지 않으면 개발이나 학습에 비용이 많이 깨질 수 있다는 점이다.</p>
<hr />
<p>Cakephp는 꽤 인기 좋은 Php 웹 프레임워크로 보인다. 무엇보다 가장 큰 장점은 <a href="http://manual.cakephp.co.kr">한글 문서</a>가 꽤 잘 구비되어 있다는 점이고, <a href="http://api.cakephp.org/">Cakephp API 문서</a>도 잘 준비되어 있어서 좀 막연한 클래스나 메소드가 있을 때 참조하기 좋다.</p>
<p>Rails와 닮은 프레임워크들이 보통 그렇듯이, Cakephp도 오류 상황에 대해 꽤 친절한 편이다. 모델과 연결되는(mapping) DB 테이블이 없으면 그거 없다고 안내하고, 컨트롤러가 이상하거나 없으며 그에 대해 안내하고. 따로 문서를 보지 않고 Cakephp가 뿌려주는 오류 안내문만 따라가도 Hello world 는 아주 손쉽게 출력할 수 있다.</p>
<p>Cakephp의 좋은 점 중 하나는 웹 개발할 때 많이 쓸 법한 메소드나 기능은 아예 클래스에 기본 실행으로 탑재를 해놨다는 점이다. 예를 들면, 컨트롤러에서 화면 출력을 하는 기능이 render 라는 메소드인데, 굳이 이걸 넣지 않아도 알아서 저 함수를 실행해준다. Django는 언어 자체 특성상 소스 코드가 간결하다면, Cakephp는 Php 자체가 소스 코드를 지저분하게 하는 마력이 있다보니 아예 자주 쓸 법한 소스 문장을 쓰지 않아도 해버렸다. 뭐, 그래도 어쨌건 소스 코드가 지저부 해지는 건 어쩔 수 없다.</p>
<p>Cakephp에서 기본으로 탑재하여 쓰고 있는 템플릿 엔진은 사실 템플릿 엔진이라 부르기 민망한 놈이다. 그냥 템플릿 파일 안에 Php로 코딩을 하는 것이다. 몇 번이나 재차 말하듯이 php의 소스 코드는 놀라울만큼 지저분해지기 쉬운 편이라서(난 Perl이나 C 소스보다 php소스를 더 싫어한다), 웹 디자이너가 만지작 거릴 템플릿 파일도 php 코드로 지저분해지기 쉽다.</p>
<p>이 문제는 템플릿 엔진을 <a href="http://www.xtac.net">Template_</a>같은 녀석으로 갈아 끼우면 <a href="http://coolengineer.com/409">쉽게 해결</a>된다. 바로 이 점도 Cakephp 장점 중 하나이다. vendor 라는 정책(?)을 통해 꽤 쉽게 Cakephp 요소 요소를 다른 걸로 갈아 끼우거나 보완할 수 있게 해놨다.</p>
<p>Cakephp는 Django와는 달리 다중 DB 접속 기능을 지원한다. 사실 원하는 만큼 깔끔하고 멋지게 제공하진 않지만, 어쨌건 되긴 된다. 좀 석연치 않은 부분은 Cakephp의 기본 흐름대로 다중 DB에 접근을 할 때 DB마다 따로 지정한 전구분자(prefix)를 제대로 처리하지 못하거나, 모든 DB에 모델에 연결될 테이블이 있어야 한다는 점이다. Hannal 모델은 db1 에 연결하고, peculiarday 모델은 db2에 연결할 때, db1 과 db2 모두 Hannal과 peculiarday 모델용 DB 테이블이 있어야 한다. 이건 아직 확신을 못하는 게 내가 아직은 Cakephp 전체 흐름에 아주 능숙하지 않기 때문이다.</p>
<p>대체로 Cakephp 기능들은 만족스럽다. Cakephp 뿐 아니라 php 자체에 함수들이 워낙 많은데다, 많은 사람들이 쓰는 언어이다 보니 쓸만한 라이브러리가 정말 많다. 그래서 검증되고 쓸만한 기능을 찾지 못해 시간 낭비할 일은 별로 많지 않다.</p>
<p>다만, Cakephp 자체가 좀 느린 편이다. php 반응 속도는 빠른 편이라고 생각하는데, Cakephp는 좀 멈칫하는 것이 느껴진다. 전처리저장소(Caching) 기능을 쓰면 낫긴 하지만, 여러 단계를 거치는 과정 자체가 좀 느리다. Django와 비교하면 많이 답답하다. 둘 다 Fast-cgi 로 돌렸는데 화면 반응은 확실히 Django가 빠르다.</p>
<p>요즘이야 컴퓨터 부품 값이 워낙 싸서 좀 된다 싶은 서비스라면 저렴하게 웹 서버 여러 대 열면 어느 정도 속도는 보장 될테고, 어느 정도 안정된 반응 속도만 보여준다면, 그러니까 아주 빠르지도 않지만 그렇다고 아주 느려지는 현상도 별로 없는 일정함만 보장된다면 대형 서비스에선 아주 빠른 속도가 꼭 필요하지 않을 수는 있다. 즉, Cakephp가 살짝 느린 응답을 보인다고 해서 속상해 할 일은 없다고 본다. 게다가 슬쩍 보건데 Cakephp가 Rails 보다는 빠른 것 같다. 이 정도면 좋지 뭐.</p>
<hr />
<p>아마 요즘 회사에서 하는 일 중 내 역할이 끝나면 난 다시 Cakephp를 만질 일은 없을테고(php 자체를 별로 좋아하지 않으니까), Turbogears가 마음에 든다면 Django도 다시 건드리진 않을 것 같다. 둘 다 괜찮은 프레임워크이긴 하지만, 이리 저리 써보니 내 성향에 꼭 들어 맞진 않는다. 웹 개발을 주업이 아닌 취미로 해서 내가 이놈들을 내 입맛에 맞게 고쳐가며 쓰는 상황을 애써 피하려다 보니 입맛에 안맞으면 안쓰게 된다. 현재까지는 그래도 Django가 가장 낫긴 하지만 말이다. <img src='http://www.hannal.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (내가 다중 DB 접속 기능을 쓸만큼 규모가 큰 웹 서비스를 개발할 일은 없으니까)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/blarblar_about_some_web_frameworks-django_cakephp/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>python에서 초성/중성/종성 뽑아내기, 음소로 나누기</title>
		<link>http://www.hannal.net/blog/split_hangul_by_python/</link>
		<comments>http://www.hannal.net/blog/split_hangul_by_python/#comments</comments>
		<pubDate>Sun, 17 Feb 2008 10:32:31 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[한글]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/python%ec%97%90%ec%84%9c-%ec%b4%88%ec%84%b1%ec%a4%91%ec%84%b1%ec%a2%85%ec%84%b1-%eb%bd%91%ec%95%84%eb%82%b4%ea%b8%b0-%ec%9d%8c%ec%86%8c%eb%a1%9c-%eb%82%98%eb%88%84%ea%b8%b0/</guid>
		<description><![CDATA[기록 차원에서 간단하게 적어두기.
아래 코드들은 CJKCodec 이 설치된 python 2.4부터 가능하며, 전부 unicode(utf-8)로 처리된다. 만약, CJKCodec이 안깔려있다면 CJKPython에서 받아서 깔면 된다.
1. 글자 종류 알아내기
* 코드

# -*- coding:utf-8 -*-
from unicodedata import name

str = u'가'

print name(str)[:6]


* 실행 결과

>>> HANGUL


2. 한글을 음소로 나누기
* 코드

# -*- coding:utf-8 -*-
import hangul

str = u'안'

print hangul.split(str)


* 실행 결과

>>> (u'\u3147', u'\u314f', u'\u3134')


3. 종성(끝소리) 있는지 [...]]]></description>
			<content:encoded><![CDATA[<p>기록 차원에서 간단하게 적어두기.<br />
아래 코드들은 CJKCodec 이 설치된 python 2.4부터 가능하며, 전부 unicode(utf-8)로 처리된다. 만약, CJKCodec이 안깔려있다면 <a href="http://cjkpython.berlios.de/index-ko.html">CJKPython</a>에서 받아서 깔면 된다.</p>
<h3>1. 글자 종류 알아내기</h3>
<blockquote><p>* 코드</p>
<pre>
# -*- coding:utf-8 -*-
from unicodedata import name

str = u'가'

print name(str)[:6]
</pre>
</blockquote>
<blockquote><p>* 실행 결과</p>
<pre>
>>> HANGUL
</pre>
</blockquote>
<h3>2. 한글을 음소로 나누기</h3>
<blockquote><p>* 코드</p>
<pre>
# -*- coding:utf-8 -*-
import hangul

str = u'안'

print hangul.split(str)
</pre>
</blockquote>
<blockquote><p>* 실행 결과</p>
<pre>
>>> (u'\u3147', u'\u314f', u'\u3134')
</pre>
</blockquote>
<h3>3. 종성(끝소리) 있는지 확인</h3>
<blockquote><p>* 코드</p>
<pre>
# -*- coding:utf-8 -*-
import hangul

str = u'안'

if hangul._has_final(str):
    print 1
else:
    print 0
</pre>
</blockquote>
<blockquote><p>* 실행 결과</p>
<pre>
>>> 1
</pre>
</blockquote>
<h3>4. 초성만 뽑아내기</h3>
<blockquote><p>* 코드</p>
<pre>
# -*- coding:utf-8 -*-
import hangul

str = u'안'

a = []
for ch in str:
    if name(ch)[:6] == 'HANGUL':
        a.append(hangul.split(ch)[0])
</pre>
</blockquote>
<blockquote><p>* 실행 결과</p>
<pre>
>>> ['ㅇ','ㄴ','ㅎ','ㅅ','ㅇ']
</pre>
</blockquote>
<p>중성만 뽑아내려면 <strong>hangul.split(ch)[0]</strong>을 <strong>hangul.split(ch)[1]</strong>, 종성은 <strong>hangul.split(ch)[2]</strong>이라고 하면 된다.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/split_hangul_by_python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>django 0.96 에서 0.96.1로 판올림 할 때 주의할 점</title>
		<link>http://www.hannal.net/blog/django_096_to_0961/</link>
		<comments>http://www.hannal.net/blog/django_096_to_0961/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 15:32:35 +0000</pubDate>
		<dc:creator>Hannal</dc:creator>
				<category><![CDATA[잘난 척 하기]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://www.hannal.net/blog/django_096_to_0961/</guid>
		<description><![CDATA[python에서 쓸만한 웹 프레임워크인 django를 0.96에서 0.96.1로 판올림 할 때 주의할 점이 있습니다. Django 공식 누리집에는 0.96을 기준으로 문서가 나와있어서 무작정 django를 최신판으로 판올림하면 오류가 발생합니다. 잘 되던 소스가 갑자기 뻗어서 깜짝 놀랐네요.
DB Model
기존엔 문자열 최대 길이를 지정할 때 maxlength 라는 예약어를 썼는데 0.96.1부터는 max_length를 씁니다.
class Entries(models.Model):
	me2permalink = models.CharField(max_length=250, null=False)
	content = models.TextField(max_length=150, null=True)
	comment_count = models.SmallIntegerField(default=0, [...]]]></description>
			<content:encoded><![CDATA[<p>python에서 쓸만한 웹 프레임워크인 django를 0.96에서 0.96.1로 판올림 할 때 주의할 점이 있습니다. Django 공식 누리집에는 0.96을 기준으로 문서가 나와있어서 무작정 django를 최신판으로 판올림하면 오류가 발생합니다. 잘 되던 소스가 갑자기 뻗어서 깜짝 놀랐네요.</p>
<h3>DB Model</h3>
<p>기존엔 문자열 최대 길이를 지정할 때 <strong>maxlength</strong> 라는 예약어를 썼는데 0.96.1부터는 <strong>max_length</strong>를 씁니다.</p>
<pre>class Entries(models.Model):
	me2permalink = models.CharField(<strong>max_length</strong>=250, null=False)
	content = models.TextField(<strong>max_length</strong>=150, null=True)
	comment_count = models.SmallIntegerField(default=0, null=True)
	voted = models.SmallIntegerField(default=0, null=True)
	reg_date = models.DateTimeField(auto_now_add=True)
	channel = models.SmallIntegerField(default=1, null=False)
</pre>
<p>위 예제는 <a href="http://shadow.hannal.com/me2day">미투데이용 그림자놀이</a>에서 쓰고 있는 글 저장 테이블.</p>
<h3>i18n에서 ugettext 오류</h3>
<p>0.96.1에선 <strong>ugettext</strong> 가 빠졌습니다. 그냥 <strong>gettext</strong>를 쓰면 됩니다. 어차피 python 자체도 unicode 기반으로 돌아가는데 ugettext가 좀 무의미하긴 했죠.</p>
<pre>from django.utils.translation import <strong>gettext</strong> as _</pre>
<h3>HttpResponse에서 content_type</h3>
<p>HttpResponse로 문자열을 뿌릴 때 <strong>content_type=&#8217;text/javascript&#8217;</strong> 이런 식으로 content_type을 쓰면 안됩니다. 0.96.1부터 없어졌기 때문이죠. 원래 있던 mimetype만 쓰면 됩니다.</p>
<pre>HttpResponse(ret_data, <strong>mimetype</strong>='text/javascript')</pre>
<h3>template tag로 문자열 넘길 때 utf-8 문제</h3>
<p>django에서 템플릿 태그를 만들어서 쓰고 있습니다. 문자열을 넘기면 일부를 잘라다 출력합니다.</p>
<p>{{comment.entry.content|cutstring:20}}</p>
<p>이러면 comment.entry.content 에 들어가 있는 문자열을 내가 만든 cutstring이라는 함수로 넘깁니다. 이 함수는 이렇게 생겼습니다.</p>
<pre>def cutstring(value, length):
	if len(value) > length:
		return value[0:length] + '...'
	return value
cutstring = stringfilter(cutstring)
</pre>
<p>보시다시피 아주 간단하죠. 근데 0.96.1로 판올림을 하니까 value로 넘겨 받은 문자가 utf-8가 아니라 ascii였습니다. 언제나 그런 것도 아니고 어떨 때는 unicode로 넘기고 어떨 때는 ascii. -_-; 이 둘 큰 차이점은 ascii는 위와 같이 문자열을 자를 때 byte 단위로 자르고, unicode는 글자 단위로 자르는 데 있습니다. 이때문에</p>
<pre>s1 = '안녕? 반가워'
s2 = u'안녕? 반가워'</pre>
<p>라고 하고, s1[0:5] 라고 하면 &#8216;안녕?&#8217;이 나오고, s2[0:5]라고 하면 &#8216;안녕? 반&#8217;이 나옵니다.</p>
<p>실제로 utf-8로 처리 됐으면 &#8216;나만의 (자칭 귀여운) 강박증. 걸을&#8217; 이라고 잘려야 할 문자열이 ascii로 되면서 &#8216;나만의 (자칭 �&#8217;라고 잘렸습니다.</p>
<p>이런 경우 <a href="http://www.djangoproject.com/documentation/unicode/#conversion-functions">문서에서는 force_unicode()</a>를 쓰라고 하지만, svn이나 웹으로 받은 django 0.96.1 어디에도 저런 놈은 없었습니다. 문서대로라면 django/utils/encode.py 에 있어야 하는데, 0.96.1엔 없고 <strong><ins datetime="2008-02-09T09:57:10+00:00">0.97 pre판부터 django/utils/encoding.py 에 있습니다</ins></strong>.</p>
<p>결국, 강제로 unicode로 문자열을 바꿔서 해결했습니다.</p>
<pre>def cutstring(value, length):
	<strong>if type(value) != 'unicode':
		value = unicode(value, 'utf-8')</strong>
	if len(value) > length:
		return value[0:length] + '...'
	return value
cutstring = stringfilter(cutstring)
</pre>
<p>단, 0.97 pre판부터는 위와 같이 하면 unicode는 지원하지 않는다며 오류가 납니다. 이때에는 value = unicode(value, &#8216;utf-8&#8242;) 이라고 하지 말고 <strong>value = force_unicode(value)</strong>이라고 해야 합니다. 이런 식으로 처리하면 되겠죠. (start_unicode 같은 애들도 있는데, 각 각의 차이점은 <a href="http://www.djangoproject.com/documentation/unicode/#conversion-functions">Unicode data in Django</a> (공식 문서)를 참조하세요.)</p>
<pre>
import django
<strong>if django.VERSION[0] == 0 and django.VERSION[1] >= 97:
    from django.utils.encoding import force_unicode</strong>

def cutstring(value, length):
	if type(value) != 'unicode':
            <strong>if django.VERSION[0] == 0 and django.VERSION[1] < 97:
		value = unicode(value, 'utf-8')
            else:
                value = force_unicode(value)</strong>

	if len(value) > length:
		return value[0:length] + '...'
	return value
cutstring = stringfilter(cutstring)
</strong></pre>
<p>아참. 넘어오는 문자열이 혹시 utf-8가 아니라 euc-kr 같은 것이라면 unicode(value, &#8216;utf-8&#8242;) 가 아니라 unicode(value, &#8216;euc-kr&#8217;) 이라고 해야 합니다..</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hannal.net/blog/django_096_to_0961/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
