Skip navigation

Abstract이란 긴 논문이나 연구를 한 두장 정도로 짧게 줄여 쓴 요약본을 말합니다. 한국어로는 ‘초록’ 이라고 일컫습니다. 때로는 수백 페이지에까지 달하는 연구 내용을 모두 한 두 장, 때로는 200~300 자 안에 담아야 하기 때문에 abstract 쓰기는 결코 쉬운 일이 아닙니다.

많은 독자들이 abstract만을 읽고 연구의 가치를 먼저 판단하고, 학문 분야에 따라 학회에 전체 논문이 아닌 abstract을 제출하여 연구를 평가 받는다는 점을 생각하면, abstract을 잘 쓰는 것은 학문을 하는 사람들에게 매우 중요한 능력입니다.

안타깝게도, 여러 차례 검색을 해도 abstract 쓰기의 가이드라인을 잘 정리한 한국 싸이트를 찾기 어려웠습니다. 제게도 abstract을 쓰는 것이 늘상 너무나 어려운 일이지만, 제가 MIT에서 받은 abstract 쓰기를 지도하는 교육과, 교수님들께 abstract을 수정 받으며 알게 된 사실을 바탕으로 기본 원칙을 몇 가지 나누어 보고자 합니다.

학문 분야별로 abstract의 성질과 구성이 많이 다를 수 있다는 점을 감안하여, 오늘은 인문/공학 등 분야별로 제약을 받지 않는 “기본”적이고 “보편”적인 원칙을 서술해 보도록 하겠습니다.

(1) 미래 시제를 피하자.

Abstract의 시작입니다.

The current study will explore ….

언뜻 생각하기에, 앞으로 논할 내용을 소개하는 첫 부분에 미래형 시제를 쓰는 것이 괜찮아 보입니다. 하지만 abstract에 미래형 시제를 쓰게 되면, 아직 연구가 덜 진행되었다는 느낌, 이 연구를 통해 발견한 점이 아직은 없다는 모호한 느낌을 줍니다.

미래형 시제는, 연구를 충분히 진행해서 그 연구의 성과를 명확하게 주장해야 하는 abstract의 전체에서 피해야 하는 시제인데, 특히 시작 부분에 미래형 시제를 쓰는 실수가 많습니다. abstract은 연구자가 오랜 시간에 거쳐 연구를 진행하고 충분히 그 성과가 증명 된 이후, 그것을 report 하는 글이라는 점을 고려 하셔서 현재형으로 쓰시는 것이 좋습니다. 과거형은 미래 시제만큼 황당하진 않지만, 현재 시제에 비해 생생한 느낌이 덜 합니다. 물론, 연구를 이미 진행했고, 결과가 모두 나온 상태이지만, 현재 시제로 그 성과를 생생히 전달하는 것이 가장 효과적입니다.

(2) 모호한 형용사와 부사를 제거하자.

위의 (1) 에서 사용한 예시를 시제를 수정하여 내용을 이어가 보겠습니다.

The current study explores the phenomenon of X, one of the most interesting issues that has been widely discussed by many researchers in the field of Y recently.

이 문장은 한마디로 엉망 입니다. 이유는 밑줄이 그어진 단어들에서 발견하실 수 있습니다. 단어들의 공통점을 발견하셨지요? 모두 정확성이 전혀 없는 추상적 형용사나 부사 입니다. 제가 첫 abstract을 썼을 때 지도 교수님께서 위와 같이 모든 추상 형용사/부사에 형광펜을 쳐 주셨었는데, 종이가 온통 형광색이라 제 스스로도 경악을 하였습니다.

우리는 연구의 거창한 성과를 내세우기 위해 자신도 모르게 이런 화려한 수식어를 많이 쓰게 되는 것 같습니다. 하지만, abstract의 생명력은 “정확성”입니다. 정확한 예시나 인용 문구를 제시하고, 이전 연구의 연도와 연구자를 명확하게 명시하여, 연구자가 학문 분야에서 본 연구의 위치를 아주 정확하게 인식하고 있다는 모습을 보여 주셔야 합니다.

Abstract을 다 쓰신 후 처음으로 돌아가 추상적 수식어가 없는지 확인해 보시기 바랍니다. 추상적 표현이 유독 많은 부분은 사실상 본인이 잘 알지 못하거나, 철저히 조사해 보지 않은 부분인 경우가 많습니다. 이런 수식어는 독자에게 연구자가 이 연구에 정통하지 않았다는 느낌을 줄 뿐만이 아니라 연구의 신뢰성도 떨어뜨립니다. Abstract은 문학 글쓰기와는 달리 조금은 건조해도 “정확” 하고 “명쾌”하게 쓰는 글 임을 기억하시기 바랍니다.

(3) 독자의 지식을 믿지 말라.

위의 문장 (2) 다음 다음과 같은 문장이 이어진다고 가정해 봅시다.

I show two ways in which Korean speakers realize domain-initial strengthening and argue that those are opposite to what is found in other languages (It could be the case that Korea is also one of universal cases).

Abstract을 읽거나 심사하는 사람이 해당 분야를 전혀 모르는 경우는 드뭅니다. 하지만 독자가 나 만큼 내 연구와 관련된 지식을 가지고 있다고 생각하는 것 또한 위험합니다. 저는 한국어 데이터를 다루면서 많이 범했던 실수인데, 우리에게 너무 당연한 현상도 한국어를 전혀 모르는 사람에게는 당황스러울 수 있습니다.

위 예시의 경우, 언어학을 하는 사람이라면 당연히 domain-initial strengthening이 무엇인지 그리고, 그것이 언어 보편적으로 보통 어떻게 실현되는지 안다는 두 가지 사실을 가정 하고 있습니다. 하지만 새로운 개념이나 화제를 처음 제시할 때는 최소한의 설명이라도 첨가하여 본 현상을 모르는 독자들에게 친숙하게 시작하여야 합니다.

예를 들어, domain-initial strengthening, a phenomenon which …. , 처럼 comma 사이에 짧게라도 이 현상이 무엇인지 설명하고, 이 현상을 처음 발견한 사람을 인용해 주는 것이 좋습니다. 또한 언어 보편적으로는 이 현상이 어떻게 실현되는지 우선 설명한 다음, 한국어의 경우 보편적 경우와 반대이다라고 설명을 해야지 위와 같이 독자가 당연히 보편적 실현 방식을 알 것이란 가정을 해 버리고 서술을 해서는 안되겠습니다.

(4) 압박 수비;관대함은 덕이 아닌 악이다.

위의 예시 (3)에서 또 하나 잘못된 부분은 바로 괄호 안의 내용입니다. 이 연구자의 경우, 처음에는 언어 보편 현상 A가 있는데, 한국어는 이와 반대라고 주장 합니다. 그 이후 다른 측면에서 생각해 보면, 한국어 또한 보편 현상 A와 동일한 경우로 생각할 수 있는 여지가 남아 있다는 말을 괄호 안에서 슬며시 하고 있습니다.

이와 유사한 경우로, 이론 A로 자신의 연구를 설명했는데, 이론 B또한 본 연구를 설명할 수 있는 경우를 많이들 경험하셨을 것입니다. 이런 경우, 위와 같이 괄호 안에 본인이 현재 하고 있는 주장 이외에, 다른 분석도 가능하다는 흐릿한 문장을 첨가 한다면 연구의 성과를 흐리게 합니다.

이론이란, 수 많은 데이터 관찰을 통해 최대한 정제. 보편화 시킨 추상적 지식입니다. 때문에 한 연구에서 발견한 현상이 특정 이론에 반론을 제시할 가능성도 있지만, 두 가지 이상의 이론을 지지할 수 도 있는 법입니다. 하지만 어떤 연구든 그 학문 분야에서 ‘기여하는 바’가 있어야 한다는 점을 감안할 때, 이것도 맞고 저것도 맞다는 관대함은 절대 미덕이 아닙니다. 더 철저한 분석을 통해 자신의 주장을 정확히 하나의 목소리로 이어 나갈 수 있어야 합니다.

(5) 결론; implication 을 생각해 보자.

(4) 에서도 설명드렸지만, 연구가 유의미하려면 관련 분야에 영향력이 있어야 합니다. 현재 이론에 문제를 제기 하거나, 이론을 입증하는 근거를 찾았다거나 하는 등입니다. 자신이 연구를 진행하고 무언가를 발견했다면 “So what?” 이라는 질문을 해 보시기 바랍니다.

저는 어린 아이들의 언어 학습 발달을 연구하면서 아주 재미있는 ‘관찰’을 한 적이 있습니다. 아이들의 창의력과 기발한 표현력이 경이로웠습니다. 그러나 “So what?”이라는 질문을 했을 때 그것이 하나의 “연구”로 발전하여 언어 습득이라는 연구 분야에 줄 수 있는 “implication”은 별로 없는 현상 이었습니다. 그런 경우 그것은 재미있는 “관찰”일 수는 있어도 큰 연구로 발전 할 수 없다는 점을 깨달았습니다.

자신의 관찰이 거시적으로 보아 이 학문 분야에 기여할 수 있는 바가 있다면, 결론 부분에 밝혀 주시기 바랍니다. 결론 부분은, 앞서 쓴 내용을 요약만 하는 부분이 아니라, 바로 이렇게 연구의 implication 을 설명하고 이후 연구자들에게 새로운 연구의 영감이나 과제를 제시하는 부분이라고 생각하시면 좋을 듯 합니다.

그럼, 아래의 예시를 생각해 봅시다.

To conclude, I believe that findings in this study will have great impact on X theory.

공허한 결론 입니다. (2) 에서 이미 밝힌 바와 같이 “great impact”라는 말이 모호할 뿐더러 무슨 implication이 있는 연구인지 전혀 알 수가 없습니다.

결론에서는 장황하고 공허한 문장보다는, 이 연구로 밝힌 사실은 이론 X를 일부 입증/반증하며, 이것을 확실히하기 위해서는 a, b, c와 같은 관찰이 더 진행되어야 한다는 구체적인 내용이 포함 되어야 합니다. 이는 본인의 차후 연구 방향을 스스로 생각할 수 있는 기회일 뿐만이 아니라 유사한 관심사를 가진 연구자들에게 관련연구를 진행하여 학계 전체에 발전을 가져 올 수 있는 힘을 실어줄 수 있을 것 입니다.

출처: http://eduhow.tistory.com/61

libs/serialization/example/demo_gps.hpp

#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_gps.hpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/version.hpp>

// This illustration models the bus system of a small city.
// This includes, multiple bus stops,  bus routes and schedules.
// There are different kinds of stops.  Bus stops in general will
// will appear on multiple routes.  A schedule will include
// muliple trips on the same route.

/////////////////////////////////////////////////////////////
// gps coordinate
//
// llustrates serialization for a simple type
//
class gps_position
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);

    int degrees;
    int minutes;
    float seconds;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar  & BOOST_SERIALIZATION_NVP(degrees)
            & BOOST_SERIALIZATION_NVP(minutes)
            & BOOST_SERIALIZATION_NVP(seconds);
    }

public:
    // every serializable class needs a constructor
    gps_position(){};
    gps_position(int _d, int _m, float _s) :
        degrees(_d), minutes(_m), seconds(_s)
    {}
};

std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}

/////////////////////////////////////////////////////////////
// One bus stop
//
// illustrates serialization of serializable members
//

class bus_stop
{
    friend class boost::serialization::access;
    virtual std::string description() const = 0;
    gps_position latitude;
    gps_position longitude;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & BOOST_SERIALIZATION_NVP(latitude);
        ar & BOOST_SERIALIZATION_NVP(longitude);
    }

protected:
    bus_stop(const gps_position & _lat, const gps_position & _long) :
        latitude(_lat), longitude(_long)
    {}
public:
    bus_stop(){}
    friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
    virtual ~bus_stop(){}
};

BOOST_IS_ABSTRACT(bus_stop)

std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
    return os << bs.latitude << bs.longitude << ' ' << bs.description();
}

/////////////////////////////////////////////////////////////
// Several kinds of bus stops
//
// illustrates serialization of derived types
//
class bus_stop_corner : public bus_stop
{
    friend class boost::serialization::access;
    std::string street1;
    std::string street2;
    virtual std::string description() const
    {
        return street1 + " and " + street2;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // save/load base class information
        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
        ar & BOOST_SERIALIZATION_NVP(street1);
        ar & BOOST_SERIALIZATION_NVP(street2);
    }
public:
    bus_stop_corner(){}
    bus_stop_corner(const gps_position & _lat, const gps_position & _long,
        const std::string & _s1, const std::string & _s2
    ) :
        bus_stop(_lat, _long), street1(_s1), street2(_s2)
    {
    }
};

class bus_stop_destination : public bus_stop
{
    friend class boost::serialization::access;
    std::string name;
    virtual std::string description() const
    {
        return name;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
            & BOOST_SERIALIZATION_NVP(name);
    }
public:
    bus_stop_destination(){}
    bus_stop_destination(
        const gps_position & _lat, const gps_position & _long, const std::string & _name
    ) :
        bus_stop(_lat, _long), name(_name)
    {
    }
};

/////////////////////////////////////////////////////////////
// a bus route is a collection of bus stops
//
// illustrates serialization of STL collection templates.
//
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient.  That is objects pointed to by more than one
// pointer are stored only once.  In such cases only one such
// object is restored and pointers are restored to point to it
//
class bus_route
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
    typedef bus_stop * bus_stop_pointer;
    std::list<bus_stop_pointer> stops;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // in this program, these classes are never serialized directly but rather
        // through a pointer to the base class bus_stop. So we need a way to be
        // sure that the archive contains information about these derived classes.
        //ar.template register_type<bus_stop_corner>();
        ar.register_type(static_cast<bus_stop_corner *>(NULL));
        //ar.template register_type<bus_stop_destination>();
        ar.register_type(static_cast<bus_stop_destination *>(NULL));
        // serialization of stl collections is already defined
        // in the header
        ar & BOOST_SERIALIZATION_NVP(stops);
    }
public:
    bus_route(){}
    void append(bus_stop *_bs)
    {
        stops.insert(stops.end(), _bs);
    }
};
std::ostream & operator<<(std::ostream &os, const bus_route &br)
{
    std::list<bus_stop *>::const_iterator it;
    // note: we're displaying the pointer to permit verification
    // that duplicated pointers are properly restored.
    for(it = br.stops.begin(); it != br.stops.end(); it++){
        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
    }
    return os;
}

/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
//
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
// See definition of operator<< <pair<F, S> >(ar, pair)
//
// illustrates nesting of serializable classes
//
// illustrates use of version number to automatically grandfather older
// versions of the same class.

class bus_schedule
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & BOOST_SERIALIZATION_NVP(schedule);
    }
    // note: this structure was made public. because the friend declarations
    // didn't seem to work as expected.
public:
    struct trip_info
    {
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version)
        {
            // in versions 2 or later
            if(file_version >= 2)
                // read the drivers name
                ar & BOOST_SERIALIZATION_NVP(driver);
            // all versions have the follwing info
            ar  & BOOST_SERIALIZATION_NVP(hour)
                & BOOST_SERIALIZATION_NVP(minute);
        }

        // starting time
        int hour;
        int minute;
        // only after system shipped was the driver's name added to the class
        std::string driver;

        trip_info(){}
        trip_info(int _h, int _m, const std::string &_d) :
            hour(_h), minute(_m), driver(_d)
        {}
        ~trip_info(){
        }
    };
//  friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
private:
    std::list<std::pair<trip_info, bus_route *> > schedule;
public:
    void append(const std::string &_d, int _h, int _m, bus_route *_br)
    {
        schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
    }
    bus_schedule(){}
};

BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
BOOST_CLASS_VERSION(bus_schedule, 2)

std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
{
    return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
}
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
{
    std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
    for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
        os << it->first << *(it->second);
    }
    return os;
}

#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP

Reference: http://www.boost.org/doc/libs/1_35_0/libs////serialization/example/demo_gps.hpp

Friend function: member function 아닌 함수가 private data access 있게 해주는 C++ 메커니즘.

Method(member func) privte data access하는 것은 너무 엄격하여 특정 프로그래밍 문제를 해결하지 못하는 경우가 있다. Friend 함수는 member function 가지는 동등한 접근 권한을 가진다

.
 

 

어떤 경우에 필요할까?

Binary operator 경우.

A = B*2.75;                         //A = B.operator*(2.75)

A = 2.75*B;                         // 또한 가능해야 하지만 operator overloading에는 대응 안된다. 왼쪽 operand object 아니기 때문.

 

이때, Time class  friend 함수로 다음을 제공한다

Friend Time operator*(double m, const Time& t);  //class 선언. Class designer friend 함수의 prototype 선언해둔다. (주인이 어떻게(how) 이용하라고 친구에게 허락한다)

 

Time operator*(double m, const Time& t)                           //class 외부의 definition. class 사용하는 입장의 개발자가 friend 함수를 구현한다 (친구는 class 내부의 데이터를 접근한다)

{

Time result;

long totalminutes = t.hours * mult * 60 + t.minutes*mult;

result.hours = totalminutes/60;

result.minutes = totalminutes % 60;

return result;

}

 

사실 다음과 같이 함으로써 friend function 사용치 않을 수도 있다.

Time operator*(double m, const Time& t)

{

    return t*m;        //t.operator*(m) 사용

}

 

그럼에도 불구하고 friend 만드는 것이 바람직하다.


잇점
: friend 함수가 class 공식 interface 된다. friend 함수가 private data 직접 접근할 필요가 생겼을 , class 선언은 그대로 두고 function definition 바꾸면 된다.


**
클래스 설계에 따라서는 간혹, 특별히 클래스에 대한 데이터형 변환을 정의했을 경우에, 멤버가 아닌 버전이 유리할 수도 있다

 

<< overloading

cout << x << y;                  //(cout<<x) << y; 동일

 

ostream& operator<<(ostream& os, const Time& t)

{

os<< t.hours <<”시간, << t.minutes <<”분”;

return os;                            //ostream객체를 return하므로 (cout<<x)<<y 가능함

}

 

Reference: http://callibri.egloos.com/2955544

environment: gem1.2 + ruby1.87
program/bin/gem:8:in `require’: no such file to load — rubygems (LoadError)

solution is:
cp -a ~/program/lib/rubygems ~/program/lib/ruby/1.8/
cp ~/program/lib/rubygems.rb ~/program/lib/ruby/1.8/

Reference: http://biglaughing.blogspot.com/2008/07/bingem8in-require-no-such-file-to-load.html

What a lovely movie …

200 – Time

Very Easy

 

500 – BinaryCode

Easy

 

1100 – PowerOutage

 This problem has an interesting property. It is that if we know the longest weight to a leaf node then we can easily calculate the mininum number of minutes to check  all of the transformers.

 The property comes from the fact that if the technician want to exit from the ducts then the minimum number of minutes to check all the transformer is twice of the sum of all duct length. So the condition that the techinician doesn`t come out from the last leaf node means that the longgest way to reach for a leaf node lastly is the minimum path to visit all ducts.

 So we can get the solution by “subtract the maximum length to a leaf from the twice of sum of all ducts“.

Differences between

String.split() vs StringTokenizer

String.split() produces results including null string.

StringTokenizer skips null string.

 

Example

http://smartsql.tistory.com/tag/Java#recentComments

I searched some papers about blog classificaion.

And I found some of them.

Here are list of the papers.

  1. Finding patterns in blog shapes and blog evolution, ICWSM `07
  2. Semi-Supervised Learning for Blog Classificatioin, AAAI `08
  3. Experiments with Mood Classification in Blog Posts, Stylistic Analysis Of Text For Information Access, `05
  4. BlogHarvest: Blog Mining and Search Framework, COMAD `06

I`ll read them until friday.

I`m in a confused situation, but I can avoid it by preparing myself.

 

First, I have to change my habits.

There is no workinig overnight.

 

Second, I have to improvement myself.

What abilities I have to improve?

– Reading English stuff speedly.

– Have a strong body.

– Think, and think, and think for my brain.

 

The above things that I mentioned can be accomplished by some plans.

To get speedy in reading, I`ll choose some papers that I`d seen.

And read the papers carefully focused on the expressions.

After that carefully think the main idea and what is the author`s thought.

And to have a strong body, I have to lead my self a regular life with some exercises.

Finally, that is awful thing. Because I can`t find the way to be.

I want to wake up my brain. But there is one thing obvious to me for it.

I have to have a strong body.

So I`ll focus on my habits and reading !!!

After busy days, I`ll execute the plan ASAP.

 

I saw this video so many times before when I need to be motivated.

I want to be a person who effects the world like Steve Jobs.

It is my ultimate goal.