글쓴이 보관물: snowall

snowall에 대하여

onecup, research department

파이썬에서 range 함수

어떤 언어든지간에 어떤 변수를 정해진 범위 내에서 한번씩 적용시켜가면서 반복 실행하는 구문은 필요하다. 파이썬에서는 for 구문으로 구현하고 정해진 범위를 리스트로 주도록 되어 있다.

예를 들어, C언어에서 for(i=0;i<10;i++)으로 주어진 반복문이라면 파이썬에서는 for i in range(0, 10) 으로 쓸 수 있다. 이때 주의해야 할 점은 range가 함수라는 부분이다. range(a, b, c)는 a부터 b까지 c칸씩 달리는 리스트를 되돌려 준다. c=1은 기본 사항이다.


[각주:

1

]





http://docs.python.org/release/1.5.1p1/tut/range.html

그러나, 나에게 필요한 것은 for(i=0.0;i<1.0;i+=0.1)과 같은 구문이었고 파이썬에서 for i in range(0.0, 1.0, 0.1)은 나에게 좌절을 안겨주었다. range는 int에서만 잘 작동하는 함수였기 때문이다. 그래서 일단은 다음과 같은 코드를 작성해서 썼다.

x = 0.0

for i in range(0, 10):

x=x+0.1

function(x)

급한대로 이렇게 쓰긴 했는데, 이건 for구문이지만 while같다. 이럴거면 그냥 while을 쓰는게 낫지 싶은 느낌? 그래서 다른 방법들을 찾아보았다. 기본적으로는, 파이썬의 for문은 주어진 리스트 안의 변수들을 하나씩 순서대로 적용한다. 그럼 내가 원하는 대로 0.1씩 증가하는 리스트를 만들어서 주면 된다. 예를 들어

for i in [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]:

function(x)

이렇게 쓰는 것은 의도한 대로 작동하는 구문이다. 물론 이건 10개니까 손으로 썼지만 100만개쯤 되면 손으로 쓰는건 컴퓨터 편하자고 사람이 고생하는 비극을 초래하므로 좀 더 멋진 방법을 찾아야 한다.


http://stackoverflow.com/questions/477486/python-decimal-range-step-value



http://code.activestate.com/recipes/66472/


몇가지 방법을 찾았는데, numpy에서 제공하는 arange 함수를 쓰는 방법이 있고, frange함수를 새로 정의하는 방법이 있다. 어떻든, 위에 쓴 0.0부터 1.0까지의 리스트를 제공하기만 하면 되고, 여러 사람들이 이 문제를 해결하고 있다.

그러다 보니, 문득 range함수를 오버로딩하면 안되는건가? 하는 생각이 들어서 검색해 보았다. 물론 이런 생각을 나만 하는건 아니었다.


http://ironboundsoftware.com/blog/2007/05/29/a-shortfall-of-python-no-function-overloading/



http://www.artima.com/weblogs/viewpost.jsp?thread=155514


귀도 반 로썸도 그런 생각을 했고, 2006년에 대충 구현을 해봤다고 하니 파이썬3에서는 잘 되지 않을까 싶었다. 그러나 그렇게 되지 않은 것 같다.





http://openlook.org:625/blog/2008/12/04/python3/



http://kldp.org/node/123275#comment-555572






아무튼, 일단 range 대신에 새로운 다른 함수로 정의해서 사용해야 한다는 점을 알게 되었다.


  1. 좀 더 정확히 쓰자면, for i in range(0, 10)이랑 같은 C언어 구문은 for(i=0;i<=10;i++)이다.
    [본문으로]

평균과 분산이 바뀔 때

프로그램을 만들다 보니 별걸 다 하게 되는 상황이다. (납땜하다가 사포질하다가 왜 프로그래밍이냐면, 웃지요 -_-; 내 일이 원래 그렇다. 뭐든지 다 하는…)

실험 결과를 분석하는 프로그램인데, 분석은 별게 아니라 입력값의 평균과 표준편차(분산의 제곱근)를 계산하는 프로그램이다. 문제는 입력값을 적절히 구분해야 한다는 점이다. 즉, 지금 읽어온 입력값이 마지막 값이 아닐 수도 있다는 것이 문제점이다. 원래는 다음과 같이 프로그램을 설계해야 한다.

항목이 여러개 있다. A샘플, B샘플 …

각 샘플마다 실험 측정값이 있다. 1번, 2번, …

당연히 각 샘플마다 평균과 분산을 구해야 한다. 문제는 샘플이 순서대로 정렬되어 있지 않고 뒤섞여 있다는 점이다.

1. 샘플을 순서대로 정렬한다.

2. DB에 넣어서 Group by로 묶은 후 평균과 분산을 구한다.

알고리즘은 이게 가장 단순한데 실제 구현은 삽질이다. 왜냐하면 난 VB.net에서 개발을 하려고 하고 있고, 여기서 DB를 쓰려면 MSSQL을 쓰든가 전에 여기서 언급했던 SQLite의 VB 포트를 쓰든가 해야 하는데, 어쨌거나 SQL까지 다루는 건 골치아픈 일이다. 따라서 저 정렬 부분을 직접 구현해야 하나 하는 고민이 들다가 귀찮으니까 그러지 말자고 생각했다.

1. 데이터 테이블을 싹 읽어서 샘플이 어떤 종류가 있는지 목록을 만든다.

2. 목록에서 순서대로 읽어다가 평균과 분산을 구한다. 즉, 데이터 테이블을 읽으면서 A샘플 값만 골라서 평균과 분산을 구하고, 데이터 테이블을 또 읽으면서 B샘플 값만 골라서 구하고 … 끝날때까지 반복.

그나마 조금 단순하지만 데이터 테이블을 너무 여러번 읽는다. 더군다나, 항목 구분이 샘플로만 이뤄지는게 아니라 실험 날짜와 샘플의 위치에 따라서도 달라진다. 즉, 같은 샘플이라도 다른 날짜라면 따로 분석해야 하고, 다른 위치라고 해도 따로 분석해야 한다. 이러면 항목 구분 목록을 여러개 만든 후 각각의 목록을 이용해서 모든 경우의 수를 다 따지는 루틴을 넣어야 하는데 이건 다시 삽질이다.

그래서

1. 데이터 테이블에서 한줄을 읽어온다.

2. 기존에 없던 항목 구분이면? 새로 항목 구분을 만들어 주고 데이터 분석을 갱신한다

2. 기존에 있던 항목 구분이면? 해당 항목 구분에 데이터 분석을 갱신한다

3. 끝까지 간다.

여기에 데이터 분석을 갱신하는 루틴이 추가되는데 이게 조금 수학적이다. 그래서 이 글은 수학에 구분되어 있다.

지금까지 N개의 자료를 이용해서 평균과 분산을 계산했다고 하자. 이걸 $m$과 $\sigma^2$라고 하자. 그런데 여기에 N+1번째 자료인 $x_{N+1}$가 새로 들어왔다. 어쩌지?

새로운 평균 $m’$은 다음과 같이 구할 수 있다. (왜 그런가는 암산으로 해보자.)

$m’ = \frac{mN+x_{N+1}}{N+1}$

그리고 새로운 분산 $\sigma ‘ ^2$은 다음과 같이 구할 수 있다. 왜 그런가는 직접 계산해 보자.

$\sigma ‘ ^2= \frac{N(\sigma ^2 + m^2) + x_{N+1}^2}{N+1} – m’^2$

어쨌든 위와 같은 간단한 계산으로 자료가 추가될 때마다 평균과 분산을 갱신할 수 있다. 물론 이게 위에서 여러번 읽어오는 알고리즘보다 더 계산양이 적을지 어떨지는 모르겠다. 난 단지 이런 방식으로 프로그램을 만들고 싶었을 뿐이다.

————-

최근에 이 알고리즘을 다시 사용해야 해서 생각해보니, 그냥 단순하게 계산해도 된다.

N개의 자료의 평균과 분산을 알고 싶으면, x(i)의 합과 x(i)의 제곱의 합을 일단 다 계산한다.

그리고 자료를 출력하라고 요청하는 시점에 평균과 분산을 한번만 계산하면 된다.

처음에 생각한 공식은 점화식으로 주어진 공식이었고 좀 더 흥미로운 계산이지만, 컴퓨터한테 일 시키려면 새로 생각한 방법이 좀 더 나을 것 같다. (물론, 처음의 공식도 쓸모가 있긴 하다.)

matplotlib

삽질하던 CCD화면의 처리 문제를 matplotlib으로 한번에 처리해버렸다. 16비트 Grayscale 자료를 알아서 Pseudocolor로 바꿔주다니, 똑똑한 녀석이다. 물론 20초 걸리던 루틴도 1.5초만에 처리하는 멋진 서비스를 해 주었다.


http://matplotlib.sourceforge.net/

Matlab을 쓰던 사람들이 만들었다고 한다. 그래프 그리는데 필요한 루틴은 거의 다 들어가 있는듯 싶다. 물론, 나보고 그래프 그리라고 하면 gnuplot으로 그릴 것 같지만. Matlab쓰던 사람들한테는 매우 유용한 라이브러리인듯 싶다. (난 Matlab을 만져본적이 전혀 없어서 어차피 배워야 하는 입장이지만.)

파이어폭스 8.0

Nightly 버전이 8.0으로 올라갔다. 물론 알파 버전이다. 5.0이 정식으로 공개되면서 6.0이 베타 버전, 7.0이 오로라 버전으로 승격되었다. 그런데 4.0부터 8.0까지 인터페이스는 다 같다. 크롬의 엄청나게 빠른 업데이트를 따라가는 건 좋은데, 이런 수준이라면 Nightly는 크게 의미 없지 싶다. 뭐, 어쨌든 개발자들 맘대로인 것이고 나는 그저 알파버전이 좋아서 사용하고 있는 것 뿐이니…

절대로 일반 사용을 권장하지는 않는다. 단지 나는 사용할 뿐이다. 쓰다가 치명적인 오류가 발생하여 매우 중요한 자료를 날려먹더라도 그러려니 하고 넘어가려는 각오를 한 사람에게만 사용할 것을 권한다. (물론 정식 공개버전도 모질라 재단이 책임지거나 하지는 않지만.)

자기 얼굴에 침뱉기

자기 얼굴에 침뱉기는 스스로를 못나 보이고 욕보이게 하는 말이나 행동을 모르거나 알거나 아무튼 하고 있는 것을 말한다.

하지만 실제로 자기 얼굴에 침을 뱉기는 꽤 어렵다. 누워서 침뱉기 외에는 방법이 없고, 누워서 침뱉기는 별도의 속담으로 존재하므로 누워서 침뱉기는 빼고 자기 얼굴에 침을 뱉어 봐야한다.

어쩌면 꽤 하기 어려운 일을 뜻하는 말 아니었을까.

기말고사 결과

영미아동문학: D

영연방의 사회와 문화: C-

테스트영어연습: A-

영어교수법: A-

영어학 개론: C+

영시읽기의 기초: A

내 성적표는 왜 늘 극단적인가…-_-;

파이썬에서의 = 연산자

프로그램을 만들다 보면 “=”기호를 많이 사용하게 된다. VB에서 =는 2가지 작용을 하는데, 한가지는 양 변에 있는 두 존재를 비교하여 같은지 다른지 판단한 후 참/거짓을 알려준다. 다른 하나는 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다.

C언어에서 =는 1가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다. C언어에서 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.

파이썬에서도 =기호는 두가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어주거나, 오른쪽에 있는 존재를 왼쪽에 있는 존재와 같은 놈으로 만들어 준다. 파이썬에서도 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.

예를들어

a = 1

b = a

a = 11

print(a)

print(b)

이런 프로그램을 실행시키면 파이썬의 출력은

11

1

이 된다. 즉, 이 경우에는 변수 a의 값이 변수 b로 복사되고, a와 b는 아무 관련 없는 모르는 사이가 되었다. a를 바꾸더라도 b는 변하지 않는다.

그런데

a = [10,20]

b = a

a[1]=11

print(a)

print(b)

위와 같은 프로그램을 실행시키면 출력은

[10, 11]

[10, 11]

이 된다. 이 경우에는, a와 b가 완전히 같은 존재가 되어 a를 바꾸면 b도 바뀌게 된다. 만약 a를 b로 복사해서 넣고 싶다면 copy 모듈을 불러와야 한다.

import copy

a = [10,20]

b = copy.copy(a)

a[1]=11

print(a)

print(b)

이렇게 하면 b는 a의 내용을 복사해서 받은 존재가 되어 a가 변해도 b는 변하지 않는다. (반대도 마찬가지) 따라서 이 프로그램의 출력은 다음과 같다.

[10, 11]

[10, 20]

아무튼. 직관적인 내용이므로 알면 편한데 문서 대충 읽고 개발하는 내게는 충격적이었다. 이게 왜 바뀌지? 싶은거…

물론 이런식으로 존재 자체에 대한 =연산자는 VB나 C/C++에는 없다. 별다른 생각 없이 직관적으로 =연산자를 사용해서 존재에 존재를 연관시키는 것이 장점이긴 한데, 존재의 종류에 따라 작동이 달라지는 것은 일관적이지는 않은 행동인것 같다. (물론, +연산자도 문자열 변수와 수치형 변수에 대해 다르게 작동하며 이것도 일관적인 행동은 아니다. 다만 직관적인 행동이다.)

얼마나 대충 살면 적당할까?


http://blog.aladin.co.kr/sanga/4740583

“영원히 살 것 처럼 배우고 내일 죽을것 처럼 살아라” 라는 말이 있다. 누가 했는지 그 말 참 멋있다. 그러나 그렇게 살기는 좀 힘들어 보인다.

아무리 생각해도 내가 내일 죽을 것 같진 않기 때문이다. (영원히 살 것 같지도 않다.) 극단적으로 치열한 삶의 한 단면이랄까.

어느정도로 적당히 살면 적당할까? 어차피 죽긴 죽을텐데 말이다.

내 생각에는, 100년 정도 살 것 처럼 배우고, 한 5년후에 죽을 것 처럼 살면 적당하지 않을까 싶다.

이런 생각의 반대쪽 극단에는 영원히 살 것처럼 그냥 살고, 내일 죽을 것 처럼 배우는 것이 있겠다. 잘 생각해보면 이것도 그렇게 사는 것이 가능하기만 하다면, 뭔가 그럴듯하게 느껴진다.

어떻게 살 것인가. 정하는 것도 본인의 몫이고 지키는 것도 본인의 몫이며 바꾸는 것도 본인의 몫이다.

문제는 해결

해결을 하긴 했다.

self.wxImg = wx.EmptyImage(pilImg.size[0], pilImg.size[1])

for i in range(1024):

for j in range(1024):

x = int(f.getData()[0][j][i]/256)

self.wxImg.SetRGB(i, j, x, x, x)

이제 문제는, 너무 느리다는거…-_-;

파이썬의 단점

아… 막막함이여.

이제 파이썬 프로그램을 다른 컴퓨터에 설치해서 실행시켜야 하는데 문제가 있다. 사용하는 라이브러리들을 전부 복사해서 넣어줘야 한다는 것이다.

이게 왜 문제냐면, 그 컴퓨터는 인터넷에 연결이 되지 않기 때문이다.

dll파일 몇개로 해결될 수준이 아닌거임.

일단은, 내 컴퓨터에 설치된 파이썬의 디렉토리를 통째로 복사해서 넣으면 될 것 같긴 하다. 다행히 200MB밖에 안되네.

컴파일되지 않으니 항상 인터프리터가 있어야 하고, 다른 라이브러리를 썼으면 그것도 같이 줘야 한다. 프로그램 자체는 200줄밖에 안되는데 딸려가는 놈이 더 많은 괴이한 경우. (VB.net도 그렇지만, 그건 닷넷 프레임워크 하나만 설치하면 되는데, 파이썬은 파이썬 인터프리터와 사용된 라이브러리 전부를 다 설치해야 한다.)