파이썬 기초3

하루만에 뭔가 다 써버린 느낌이지만.




lecture3.py

# -*- coding:utf-8 -*-

# Python lecture 3

# keeHwan Nam, Dept. of physics, KAIST, 2013.

# class(클래스) 란?

# class는 함수와 자료의 모음이다.

# class는 하나의 자료형이다.

class myClass:

abc = 0

b = “AB”

def myF(self, x, y):

return x+y

# 위와 같은 식으로 class라는 단어를 사용하여 클래스를 정의한다. 보면 알겠지만, 클래스는 그 안에 변수를 담을 수도 있고, 함수를 담을 수도 있다.

# 클래스를 사용해야 하는 경우는 함수와 자료를 한번에 다룰 때 편한 경우들이다. 예를 들어 보자.

a = myClass() # 정의할 때는 이름인 myClass 뒤에 ()를 붙이지 않았지만, 사용할 때는 붙인다. 왜냐하면, 처음 사용할 때 함수를 불러오기 때문이다.

# 무슨 함수? 잠시 후에 알게 된다. 그렇다 치자.

a.abc = 123

# 위와 같이, 클래스 안에 있는 변수인 abc를 “멤버 변수”라고 한다. 그리고 사용할 때는 a.abc처럼 클래스 변수이름을 먼저 써주고, 점을 찍은 다음 멤버 변수 이름을 써준 다음 사용한다.

a.myF(1, 2)

# 또한, 클래스 안에 있는 함수인 myF를 사용할 수도 있다. 이것을 “멤버 함수”라고 부른다. 사용법은 일반 함수와 같지만, 클래스 변수 이름을 먼저 쓰고 점을 찍어야 한다는 점이 다르다.

# 뭔가 불편해 보이는데 클래스를 왜 사용할까?

# 만약, 어떤 사람이 있는데 이 사람이 이름, 생일, 나이 등의 속성과 걸어다니기, 소리치기 등의 기능이 있다고 해 보자. 그럴 수 있다. 이런 기능을 구현하기 위해서, 리스트를 쓸 수 있다.

def walk(displacement):

position+=displacement

def shout(sentence):

play(sentence)

person1 = [“MyName”, “05, Jul”, 24, walk, shout]

”’

위와 같이 해도 “사람” 처럼 쓸 수는 있다. (이상하게 보이겠지만, 리스트 안에 함수도 들어갈 수 있다. 물론 person1[4](42,24)처럼 사용해도 잘 작동한다!)

하지만, 뭔가 알 수 없는 불편함이 있다. person1[0]이 person1의 이름을 알려준다는 것을 미리 알고 있지 않으면 어떻게 처리할 것인가? 이대로 놔두면, 쓰기만 하는 남들은 몰라도 일단 프로그램을 만들고 있는 내가 불편하다. (물론 파이썬에서는 ‘키워드’라는 것이 있지만, 일단 넘어가자.)

그래서 이런것들을 해결하기 위해서 클래스라는 개념이 등장한다. 클래스는 위의 모든 것들을 그냥 다 갖고 있는 하나의 덩어리이다.

”’

class person:

name = “”

birth = “”

position = [0, 0]

def walk(self, displacenemt):

self.position+=displacement

# 간단히 쓰기 위해서 person이 가져야 하는 특성들 몇개만 써 보았다.

# 이제, 어떤 사람을 만들기 위해서는 다음과 같이 사용하면 된다.

person1 = person()

person1.name = “Nam”

person1.birth = “5, Jun”

# 등등등. 대충 위와 같이 쓰면 된다. 여기서 self.라는 녀석이 뭘까? 의문이 들었다면 당신은 파이썬에 소질이 있는 것이다.(라고 본 필자는 생각한다.) 늦지 않은 시점에 self에 대해서 설명할 것이므로 걱정하지 말자.

# 클래스를 왜 써야 하는지 아직 잘 모르겠다면, 일단 클래스라는 것이 있고, 남들이 class 구문을 썼을 때 그게 무슨 뜻이고 어떻게 작동하는지 정도만 이해하고 넘어가도 좋다.

# 위에서는 person1의 속성을 정하기 위해서 person1.name, person1.birth 등등을 나중에 따로 정해주어야 했다. 하지만, 대체로 인간은 날 때부터 생일이 정해지고 이름이 정해진다. 그러므로, 애초에 만들 때 부터 이런 것들을 정해줄 수 있다면 더 좋을 것이다. 그래서 생성자가 존재한다.

class person:

def __init__(self, givenname, birthday):

self.name = givenname

self.birth = birthday

def walk(self, displacement):

self.position+=displacement

# 위와 같이 클래스를 정의해 보자. 여기서 밑줄 두개__가 붙어있는 함수인 __init__은 매우 중요하다. __init__(self, …) 이 형식은 그 자체로 쓰이는 정해진 이름이므로 다른 용도로 쓰면 안된다. __init__이 하는 역할은, 클래스 변수가 처음 만들어질 때 입력받은 변수를 이용해서 클래스 멤버들이 가지는 초기값을 정하는 것이다.

# __init__ 은 “생성자(constructor)”라고 부른다.

”’

잠깐. self는 무엇일까? 더이상 이 설명을 늦출 수 없게 되었다.

self는 클래스 변수 자기 자신을 나타낸다. 가령,

person1 = person()

이런식으로 person1이라는 변수가 생겼다고 하자. person1은 클래스 변수이므로, 멤버 변수로 name이 있고, 이 변수를 호출하기 위해서는 person1.name이라고 부르면 된다.

문제는 person1의 안에 있는 함수들이 person1.name을 부르고 싶을 때이다.

왜냐하면, person1의 안쪽에서는 person1이 뭔지 모르기 때문이다. 이런 특징을 변수의 범위(scope)라고 하는데, 잘 모르면 여기서는 넘어가도 좋다. 하지만 scope에 대해서는 언젠가 공부하게 될 것이다. 이런거 잘못 알아서 생긴 오작동은, 손톱밑에 낀 가시처럼 해결하기도 어려우면서 심각하기는 무시무시한 영향을 만들어 낼 수도 있기 때문이다.

person1의 안쪽에 있는 멤버 함수인 walk를 살펴 보자. 그 안에서 position을 부르기 위해서 self.position을 사용했다. person1의 밖에 있는 애들은 position을 사용하기 위해서 person1.position이라고 불러내면 되고, person1의 안에 있는 walk는 position을 사용하기 위해서 self.position을 사용했다.

또 다른 특징은, 멤버 함수를 정의할 때 self가 가장 앞에 들어간다는 점이다. 이것은 파이썬이 가진 중요하면서 이상한 특징인데, 파이썬에서 클래스 안에 있는 멤버 함수들은 자기 자신이 멤버 함수라는 사실을 알기 위해서 변수 중 가장 먼저 self를 인자로 받아야 한다. 뭐 기본이니까 그냥 그러려니 하고 넘어가면 되겠다.

실제로 사용할 때는 person1.walk(displacement)처럼, self는 빼고! 사용해야 한다. 또한, person1의 안쪽에서 불러낼 때에도 self.walk(displacement)처럼 사용하면 된다. 왜 walk(self, displacement)처럼 사용하지 않느냐고 묻는다면, walk(self, displacement)에 있는 self는 self.walk(displacement)처럼 사용할 때 앞으로 빠져나와서 self.가 되었기 때문이다. 이것도 잘 이해가 안간다면 그러려니 하면 된다.

”’

# 생성자를 잘 사용하면 클래스 변수를 편리하게 부려먹을 수 있으므로 어떻게 하면 보다 편하게 될지 잘 생각해 보자.

# 사실은 멤버 함수를 “메소드”라고 부른다. 멤버 함수라고 부르든 메소드라고 부르든 뭐 그렇게 중요하진 않지만.

# 이제 상속(inheritance)에 대해서 알아보자. 프로그래머에게 상속은 알든 모르든 아주 중요한 개념이다.

# 클래스는 자기 자식 클래스에게 자신의 속성을 상속시켜줄 수 있는데, 사용법은 간단하다. 일단 위에서 person이라는 클래스가 정의되어 있었으니 이 클래스를 부모 클래스로 하는 자식 클래스를 하나 만들어 보자.

class korean(person):

nationality = “KOREA”

def speak(self):

print “안녕”

# 위와 같이, person의 속성을 상속 받은 korean이라는 클래스를 만들 수 있다. 사용법은 똑같은데,

jspark = korean(“J.S.Park”, “9, Oct”)

# 위와 같이 그냥 똑같이 사용하면 된다. 아, 그런데 왜 이름과 생일을 처음부터 입력 받을 수 있는걸까? 그것이 바로 ‘상속’이라는 것이다. korean이라는 클래스는 person의 속성을 그대로 이어받았기 때문에, 생성자__init__()도 그대로 이어받았다.

# 물론 korean의 생성자를 나름대로 새로 정의할 수 있다.

class korean(person):

nationality = “KOREA”

def __init__(self, language):

self.lan = language

def speak(self):

print “안녕”

# 나름대로 새로 정의한 생성자를 person에서 정의한 생성자랑 같이 사용하고 싶다면, 다음과 같이 사용해 볼 수도 있다.

class korean(person):

nationality = “KOREA”

def __init__(self, language, givenname, birth):

person.__init__(givenname, birth)

self.lan = language

def speak(self):

print “안녕”

# 대충 이런 식으로 사용할 수 있다. 여러 부모에게서 상속받는 다중상속도 가능한데, 이건 언젠가 설명해 볼 기회가 있을지도 모르겠다.

”’ (몰라도 되는 쓸데없는 부연설명) 어떤 사람들은 클래스와 클래스의 상속을 사용할 수 있으니 파이썬이 객체지향형 언어라고 주장한다. 그러나 파이썬은 class가 있기만 할 뿐, 객체지향형 언어에서 클래스가 갖춰야 하는 다형성, 은폐성 등을 기본적으로 지원하지 않는다. 물론 파이썬에서도 사람들끼리의 약속으로 은폐성을 제공하고, 조건문을 복잡하게 사용해서 다형성을 제공할 수 있지만 C++이나 Java에서처럼 간단하게 제공하는 것은 아니다. 물론 이것은 필자 개인의 의견일 뿐으로, 파이썬이 객체지향헝 언어의 특성을 갖고 있다는 점을 부정하고 싶지는 않다. 또한, 객체지향형 언어로 할 수 있는 것을 모두 할 수 있다는 점을 부정할 수 없다. 단지, 객체지향형 언어의 모든 특성을 갖고 있는 완전한 객체지향형 언어가 아니라고 말하고 싶을 뿐이다.

”’

파이썬 기초2

파이썬 기초 강좌 두번째.




lecture2.py

# -*- coding:utf-8 -*-

# Python lecture 2

# keeHwan Nam, Dept. of physics, KAIST, 2013.

# scipy / numpy 사용하기

”’

물리학, 수학, 공학 등 이공계 전반에서 파이썬을 사용하는 사람들 수가 늘어나면서 이공계에서 사용하는 수학 함수들에 대한 요구가 늘어났고, 따라서 사람들은 그런 수학 함수를 파이썬 모듈로 만들어서 제공한다. 거의 대부분의 이공계용 모듈들이 공짜로 제공되며, 심지어 소스도 공개되어 있는 오픈소스로 제공된다.

이 사람들이 어떻게 구현했는지 알아보고 싶을 때, 직접 소스를 열어서 살펴볼 수도 있고, 만약 뭔가 개선할 부분이 있다면 직접 고쳐서 투고할 수도 있다. 물론 이런거 만드는 사람들이 고수들이라 워낙에 잘 만들어져 있기 때문에 내가 손댈만한 부분은 없지만, 가끔 뭔가 고쳐야 할 부분이 있을지도 모르지 않은가.

어쨌든, 그 안에 어떻게 구현되었는지는 모르더라도, 이런 모듈들을 필요할 때 가져다 쓰는 것은 중요한 일이다. 그래서 소개하는 모듈이 scipy와 numpy이다.

numpy는 수치해석을 파이썬으로 하기 위해 필요한 거의 모든 것이 들어 있는 패키지이다.

공식 홈페이지: http://www.numpy.org/

scipy는 이공계에서 쓰는 수많은 함수들이 많이 들어 있는 패키지이다.

공식 홈페이지: http://www.scipy.org/

어쨌거나 둘 다 필요하므로 둘 다 설치하도록 하자.

설치하다보면, 운영체제 버전, 특히 윈도우즈에서 설치하는 경우 32비트/64비트 문제와 파이썬2.7이냐 파이썬3.3이냐 매우 골치아프게 다가온다. 실제로 당신이 이 문제를 해결하려면 나도 잘 알 수 없는 삽질을 해야 하는데, 그 모든 삽질을 미리 해두신 성인이 계셔서 이 우주는 살만하다는 사실을 알 수 있다.

http://www.lfd.uci.edu/~gohlke/pythonlibs/

위의 홈페이지에서 필요한 패키지들을 받아서 설치하기 전에 크리스토프 골케 님에게 감사의 인사를 마음속으로 하도록 하자.

http://wiki.scipy.org/Tentative_NumPy_Tutorial

numpy와 scipy의 경우, 매우 설명이 잘 되어 있는 자습서(Tutorial)를 제공한다. 영어를 잘 몰라도, 거기에 나와 있는 예제들만 한번씩 다 실행시켜 보면 대충 뭐가 어떻게 돌아가는지 알 수 있을 것이다.

”’

import numpy as np

# numpy는 대체로 as np로 줄여서 불러온다.

# 어쨌거나 위와 같이 하면 np.으로 시작하는 함수들을 모두 사용할 수 있다. np.조차 사용하기 귀찮다면

from numpy import *

# 배웠듯이, 위와 같이 불러오도록 하자. 다만, 파이썬 내장함수와 numpy의 함수들 중 몇개가 이름이 겹치긴 한다. 혹시 그런 함수들을 구분해서 사용해야 하는 경우라면 주의하도록 하자.

”’

http://docs.scipy.org/doc/numpy/reference/

http://docs.scipy.org/doc/scipy/reference/

위의 주소에 들어가 보면, numpy와 scipy에서 제공하는 여러 기능들에 관한 설명이 적혀 있다.

쭉 살펴보다가, ‘이거다!’ 싶으면 클릭해서 열어보고 그 안에 원하는 함수를 찾아서 사용하면 된다.

못들어본게 많을 순 있어도, 필요한게 없는 경우는 거의 없을 것이다.

”’

# 예를 들어, 금융을 하다 보면 만날 수 있다는 현재 가치에 관한 함수가 있다. fv()라고 한다.

print numpy.pv(12., 2., 1)

# 위와 같이 실행시키면 -0.082840236686390539 이라는 값을 얻을 수 있을 것이다.

# 그리고 numpy의 모든 함수는 다음과 같은 입력도 처리해 준다.

print numpy.pv([12.,3], [2.,4], [1,4])

# 앞에서는 숫자 한개씩 입력했지만, 이번엔 여러개의 리스트를 입력했다. 이렇게 되면, “알아서, 척척” 첫번째 값끼리 대입한 함수값, 두번째 값끼리 대입한 함수값을 출력해준다. 즉, 결과는 array([-0.08284024, -1.328125 ])이 된다.

# 아주 많이 사용되는 모듈 중, 고속 푸리에 변환(FFT) 모듈이 있을 것이다. 이 모듈의 경우, 아무 생각 없이 import numpy 라고 하면 안된다. 즉,

numpy.fft.fft(array[1,2,3,4])

# 위와 같이 실행시키면 안된다는 뜻이다.

# 이 모듈은 numpy가 아니라 numpy.fft를 불러와야 한다. 이것은 실제로 디렉토리를 찾아가 보면, fft는 덩어리가 크기 때문에 별도의 디렉토리에 나누어져 들어가 있다. 즉, numpy가 설치된 디렉토리 밑에 fft라는 디렉토리가 따로 있어서, 그 밑에 있는 파일들을 불러와야 한다는 뜻이다. 따라서 numpy라고만 하면 안된다.

import numpy.fft

import numpy.fft as npfft

# 잘 모르겠다면, fft같은 모듈들은 위와 같이(둘 중 하나로) 불러와서 써야 한다는 사실만 기억하면 된다.

# 이런 모듈들이 몇개(은근히 많이) 있는데, 위의 reference를 꼼꼼히 잘 읽어보면 어떻게 사용해야 하는지 알 수 있을 것이다.

# 이러한 내용은 scipy도 마찬가지이다.

import scipy

# scipy의 사용은 위와 같이 사용한다.

# 베셀 함수, 르장드르 함수 등 특별한 함수들은 scipy.special이라는 모듈에 별도로 저장되어 있다. 따라서 베셀 함수를 불러오고 싶다면,

import scipy.special

# 위와 같은 방식으로 모듈을 불러와야 한다.

# 그렇게 되면, 이제 0차 1종 베셀 함수를 다음과 같이 불러올 수 있다.

print scipy.special.j0(0.5)

# 그 외에, 아주 많은 함수들이 있지면 여기서 모두 소개하는 것은 scipy 사용설명서 번역과 같은 작업이므로 생략하도록 하겠다.

파이썬 기초1

파이썬을 그닥 좋아하지 않지만, 그렇다고 이공계에 있으면서 파이썬을 버릴 수는 없을 것 같다. 연구실에서 학생들끼리 파이썬 스터디를 하기로 했고, 내가 파이썬 파트를 맡아서 가르쳐 주기로 했기 때문에, 어쨌든 강의록을 써 보았다.

이 설명은 파이썬 2.7.4 기준이다. 파이썬3.3에서는 뭐가 어떻게 변할지 잘 모르겠다.


http://snowall.tistory.com/2407

파이썬 설치는 위의 글을 참고하면 될 듯하다.

강의록 파일과 본문을 첨부한다.




lecture1.py

# -*- coding:utf-8 -*-

# Python lecture 1

# keeHwan Nam, Dept. of physics, KAIST, 2013.

”’

파이썬 코드 읽는 법.

1. 한 줄에서, # 이후는 모두 주석이다. 즉, #가 등장한 다음부터는 해석하지 않는다.

2. 파이썬에서는 들여쓰기가 매우 중요하다. (나중에 다시 설명. 아무튼 들여쓰기가 매우 중요함!)

3. 코드에 한글을 쓰고 싶으면 # -*- coding:utf-8 -*- 을 첫줄에 붙여넣기 해야 한다. # 부터 -까지 전부 다. 심지어 주석에 한글이 있어도 반드시 필요하다.

”’

# 간단한 숫자 계산

print 3+5 # int + int = int

print 3.+5. # float + float = float

print 3+5. # int + float = float

print .3+.5 # float + float = float

print 10.5e5 # scientific notation sample 1

print 102.4e-4 # scientific notation sample 2

# print는 그 뒤에 있는 놈을 화면에 출력시키는 명령어이다.

# 변수 사용

a = 423 # variable 1

b = 302 # variable 2

print a+b # a+b

”’

파이썬에서 변수는 미리 선언할 필요 없이, 필요할 때 그때그때 만들어서 쓰면 된다.

하나의 프로그램 내에서 변수는 그냥 막 갖다가 쓰면 된다.

”’

a = ‘abcd’

print a

# 앞에서 분명 a라는 변수에 423을 넣고 사용했지만, 여기에 ‘abcd’라는 문자열을 집어넣어도 아무 상관 없다.

# 흔한 연산자

a+=1 # 이 구문은 a=a+1과 동일하다. 물론 1뿐만 아니라 +할 수 있는 아무 숫자나 넣어도 된다.

a-=3

a*=32.

a/=3

# 사칙연산에 대하여 다 되어 있다. 뿐만 아니라 +, -, *, /가 존재하는 연산이면 대충 다 된다고 보면 된다.

# 함수 선언과 사용

”’

파이썬 내장 함수는 굳이 선언할 필요 없이 그냥 사용하면 된다.

그러나 파이썬 내장함수만으로 모든 프로그램을 만들 수는 없고, 내가 직접 함수를 만들어야 하는 경우가 있다.

또는 남이 만든 함수를 사용해야 하는 경우가 있다.

”’

def myfunctionname(variable1, variable2): # 함수는 def를 이용하여 함수라는 걸 알려주고, def 뒤에 함수 이름과 함수가 사용할 변수를 써준다. 끝에는 :를 붙여서 함수가 시작된다는 사실을 알려준다. 여기서 variable1과 variable2는 함수 안에서 사용할 수 있는 변수들이 된다.

print “My first function!” # 함수에 포함되는 줄들은 무조건 한 칸 들여쓰기를 사용한다. 탭으로 해도 좋고 4칸 들여쓰기나 8칸 들여쓰기를 해도 된다. 중요한건 들여쓰기를 한다는 사실이다.

return 2*variable1+variable2 # 함수의 끝은 return 으로 끝난다. 만약 return이 아무데도 없으면, 파이썬은 함수에 써있는 할 일들을 처리 하고 함수를 적당히 끝낸다. return이 있으면 그 자리에서 확실히 끝낸다. return 뒤에 있는 값을 함수를 불러온 자에게 넘겨주면서 함수는 끝난다.

print myfunctionname(142, 345) # 함수를 부를 때는 이름을 부르고, 그 다음 괄호 안에 사용할 변수를 써준다. 변수의 개수가 안맞으면 에러가 난다.

def myfunction2(v1): # 두번째 함수를 정의해 보았다.

print “My second function.”

return v1*3.

print myfunction2(myfunctionname(524, 394)) # 이렇게 합성함수도 된다. 사용법은 수학에서 본 합성함수와 같다.

# 참/거짓

condition = True # 일단 참은 True, 거짓은 False이다.

# 조건 판단 후 분기. 조건 판단 후 분기는 if를 사용한다.

# if 다음에 있는 구문이 True로 판정되면 그 다음줄에 있는 명령어들이 쭉 실행된다. 여기서도 들여쓰기 해놓은 곳 까지만 한 덩어리로 친다. 들여쓰기에 항상 주의하자.

if a>b:

print a

else:

print b

#else 구문은 있어도 되고 없어도 된다. 있으면 if의 조건이 틀렸을 때 else부분이 실행되고, 없으면 그냥 넘어간다. 물론 들여쓰기는 필수.

i=0

while condition:

i=i+1

print i

# while은 condition이 True인 동안 계속 실행된다. 즉, 위와 같이 써놓으면 무한히 계속 실행된다.

while condition:

condition = False

print condition

# 위와 같이 해놓으면 1번 실행되고 끝난다. 어쨌든.

while condition:

i=i+1

if i>40

print i

condition = False

# 위와 같이 하면 i가 41이 될 때 까지만 수행되고 그 다음에 수행이 안된다. 같은 얘기를 다음과 같이 할 수도 있다.

condition = 1

while condition<40:
condition=condition+1

print(condition)

# 위와 같이 해 두면 condition이 1씩 증가하다가 condition<40이 false가 되면 멈출 것이다. # 물론 위의 두 경우는 실제로 구현해 보면 사소해 보이는 차이가 있다. 그건 나중에 삽질하면서 배우는 것이 더 빠르게 배울 수 있다. # 리스트(list), 튜플(tuple), 어레이(array)
# 여러개를 한번에 묶어서 나타낼 수 있는 자료형은 리스트, 튜플, 어레이가 있다.

a = [1,2,3,4] # 리스트의 예

b = (“a”, “b”, “c”) # 튜플의 예

c = array.array(‘l’, [2,4,5,3]) # 어레이의 예. 이 예제는 아직 실행되지 않을 것이다. 그 이유는 나중에 알도록 하고 일단 이런게 있다는 것만 알아두자.

”’

리스트, 튜플, 어레이의 사용법은 유사하지만 사소한 차이가 있다. 파이썬 개발자들이 왜 이래놨는지는 잘 모르겠지만.

1. 리스트와 튜플의 원소는 아무거나 다 된다. 숫자, 문자열, 함수, 리스트, 튜플 등 아무거나 다 된다. 리스트의 원소가 튜플이어도 된다. 어레이는 아무거나 쓸 수 없고, 정해진 규칙이 따로 있다.

2. 그 안에 있는 원소 중 하나만 불러올 때는 이름 다음에 네모괄호[]를 써서 사용한다. 이 방식은 어레이, 리스트, 튜플 상관 없다. abc[3]는 abc에 있는 4번째 원소를 불러온다.

3. 여기서, abc[3]이 abc의 3번째 원소가 아니라, 4번째 원소라는 점에 주의하자. 파이썬은 숫자를 0부터 센다!

4. 튜플은 한번 정해지면 안에 있는 내용을 고칠 수 없다. 만약 고치고 싶다면, 처음부터 끝까지 한번에 다시 지정해야 한다.

5. 일부를 고르고 싶으면 abc[3:5]같이 고를 수 있다. 이렇게 하면 4번째 부터 5번째 까지 골라진다. 왜 3~5인데 3번째부터 5번째가 아닌지, 왜 4번째부터 6번째까지가 아닌지, 묻지 말자.

6. 뒤에서부터 고를 수도 있다. 가장 뒤에 있는 원소는 -1번째이다. 즉, abc[-1]은 가장 끝에 있는 원소이고, abc[-2]는 가장 끝에서 두번째 있는 원소이다. 왜 가장 끝이 이번엔 -0이 아닌지, 역시 묻지 말자.

7. 특정 지점부터 끝까지, 처음부터 특정 지점까지 고르고 싶으면 abc[3:]이나 abc[:3]처럼 쓸 수도 있다. abc[3:]은 4번째 원소부터 끝 원소까지 전부 다 고른다.

8. 가령 abc[:-4]라고 하면, 처음부터 시작해서 끝에서 4번째 원소까지 골라준다. abc[-3]이라고 하면 끝에서 3번째 원소부터 끝까지 골라준다.

9. 리스트, 튜플, 어레이는 이게 기본이고, 이걸 갖고 놀 수 있는 아주 많은 종류의 내장 함수들이 있다. 그건 나중에 다시 설명할 기회가 있을 것 같다.

10. 리스트와 어레이는 +를 이용해서 이어붙일 수 있다. 즉, [a,b,c]+[3,3,4]=[a,b,c,3,3,4]이다.

”’

# for 구문을 이용한 반복문

”’리스트, 튜플, 어레이를 위와 같이 길게 설명한 이유는 for 구문 때문이다. 물론 for 구문 아니어도 얘들은 쓸모가 많기 때문에 알아두면 좋지만, for 구문을 잘 쓰기 위해서는 잘 알아두는 것이 필요하다.

”’

for i in [1,2,3,4]:

print i

”’

위와 같은 구문이 for문의 가장 기본적인 사용법이다. for는 구문 시작이고, i는 for 구문 내부에서 사용할 변수 이름이다. in은 그 뒤에 있는 리스트, 어레이, 튜플에서 앞에서부터 값을 하나씩 꺼내서 i에 던져주는 역할을 한다.

다시 말해서, for 구문은 in 뒤에 있는 목록에 있는 값을 하나씩 i에 대입하면서 계속 반복 실행할 때 사용하는 구문이다.

여기서도 들여쓰기는 매우 중요하다.

in 뒤에 오는 것은 뭐가 됐든 목록이기만 하면 된다. 그럼 알아서 하나씩 던져준다.

위와 같은 간단한 구문으로 시작하는 for 문이지만, 실전에서는 매우 강력하다. 지금 목록의 원소가 4개밖에 없으니 그냥 간단해 보이지만, 이런 작업을 수만번, 수십만번씩 반복 처리하려면 그건 그야말로 시간낭비이고 끔찍한 일이 될 것이다. 그거 처리할 시간에 머리를 굴려서 for 문으로 처리하도록 하고 우리는 커피 한잔을 쪽 빨면서 기다리는 것이 더 낫다.

”’

# 파일 입출력

# 파이썬에서의 파일 입출력은 매우 간단하다.

myfile = open(“filename.txt”, “w”)

”’

위와 같이 하면 된다. open 함수는 내장 함수인데, 실제로 파일을 열어준다. filename.txt는 내가 사용하려는 파일 이름이고, 원하는 대로 바꿔줄 수있다. “w” 부분은 내가 파일을 갖고서 뭘 할건지 알려주는 부분인데, 그 뜻은 다음과 같다.

“r” = 읽기만 하겠다.

“w” = 쓰기만 하겠다. 원래 파일에 뭐가 기록되어 있든지 상관 없이 처음부터 다 덮어쓸 생각이다. 파일이 없다면 만들 것이다.

“a” = 쓰기만 하겠다. 원래 파일에 뭐가 기록되어 있다면, 그 뒤에부터 이어붙일 것이다. 파일이 없다면 만들 것이다.

“r+” = 읽기도 하고 쓰기도 하겠다. 쓸 때는 원래 파일에 기록된거 다 무시하고 덮어쓴다. 파일이 없다면 에러가 난다.

”’

myfile.write(“abcd”)

myfile.write(a)

# 위와 같이, “w”를 이용하서 파일을 열었으면 write명령을 이용해서 파일에 실제로 기록할 수 있다. 여기서 마침표.가 보이는데, 그건 “myfile이라는 곳에 write해라.”라는 뜻으로 해석하면 된다. 자세한건 나중에 클래스를 공부하고 나서 생각할 것이다.

# 파일의 끝에 줄을 넘기고 싶다면? (엔터를 친 것처럼 그 다음줄에 기록하고 싶다면?) \n을 사용한다.

myfile.write(“abcd\n”)

# 위와 같이, 다 쓰고나서 \n을 써준다면, \n은 실제로는 \n으로 적히는 것이 아니라, 그 위치에서 엔터키를 친 것처럼 그 다음줄로 넘어가는 것으로 해석된다.

myfile.close()

# 파일을 다 쓴 이후에는 close()를 해줘야 실제로 기록된다! 이것은 매우 중요하다.

# 물론 write까지만 해 놓고 close를 하지 않더라도, 프로그램이 종료되는 시점에 실제로 기록되기는 한다. 하지만 계산하다가 중간에 컴퓨터가 꺼지거나 했을 때, 지금까지의 계산 결과라도 살리고 싶다거나 하면 close()를 사용해서 실제로 기록 하는 것이 좋다.

# close()가 하는 역할은 실제로 기록하고, 파일을 닫는다. 즉, close()를 사용한 이후에는 myfile.write()같은 명령을 이용해서 파일에 뭘 더 쓴다거나, myfile.read()를 이용해서 읽어온다거나 할 수 없다. 이미 닫혔기 때문이다.

# 만약 기록만 하고 아직 파일을 닫고 싶은건 아니라면 flush()가 있다.

myfile.flush()

# 위와 같이 명령하면, 실제로 파일이 기록되지만 파일을 닫지는 않는다.

myfile = open(“filename.txt”, “r”)

# 이제, 읽기 전용으로 파일을 읽어보자.

myfile.read()

# 위의 명령어를 쓰면 파일을 한방에 처음부터 끝까지 다 읽어온다. 그리고 파일 보고 있는 위치를 끝으로 옮겨둔다.

a = myfile.read()

# 위와 같이 쓰면 myfile에서 읽어온 데이터를 a라는 변수에 저장시켜 줄 것이다. 그리고 파일 보고 있는 위치를 끝으로 옮겨둘 것이다.

myfile.readline()

# 위의 명령어를 쓰면 파일을 한줄만 읽어온다. 그리고 파일 보고 있는 위치를 방금 읽어온 줄의 그 다음 줄 첫 글자로 옮겨둔다.

# ‘파일 보고 있는 위치’란, 책갈피 같은 것이다. 책을 읽을 때 앞에서부터 읽다보면 어디까지 기억해 둬야 하는데, 그것과 마찬가지 역할을 하는 것이다. 원한다면 파일을 중간부터 읽을 수도 있는데, 대체로 데이터 처리할 때는 처음부터 끝까지 읽게 되므로 중간부터 읽거나, 중간까지 읽는 과정은 필요할 때 찾아보도록 하자. 어쨌든, read()나 readline()함수는 ‘파일 보고 있는 위치’에서부터 그 다음에 정해진 곳(끝 또는 그 줄 끝)까지 읽게 된다. 처음에 파일을 open()으로 열게 되면, 파일 보고 있는 위치를 파일의 시작점에 가져다 두기 때문에 우리가 “첫 부분” 부터 파일을 읽을 수 있는 것이다.

# import 써보기

import array

# import는 우리가 만들고 있는 이 프로그램 파일 안에 설명되지 않은, 다른 파일에 작성된 내용을 참고하고 싶을 때 사용한다.

# 사용법은 위와 같이 import를 써 주고 불러올 ‘모듈’ 이름을 써주면 된다. ‘모듈’은 원하는 함수가 있는 파일의 이름 또는 그런 파일이 있는 디렉토리 이름이다.

# import를 하기 전에는 해당 모듈 안에 있는 함수들을 사용할 수 없다.

# 일단 array 모듈을 불러왔으므로, 앞에서 써보지 못했던 어레이를 사용할 수 있게 된다.

c = array.array(‘l’, [2,4,5,3])

# 이제 이 코드가 작동할 것이다.

# 사용법은 모듈명 다음에 마침표.를 찍어주고 그 모듈 안에 있는, 사용하려는 함수를 불러서 쓰면 된다.

# 이렇게 import를 한 경우에는 함수 이름 앞에 모듈 이름을 절대로 생략하면 안된다. 그러나 사람들은 생략하고 싶을 때가 자주 있는데…

from array import array

# 위와 같이 import를 사용할 수도 있다. array 라는 모듈 안에서 일부분만 갖고 오는 것이다. 이 경우, array라는 모듈 안에 있는 array라는 함수만 갖다 쓰겠다고 한 경우가 된다. 이렇게 되면 array.array라고 하지 않고 array라고만 해도 작동한다. 만약 array라는 모듈 안에 있는 모든 함수를 다 갖다 쓰면서, 동시에 array.func()처럼 앞에 모듈명 붙이는걸 생략할 수 있다.

from array import *

# 이렇게 별표*를 붙여서 import하는 경우에는 전부 다 갖다 쓸 수 있으며 모듈명도 생략할 수 있다.

# 하지만 문제가 되는 경우가 있는데, 사용하려는 두 모듈에서 같은 이름의 함수가 있는 경우이다.

from moduleA import funcA

from moduleB import funcA

# 위와 같은 경우, moduleA에도 funcA가 있고,moduleB에도 funcA가 있다. 그럼 아무생각없이 funcA(x)를 실행시키면 뭐가 실행될까?

# 일단은 나중에 불러온 함수, 즉 moduleB에 있는 funcA가 실행된다. 하지만 나는 moduleA에 있는 것도 쓰고 싶다면?!

# 몇가지 해결 방법이 있는데, 가장 고전적으로는 그냥 import moduleA와 import moduleB 형식으로 불러오고, moduleA.funcA()와 moduleB.funcA() 처럼 사용하는 것이다.

# 두번째로는 as를 사용하는 것이다. 다음과 같이 써 보자.

from moduleA import funcA as funcAA

from moduleB import funcA as funcAB

# 위와 같이 쓰면 funcAA()와 funcAB()로, 두 함수가 구분되므로 마음대로 불러다 쓸 수 있다.

# 또한 as는 모듈의 전체 이름에도 사용할 수 있다.

import mylongnamedmodule as ml

# 위와 같이 쓰면 mylongnamedmodule이라는 모듈에 있는 함수 foo()를 불러올 때, mylongnamemdmodule.foo()가 아니라 ml.foo()로 불러올 수 있다. 단, as로 불러온 경우에는 as 뒤에 있는 이름만 유효하다. 즉, 위와 같이 모듈을 불러왔다면, 오히려 mylongnamemdmodule.foo() 처럼 쓰면 파이썬은 그런 모듈 모른다며 에러를 내뱉을 것이다.

심오한 질문

예전에 철학 수업을 듣다가, 교수님이 매우 심오한 질문을 던졌다.

“우유에 타서 먹는 씨리얼이 있다. 사람들은 이 씨리얼을 바삭한 상태로 먹기를 바라는데, 그럼 왜 우유에 타서 먹을까? 이상하지 않은가?”

11년 전에 들었던 질문인데, 수백리터의 우유와 수십 킬로그램의 씨리얼을 먹어봤지만 아직도 답을 모르겠다. 우유를 부었지만 바삭한 상태인 씨리얼이 조금 더 맛있는 것 같긴 한데, 기분 탓인 것 같기도 하고.

철수의 시간

요새는 고등학교 물리에서도 특수 상대성 이론을 깊이있게 다루는지, 시간 지연과 길이 수축에 대해 이야기가 나온다. EBS를 잠시 보는데, 특수 상대성 이론에 관한 이야기가 나왔다.

“정지 상태에 있는 철수가 10초 동안 관찰하는 동안, 운동 상태인 민수는 2초의 시간이 흘러갔다. 이것이 바로 시간 지연 효과이다.”라는 내용을 설명했다. 자세한 내용은 이것과 다르지만 어쨌든 대충 10초와 2초의 차이가 생겼다고 한다.

자, 그럼 움직이는 사람이 관찰했을 때 20%까지 시간이 느리게 흐르려면 얼마나 빨리 달려야 하는지 알아보자.

t에 2초, t’에 10초를 넣고 보면, 광속의 98%로 달려야 한다는 사실을 알 수 있다.

극적인 효과를 노린 건 좋지만, 이거 너무 과장한거 아닌가 하는 생각이 들었다. 아니면 나중에 발사할 국산 발사체 나로호가 이정도 속도로 화끈하게 날아가는 것을 상상하도록 해 보려는 시도일까.

1000000



2006년 8월부터 2013년 7월까지, 블로그 운영을 시작한지 딱 8년만에 100만명의 방문객을 맞이했다. 정확히 100만명이 되는 순간의 카운트를 조작 없이 잡은 것도 나름 성공이라면 성공.

천만명은 그럼 72년 후인가?

항공기 사고

http://www.slashdot.org/story/188561

아시아나 항공기 사고와 관련되어서 슬래시닷에 올라온 기사를 읽었다. 기사 본문은 “말콤 글래드웰이 ‘아시아나 항공기 사고는 한국인 기장이 위계질서를 안전지침보다 우선하였기 때문이다.’라고 주장하였다.”라는 내용이다. 그리고 그 뒤로 긴 토론이 이어지는데…

일단 한국인 조종사들은 군인 출신이 많기 때문에 필연적으로 위계질서에 민감하다는 내용으로 시작한다. 이걸로 논쟁이 붙더니, 문화적 차이와 인종차별에 대한 이야기가 나오고 영국에서 인도인들의 행태를 비판하는 댓글이 달렸다. 이걸로 인종차별주의자니 아니니 싸우다가, 여성 할례와 남성 할례에 관한 이야기가 등장한다. 그러다가 갑자기 오바마 대통령의 업적과 과실에 관한 이야기가 나온다.

그 다음, 한국어에서는 존댓말이 있고, 존댓말 때문에 윗사람과 아랫사람을 대하는 태도가 다르고, 따라서 생각도 바뀌게 된다는 이야기가 나온다. 이 부분에서 이 문제에 관한 제대로 된 논의가 나오는데, “한국 문화와 서구 문화”의 대립이 문제가 아니라 “”군대식 위계질서”가 문제라는 주장이다. 즉, 한국인이라서 문제가 된 것이라기보다 엄격한 상명하복식 위계질서가 있는 경우에는 언제라도 문제가 생긴다는 주장이 드디어 나왔다.

450개 가량의 댓글을 다 읽어봤는데, 한국과 한국 문화에 대해서 오해하는 사람도 많이 있고, 뭘 좀 알고 주장하는 사람도 없지는 않았다. 그리고 이 글에서 KOREA를 북한으로 오해하는 사람이 아무도 없었다는 점이 조금 신기했다.

댓글로 싸우는건 전세계 어디서나 공통이라는 것도 신기했고.

난 이걸 왜 다 읽은거지…OTL

http://www.slashdot.org/story/188723

후속 기사로 반박문이 올라왔다.

연애의 불가사의


http://www.hani.co.kr/arti/economy/economy_general/595307.html

이 기사를 보면 남자 입장에서 데이트 잘하기는 정말 어려운 것 같다.

여성 직장인이 가장 하기 싫은 데이트는 1위가 ‘돈을 아끼려는 티가 나는 데이트’에 이어서, 2위로 ‘식사-영화관-까페, 매일 똑같은 데이트’가 선정되었다.

동시에, 여성 직장인이 좋아하는 데이트 1위는 ‘영화관 데이트’로 선정되었다.

끝으로 여성 직장인이 생각하는 상대방의 데이트 비용은 3~5만원인데, 이 돈은 두명이 영화를 본 뒤 가벼운 식사를 할 정도의 비용이다.

영화관 데이트는 정말 좋아하지만 매일 영화관을 가는 건 싫고, 데이트 비용은 영화 보고 밥먹는 정도가 적당하다고 생각하지만 매일 영화 보러 가는건 싫다는 건가.

나야 뭐 데이트 패턴은 얼마든지 독창적으로 바꿀 수 있는데, 어쨌거나 이 설문조사 결과는 모순적인 것 같다.

영화관 데이트 좋아하는 20%와 매일 똑같은 데이트를 하기 싫어하는 20%는 서로 다른 집단으로 추정된다.

데이트는 정답이 없구나. 그때 그때 달라요.

비선형 광학

이런저런 논란과 좌절 끝에, 최종적으로 비선형 광학 연구실에 들어가게 되었다.

그래 어떻게든 되겠지.

추가.

정확한 명칭은 “마이크로/서브마이크로 광학 연구실(Micro/sub-micro optics lab)”이다. 라고 교수님께 전해들었다.

계룡산 등반

백수일때 즐겨라. 라는 속담이 있을지는 모르겠지만. 백수라서 즐길 수 있는 계룡산을 다녀왔다.

사진은 생각날 때만 찍었기 때문에 많이 비어있다.

주차요금 4000원을 내고 주차장에 차를 넣었다. 아 비싸다.



계룡산을 갈 때 동학사로 올라가거나, 갑사로 올라가는 길이 있다. 나는 둘 다 가지 않고 곧바로 삼불봉으로 올라가는 길을 골랐다. 나중에 내려오고나서 알았지만, 이렇게 올라가면 공짜다. (안그러면 입장료 2000원 있음.)



사진은 넥서스S가 수고해 주었다. 화질이 아주 좋지는 않은 것 같지만, 찍은 사람의 손떨림이 큰 영향을 주었을테니 너무 욕할 수는 없겠다.



개중에 몇개는 디자이어로 찍은 것도 있다. 이건 삼불봉 아니면 관음봉인 것 같다. 어디서 찍었는지 기억이 나지 않지만, 구름 속에 파묻힌 운치있는 봉우리들을 볼 수 있다.



넥서스S의 기능 중 하나인 파노라마 기능(안드로이드에서 제공하긴 하지만)을 사용하여 찍은 봉우리들의 풍경이다.



비슷한 위치에서 찍은 사진이다.



가다가 보니까 도룡뇽이 보였는데, 나중에 내려올 때 보니까 이끼 도룡뇽이라고, 계룡산의 보호 동물 중 하나라고 한다. 물론 여기서 잘 안보이는데, 재빠르게 도망가는 바람에 어쩔수 없이 제대로 안 찍혔다.



파노라마 사진 두번째. 여전히 어디서 찍었는지 알 수가 없다. 삼불봉에서 남매탑으로 들렀다가 관음봉으로 가서 은선폭포를 보러 가는 길 위의 어딘가이다. 아마 아까 본게 삼불봉에서 남매탑 가는 길이고 이건 관음봉인 것 같기도 하다.





바위 틈에 피어 있던 꽃. 내가 밟지 않고 가더라도 언젠가 누군가에게 밟혀서 사라지겠지만, 그래도 다시 피어날 수 있겠지.

그 유명한 애기똥풀인가 싶어서 찾아봤는데, 애기똥풀은 꽃잎이 네장이고 이건 다섯장이어서 완전히 다른 꽃이라는 사실을 알 수 있었다. 결국 뭔지는 모르겠다.


사용자 삽입 이미지

IMAG0044.jpg

사용자 삽입 이미지

IMAG0045.jpg

사용자 삽입 이미지

IMAG0046.jpg

사용자 삽입 이미지

IMAG0047.jpg

사용자 삽입 이미지

IMG_20130710_115147.jpg

사용자 삽입 이미지

IMG_20130710_115153.jpg

사용자 삽입 이미지

IMG_20130710_115229.jpg

사용자 삽입 이미지

IMG_20130710_115236.jpg

사용자 삽입 이미지

IMG_20130710_115248.jpg

사용자 삽입 이미지

IMG_20130710_115320.jpg

사용자 삽입 이미지

IMG_20130710_115329.jpg

사용자 삽입 이미지

IMG_20130710_115341.jpg

그리고 올라가던 길에 발견한 또다른 예쁜 꽃. 이럴땐 식물 도감이라도 좀 외워두고 있으면 이름이라도 알아볼텐데, 물리학 전공이다보니 이런 것들은 알 수가 없다.







올라가던 길에 찍은 탐방로의 모습이다. 문제는, 이건 시작에 불과했다는 점이다. 여기까지 왔을 때 음료수로 준비했던 핫식스 두캔을 모두 마셔버렸기 때문에 매우 목이 말랐지만 어떻게 해볼 수가 없었다. 아아 계룡산 등반시에는 물을 1리터 이상 준비할지어다.



여기까지 왔을 때, 어떤 할아버지께서 올라갔다가 정상에 구름이 껴서 불안한 마음에 등반을 포기하고 그냥 내려간다는 이야기를 하셨었다. 결과적으로 비 한방울 내리지 않는 화창한 날씨였지만.



같은 장소에서 바라본 아래쪽 계곡. 관음봉을 지나면, 이 사진의 오른쪽 아래에서 왼쪽 위로 향하는 골짜기를 따라서 쭉 내려간다. 계곡이라는 곳은 물을 따라서 내려가면 바람이 적어서 힘든 편이고, 물 위를 가로지르는 다리를 건널 때는 물이 실어온 바람 때문에 에어컨은 갖다 버리라고 할 정도로 시원하고 상쾌한 바람이 불어온다. 결국 그 바람의 부름을 뿌리치고 계속 걸어내려왔기 때문에 결국은 더운 것이지만.



이것이 관음봉을 가기 위한 마지막 계단. 이게 진짜 올라가다가 힘들었는데, 특히 조심해야 하는 것이 계단과 계단 사이에 틈에 발이 낀 상태에서 한걸음 내딛으려고 발을 들어 올리다가 “으악!”하면서 발을 못 내밀고 쓰러진다는 것.



계단을 중간쯤 올라갔을 때, 여기서도 도룡뇽이 발견되었다.



잎사귀 사이로 도룡뇽의 꼬랑지만 보인다.



결국 도망가는 도룡뇽의 현장 사진을 포착했다. 사진에 찍히면 영혼이 빨려들어간다는 미신이라도 믿었던 것일까, 사진에도 잡히지 않기 위해서 후다닥 도망가는 녀석이었다.



관음봉의 정자에서 찍은 계룡산의 경치다. 어쨌거나 시원한 바람이 쏴 하고 불어왔지만, 물이 다 떨어져서 시원하면서 괴로운 애매한 상태였었다.



관음봉을 지나서 동학사로 가는 길에 바라본 은선폭포. 물이 마른 때에는 쏟아지는 모습을 볼 수 없지만, 최근에 비가 많이 왔기 때문에 시원하게 쏟아지는 모습을 볼 수 있었다.



은선폭포 전망대에서 본 다른 쪽 절벽인 것 같다. 어디였는지는 정확히 기억나지 않는다.



그리고 이것은 은선폭포에서 찍은 파노라마 사진이다. 파노라마 사진이 길게 한눈에 들어와서 멋지긴 한데, 그래도 직접 가서 보는 것이 더 멋있다.



여긴 어디더라…



은선폭포를 보고 내려오는 길의 다리 위에서 찍은 계곡 사진. 여기서 정말 상쾌하고 시원한 바람을 맞아볼 수 있다. 내려오다가 커플이 내려오는 부분을 지나쳤는데, 이 커플의 아가씨는 계룡산을 원피스에 슬리퍼를 신고 올라왔었다. 관음봉까지 중간에 쉴만한 부분이 없었는데, 중간까지 가서 쉬다가 내려왔든지 끝까지 다 올라갔든지, 어떻든 대단한 커플이다. 남자가 계단 내려가다가 미끄러져서 슬리퍼만도 못한 운동화의 접지력을 자랑해서 약간 기분이 좋았다.



이 싼티나는 코팅 입장권은 계룡산 자연사 박물관의 입장권이다. 자연보호와 비용절감을 위하여 재활용하기 위하여 이 입장권은 박물관에 입장할 때 제출해야 한다. 안보고 기념으로 그냥 갖고 나가도 상관 없지만, 성인 1명에 9000원이라는 입장료를 생각한다면, 9000원짜리 코팅 종이를 사느니 볼거 없어도 입장하는 쪽이 상식적인 인간의 선택일 것이다.



자연사 박물관 앞 정원에 서 있는 돌. 화석인데, 스트로마톨라이트였던 것 같다.



계룡산 자연사 박물관을 설립한 청운 이기석 박사님 흉상이다. 저 앞에 써 있는 한자는 “청운”이다. 실수로라도 “쌈장”으로 읽으면 혼날줄 알도록.



이것은 공룡 뼈다. 가면 볼 수 있는걸 사진으로 전부 옮겨 오는 만행을 저지르지 않기 때문에 일부만 찍었다. 이 뼈는 공룡의 다리뼈인데 공룡이 정말 크긴 크다는 사실을 알 수 있다.



내 얼굴 크기와 비교해 보면 얼마나 큰지 알 수 있을 것이다. 별로 안 커 보이나?

(주어가 없다.)



경골어류와 연골어류의 화석이다.



미국산이었다.



사실 앞에 있던 커다란 공룡뼈는 “계룡이”의 뼈인데, 그 실물 사이즈 모형이 설치되어 있었다. 참고로, 사진에서 왼쪽 위로 길게 뻗은 것은 꼬리가 아니라 목이고, 머리가 그 위로 한참 길게 뻗은 목 위에 얹혀져 있다. 그걸 찍으려면 너무 멀리서 찍어야만 했기 때문에 그냥 확 잘라먹었다.



진짜 신기한건 공룡이 아니라, 미국 캔자스에서 발견된 공룡이 왜 “계룡이”가 되었는가이다.



계룡이의 뼈 일부이다.



또다른 뼈 일부. 이런걸 보고 있으면 원시인들 나오는 영화에서 커다란 통뼈 들고 휘둘러대는 원시인들에 대한 설정이 과장이 아니라는 걸 느낄 수 있다.





계룡이 발톱.



대삼림 아닌가? “삼립”은 빵공장 이름이었던 것 같은데. 그 회사가 3억년이나 된 전통있는 회사도 아닌 것 같고.



단식투쟁중인 개구리와 그 먹이.





단식투쟁하는 개구리 때문에 삽질중인 직원. (알바일지도.)

개구리가 밥을 먹어야 내려가는데 이놈이 배가 불렀는지 줘도 먹지를 않아서 한참 난리치다가 결국 포기하고 먹든지 말든지 하고 그냥 사무실로 돌아갔다.



자연사 박물관이라 그런지 태양계와 은하계를 다루긴 다뤘다. 마치 지구과학에서 태양계와 은하계가 나오듯이. 그런데 왜 지구과학에 천문학과 천체물리가 포함되어 있는건지 모르겠다.



잊지 말자. 인간은 모두 호모다.



이것이 그 유명한 뉴턴의 사과나무다. 영국에서 뉴턴이 만유인력의 법칙을 생각할 때 앉아있었다던 바로 그 사과나무인데, 고사 직전에 있던 나무를 살려내고 그걸 다른 나무에 접붙이고 접붙이고 해서 미국에 갔다가 다시 한국에 들여온 뉴턴의 사과나무의 직계 자손.



유명한 나무 앞에서 인증샷 찰칵.



마지막으로 찍고 간 박물관 앞 정원의 모습이다.

계룡산은 갑사가 갑이라던데, 언제 한번 따로 들러봐야겠다.