Michael Williams
December 3, 2002
http://www.pentangle.net/python/handbook/
handbook.pdf
Python in education
Michael Williams
29th June, 2005
http://www.pentangle.net/python/
http://www.awaretek.com/tutorials.html#begin
-------------------------
한 동안 python을 사용하지 않았다. 한 때는 정말 열심히 사용했었는데 말이다. 다시 보니 새롭고 금방 또 기억이 나는군. 하여튼, 쉽게 배울 수 있었던 언어로 자리매김하고 있다. 또, 까먹을지도 모르니, 여기다 걸어놓고 보도록하자. 유사한 자료에 대한 프린트는 이전에 많이 했으니깐.
http://incredible.egloos.com/1590436
-------------------------------------------------------------------------------------
서론
Python이란 무엇인가?
FORTRAN 90, C, C++, Java처럼 이것도 하나의 컴퓨터 언어이다. 1990년 Guido van Rossum (http://www.python.org/~guido/)에 의해 개발된 인터프리터 언어이다. 사전적으로 Python을 알아 보면 아래와 같다. 컴퓨터 산업과 관련된 단어들이 나타나고 있는 특징이 있습니다. 상대적으로, 상당히 늦게 태어난(?) 언어이다.
발음 기호 [páin | -n]
1 【동물】 비단뱀, 이무기
2 [P~] 【그리스신화】 거대한 뱀((Apollo신이 Delphi에서 죽인))
3 신탁(oracle); 신탁을 받는 신관(神官); 예언자무당등에붙는 귀신[심령]
컴퓨터 언어의 특징을 말하자면 각 언어들의 장점을 부각시킴으로써 언어 선택에 관한 다양한 이야기가 나올 수 있지만 FORTRAN 90 (객체지향; 대상중심, 간결한 수치 처리 기능 지원이 과학기술용으로는 많이 사용되고 있는 것이 엄연한 사실이다. 사용해보면 이유를 충분히 느낄 수 있습니다. 그런데 전산 물리학 관련 일들을 하다 보면 약간은 허전한 느낌이 든다. 예를 들어서 약간은 비슷하지만 조금은 다른 여러 가지 일들은 해야 할 경우 새로 FORTRAN 90을 만들어서 하자니 부담되고 그리고 shell 스크립트를 사용하자니 기능이 만족스럽지 못하고 조금은 답답할 때가 있다.
특정한 일은 한번의 계산으로 끝나지 않고 체계적인 파일관리와 입력자료 관리가 필요하다. 또한 코드개발 기간동안에 미쳐 구현해 두지 못한 새로운 기능의 추가가 필요한 경우 이를 위해서 많은 시간을 소모 (현 코드상에서의 추가할 항목의 위치 선택, 코딩, 디버깅할 필요를 못느낄 경우가 상당히 많다. 대부분의 연구에서는 특정한 후-데이터 처리가 필요할 뿐만 아니라 체계적인 계산들의 나열과 관련된 정리 노트가 필요하다.
왜, Python인가?
전산 물리학의 생산성을 높이기 위해서 입니다. 하나의 보조 수단으로서 사용하자는 말씀입니다. 잘 아시다시피 전산 물리학에 있어서 통상의 주화력은 FORTRAN 90이나 C (C++)입니다. 여기에 대한 이견은 없습니다. 다른 대안을 가지신 분께는 드릴 말씀이 진정 없습니다.
본 웹 페이지에 모셔진 Python을 이용한 전산 물리학 (computational physics)은 기존의 전산 물리학을 Python으로 하지는 이야기는 아니다. 지금 잘 돌아가는 그리고 검증이 끝난 여러 코드들은 더욱더 잘 사용하자는 것이다. 바로 이 새로운 언어 Python을 이용하여 전산 물리학을 더욱 즐기고 업계의 생산성을 제고하자는 것이다. 주지하는 데로, 우리의 진정한 object/goal/target 은 전산이 아니라 물리학입니다.
새로운 언어를 배울 때마다 나오는 자기 언어 자랑. 정말 지겹지만, 안 적을 수 없지만, 별로 신경을 쓰고 싶지는 않다. 다만 응용코드 개발 기간을 단축할 수 있다는 말에는 귀가 솔깃하다.
셀(shell)보다 많은 구조와 기능제공
초고수준의 언어 (very-high-level language)이다. (기계보다는 사람에게 더욱더 가까운 것이 수준이 높다고 정의함.)
응용 프로그램 개발기간을 단축할 수 있다. (눈에 확 들어오는 말!)
표준모듈이 많이 있다.
대상중심 (객체지향; 대상중심; object-oriented) 언어이다.
배우기 쉽다.
확장성이 높다.
다른 언어와의 접착력이 강하다.
무료 언어이면서 여러 가지 종류의 시스템들에서 잘 작동한다. (M$에서도!)
객체지향(대상중심)이란 ?: 특정한 응용을 위한 오브젝트 (객체;대상)를 기술하는 높은 수준의 데이터 형, 데이터 형 처리 방법들을 정의 함으로써 전체 프로그램을 단독으로 작성하는 것(다른 부 프로그램들과의 연관성을 최소화하면서 독립적으로 ...). 프로그램 전체에서 다른 부분 사이가 독립되어 있기 때문에 이해하기 쉽고 확장과 변경이 용이한 코드를 얻을 수 있는 장점이 있다.
거두절미하고 바로 이것이 어떻게 나의 전산 물리학에 도움이 되는지를 예를 들어 봅시다. sad.x라는 프로그램이 있는데 이것을 여러 번 (2000 번) 실행해야 한다고 합시다. 물론, 서로 다른 입력 파일 2000개의 만들어야 한다. sad.x는 sad.i라는 입력 파일 하나로 약 8분 정도 실행되는 것이다. 아래와 같이 multi_sad.py (실행가능 파일 속성 유지라는 파일을 하나 만든다. (차차 익숙해지면, 대부분 복사해서 하기 때문에 일도 아니다.)
컴퓨터 상에서 가장 쉬운 것이 복사라는 것을 기억하면 된다.(기본 가정: sad.x란 프로그램의 소스에 익숙하지 않아서 위에서 할 일을 직접 FORTRAN 90으로 바꿀 필요를 못 느낀다. 즉, 비용이 너무 크다고 판단될 경우. 또한 여러 번의 계산 결과를 체계적으로 저장할 필요를 느낄 경우. 일련의 linux명령어들을 순차적으로 사용하고 싶을 경우. 오랜 만에 떠오른 간단한 아이디어를 빨리 체크하고 싶을 경우. 파이썬을 이용하는 부분이 전체 계산수행 시간보다 훨씬 적을 경우.) 이 웹 페이지에 나온 기본적인 것들만 잘 알면 전산 물리학을 공부하는데 있어서 누구나 상당한 수준의 파이썬 프로그래머가 될 수 있을 것입니다.
-----------[-------시작
#!/usr/bin/env python
from Numeric import * # 몇 가지 선언들 (필요한 모듈들 불러오기); Numeric python은 따로 설치해야 한다. Python 설치 후
from string import atof,atoi,split
from posix import getpid,rename,remove,mkdir,rmdir,system
from shutil import copyfile
import os,sys,time,random
__version__="1.0.0"
def prtjobid():
# written by In-Ho Lee, KRISS, Jan. 12, 2002. 첫 번째 사용자 함수 정의
f=open('JOB_ID_PRINTED','w')
f.write('%15d \n' % os.getpid()) # 실행될 python 프로그램 process id를 적는 함수
st=time.asctime() # 날짜 알아내기
f.write('%23s \n' % st)
f.close()
return
def gen_sad_input():
natom=60 # 두 번째 사용자 함수 정의
ktmax=2000
delrr=1.e-1
xs_local= 4. -random.random()*2.
xf_local= 8. +random.random()*2.
ys_local=-1. -random.random()*2.
yf_local= 1. +random.random()*2.
zs_local=-3. -random.random()*2.
zf_local= 3. +random.random()*2.
iseed1= int( (random.random())*31327.0e0+0. )
iseed2 = int( (random.random())*30080.0e0+0. )
g=open('sad.i','w') # 파일 sad.i 만들기 시작
g.write('%16d %16.8f %s \n' % ( natom,delrr, 'natom,delrr' ))
g.write('%16d %16d %16d %s \n' % ( iseed1,iseed2,ktmax, 'iseed1,iseed2,ktmax'))
g.write('%16.8f %16.8f %s \n' % ( xs_local,xf_local, 'xs_local,xf_local'))
g.write('%16.8f %16.8f %s \n'% ( ys_local,yf_local, 'ys_local,yf_local'))
g.write('%16.8f %16.8f %s \n'% ( zs_local,zf_local, 'zs_local,zf_local'))
g.close()
return
중략--중략 (여러 개의 독립적인 함수들을 순차적으로 배치시킨다.)
if __name__ == "__main__":
# comment 사용자 메인 함수 정의 시작
print time.asctime()
prtjobid()
iseed=2003
print iseed, ' iseed in python'
random.seed(iseed) # 랜덤 함수 씨드 지정하기
for i in range(10):
print random.random() # 랜덤 함수 10 번 출력하기
for i in range(2000): # 2000번 반복하기
gen_sad_input() # 파일 sad.i 만들기
system('sad.x >TMPFILE') # 코드 sad.x 실행하기
copyfile('dim.dat', ascnum('dimer.',i))
copyfile('mid.xyz', ascnum_xyz('midpt.',i)) # 파일 복사하기
system('rm dim.dat') # 파일 지우기
system('rm TMPFILE')
-----------]-------끝
위의 sad.py (위에서 보인 내용을 저장하는 파일명이라고 가정)라는 실행파일을 실행하면 (위에서 보인 프로그램의 첫 번째 줄 때문에 이것이 가능해짐), 2000번의 일들이 순차적으로 실행된다. 아래 부분을 보면은 랜덤 넘버 10개를 프린트하고 2000번씩 사용자 저의 함수 gen_sad_input() 실행, sad.x 실행, 화일 복사, 지우기를 한다. 그 다음 모든 작업을 컴퓨터가 할 수 있도록 한다.
2000번의 input화일은 함수 gen_sad_input()이라는 함수가 직접 disk에 적는다. system()이라는 함수는 당연히 linux prompt 상에서 일을 한다는 것을 의미합니다. 파일을 지우고 (rm), 응용 프로그램을 실행 (sad.x>TMPFILE) 하고 여러분이 생각하시는 것들 모두 가능합니다.
sad.x를 실행하면 mid.dat와 mid.xyz라는 결과물들이 나온다고 가정합시다. 이들을 어떻게 잘 저장할 것인가 ? 이것도 간단하지만 중요한 기술입니다. mid.dat라는 것들은 파일 이름 끝에다 네 자리로 이루어진 번호를 주려고 합니다. 그리고 xyz라는 파일 확장자가 필요한 파일들은 네 자리 번호 뒤에다 xyz라는 확장자를 넣어주려고 합니다. dimer.0000, dimer.0001, dimer.0002, dimer.0004............2000개. midpt.0000.xyz, midpt.0001.xyz, midpt.0002.xyz,............2000천개. 이러한 일들을 위하여 비슷하지만 조금 다른 두 개의 함수들을 아래와 같이 작성했습니다. 컴퓨터의 강력한 기능 복사를 이용해서 처리했습니다. 좀 더 간결하고 현란하게 할 수 있습니다. 파이썬에서는 들여쓰기가 시행된 상태에서 C언어에서처럼 한 줄에;를 사용하여 여러 가지 표현을 쓸 수도 있습니다. 즉, 아래의 3줄 표현은 한 줄로 줄여질 수도 있습니다.
a=1.
b=2.
c=3.
a=1. ; b=2. ; c=3.
au2ang=0.529177e0 ; au2ev=2.0*13.6058e0 ; ev2kelvin=1.e0/8.617342e-5 au2kelvin=au2ev*ev2kelvin ; au2sec=2.4189e-17 ; au2cmi=2.1947e5
au2kcalpmol=627.50956e0
if 문도 비슷한 것을 찾을 수 있습니다. 아래의 두 표현은 같은 것입니다.
if a > 0 :
a=0
if a> 0 : a=0
위의 예에서 보여지지 않고 생략된 함수 2개를 아래에 나타내었습니다.
def ascnum(ichar,number):
# written by In-Ho Lee, KRISS, Jan. 12, 2002.
i=int(float(number)/1000.)
j=int((number-i*1000.)/100.)
k=int((number-j*100.-i*1000.)/10.)
l=int(number-k*10.-j*100.-i*1000.)
ic='0' ; jc='0' ; kc='0' ; lc='0'
if i == 1 : ic='1'
if i == 2 : ic='2'
if i == 3 : ic='3'
if i == 4 : ic='4'
if i == 5 : ic='5'
if i == 6 : ic='6'
if i == 7 : ic='7'
if i == 8 : ic='8'
if i == 9 : ic='9'
if j == 1 : jc='1'
if j == 2 : jc='2'
if j == 3 : jc='3'
if j == 4 : jc='4'
if j == 5 : jc='5'
if j == 6 : jc='6'
if j == 7 : jc='7'
if j == 8 : jc='8'
if j == 9 : jc='9'
if k == 1 : kc='1'
if k == 2 : kc='2'
if k == 3 : kc='3'
if k == 4 : kc='4'
if k == 5 : kc='5'
if k == 6 : kc='6'
if k == 7 : kc='7'
if k == 8 : kc='8'
if k == 9 : kc='9'
if l == 1 : lc='1'
if l == 2 : lc='2'
if l == 3 : lc='3'
if l == 4 : lc='4'
if l == 5 : lc='5'
if l == 6 : lc='6'
if l == 7 : lc='7'
if l == 8 : lc='8'
if l == 9 : lc='9'
fname=ichar+ic+jc+kc+lc # abc.0001 형태의 파일 이름 만들기
return fname
def ascnum_xyz(ichar,number):
# written by In-Ho Lee, KRISS, Jan. 12, 2002.
fname=ascnum(ichar,number)+'.xyz' # abc.0001.xyz 형태의 파일 이름 만들기
return fname
>>> a=1
>>> b=str(a).zfill(4)
>>> print b
0001
>>> c=str(a).zfill(5)
>>> print c
00001
>>> c=str(c)
>>> print c
00001
>>>
위의 예에서 프로그램 sad.x를 2000번 실행한다고 했습니다. 그리고 이를 수행하면 sad.py이라는 linux 상의 job은 process ID를 가지고 있습니다. 이것이 일하는 디렉토리에 프린트 되도록 했습니다. 이것 필요합니다. 며칠씩 job이 돌아가는 데 이것의 process ID를 모르면 아주 난감해 질 수도 있습니다. 이 일을 위해서 또 하나의 함수가 작성되었다는 것을 확인할 수 있습니다. 실제로 python job을 여러 개 사용할 경우 ps -u ihlee로 확인하면 모두 python이 수행된다고 가르쳐 주기 때문에 혼돈을 불러일으킨다. 보통 독립적인 일들은 각각 자기 디렉토리에서 계산을 수행하기 때문에 그 디렉토리에 job id를 적어두면 아주 편리합니다.
앞에서는 파이썬이 포트란 프로그램을 부르는 형식으로 예를 들었지만, 상황은 완전히 바뀔 수 있다. 이번에는 포트란 프로그램의 일부로서 파이썬이 사용되는 경우이다.물론 시스템으로 잠시 나가 있는 경우이다.
포트란에서 `시스템 콜하기`; 파이썬과의 결합?
포트란 프로그램에서 CALL SYSTEM('application.py')처럼 파이썬 스크립트를 직접 불러서 사용할 수도 있다.
이러한 경우 call system이전에 필요한 자료들을 파일로 정리해둔 다음 시스템으로 잠시 나간 다음 시스템에서 준비된 파이썬 스크립트가 자료를 사용할 수 있게 설계할 수 있다. 물론 외부의 프로그램들 (스크립트에서 준비된 일련의 명령들) 등으로 자료처리 또는 계산을 수행한 다음 다시 포트란 프로그램으로 되돌아 오는 방법이 있다. 물론 돌아오기 전에 포트란 프로그램에서 자료를 읽어들일 수 있도록 파일들을 미리 만들어주면 좋겠다, 물론 파이썬 스크립트가 관리를 해야 할 것이다. 마지막으로 포트란 프로그램에서는 준비된 자료들을 읽어들여서 계속하여 포트란으로 계산을 수행할 수 있다.
자료 적어두기: 파일열기/적기 ==포트란 명령으로 수행
call system('python_driver.py') ==포트란에서 빠져 나와서 파이썬 스크립트 실행하기.
자료 읽어들이기: 파일 열기/읽기 ==포트란 명령으로 수행
유닉스 프롬프트 상에서 아래와 같이 abc.exe라는 실행화일을 실행시키면
nohup abc.exe >output_file_name &
로그아웃해도 프로그램 실행이 죽지 않는다.
기본 사항 정리--===============
*몇 가지 필요한 기본적인 모듈들 불러다 사용할 수 있도록 프로그램 앞 부분에 특정한 방법으로 몇 가지 선언들을 해둔다. (예를 들어, system(), random(), copyfile(),.................수치 계산..., 다른 사람들이 만들어 둔 훌륭한 모듈들 사용할 수 있습니다.) 예를 들면, Numeric python은 파이썬 설치한 다음 따로 설치해 두어야 한다.그 전에 ATLAS(Automatically Tuned Linear Algebra Software)가 설치되어 있어야 한다.
*자신이 필요한 함수들을 정의한다. (포트란과 달리 소문자 대문자를 구별한다.)
*메인 부분에서는 자신이 원하는 일들을 한다.
python프로그램에서 꼭 알아야 할 기본적인 몇 가지 문법들
*들여쓰기 (indentation)는 python언어의 일부이다. 멋이 아니다!
*#을 이용하여 comment를 시작할 수 있습니다. "해쉬입니다.
*다음 줄로 이월할 때 확장 표시는 \로 한다.) "빽슬러쉬" 입니다.
*변수형 (정수형,배열,실수형, 문자형을 선언하지 않고 사용한다.
*컴파일하지 않는다. #!/usr/bin/env python를 첫 줄에 넣어서 바로 실행가능한 코드로도 만든다.
*함수 선언은 "def" 와 ":"를 사용함. 선언된 함수 다음 줄 뒤부터는 들여쓰기 필요함. if와 for뒤에도 다음 명령어들과 관련하여 다음 줄로 넘어갈 경우 들여쓰기가 반드시 필요함.
*for i in range(100): 와 같이 사용할 경우에서 i는 0부터 시작하여 0,1,2,3,4, 과 같이 ...99까지 달리면서 for loop의 안쪽의 내용을 100번 반복한다는 뜻입니다. range를 range(1,101)처럼 사용하면 1부터 100까지 i가 달립니다. 사실 range(10)는 리스트 (배열과는 차이가 있음)를 의미합니다. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*FORTRAN 90하던 사람 입장에서 화일 읽고 쓰기가 약간 불편하다. 예제를 잘 활용하면 이 또한 익숙해지리라 믿습니다.
*함수는 return되는 것이 없을 수도 있습니다. 즉, 파일을 생성한다든지..... 반환되는 것들은 return뒤에다 줄줄이 기록하면 됩니다. 예를 들어 return a,b,c,d처럼 말입니다. 여기서 a는 실수형, b는 1차원 배열, c는 2차원 배열, 그리고 d는 문자열일 수도 있습니다. 함수를 부르는 곳에서 제대로 받기만 하면 됩니다. 함수 이름을 abcd()라고 가정하면 함수를 부르는 곳에서 aa,bb,cc,dd=abcd()라고 하면 됩니다.
*파이썬 언어 안에서는 한국사회에서와 달리 과학기술이 천대받지 않습니다. Numeric Python (Numpy)이라는 강력한 모듈이 있습니다. 인스톨했다면, 불러다 사용할 수 있습니다. 과학기술에 필요한 배열은 array1=zeros(100,Float)와 같이 쉽게 0.0e0으로 초기화하면서 만들 수 있습니다. 이 경우 Numeric-20.3를 사용했습니다. 길이가 100 (인덱스는 0,1,2,....99)인 일차원 배열이 0.0e0으로 초기화되었습니다. (python에서는 0.0과 0.0e0는 같은 실수형입니다. FORTRAN식으로 이야기하면 실수형 real*8에 해당합니다. 하지만 0.d0처럼 사용하지 않습니다.) 기본적으로 double precision 수준으로 정확한 계산을 합니다. 2차원 배열 생성 및 0.0으로 초기화는 array2d=zeros((100,100),Float)와 같이 합니다. 원주율은 pi라는 곳에 저장되어 있습니다. 이렇게 수학적인 것들을 자유롭게 사용하려면 Numeric이라는 모듈을 불어다 놓은 상태여야합니다. " from Numeric import *"를 이용하면 됩니다. 굳이 설명을 붙이자면 "Numeric이라는 모듈에서 사용가능한 것들 모두 (*)를 사용할 수 있도록 수입하다"입니다. 마찬가지로 "from LinearAlgebra import solve_linear_equations"를 동원하여 아래에 표시된 것처럼 선형대수학 문제를 solution_vector=solve_linear_equations(a_matrix,b_vector)아주 간결하게 해결하실 수 있습니다. 이 계산들은 python이 제법 빨리 수행합니다. 실질적으로는 잘 알려진(그리고 잘 검정된) 수학 package들을 이용하기 때문입니다. 이들은 다른 언어 (예를 들어 C나 FORTRAN)로 만들어질 수 있습니다. Numeric python이 설치하기 전에 시스템에 ATLAS(Automatically Tuned Linear Algebra Software; fastlinear algebra routines)가 설치되어 있는지 확인할 필요가 있다. 없다면 설치해야 한다.ATLAS는 각종 소프트웨어들 MAPLE(v7 and higher), MATLAB(v6.0 and higher), Mathematica(forthcoming), MAPLE(v7 and higher), Octave등에서 사용되거나 사용될 것이다.
행렬 (matrix) 대각화 (diagonalization)를 한번 해봅시다. H는 2차원 배열이면서 정방 행렬 (n by n)입니다.
H=T+V # Hamiltonian setup
val,vec=eigenvectors(H) # matrix diagonalization (해당eigenvalue/vector를 찾아라!)
val,vec=ev_sort(val,vec) # solution sorting에 필요한 함수
def ev_sort(eigval,eigvec):
newval=zeros(len(eigval),Float)
newvec= zeros(eigvec.shape,Float)
index=argsort(eigval)
for i in index:
newval[i]=eigval[index[i]]
newvec[i,:]=eigvec[index[i],:] # FORTRAN90에서처럼
return newval,newvec
FORTRAN 사용할 때 사용하는 것들에 대응하는 것:
.and. ======= and
.or. ======= or
.gt. (>) ======= >
.ge. (>=) ======= >=
.le. (<=) ======= <=
.eq. (==) ======== ==
.ne. (/=) ======== !=
a < b < c
a
is less than b
, which is less than c
2의 제곱은 2
**
2 처럼 사용하면 됩니다.
나머지는 %를 이용합니다.
not은 논리적으로 부정을 표지합니다. not logical_variable처럼 사용.
sqrt()
exp()
log()
log10()
sin()
cos()
tan()
asin()
acos()
atan()
floor()
fabs()
pi
and append apply assert break class clock complex conjugate continue def del dir dot eigenvectors elif else except exec finally for from global identity if import in is lambda matrixmultiply max mkdir min maximum minimum not or pass path print raise random reduce return remove rename rmdir shape sleep split string system sum time try wait while Data Float Int Numeric array open write close float int input range type zeros 위에 나타낸 단어들은 "넓은 의미로 예약된 이름"들로 일반 사용자들은 변수 이름으로 피하는 것이 좋습니다.
모듈을 부를 때
from 모듈 import 변수나 함수처럼 사용하면 정확히 필요한 것들만 불러올 수도 있습니다.from Numeric import sin, cos, tan, sqrt
내장함수 int(),round(),floor(),ceil()은 각각, 소수부분 없애기, 반올림하여 정수화하기, 작거나 같은 수 중에서 가장 큰 정수로 만들기, 크거나 같은 수 중 가장 작은 정수를 취한다. floor와 ceil은 math 모듈에 있는 것이다. 정수를 실수형으로 바꿀 때는 float()을 사용한다.
내장된 유용한 함수dir(module_name)을 사용하면 편리하다.모듈의 이름이 넘겨지면, 그 모듈에서 유효한 이름들의 목록을 - 때로는 함수 - 되돌려 준다.
>>> dir(Numeric)
['ArrayType', 'Complex', 'Complex0', 'Complex16', 'Complex32', 'Complex64', 'Complex8', 'DumpArray', 'Float', 'Float0', 'Float16', 'Float32', 'Float64', 'Float8', 'Int', 'Int0', 'Int16', 'Int32', 'Int8', 'LittleEndian', 'LoadArray', 'NewAxis', 'Pickler', 'PrecisionError', 'PyObject', 'StringIO', 'Unpickler', 'UnsignedInt8', '__builtins__', '__doc__', '__file__', '__name__', '__version__', '_numpy', 'absolute', 'add', 'allclose', 'alltrue', 'arange', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', 'argmax', 'argmin', 'argsort', 'around', 'array', 'array2string', 'array_constructor', 'array_repr', 'array_str', 'arrayrange', 'arraytype', 'asarray', 'bitwise_and', 'bitwise_or', 'bitwise_xor', 'ceil', 'choose', 'clip', 'compress', 'concatenate', 'conjugate', 'convolve', 'copy', 'copy_reg', 'cos', 'cosh', 'cross_correlate', 'cumproduct', 'cumsum', 'diagonal', 'divide', 'divide_safe', 'dot', 'dump', 'dumps', 'e', 'equal', 'exp', 'fabs', 'flo
or', 'fmod', 'fromfunction', 'fromstring', 'greater', 'greater_equal', 'hypot', 'identity', 'indices', 'innerproduct', 'invert', 'left_shift', 'less', 'less_equal', 'load', 'loads', 'log', 'log10', 'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'math', 'matrixmultiply', 'maximum', 'minimum', 'multiarray', 'multiply', 'negative', 'nonzero', 'not_equal', 'ones', 'outerproduct', 'pi', 'pickle', 'pickle_array', 'power', 'product', 'put', 'putmask', 'ravel', 'remainder', 'repeat', 'reshape', 'resize', 'right_shift', 'sarray', 'searchsorted', 'shape', 'sign', 'sin', 'sinh', 'sometrue', 'sort', 'sqrt', 'string', 'subtract', 'sum', 'swapaxes', 'take', 'tan', 'tanh', 'trace', 'transpose', 'typecodes', 'types', 'where', 'zeros']
눈으로 확인하면 즉시, 그 뜻을 알아차릴 수 있는 간결한 수학적 기법들을 아래와 같이 나타내어 보았습니다.
FORTRAN 90에서 처럼 vector와 matrix 처리가 간결해졌습니다.
>>> range(1,10,2)
[1, 3, 5, 7, 9]
>>> range(10,1,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2]
>>> range(10,0,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
>>> istart=1; ifinish=9 ; idirection=1
>>> for i in range(istart,ifinish+1,idirection):
... print i
...
1
2
3
4
5
6
7
8
9
>>> istart=9; ifinish=-1; idirection=-1
>>> for i in range(istart,ifinish+1,idirection):
... print i
...
9
8
7
6
5
4
3
2
1
>>>
from Numeric import *
>>> a=array((1,2))
>>> b=array((3,4))
>>> dot(a,b)
11
>>> a=array(((1,2),(3,4)))
>>> b=a
>>> matrixmultiply(a,b) # 매우 간결합니다!
array([[ 7, 10],
[15, 22]])
>>> sin(complex(1,3.))
(8.4716454543001483+5.4126809231781934j)
>>>
>>> for i in [1,2,3,4]:
... print i
...
1
2
3
4
>>> z=complex(1.,2.)
>>> z.conjugate()
(1-2j)
>>> z.real
1.0
>>> z.imag
2.0
>>> arange(0.,1.,0.20)
array([ 0. , 0.2, 0.4, 0.6, 0.8])
>>> arange(0.0,1.2,0.20)
array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ])
>>>
>>> q=arange(0.0,1.0,0.2)
>>> sin(q)
array([ 0. , 0.19866933, 0.38941834, 0.56464247, 0.71735609])
>>>
>>> max(0.,2.,3.)
3.0
>>> maximum(0.,2.)
2.0
>>> min(0.,-1,-3.)
-3.0
>>> minimum(-3.,3.)
-3.0
>>> a=[1,2,3.,4]
>>> sum(a)
10.0
>>> b=[4,3,7,9]
>>> sort(b)
array([3, 4, 7, 9]) # 리스트의 경우와 유사하지만 다름.
>>> amat=zeros((2,2),Float)
>>> amat[0][0]=1
>>> amat[1][1]=1
>>> trace(amat)
2.0
>>> from LinearAlgebra import *
>>> determinant(amat)
1.0
>>> eigenvalues(amat)
array([ 1., 1.])
>>> eigenvectors(amat)
(array([ 1., 1.]), array([[ 1., 0.],
[ 0., 1.]]))
>>> b=inverse(amat)
>>> print b
[[ 1. 0.]
[ 0. 1.]]
>>>
>>> b=zeros(2,Float)
>>> solve_linear_equations(amat,b)
array([ 0., 0.])
>>>
>>> transpose(amat)
array([[ 1., 0.],
[ 0., 1.]])
>>>
>>> argmax(b)
0
>>> argmin(b)
0
랜덤 permutation을 구하고 싶을 경우
#!/usr/bin/env python
from RandomArray import permutation
__version__="1.0.0"
for i in range(9):
p = permutation(3)
print 'p=',p
출력
p= [2 0 1]
p= [1 0 2]
p= [0 2 1]
p= [0 1 2]
p= [1 2 0]
p= [1 0 2]
p= [0 2 1]
p= [2 1 0]
p= [0 2 1]
중요 정보를 파이썬 상에서 직접 확인할 수 있다. import Numeric을 선언한 다음 help(Numeric)을 치면. 많은 정보를 보여 준다. 역시 익숙하지 않다면 import LinearAlgebra 한 다음 help(LinearAlgebra) 로 모듈의 기능을 확인할 수 있다. 이들을 잘 정리해 둔 곳을 알고 있어도 된다.
http://pfdubois.com/numpy/html2/numpy.html
http://starship.python.net/~hinsen/
http://python.kwangwoon.ac.kr:8080/python/Modules/numpy/
파이썬에서는 www.netlib.org에서 찾아볼 수 있는 C나 FORTRAN으로 만들어진 그리고 검정이 끝난 루틴들을 이용하여 계산을 한다. 이들을 python으로 다시 작성하는 것은 굉장히 좋지 않은 아이디어 일뿐만 아니라 디버깅하는데 너무나 오랜 시간을 잡아먹을 것이다. 따라서 그들은 C나 FORTRAN으로 돌아 가야한다. 다만 python 쪽으로 데이터들이 자유롭게 넘나들 수 있어야 한다. 이렇게 함으로써 인터프리터 언어의 한계인 느린 계산으로부터 생기는 한계를 극복할 수 있다. 결국은 상당히 효율적인 (C나 FORTRAN 속도도 유지하면서 very-high-level 언어의 특징은 여전히 살아있다.) 프로그램이 완성되는 것이다. 이러한 아이디어는 굉장한 것을 의미할 수 있다. 즉, 초보자 (물리학자, 물론 항상 이렇게 될 필요는 없지만)가 프로그램을 해도 숙련자 (전산 전문가)가 한 것과 거의 같은 성능을 얻어낼 수 있다. 느리지만 뱀처럼 유연한 몸 동작 (유연한 사고)으로 생산성을 높일 수 있습니다. 프랑스의 세계적인 축구 스타 지네딘 지단 선수를 보면, 그의 몸 동작은 결코 남들보다 빠르다고 할 수 없습니다, 반면 그 선수는 유연한 몸 동작과 확실한 볼키핑, 그리고 빠른 동료 선수들에게 찔러주는 환상적이고 정확한 패스워크와 골을 이끌어 내기 위한 탁월한 찬스-메이킹 능력을 가지고 있습니다, 우리가 물리학 관련 프로그래밍에서 원하는 것 바로 이것입니다.
파일관리 생각하니 이것을 이야기하지 않을 수 없습니다.
if os.path.exists('CHG'):
존재할 경우 할일들
os.path.exists라는 명령어를 사용하면 지금 디렉토리에 파일 이름 CHG라는 파일이 존재하는지 안하는지를 체크할 수 있습니다. 즉, os.path.exists('CHG') 값이 0 (거짓을 의미함)이면 'CHG'라는 파일이 존재하지 않음을 의미합니다. system()명령어를 사용할 때, 예를 들어 system('qsub work.0003/pbs_script_file')에서처럼 변수형태의 pbs파일 명을 사용하고자 할 때는 다음과 같이 한다. j=3 ; f_name=ascnum('work.',j)+'/pbs_script_file' ; system('qsub '+f_name+'')
디스크에 있는 파일들의 목록을 취할 때는 glob 모듈의 glob함수를 사용하면 아주 편리하다. 실제 사용될 수 있는 형태를 보면 아래와 같다.
import glob,time
import os.path
file_list=glob.glob('*')
for f_name in file_list:
if os.path.isfile(f_name):
print f_name,' is a regular file'
print os.path.getsize(f_name)
print os.path.getatime(f_name)
print time.ctime(os.path.getatime(f_name))
elif os.path.isdir(f_name):
print f_name,' is a directory'
elif os.path.islink(f_name):
print f_name,' is a symbolic link'
glob.glob('*.gif')
glob.glob('*.dat') 처럼 사용될 수 있습니다.
os.listdir('.') 도 현재 디렉토리의 파일 목록을 얻을 때 사용할 수 있습니다. 현재 프로세스의 작업 디렉토리 이름:os.getcwd()
여기서 설명 못드린 파이썬의 많은 기능들 또는 함수들은 www.google.com에서 찾으시면 됩니다. 다른 언어에서 사용하시던 기능 대부분이 파이썬에 있습니다. 보통 "키워드 + python"하시면 될 것입니다("python -snake -monty" 진짜 뱀과 티비 프로그램은 제외). 또는 www.python.org/doc/current/lib를 직접 방문하세요. os.getcwd() os.getuid() os.getuname() os.path.getsize(file_name) os.path.split(file_name)
프로그램을 하려고 하면 제어구조라고 하여 if,for,while등이 필요합니다.
if 절 구조 익히기:
if x < 0:
print 'negative' ...
elif x == 0:
print 'zero'
elif x == 1:
print 'one'
else:
print 'more'
import sys
print "Start"j = 5j=11if j > 10: print j,"printing"else: sys.exit() def renexp(tmp):
# written by In-Ho Lee, KRISS, March 6 (2003)
iftmp <= -745.0 :
tenexp=exp(-745.0)
eliftmp >=709.0 :
tenexp=exp(709.0)
else :
tenexp=exp(tmp)
return tenexp
for 절 구조 익히기:
for n in range(2,10):
for x in range(2,n):
if n%x == 0:
print n, 'equals', x, '*', n/x
break
else:
print n,' is a prime number'
for i in range(1,13): print "%d x 12 = %d" % (i, i*12)
while 절 구조 익히기:
x = 0 while x < 10: print x x = x + 1 j = 1while j <= 12: print "%d x 12 = %d" % (j, j*12) j = j + 1
루프가 break 문으로 종료하지 않았다면 else 문이 실행된다. 마찬가지로 while 문에서도 조건식이 거짓이 되어 종료하면 뒤따르는 else 문이 실행되게 할 수 있다. break는 가장 안쪽의 for 또는 while 루프를 빠져 나올 때 사용합니다. 계산 중간에 프로그램 수행을 끝내고 싶으면 sys.exit()를 사용하면 된다. 도스 창에서는 <Ctrl-Z>
전역변수는 함수 안에서도 얼마든지 사용할 수 있습니다.
윈도우에 설치하기는 아주 쉽습니다. Python-2.2.2.exe를 다운받아서 (www.python.org)그냥 클릭 계속하면 됩니다.
Python-2.2설치 와 Numeric-20.? 추가하기 (linux에 설치하기)
슈퍼-유저 입장에서 다운로드 받은 관련화일들 (Python-2.2.tar.gz 와 Numeric-20.?.tar.gz)을 /usr/local/PYTHON_INSTALL에 두고 아래와 같이 한다. (http://www.python.org, www.python.or.kr참조)
./configure
make
make install
Python-2.2 설치 후 Numeric-20.?를 설치한다.
python setup.py install
설치 후 일반 유저 입장에서 아래의 명령어를 입력해 보세요.
python
Python 2.2 (#1, Nov 27 2002, 15:26:20)
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
처럼 나오면 성공입니다.1+2라고 입력하고 enter를 치십시오. 3이 나오면 성공적으로 더하기를 하신 것입니다. from Numeric import *라고 입력하고 enter를 치십시오. 다음 원주율을 알아보실 수 있습니다. pi를 입력하여3.1415926535897931 이 나오면 성공입니다. 이 상태에서 python 모드 탈출하기 위해서 quit라고 하니까 control D를 치라고 합니다. 이 경우에서 알 수 있듯이 파이썬은 훌륭한 계산기도 됩니다. 곱하기와 나누기는 각각 *와 /로 할 수 있습니다. 복소수도 아래에서와 같이 간단히 처리됩니다. 보시면 즉시에 아실 정도로 간단합니다. 또한 a=complex(1.,2.)이라면 이 복소수의 실수, 허수 부분은 각각 a.real, a.imag로 접근할 수 있습니다.
>>> complex(0.,1.)*complex(0.,1.)
(-1+0j) # 복소수 표현입니다.
Numeric를 포함하면서 보다 혁신적인 과학 기술 지원 module은 SciPy입니다.
http://www.scipy.org/ Scientific tools for Python
SciPy is a set of open source scientific/numeric tools for Python. It currently supports special functions, integration, ordinary differential equation (ODE) solvers, gradient optimization, genetic algorithms, parallel programming tools, an expression -> C++ compiler for fast execution, and others. SciPy also has plotting functions for quickly visualizing data.
http://sourceforge.net/projects/pympi/ pyMPI
MPI를 이용한 parallel python 프로그래밍
스크립트(Script) :스크립트는 때로, 명령어들이 파일 내에 미리 저장되어 있다가 파일이름을 마치 하나의 명령어처럼 입력했을 때, 운영체계의 명령어 인터프리터에 의해 파일 내의 내용이 차례로 수행되는 명령어 목록을 의미하는 것으로 사용되는 경우도 있다 (MS-DOS의 배치파일) 멀티미디어 개발 프로그램들에서 말하는 "스크립트는 상영될 멀티미디어 파일의 순서를 지칭하기 위해 입력된 명령어 순서를 의미한다. 게임에서는 매크로 연출, 매크로 씬으로 사용된다.
class
#!/usr/bin/env python
class player:
def kick(self):
return 'kick the ball'
def heading(self):
return 'heading the ball'
ronaldo=player()
print ronaldo.kick()
print ronaldo.heading()
print gerrard.kick()
print gerrard.heading()
#!/usr/bin/env python
class player:
strength= 0
speed= 0
stamina= 0
agility= 0
def kick(self):
return 'kick the ball'
def heading(self):
return 'heading the ball'
def take_a_rest(self):
self.stamina= self.stamina+10
self.agility= self.agility+2
self.speed= self.speed+5
ronaldo=player()
print ronaldo.kick()
print ronaldo.heading()
print 'Ronaldo'
ronaldo.strength= ronaldo.strength+10
ronaldo.speed= ronaldo.speed+10
ronaldo.stamina= ronaldo.stamina+10
ronaldo.agility= ronaldo.agility+15
print ronaldo.strength
print ronaldo.speed
print ronaldo.stamina
print ronaldo.agility
ronaldo.take_a_rest()
print 'Ronaldo'
print ronaldo.strength
print ronaldo.speed
print ronaldo.stamina
print ronaldo.agility
park=player()
print park.kick()
print park.heading()
print park.strength
print park.speed
print park.stamina
print park.agility
print 'Park takes a rest'
park.take_a_rest()
print 'Park'
print park.strength
print park.speed
print park.stamina
print park.agility
#!/usr/bin/env python
class person:
eyes=2
nose=1
mouth=1
ears=2
arms=2
legs=2
def eat(self):
print 'eat'
def sleep(self):
print 'sleep'
def talk(self):
print 'talk'
class player(person):
def football(self):
print 'play football'
lee=person()
print lee.mouth
lee.talk()
seol=player()
print seol.mouth
seol.talk()
seol.football()
#!/usr/bin/env python
class Shape:
area=0.
varia=9.
def __add__(self,other):
return self.area + other.area
a.area=10.
b=Shape()
b.area=30.
print a+b
#!/usr/bin/env python
class Shape:
area=0.
varia=9.
def __add__(self,other):
return self.area + other.area
def __cmp__(self,other):
if self.area < other.area :
return -1
elif self.area == other.area :
return 0
else :
return 1
a.area=10.
b=Shape()
b.area=30.
print a+b
if a < b : print 'b > a'
if a == b : print 'b = a