프로그래밍이 점점 재미있어지는 요즘이다.
특히 안드로이드 프로그래밍을 시작한 지금, 뭔가 해 보겠다는 의욕이 조금은 더 생기는 것 같다.
그러나 한편으로는 진짜 공부해야 할 것들을 놓치는 건 아닌지 걱정이 되기도 한다.
그런 의미에서 그동안 생각만 해 왔던 WordNet 자원을 한번 사용해 보기로 하고 열심히 찾았다.
난 역시 한계가 있는가, 스스로 찾은 자료는 정말 이해하기 어렵가 사용하는 것도 안되었다.
http://opensource.ebswift.com/WordNet.Net/
하지만 이 사이트에서 Google Developer 내에 있는 오픈 소스를 다운로드받을 수 있는 방법인
TortoiseSVN 을 세팅하고 사용하는 방법을 알 수 있어서 그다지 손해는 아니었다고 생각되었다.
http://opensource.ebswift.com/WordNet.Net/howtocheckout.aspx
헤매던 중 마침 Nimit가 조언을 해 주고 좋은 자료를 찾아줘서 다운로드를 받을 수 있었다.
안내 페이지 - http://links.cse.msu.edu:8000/members/matt_gerber/index.php/NLP_software#WordNet_API
진짜 자료 위치 - http://links.cse.msu.edu:8000/svn/NLP/Source/ResourceAPIs/WordNet/
열심히 쳐다보고 이리저리 강구해서 드디어 WordNet 3.0 자료를 C#으로 찾아볼 수 있도록 하는 작업을 완료했다.
이제 사용만 하면 되는가... 싶어서 열심히 (사실 개체정의만 끌어다 쓰기 때문에 쉽지만) 짰는데
이런... 한번은 잘 되는데 두번째 넣으니 다른 프로세스가 사용하고 있다고 IO Exception이 나오네...
Process 문제이나 Thread로 정의를 했는가 싶어 책을 뒤지고,
구조적 문제가 아닌 가 싶어 살핀답시고 내용도 구조도 모르는 소스코드 파일 쳐다보고,
뭐 도움 얻을 일 없을까 해서 질문을 할까 말까, 뭘 질문해야 하나 고민하다 이틀을 그냥 보냈다.
그러다 갑자기 오늘 아침에 개체가 프로세스에 중복된다면 놔 주면 되잖나 하는 생각을 했다.
그냥 개체 선언 끝머리에 Close()를 달아주는 것... stream이나 XmlDocument 사용시 필수인 것들.
붙이고 나니 이런, 잘 된다. 여하튼 머리는 폼으로 있는 게 아니라 쓰라고 있는 것임을 다시 한번 느끼며
오늘도 또 다음 단계를 향해서 나아간다. 비록 소가 걷듯 횡보이지만, 힘들어도 재미있다^^
Showing posts with label 01 C#. Show all posts
Showing posts with label 01 C#. Show all posts
2010-06-27
2010-04-09
Inconsistent Accessibility 에러의 해결
참조페이지 : http://msdn.microsoft.com/ko-kr/library/be25s2h2.aspx
Copy & Paste를 많이 하고 컴파일을 하다 보니 에러에 접하는 일이 많아진다.
이번에는 Inconsistent Accessibility 에러가 발생하고 있었는데, 쉬운 듯 하면서도 해결을 못했다.
그래도 이번에는 MSDN을 참고하면서 금방 해결할 수가 있었다.
하나의 Class 내에 자료형으로 사용하는 또 하나의 Class를 사용하고 있었는데,
자료형으로 사용하는 Class를 Public 지정을 안해 놨더니 access할 수 없다고 에러가 나는 거였다.
해당 Class를 Public으로 명시해 주었더니 바로 해결이 되었다.
더불어 명시가 없으면 Private class로 취급한다는 사실도 알게 되었다.
알면 알 수록 신기한... 일들이...
Copy & Paste를 많이 하고 컴파일을 하다 보니 에러에 접하는 일이 많아진다.
이번에는 Inconsistent Accessibility 에러가 발생하고 있었는데, 쉬운 듯 하면서도 해결을 못했다.
그래도 이번에는 MSDN을 참고하면서 금방 해결할 수가 있었다.
하나의 Class 내에 자료형으로 사용하는 또 하나의 Class를 사용하고 있었는데,
자료형으로 사용하는 Class를 Public 지정을 안해 놨더니 access할 수 없다고 에러가 나는 거였다.
해당 Class를 Public으로 명시해 주었더니 바로 해결이 되었다.
더불어 명시가 없으면 Private class로 취급한다는 사실도 알게 되었다.
알면 알 수록 신기한... 일들이...
2010-02-22
이제서야 구현한 Recursive algorithm
남이 해놓은 설명만 보면서 살다가 생각좀 해서 이제서야 구현했다.
아직까지는 잘 되는 것 같은데... 알 수 없는 일이다^^
아래는 query를 공백을 기준으로 string[]으로 나눠서 놓고
검색결과 content를 공백으로 나눈 string[]와 비교해서 부분일치 및 완전일치를 카운트하는 예제다.
비교의 정확성을 위해서 porter stemmer를 이용했다.
int queryindex = 0;
int contentindex = 0;
Again:
if (myps.DoFilter(query[queryindex]) == myps.DoFilter(termindoc[contentindex]))
{
countbroken[queryindex]++;
isBrokenCountExist = true;
contentindex++;
if (queryindex == query.Length - 1)
{
count++;
queryindex = 0;
if (contentindex < termindoc.Length)
{
goto Again;
}
else
{
goto Exit;
}
}
else
{
queryindex++;
if (contentindex < termindoc.Length)
{
goto Again;
}
else
{
goto Exit;
}
}
}
}
Exit :
아직까지는 잘 되는 것 같은데... 알 수 없는 일이다^^
아래는 query를 공백을 기준으로 string[]으로 나눠서 놓고
검색결과 content를 공백으로 나눈 string[]와 비교해서 부분일치 및 완전일치를 카운트하는 예제다.
비교의 정확성을 위해서 porter stemmer를 이용했다.
int queryindex = 0;
int contentindex = 0;
Again:
if (myps.DoFilter(query[queryindex]) == myps.DoFilter(termindoc[contentindex]))
{
countbroken[queryindex]++;
isBrokenCountExist = true;
contentindex++;
if (queryindex == query.Length - 1)
{
count++;
queryindex = 0;
if (contentindex < termindoc.Length)
{
goto Again;
}
else
{
goto Exit;
}
}
else
{
queryindex++;
if (contentindex < termindoc.Length)
{
goto Again;
}
else
{
goto Exit;
}
}
}
}
Exit :
2009-09-08
ContextSwitchDeadlock 에러의 해결
참고 : http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/8630a1bb-fc65-49e5-8b37-bf77378e380f
그동안 많은 텍스트 데이터 조작을 통해서 작업을 하다 보니 CPU나 메모리 자원이 부족한 경우가 많았다.
특히 개발 초기에는 개체를 해제하는 Close() 명령을 아예 모르다 보니 무한정 자원을 붙잡고 있는 경우도 있었고
형태소 분석기의 자료처리 한계 도달 등 한정적인 상황에 대한 대처만 해 왔던 터라 이해가 부족한 것도 사실이었다.
이번에는 프로그램 전반에서 텍스트 데이터를 광범위하게 사용하고 있으며, 분석 과정에 시간이 많이 소요되는
웹 자료 가져오기 (HttpWebRequest / Response)도 자주 사용하다 보니 같은 문제에 직면하게 되었다.
그동안 임시방편으로 사용하던 Application.Doevents()와 같은 Message Pump 해결방법으로는 무리가 되었다.
결국은 에러 메시지를 기반으로 ContextSwitchDeadlock 문제의 근본적인 해결을 추구하는 게 좋을 것 같았다.
기본적으로 Deadlock이 자원공유 위반으로부터 야기된다는 것을 초급교재에서 보아서 알고 있었고
프로그래밍시에 이 부분은 기본적으로 회피하면서 작업을 해 왔기에 (이름을 다르게 하는 등) 더욱 혼동이 되었는데
오늘 비로소 문제를 해결한 것 같다.
참고 자료의 해석에 따르면, CLR을 COM 기반으로 해석하는 가운데 해당 에러의 우려가 감지되는 경우 리턴되는 메시지로,
크게 위험성은 없는 것이라고 한다.
물론 실시간 시스템 등 연구 목적이 아닌 경우는 응답이 무한정 길어질 염려는 있는 것으로 보이지만
내게는 그저 불편할 뿐이니...
해결 방법으로 가장 간단하게 제시된 것은 VS Debugger에서 해당 에러 메시지의 리턴을 안 하게
옵션을 해제하는 방법이다.
메뉴바의 Debug - Exceptions - Managed Debugging Assistants 항목에서 ContextSwitchDeadlock 체크를 지우는
아주 간단한 작업만으로 이 문제가 해결되는 것으로 보인다.
지금 보다 큰 작업으로 테스트를 하고 있는데 잘 작동이 되는 것으로 생각되고 있다.
하지만 앞에서 말한 대로 단점도 분명히 존재하는 경우이니 옵션에 대한 지식은 필수일 것으로 생각된다.
그동안 많은 텍스트 데이터 조작을 통해서 작업을 하다 보니 CPU나 메모리 자원이 부족한 경우가 많았다.
특히 개발 초기에는 개체를 해제하는 Close() 명령을 아예 모르다 보니 무한정 자원을 붙잡고 있는 경우도 있었고
형태소 분석기의 자료처리 한계 도달 등 한정적인 상황에 대한 대처만 해 왔던 터라 이해가 부족한 것도 사실이었다.
이번에는 프로그램 전반에서 텍스트 데이터를 광범위하게 사용하고 있으며, 분석 과정에 시간이 많이 소요되는
웹 자료 가져오기 (HttpWebRequest / Response)도 자주 사용하다 보니 같은 문제에 직면하게 되었다.
그동안 임시방편으로 사용하던 Application.Doevents()와 같은 Message Pump 해결방법으로는 무리가 되었다.
결국은 에러 메시지를 기반으로 ContextSwitchDeadlock 문제의 근본적인 해결을 추구하는 게 좋을 것 같았다.
기본적으로 Deadlock이 자원공유 위반으로부터 야기된다는 것을 초급교재에서 보아서 알고 있었고
프로그래밍시에 이 부분은 기본적으로 회피하면서 작업을 해 왔기에 (이름을 다르게 하는 등) 더욱 혼동이 되었는데
오늘 비로소 문제를 해결한 것 같다.
참고 자료의 해석에 따르면, CLR을 COM 기반으로 해석하는 가운데 해당 에러의 우려가 감지되는 경우 리턴되는 메시지로,
크게 위험성은 없는 것이라고 한다.
물론 실시간 시스템 등 연구 목적이 아닌 경우는 응답이 무한정 길어질 염려는 있는 것으로 보이지만
내게는 그저 불편할 뿐이니...
해결 방법으로 가장 간단하게 제시된 것은 VS Debugger에서 해당 에러 메시지의 리턴을 안 하게
옵션을 해제하는 방법이다.
메뉴바의 Debug - Exceptions - Managed Debugging Assistants 항목에서 ContextSwitchDeadlock 체크를 지우는
아주 간단한 작업만으로 이 문제가 해결되는 것으로 보인다.
지금 보다 큰 작업으로 테스트를 하고 있는데 잘 작동이 되는 것으로 생각되고 있다.
하지만 앞에서 말한 대로 단점도 분명히 존재하는 경우이니 옵션에 대한 지식은 필수일 것으로 생각된다.
2009-08-28
String을 HtmlDocument 형식으로 변환
요즘 너무 노는 내용만 올린 것 같아서 공부 내용도 첨가...^^
(Http)WebRequest를 이용해서 가져온 Stream 형식의 웹 페이지 소스를 String으로 받는 경우는 정보가 많은데
Stream이나 String 형식을 html 형식으로 바꾸는 방법을 찾기는 쉽지 않았다.
이를 다루는 방법은 HtmlDocument 개체를 이용하거나 MS html 형식인 mshtml 네임스페이스를 이용,
여기서 지원하는 IHTMLDocument(2,3,4 등등) 개체를 사용하는 것인데,
후자의 경우 각 개체들이 지원하는 method가 달라서 혼동의 여지가 있다.
간단하게 String 형식을 HtmlDocument 형식으로 바꾸는 코드는 다음과 같다.
using System.Windows.Forms
// temphtml 개체에 String 형식의 html 데이터가 들어있을 때
HtmlDocument myhtml;
WebBrowser wb = new WebBrowser();
// Form의 WebBrowser 개체를 이용하므로 javascript의 경우 에러가 발생할 수 있다.
// 단순한 내용 표시 목적의 경우로서 스크립트 에러창이 뜨는 것을 무시하고 계속 표기하는 옵션
wb.ScriptErrorsSuppressed = true;
wb.DocumentText = "";
myhtml = wb.Document.OpenNew(true);
myhtml.Write(temphtml);
(Http)WebRequest를 이용해서 가져온 Stream 형식의 웹 페이지 소스를 String으로 받는 경우는 정보가 많은데
Stream이나 String 형식을 html 형식으로 바꾸는 방법을 찾기는 쉽지 않았다.
이를 다루는 방법은 HtmlDocument 개체를 이용하거나 MS html 형식인 mshtml 네임스페이스를 이용,
여기서 지원하는 IHTMLDocument(2,3,4 등등) 개체를 사용하는 것인데,
후자의 경우 각 개체들이 지원하는 method가 달라서 혼동의 여지가 있다.
간단하게 String 형식을 HtmlDocument 형식으로 바꾸는 코드는 다음과 같다.
using System.Windows.Forms
// temphtml 개체에 String 형식의 html 데이터가 들어있을 때
HtmlDocument myhtml;
WebBrowser wb = new WebBrowser();
// Form의 WebBrowser 개체를 이용하므로 javascript의 경우 에러가 발생할 수 있다.
// 단순한 내용 표시 목적의 경우로서 스크립트 에러창이 뜨는 것을 무시하고 계속 표기하는 옵션
wb.ScriptErrorsSuppressed = true;
wb.DocumentText = "";
myhtml = wb.Document.OpenNew(true);
myhtml.Write(temphtml);
2009-05-21
SlothLib - 8. BasicVector 개체
이쯤해서 의문이 들 것 같다.
"뭐하러 이렇게 복잡하게 사용하나. 그냥 정의해서 사용하면 될 것을..."
맞는 말씀이다. 능력이 되면 그냥 짜면 될 것 같다.
하지만 SlothLib의 능력은 생각보다 범위가 넓고, 편리한 사용을 위해 많은 것들이 준비되어 있다.
물론 설명이 자세하지 않고 일본어로 간략하지만...
그 좋은 예가 BasicVector 개체이다.
http://www.dl.kuis.kyoto-u.ac.jp/slothlib/help/에 가서 SlothLib.LinearAlgebra.FeatureVector ► BasicVector class 부분을 참고하시면 될 것 같다.
간단히 말해서, 빈도(Frequency)를 저장할 수 있는 개체인데 범위가 매우 넓다.
- 값이 double 형식으로 저장되므로 정수단위, 소수단위 모든 값의 저장이 가능하다.
- 인덱스는 List 형식이므로 string 뿐만 아니라 어떠한 개체든 가능하다.
"뭐하러 이렇게 복잡하게 사용하나. 그냥 정의해서 사용하면 될 것을..."
맞는 말씀이다. 능력이 되면 그냥 짜면 될 것 같다.
하지만 SlothLib의 능력은 생각보다 범위가 넓고, 편리한 사용을 위해 많은 것들이 준비되어 있다.
물론 설명이 자세하지 않고 일본어로 간략하지만...
그 좋은 예가 BasicVector 개체이다.
http://www.dl.kuis.kyoto-u.ac.jp/slothlib/help/에 가서 SlothLib.LinearAlgebra.FeatureVector ► BasicVector class 부분을 참고하시면 될 것 같다.
간단히 말해서, 빈도(Frequency)를 저장할 수 있는 개체인데 범위가 매우 넓다.
- 값이 double 형식으로 저장되므로 정수단위, 소수단위 모든 값의 저장이 가능하다.
- 인덱스는 List 형식이므로 string 뿐만 아니라 어떠한 개체든 가능하다.
SlothLib - 7. YahooJpWebElement (하)
이제 소스를 단위별로 살펴보면서 무엇이 들었는지 생각해 보자.
// 기본적으로 제공되는 dll 외에 추가해야 할 부분들
using System.IO;
using System.Xml;
using System.Xml.XPath;
using SlothLib.Web.Search;
// Form 부분 코드는 생략하였다.
private void ResultBoss (string QueryString, string Count)
{
// 검색결과를 저장할 개체 차용 - YahooJpWebElement 개체를 빌려온다.
// 사실 class를 다시 정해도 되겠지만... SlothLib의 효용성을 극대화한다는 차원에서...
List ResultElementList = new List();
// Yahoo! BOSS 질의형식을 충분히 따라서 간다.
string tQuery = "http://boss.yahooapis.com/ysearch/web/v1/"+ QueryString.Trim() + "?format=xml&count=" + Count + "&appid=받은 API Key";
// 검색결과를 획득하는 부분
// HttpWebRequest로 치환한 것을 볼 수 있는데, Http에 대한 사용의 경우는
// 이 개체를 사용하는 것이 더욱 효율적이라고 한다.
// 실제로 반환하는 검색결과의 개수가 많을 수록 효율적임을 체감했다.
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(tQuery);
// 밀리초 기준의 Timeout 개체를 이용해서 자동질의의 딜레이를 처리해 주기도 한다.
// myRequest.Timeout = 5000;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream();
// 이제 받아온 검색결과를 XML 형태로 변환한다. 선언하고 집어넣으면 끝.
// 특히 Close()를 빼먹으면 퍼포먼스에 심대한 영향을 미친다.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(myStream);
myStream.Close();
myResponse.Close();
// 여기서부터는 Yahoo! BOSS의 XML 형식 응답의 구조를 파악하여 적용한 내용이므로
// 응답형식 자체가 바뀌거나 다른 API를 사용하는 경우는 추가 연구가 필요하다.
// 먼저 루트요소를 획득한다.
XmlElement xmlRoot = xmlDoc.DocumentElement;
// 검색 결과수 추출 및 저장
// API 해설에 보면 totalhits와 deephits가 있는데, 경험적으로 우리가 보는 결과수는
// totalhits로 보인다. 노드에서 attribute 값을 끌어내는 데 표준적인 형태.
XmlNodeList xHitPath = xmlRoot.GetElementsByTagName("resultset_web");
foreach (XmlElement xe in xHitPath)
{
Hit = xe.GetAttribute("totalhits");
}
// 검색 결과 추출 및 저장
// XML Node를 검색할 때 기준이 되는 NodeList를 바꾸어 준다.
XmlNodeList xmlResultList = xmlRoot.GetElementsByTagName("result");
int rank = 0;
// GetElementString() 함수는 맨 아래 정의되어 있으므로 참조 바람.
// 가급적 Yahoo! Japan 검색 결과와 맞추는 데 중점을 두었다.
// 필요한 대로 개체를 치환하여 사용하면 되겠다.
// node의 값과 attribute 값을 가져오는 부분의 차이를 눈여겨 보시길...
foreach (XmlElement xmlResult in xmlResultList)
{
rank++;
string title = GetElementString(xmlResult.GetElementsByTagName("title"));
string summary = GetElementString(xmlResult.GetElementsByTagName("abstract"));
string url = GetElementString(xmlResult.GetElementsByTagName("url"));
string date = string.Empty;
string clickurl = GetElementString(xmlResult.GetElementsByTagName("ClickUrl"));
string mimetype = string.Empty;
string cacheUrl = string.Empty;
string cacheSize = string.Empty;
// 인터페이스로 구성되어 있는 YahooJpWebElement에 이 순위의 값들을 집어넣는다.
YahooJpWebElement result = new YahooJpWebElement(rank, title, summary, url, clickurl, mimetype, date, cacheUrl, cacheSize);
// 사전 정의한 결과값의 list 개체에 잘 저장해 준다.
ResultElementList.Add(result);
}
}
private string GetElementString(XmlNodeList nodeList)
{
if (nodeList.Count == 0)
return string.Empty;
else
return nodeList[0].InnerText;
}
원래 있었던 try - catch 문은 어디로 갔을까?^^
이 부분을 넣지 않으면 XmlException에 대한 처리가 되지 않아 실행이 되지 않는다.
이곳에서는 설명을 보시고 꼭 원래의 코드로 실행해 보시길 부탁드린다.
// 기본적으로 제공되는 dll 외에 추가해야 할 부분들
using System.IO;
using System.Xml;
using System.Xml.XPath;
using SlothLib.Web.Search;
// Form 부분 코드는 생략하였다.
private void ResultBoss (string QueryString, string Count)
{
// 검색결과를 저장할 개체 차용 - YahooJpWebElement 개체를 빌려온다.
// 사실 class를 다시 정해도 되겠지만... SlothLib의 효용성을 극대화한다는 차원에서...
List
// Yahoo! BOSS 질의형식을 충분히 따라서 간다.
string tQuery = "http://boss.yahooapis.com/ysearch/web/v1/"+ QueryString.Trim() + "?format=xml&count=" + Count + "&appid=받은 API Key";
// 검색결과를 획득하는 부분
// HttpWebRequest로 치환한 것을 볼 수 있는데, Http에 대한 사용의 경우는
// 이 개체를 사용하는 것이 더욱 효율적이라고 한다.
// 실제로 반환하는 검색결과의 개수가 많을 수록 효율적임을 체감했다.
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(tQuery);
// 밀리초 기준의 Timeout 개체를 이용해서 자동질의의 딜레이를 처리해 주기도 한다.
// myRequest.Timeout = 5000;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream();
// 이제 받아온 검색결과를 XML 형태로 변환한다. 선언하고 집어넣으면 끝.
// 특히 Close()를 빼먹으면 퍼포먼스에 심대한 영향을 미친다.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(myStream);
myStream.Close();
myResponse.Close();
// 여기서부터는 Yahoo! BOSS의 XML 형식 응답의 구조를 파악하여 적용한 내용이므로
// 응답형식 자체가 바뀌거나 다른 API를 사용하는 경우는 추가 연구가 필요하다.
// 먼저 루트요소를 획득한다.
XmlElement xmlRoot = xmlDoc.DocumentElement;
// 검색 결과수 추출 및 저장
// API 해설에 보면 totalhits와 deephits가 있는데, 경험적으로 우리가 보는 결과수는
// totalhits로 보인다. 노드에서 attribute 값을 끌어내는 데 표준적인 형태.
XmlNodeList xHitPath = xmlRoot.GetElementsByTagName("resultset_web");
foreach (XmlElement xe in xHitPath)
{
Hit = xe.GetAttribute("totalhits");
}
// 검색 결과 추출 및 저장
// XML Node를 검색할 때 기준이 되는 NodeList를 바꾸어 준다.
XmlNodeList xmlResultList = xmlRoot.GetElementsByTagName("result");
int rank = 0;
// GetElementString() 함수는 맨 아래 정의되어 있으므로 참조 바람.
// 가급적 Yahoo! Japan 검색 결과와 맞추는 데 중점을 두었다.
// 필요한 대로 개체를 치환하여 사용하면 되겠다.
// node의 값과 attribute 값을 가져오는 부분의 차이를 눈여겨 보시길...
foreach (XmlElement xmlResult in xmlResultList)
{
rank++;
string title = GetElementString(xmlResult.GetElementsByTagName("title"));
string summary = GetElementString(xmlResult.GetElementsByTagName("abstract"));
string url = GetElementString(xmlResult.GetElementsByTagName("url"));
string date = string.Empty;
string clickurl = GetElementString(xmlResult.GetElementsByTagName("ClickUrl"));
string mimetype = string.Empty;
string cacheUrl = string.Empty;
string cacheSize = string.Empty;
// 인터페이스로 구성되어 있는 YahooJpWebElement에 이 순위의 값들을 집어넣는다.
YahooJpWebElement result = new YahooJpWebElement(rank, title, summary, url, clickurl, mimetype, date, cacheUrl, cacheSize);
// 사전 정의한 결과값의 list 개체에 잘 저장해 준다.
ResultElementList.Add(result);
}
}
private string GetElementString(XmlNodeList nodeList)
{
if (nodeList.Count == 0)
return string.Empty;
else
return nodeList[0].InnerText;
}
원래 있었던 try - catch 문은 어디로 갔을까?^^
이 부분을 넣지 않으면 XmlException에 대한 처리가 되지 않아 실행이 되지 않는다.
이곳에서는 설명을 보시고 꼭 원래의 코드로 실행해 보시길 부탁드린다.
2009-05-17
SlothLib - 6. YahooJpWebElement (중)
그러면 영문검색엔진에서 YahooJpWebElement를 사용하는 방법을 연구해 보자.
일단 참조를 추가하는 것은 (상)편 1, 2번의 방법과 동일하다.
이렇게 참조를 추가하면 SlothLib가 제공하는 인터페이스를 사용할 수 있게 된다.
함수를 하나 만들어 보기로 하자.
입력은 검색어인 Querystring과 요망 검색결과수인 Count 변수로 하고
출력은 검색 결과 자체로 생각해 보자.
웹 소스를 얻어올 수 있는 방법은 2가지인데,
가장 간단한 것은 WebClient 개체를 이용하는 것이다.
그러나 이 방법은 대상 웹 소스가 많을 때는 부하가 걸리므로
WebRequest, WebResponse를 이용하는 방법을 추천한다.
using System.IO;
using System.Xml;
using System.Xml.XPath;
using SlothLib.Web.Search;
private void ResultBoss (string QueryString, string Count)
{
// 검색결과를 저장할 개체 차용 - YahooJpWebElement 개체를 빌려옴
List<YahooJpWebElement> ResultElementList = new List<YahooJpWebElement>();
string tQuery = "http://boss.yahooapis.com/ysearch/web/v1/"+ QueryString.Trim() + "?format=xml&count=" + Count + "&appid=받은 API Key";
try
{
// 원시 검색결과 획득
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(tQuery);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream();
// XML 형태로 변환
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(myStream);
myStream.Close();
myResponse.Close();
// 루트요소 획득
XmlElement xmlRoot = xmlDoc.DocumentElement;
// 검색 결과수 추출 및 저장
XmlNodeList xHitPath = xmlRoot.GetElementsByTagName("resultset_web");
foreach (XmlElement xe in xHitPath)
{
Hit = xe.GetAttribute("totalhits");
}
// 검색 결과 추출 및 저장
XmlNodeList xmlResultList = xmlRoot.GetElementsByTagName("result");
int rank = 0;
foreach (XmlElement xmlResult in xmlResultList)
{
rank++;
string title = GetElementString(xmlResult.GetElementsByTagName("title"));
string summary = GetElementString(xmlResult.GetElementsByTagName("abstract"));
string url = GetElementString(xmlResult.GetElementsByTagName("url"));
string date = string.Empty;
string clickurl = GetElementString(xmlResult.GetElementsByTagName("ClickUrl"));
string mimetype = string.Empty;
string cacheUrl = string.Empty;
string cacheSize = string.Empty;
YahooJpWebElement result = new YahooJpWebElement(rank, title, summary, url, clickurl, mimetype, date, cacheUrl, cacheSize);
ResultElementList.Add(result);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private string GetElementString(XmlNodeList nodeList)
{
if (nodeList.Count == 0)
return string.Empty;
else
return nodeList[0].InnerText;
}
일단 참조를 추가하는 것은 (상)편 1, 2번의 방법과 동일하다.
이렇게 참조를 추가하면 SlothLib가 제공하는 인터페이스를 사용할 수 있게 된다.
함수를 하나 만들어 보기로 하자.
입력은 검색어인 Querystring과 요망 검색결과수인 Count 변수로 하고
출력은 검색 결과 자체로 생각해 보자.
웹 소스를 얻어올 수 있는 방법은 2가지인데,
가장 간단한 것은 WebClient 개체를 이용하는 것이다.
그러나 이 방법은 대상 웹 소스가 많을 때는 부하가 걸리므로
WebRequest, WebResponse를 이용하는 방법을 추천한다.
using System.IO;
using System.Xml;
using System.Xml.XPath;
using SlothLib.Web.Search;
private void ResultBoss (string QueryString, string Count)
{
// 검색결과를 저장할 개체 차용 - YahooJpWebElement 개체를 빌려옴
List<YahooJpWebElement> ResultElementList = new List<YahooJpWebElement>();
string tQuery = "http://boss.yahooapis.com/ysearch/web/v1/"+ QueryString.Trim() + "?format=xml&count=" + Count + "&appid=받은 API Key";
try
{
// 원시 검색결과 획득
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(tQuery);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream();
// XML 형태로 변환
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(myStream);
myStream.Close();
myResponse.Close();
// 루트요소 획득
XmlElement xmlRoot = xmlDoc.DocumentElement;
// 검색 결과수 추출 및 저장
XmlNodeList xHitPath = xmlRoot.GetElementsByTagName("resultset_web");
foreach (XmlElement xe in xHitPath)
{
Hit = xe.GetAttribute("totalhits");
}
// 검색 결과 추출 및 저장
XmlNodeList xmlResultList = xmlRoot.GetElementsByTagName("result");
int rank = 0;
foreach (XmlElement xmlResult in xmlResultList)
{
rank++;
string title = GetElementString(xmlResult.GetElementsByTagName("title"));
string summary = GetElementString(xmlResult.GetElementsByTagName("abstract"));
string url = GetElementString(xmlResult.GetElementsByTagName("url"));
string date = string.Empty;
string clickurl = GetElementString(xmlResult.GetElementsByTagName("ClickUrl"));
string mimetype = string.Empty;
string cacheUrl = string.Empty;
string cacheSize = string.Empty;
YahooJpWebElement result = new YahooJpWebElement(rank, title, summary, url, clickurl, mimetype, date, cacheUrl, cacheSize);
ResultElementList.Add(result);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private string GetElementString(XmlNodeList nodeList)
{
if (nodeList.Count == 0)
return string.Empty;
else
return nodeList[0].InnerText;
}
2009-05-15
SlothLib - 5. YahooJpWebElement (상)
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/?%BC%C2%C1%A9%B2%F2%C0%E2%2F%C6%FE%CC%E7%28Web%29
이제서야 본격적인 내용으로 진입하는 기분이다...
일단 웹 검색 결과를 가져오는 개체인 YahooJpWebElement 개체에 대해 알아보자.
SlothLib에서는 유용한 개체들을 인터페이스로 구현하여 제공하고 있으며,
이중에서 웹 검색 결과의 저장에 가장 기본이 되는 개체는 바로 YahooJpWebElement이다.
본래의 사용법으로는 그저 개체를 생성하고 검색어를 보내기만 하면
Yahoo! Japan의 해당 검색 결과를 가져올 수 있도록 간단하게 설계되었지만
불행하게도 영문이나 한글 등 Yahoo! Japan 이외의 검색엔진을 사용할 경우에는
어쩔 수 없이 개체를 이해하고 조금 만져줘야 한다...
인터페이스인 YahooJpWebElement에는 다음과 같은 항목이 들어가는데
이는 Yahoo! Search API의 응답형태를 그대로 활용한 경우가 되겠다.
- Rank : 검색된 결과의 순위. API에서는 제공되지 않으므로 별도 카운트가 필요하다.
- Title : 결과 제목
- Summary : 결과 요약 (snippet)
- Url : 결과 웹 주소
- Date : API에서 제공하는 결과 수집 시간
- ClickUrl : Yahoo!에 연결되어 있는 웹 주소
- 기타 : Mimetype, CacheUrl, CacheSize (필요에 따라 사용)
예에서 알수 있듯이 주로 사용되는 것은 Rank, Title, Summary, Url 정도가 되겠다.
이 게체를 이용하는 법은 매우 간단하다.
1. 일단 Visual Studio 에서 "참조 추가" 항목을 이용하여 참조 라이브러리를 프로젝트에 포함시킨다.
해당되는 파일은 SlothLib.Web.Search.Base.dll,
SlothLib.Web.Search.YahooJapanWebService.dll 이다.
2. 코드의 System 템플릿 부분에 다음 항목을 추가한다.
using SlothLib.Web.Search
3. 질의 입력 / 결과 출력 텍스트박스와 버튼을 하나 만들고 다음 항목을 추가한다.
private void btnSearch_Click(object sender, EventArgs e)
{
tbResult.Text = "";
IWebSearch yahoo = new YahooJpWebSearch("slothlib");
IWebSearchResult result = yahoo.DoSearch(tbQuery.Text, 10);
foreach (IWebElement element in result.ResultElements)
{
tbResult.Text += element.Title + "\r\n";
}
}
이렇게 하면 result 개체 내에 검색 결과 (10개)가 포함된다.
그러나 이런 간편함을 늘 누릴 수 없다는 것이 문제다.
이 구현은 Yahoo! Search API를 이용하므로 일일 IP당 5,000개의 질의로 제한되며
이곳 연구실의 몇몇 인원들이 그냥 이렇게 쉽게 사용하므로 때때로 한계에 도달한다는 문제점이 있다.
물론 다음날 12시경 다시 사용할 수 있게 되지만 불편한 점이 아닐 수 없다.
이제서야 본격적인 내용으로 진입하는 기분이다...
일단 웹 검색 결과를 가져오는 개체인 YahooJpWebElement 개체에 대해 알아보자.
SlothLib에서는 유용한 개체들을 인터페이스로 구현하여 제공하고 있으며,
이중에서 웹 검색 결과의 저장에 가장 기본이 되는 개체는 바로 YahooJpWebElement이다.
본래의 사용법으로는 그저 개체를 생성하고 검색어를 보내기만 하면
Yahoo! Japan의 해당 검색 결과를 가져올 수 있도록 간단하게 설계되었지만
불행하게도 영문이나 한글 등 Yahoo! Japan 이외의 검색엔진을 사용할 경우에는
어쩔 수 없이 개체를 이해하고 조금 만져줘야 한다...
인터페이스인 YahooJpWebElement에는 다음과 같은 항목이 들어가는데
이는 Yahoo! Search API의 응답형태를 그대로 활용한 경우가 되겠다.
- Rank : 검색된 결과의 순위. API에서는 제공되지 않으므로 별도 카운트가 필요하다.
- Title : 결과 제목
- Summary : 결과 요약 (snippet)
- Url : 결과 웹 주소
- Date : API에서 제공하는 결과 수집 시간
- ClickUrl : Yahoo!에 연결되어 있는 웹 주소
- 기타 : Mimetype, CacheUrl, CacheSize (필요에 따라 사용)
예에서 알수 있듯이 주로 사용되는 것은 Rank, Title, Summary, Url 정도가 되겠다.
이 게체를 이용하는 법은 매우 간단하다.
1. 일단 Visual Studio 에서 "참조 추가" 항목을 이용하여 참조 라이브러리를 프로젝트에 포함시킨다.
해당되는 파일은 SlothLib.Web.Search.Base.dll,
SlothLib.Web.Search.YahooJapanWebService.dll 이다.
2. 코드의 System 템플릿 부분에 다음 항목을 추가한다.
using SlothLib.Web.Search
3. 질의 입력 / 결과 출력 텍스트박스와 버튼을 하나 만들고 다음 항목을 추가한다.
private void btnSearch_Click(object sender, EventArgs e)
{
tbResult.Text = "";
IWebSearch yahoo = new YahooJpWebSearch("slothlib");
IWebSearchResult result = yahoo.DoSearch(tbQuery.Text, 10);
foreach (IWebElement element in result.ResultElements)
{
tbResult.Text += element.Title + "\r\n";
}
}
이렇게 하면 result 개체 내에 검색 결과 (10개)가 포함된다.
그러나 이런 간편함을 늘 누릴 수 없다는 것이 문제다.
이 구현은 Yahoo! Search API를 이용하므로 일일 IP당 5,000개의 질의로 제한되며
이곳 연구실의 몇몇 인원들이 그냥 이렇게 쉽게 사용하므로 때때로 한계에 도달한다는 문제점이 있다.
물론 다음날 12시경 다시 사용할 수 있게 되지만 불편한 점이 아닐 수 없다.
2009-04-18
SlothLib - 4. 시작
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/?%A5%C0%A5%A6%A5%F3%A5%ED%A1%BC%A5%C9
이제 본격적으로 시작해 보자. 사용할 수 있는 자료는 Visual Studio용과 Java용이 분리되어 있다.
명색이 C#에 관한 이야기이므로 Visual Studio용을 다운받도록 하자.
(사실 Java용은 사용을 안해봐서 모른다^^;)
페이지의 중앙에 보면 두개의 링크가 보일 것이다.
SlothLib1.0betasf49dll.zip 으로 되어있는 링크는 dll로 참조 라이브러리로 사용한다.
자신이 사용할 적당한 폴더에 다운로드 받아서 압축을 풀어 놓으면 되겠다.
참조 : 난 여기서 초보적 헤멤을 경험했다. dll을 저장해 놓는다고 C#이 자동으로 찾아주는 것이 아니라
내가 직접 참조경로를 정해 주어야 한다. 이 부분은 다음에 다시 언급하도록 한다.
SlothLib1.0betasf49src.zip 으로 되어있는 링크는 소스코드로 SlothLib의 구조가 궁금하면 다운로드 받으면 된다.
개인적으로 구조를 알면 무척 도움이 될 것으로 기대하긴 하지만 워낙 좀 복잡한지라... 쩝...
이제 본격적으로 시작해 보자. 사용할 수 있는 자료는 Visual Studio용과 Java용이 분리되어 있다.
명색이 C#에 관한 이야기이므로 Visual Studio용을 다운받도록 하자.
(사실 Java용은 사용을 안해봐서 모른다^^;)
페이지의 중앙에 보면 두개의 링크가 보일 것이다.
SlothLib1.0betasf49dll.zip 으로 되어있는 링크는 dll로 참조 라이브러리로 사용한다.
자신이 사용할 적당한 폴더에 다운로드 받아서 압축을 풀어 놓으면 되겠다.
참조 : 난 여기서 초보적 헤멤을 경험했다. dll을 저장해 놓는다고 C#이 자동으로 찾아주는 것이 아니라
내가 직접 참조경로를 정해 주어야 한다. 이 부분은 다음에 다시 언급하도록 한다.
SlothLib1.0betasf49src.zip 으로 되어있는 링크는 소스코드로 SlothLib의 구조가 궁금하면 다운로드 받으면 된다.
개인적으로 구조를 알면 무척 도움이 될 것으로 기대하긴 하지만 워낙 좀 복잡한지라... 쩝...
2009-04-16
SlothLib - 3. 시작전 준비
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/?%C1%B0%BD%E0%C8%F7
C# 라이브러리로 되어있는 SlothLib를 사용하기 위해 다음과 같은 사항을 준비해야 한다.
1. 당연한 이야기지만 Visual Studio 2005 또는 그 이상이 인스톨되어 있어야 한다.
2. 제공하는 라이브러리 외에 외부 프로그램을 이용하는 경우가 있다.
이 경우 외부 프로그램을 다운받아놓고 C#에서 경로를 설정해서 사용한다.
필요한 경우는 다음과 같다.
 가. Chasen(茶筌), MeCab : 일본어 형태소분석기 (도쿄대학)
  Charsen : http://sourceforge.jp/projects/chasen-legacy/files/
  Mecab : http://sourceforge.net/project/showfiles.php?group_id=177856
  - 별다른 세팅이 필요 없으며, 개인적 관점에서 무척 빠르고 성능도 뛰어나다고 본다.
 나. SS Tagger : 영어 형태소분석기 (도쿄대학)
  http://www-tsujii.is.s.u-tokyo.ac.jp/~tsuruoka/postagger/
  - 영어의 경우는 이것을 이용한다. 속도는 느린 편, 현재 내가 사용하는 형태소분석기
  - 역시 별다른 세팅이나 Training과정이 필요 없는 것이 큰 장점
  - 성능은 괜찮은 것 같은데 특수문자 (<,>,# 등)를 잘못 인식하는 경우가 많다.
 다. TreeTagger : 독일 Stuttgart대학에서 만든 형태소분석기
  http://www.ims.uni-stuttgart.de/projekte/corplex/TreeTagger/
  - 다양한 언어를 지원 (독어, 영어, 불어, 이탈리아어 등 12개 언어)
  - Training이 필요하고 Perl 인터페이스가 필요하다.
  # 안써봐서 성능은 모르겠다. 나중에 써볼 생각
 라. xdoc2txt
  http://www31.ocn.ne.jp/~h_ishida/xdoc2txt.html#download
  - pdf, word, excel 등 각종 바이너리 문서로부터의 텍스트 추출 툴
  - 사용해 본 적이 없어서 모르겠다.
C# 라이브러리로 되어있는 SlothLib를 사용하기 위해 다음과 같은 사항을 준비해야 한다.
1. 당연한 이야기지만 Visual Studio 2005 또는 그 이상이 인스톨되어 있어야 한다.
2. 제공하는 라이브러리 외에 외부 프로그램을 이용하는 경우가 있다.
이 경우 외부 프로그램을 다운받아놓고 C#에서 경로를 설정해서 사용한다.
필요한 경우는 다음과 같다.
 가. Chasen(茶筌), MeCab : 일본어 형태소분석기 (도쿄대학)
  Charsen : http://sourceforge.jp/projects/chasen-legacy/files/
  Mecab : http://sourceforge.net/project/showfiles.php?group_id=177856
  - 별다른 세팅이 필요 없으며, 개인적 관점에서 무척 빠르고 성능도 뛰어나다고 본다.
 나. SS Tagger : 영어 형태소분석기 (도쿄대학)
  http://www-tsujii.is.s.u-tokyo.ac.jp/~tsuruoka/postagger/
  - 영어의 경우는 이것을 이용한다. 속도는 느린 편, 현재 내가 사용하는 형태소분석기
  - 역시 별다른 세팅이나 Training과정이 필요 없는 것이 큰 장점
  - 성능은 괜찮은 것 같은데 특수문자 (<,>,# 등)를 잘못 인식하는 경우가 많다.
 다. TreeTagger : 독일 Stuttgart대학에서 만든 형태소분석기
  http://www.ims.uni-stuttgart.de/projekte/corplex/TreeTagger/
  - 다양한 언어를 지원 (독어, 영어, 불어, 이탈리아어 등 12개 언어)
  - Training이 필요하고 Perl 인터페이스가 필요하다.
  # 안써봐서 성능은 모르겠다. 나중에 써볼 생각
 라. xdoc2txt
  http://www31.ocn.ne.jp/~h_ishida/xdoc2txt.html#download
  - pdf, word, excel 등 각종 바이너리 문서로부터의 텍스트 추출 툴
  - 사용해 본 적이 없어서 모르겠다.
2009-04-15
SlothLib - 2. 개요
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/?%A4%CF%A4%B8%A4%E1%A4%C6%A4%CE%CA%FD%A4%D8
그렇다면 과연 SlothLib는 무엇이며 어떠한 기능을 가지고 있는가?
SlothLib는 수년전 일본 교토대학교에서 프로젝트로 추진한 Web text 자료의 종합 및 분석을 위한 기능을 종합한 라이브러리이다.
개인적인 관점으로는 유용한 자료들이 다수 포함되어 있다고 생각한다.
개발자는 소개 페이지에서 다음과 같이 소개하고 있다.
---
SlothLib는「게으름뱅이 라이브러리(なまけものライブラリ)」로부터 명명된 것으로, Web 정보 검색 등에 필요한 여러가지 소프트웨어의 라이브러리입니다. 연구의 아이디어·착상을 얻고 나서 시작 시스템이 가동하기까지 필요로 하는 시간을 큰 폭으로 축소할 수 있는 것이 특징입니다.
---
결코 게으름뱅이라 볼 수 없는 이 방대한 라이브러리는 dll을 다운로드하고 참조하는 것만으로도 그 힘을 발휘하는 전형적인 C#의 응용 형태라 아니할 수 없다.
그러나 부족한 점도 있으니...
1. Yahoo! Japan API를 이용하여 각종 검색정보를 추출한다.
   따라서 일본 자료를 확인하는 데는 좋으나 다른 언어 (영어, 한국어) 검색자료는 구조를 직접 만들어야 한다.
   나 역시 SlothLib에서 제공하는 개체의 특성을 십분 활용하여 코드를 직접 작성했다.
2. MSDN 스타일의 설명이 일부 있기는 하지만 (물론 일본어임) 초보가 활용하기에는 너무나 부족한 수준이다..
   개발자에게 문의한 결과 프로젝트가 현재 수준에서 종료되어 더이상 업데이트가 안되고 있으며 개발자 역시 설명 부분의 보강이 필요하다고 느끼고 있다고 했다.
하긴 이 글을 쓰는 것도 한글로 해설을 하고자 함이다...
3. 하루에 사용할 수 있는 최대 질의(query) 수는 5,000개 까지다.
   이는 Yahoo! Japan API의 고유 특성으로 하루에 5,000개까지 지원하며,
   만일 이 한도가 넘으면 당일 API 접속이 차단되어 익일 재개된다.
   문제점은 많은 연구원들이 이용하므로 합계 5,000번 질의가 되는 시점이 심심찮게 생긴다는 점이다.
   나는 API 접속 회수에 제한이 없는 Yahoo! BOSS Search API를 이용하여 이 문제점을 해결하였다.
그렇다면 과연 SlothLib는 무엇이며 어떠한 기능을 가지고 있는가?
SlothLib는 수년전 일본 교토대학교에서 프로젝트로 추진한 Web text 자료의 종합 및 분석을 위한 기능을 종합한 라이브러리이다.
개인적인 관점으로는 유용한 자료들이 다수 포함되어 있다고 생각한다.
개발자는 소개 페이지에서 다음과 같이 소개하고 있다.
---
SlothLib는「게으름뱅이 라이브러리(なまけものライブラリ)」로부터 명명된 것으로, Web 정보 검색 등에 필요한 여러가지 소프트웨어의 라이브러리입니다. 연구의 아이디어·착상을 얻고 나서 시작 시스템이 가동하기까지 필요로 하는 시간을 큰 폭으로 축소할 수 있는 것이 특징입니다.
---
결코 게으름뱅이라 볼 수 없는 이 방대한 라이브러리는 dll을 다운로드하고 참조하는 것만으로도 그 힘을 발휘하는 전형적인 C#의 응용 형태라 아니할 수 없다.
그러나 부족한 점도 있으니...
1. Yahoo! Japan API를 이용하여 각종 검색정보를 추출한다.
   따라서 일본 자료를 확인하는 데는 좋으나 다른 언어 (영어, 한국어) 검색자료는 구조를 직접 만들어야 한다.
   나 역시 SlothLib에서 제공하는 개체의 특성을 십분 활용하여 코드를 직접 작성했다.
2. MSDN 스타일의 설명이 일부 있기는 하지만 (물론 일본어임) 초보가 활용하기에는 너무나 부족한 수준이다..
   개발자에게 문의한 결과 프로젝트가 현재 수준에서 종료되어 더이상 업데이트가 안되고 있으며 개발자 역시 설명 부분의 보강이 필요하다고 느끼고 있다고 했다.
하긴 이 글을 쓰는 것도 한글로 해설을 하고자 함이다...
3. 하루에 사용할 수 있는 최대 질의(query) 수는 5,000개 까지다.
   이는 Yahoo! Japan API의 고유 특성으로 하루에 5,000개까지 지원하며,
   만일 이 한도가 넘으면 당일 API 접속이 차단되어 익일 재개된다.
   문제점은 많은 연구원들이 이용하므로 합계 5,000번 질의가 되는 시점이 심심찮게 생긴다는 점이다.
   나는 API 접속 회수에 제한이 없는 Yahoo! BOSS Search API를 이용하여 이 문제점을 해결하였다.
2009-04-14
SlothLib - 1. 시작하면서...
우리 학교 라이브러리 중 C#을 사용하는 나에게 가장 쓸모있다고 여겨지는 것.
설명은 앞으로 계속적으로 연재하듯 써 나갈 생각이다.
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/
설명은 앞으로 계속적으로 연재하듯 써 나갈 생각이다.
해당 페이지 : http://www.dl.kuis.kyoto-u.ac.jp/slothlib/
C#에 대한 단상
즐거운 마음은 아니지만 뭔가는 해보겠다는 의지로
C#을 시작한 지가 벌써 3년...
아직도 MSDN과 내가 작성한 코드 주석을 보지 않고는
진도를 못나가는 초보딱지지만
앞으로는 더 잘 해볼 생각이 많다...
C#을 시작한 지가 벌써 3년...
아직도 MSDN과 내가 작성한 코드 주석을 보지 않고는
진도를 못나가는 초보딱지지만
앞으로는 더 잘 해볼 생각이 많다...
Subscribe to:
Posts (Atom)