레이블이 PYTHON인 게시물을 표시합니다. 모든 게시물 표시
레이블이 PYTHON인 게시물을 표시합니다. 모든 게시물 표시

2015년 10월 13일 화요일

Wiki and Jupyter

Wiki and Jupyter

위키

  • 여러가지 위키를 상당기간 검토하거나 사용해 봤다.
  • 미디어위키. 일단 가장 표준적인 시스템이라는 점에서 보증할 수 있고, 기능이 풍부하며, 확장성 역시 좋다. 그러나 미디어위키 문법은 아주 지저분하고, APM 시스템 기반이라 포터블 하지는 못하다.
  • 깃허브 골룸. DB 의존적이지 않은 대신 Git을 통해 버전관리가 이루어진다. 어차피 DB가 필요한 만큼의 대규모 위키를 운영할 것도 아니므로 이것은 전혀 문제되지 않는다. 또 깃허브 향 마크다운 문법 역시 매력적이다. 설치 방법도 크게 까다롭지는 않다. 그럼에도 불구하고 뭔가 부족하다는 느낌이 든다. 하지만 기본 개념 자체는 아주 좋다.
  • 징고(Jingo). 골룸 비스무레한 것을 node.js와 자바스크립트로 만들어 놓은 것이다. 역시 상당히 좋지만 아직 완성도가 너무 낮다. 겨우 구색만 갖춘 느낌. 그러나 역시 node.js 기반의 소프트웨어는 항상 나를 기쁘게 한다.
  • 티들리위키. 단순무식한게 아주 좋고, 달랑 하나의 파일만으로 포터블성이 극대화된게 아주 천재적이다. 다만 기본 UI가 위키라기 보다는 블로그에 가깝다. 아쉬운 점은, 티들리위키 문법을 사용하고 싶지는 않기 때문에 마크다운 플러그인을 넣어 봤는데 지나치게 허접하다는 점이다.
  • 기타 서비스형 위키로, Torchpad를 사용하고 있는데... 골룸처럼 깃허브향 마크다운 문법 기반이라 너무 좋고, 필요한 확장이 모두 기본적으로 셋팅되어 있을 뿐만 아니라, 그림 삽입 같은 것은 그냥 마우스 드래그만 해 주면 자동적으로 업로드 및 태깅이 되기 때문에 너무 편하다. 단점은 한글 입력시 끝글자가 사라져 버리는 버그가 있고, 깃허브 연동 기능이 아직 제공되지 않는다. 그리고 커뮤니티가 거의 죽어있는 것을 봐서는 곧 망할 것 같은 느낌이 들어 불안하다. 서비스형 위키는 아무래도 내가 통제할 수 없다는 점 때문에 심리적인 불안감을 떨치기 어렵다.

Jupyter

  • 그런데, iPython notebook 즉 Jupyter를 보면, 기본적으로 훌륭하게 마크다운 문법이 지원되는 점을 볼 수 있다.
  • 게다가 한큐에 서버 셋팅까지 되고...
  • 각종 언어 커널만 심어주면 인라인으로 코딩 및 결과까지 보여준다.
  • 그리고 이 모든 걸 전부 다 .ipynb 파일 하나에 싹 다 저장할 수 있다.
  • 게다가 온라인, 오프라인 어느쪽으로든 이건 .html로 렌더링을 쉽게 해 줄 수 있다.
  • 심지어 깃허브에서는 직접 렌더링해서 볼 수 있다.
  • 아무튼 킹왕짱이다.

아이디어

  • 아이디어는 간단하다.
  • Jupyter를 뜯어고쳐서(?) 골룸 위키 처럼 만들어보면 어떨까?
  • 즉 위키 문서 파일 역할을 .ipynb 파일이 하도록 시스템을 구성해 주고, Jupyter 프론트엔드 쪽에 문서 검색기능 같은 추가 요소를 더 주는 것이다.
  • 그리고 화면 좌측에 트리 같은걸 자동 생성해서 브라우징 할 수 있도록 해 주면 더 좋겠다.
  • 그리고 열람 모드에서는 Jekill 같은 느낌으로 그냥 열람만 할 수 있도록 하고, 편집 모드에서는 Jupyter 네이티브로 편집 가능하도록 해 준다.
  • 그러면 코딩과 문서의 환상적인 조합이 이루어질 뿐만 아니라, 퍼블리싱까지 되는 셈이다.

2015년 7월 5일 일요일

Jongrae - 공학자를 위한 Python 사용법 (링크 스크랩)


구글링을 하다가 우연히 검색된 좋은 자료라서 스크랩 해 둡니다.
텀블러에 올라간 자료라서 열람하기에 조금 불편하긴 하지만...

Python의 사용방법들 중에서 공학용으로 사용하기에 좋은 소위 Scientific Python 툴체인을 사용하는 과정을 첫걸음부터 아주 친절하게 설명해 주신 내용입니다.
한국어로 된 자료들 중에서 이정도로 입문자를 위해 친절하게 된 자료는 아직 거의 별로 없는 것 같아서 소중한 자료인 듯 합니다.



글을 쓰신 김종래 박사가 어떤 분인지 잘 몰랐는데, 링크를 따라서 보니깐 영국 글래스고 대학교 교수를 역임하고 현재는 영국 리즈(Leeds) 대학교의 Robust Lab 교수로 계신 분인 듯 합니다. ( https://sites.google.com/site/robustlabjongrae/ )







Python 같은 것들은 범용 언어이기 때문에, 찾을 수 있는 대부분의 초보자용 강좌 도큐먼트들은 대부분 일반적인 어플리케이션 개발자 또는 웹 개발자를 위한 강좌 위주라서, 기계공학도에게는 잘 맞지 않아서 아쉬웠는데, 기계공학-제어공학 하는 교수님이 이런 자료를 작성해 주니까 역시 도움이 되는 것 같습니다.


Jongrae - 공학자를 위한 Python 사용법

http://myjr52.tumblr.com/post/106505817926/python-1
http://myjr52.tumblr.com/post/106558290981/python-2
http://myjr52.tumblr.com/post/106624206806/python-3
http://myjr52.tumblr.com/post/106841302374/python-4
http://myjr52.tumblr.com/post/106911428671/python-5
http://myjr52.tumblr.com/post/107019242556/python-6
http://myjr52.tumblr.com/post/107308116126/python-7
http://myjr52.tumblr.com/post/107353965866/python-8
http://myjr52.tumblr.com/post/107535551561/python-9
http://myjr52.tumblr.com/post/107596017061/python-10
http://myjr52.tumblr.com/post/107610104726/python-11
http://myjr52.tumblr.com/post/107976618856/python-12
http://myjr52.tumblr.com/post/108253720176/python-13
http://myjr52.tumblr.com/post/108360870881/python-14
http://myjr52.tumblr.com/post/108838760626/python-15
http://myjr52.tumblr.com/post/109586202081/python-16
http://myjr52.tumblr.com/post/109764306211/python-17
http://myjr52.tumblr.com/post/110632662971/python-18
http://myjr52.tumblr.com/post/111561347426/python-19
http://myjr52.tumblr.com/post/114505245981/python-20
http://myjr52.tumblr.com/post/114584621986/python-21
http://myjr52.tumblr.com/post/115031578791/python-22
http://myjr52.tumblr.com/post/116023290841/python-23






학부생 시절에 (멍청하게 눈만 꿈벅대고 있던 단순무식한) 기계공학과 학생들에게, 좌절하지 않고 Matlab이나 초창기 Web용 CGI 프로그램 짜는 걸 차근차근 첫걸음부터 인내심을 가지고 가르쳐주시던 저의 지도교수님의 모습이 생각나네요...



2015년 5월 17일 일요일

Julia Code : COMBI REDUCER with Planetary & Harmonic Drive v05


MIT에서 만든 Julia Language에 대해서 관심을 계속 가지고 있었는데, 이제 v0.3 이상으로 올라가면서 꽤 쓸만해 진 모양이다.  특히 아마존 웹 서비스에다가 이걸 올려서 클라우드 서비스까지 해 주기 때문에 어렵게 PC에 개발환경 구축하느라 진땀 빼지 않아도 되어서 더 좋다.

나에게 필요한 것은, 컴퓨터공학적인 최적화라던가 대규모 데이타를 효과적으로 다루는 것이 아니고, 높은 수준의 공학용 계산기 내지는 간단한 스크립트 엔진이다.

여러가지 많이 검토해 봤는데 Julia가 역시 최신기술의 집약체이다 보니 모든 조건에 다 부합하는 것 같다.

아래는 어떤 문제를 풀기 위해 Julia를 실무적으로 사용해 본 예이다.
원래는 Matlab m-code로 작성해서 FreeMat, Octave 따위로 돌려보던 것인데, Julia로 테스트해 보기 위해 컨버젼도 해 보고 완전히 새로 작성도 해 보았다.

m-code를 Julia code로 자동 컨버젼해주는 패키지도 Julia 패키지 라이브러리에 있으나, 일단 직접 수동으로 컨버젼 해 보았더니 함수 이름 바꿔준다던가 정도의 문법 수정으로 20분만에 끝났다.

그리고 Julia에 좀 더 부합하도록 몇가지 기능을 추가하고 수식도 새로 적용하고 해서 새로 만들었다.


---------------------------------------------------------------------------------------------------------------


본 Julia Code는 기존의 버전을 Julia 문법에 좀 더 부합하게 고치고, Interactive 기능을 추가한 버전이다.

최외곽 서큘러 스플라인 잇수(Number of Teeth)와 그 안쪽으로 들어가면서 조립되는 각 기어의 잇수의 차이를 기준으로 사양이 자동으로 잡히도록 하였고, Sun Gear의 반지름이 음수로 나오면 색상이 붉은 색으로 변하면서 경고 문구가 표시되도록 하였다.

기타 파라미터들은 관계를 조정하여 기하학적인 모순 상황이 발생하지 않도록 하였다.

타원 변형된 Flex Spline의 원주길이는 다음 공식을 기본으로 하였다.


* Annotations

$a$ : 긴 축의 지름 (Known)

$x$ : 짧은 축의 지름 (Unknown)

$\varepsilon$ : 이심률 (Known)

$L$ : 타원의 원주길이 (Known)


* Notations

$\varepsilon = \sqrt{ 1 - \frac{x^2}{a^2} }$

$L = 2aE(\varepsilon) = \pi a \left[  1 - \left( \frac{1}{2} \right)^2 \varepsilon^2 -  \left( \frac{1 \cdot 3}{2 \cdot 4} \right)^2 \frac{\varepsilon^2}{3} - \left( \frac{1 \cdot 3 \cdot 5}{2 \cdot 4 \cdot 6} \right)^2 \frac{\varepsilon^2}{5} - ... \right]$


* Remarks

$E(\varepsilon)$은 제2종 타원정적분 연산기호이다.  타원정적분은 엄밀하게 풀이하기가 어렵기 때문에, 이를 풀어쓴 우변의 무한급수 식을 이용하기로 한다.  급수의 항이 늘어날 수록 해(Solution)의 개수가 늘어나기 때문에 적합한 해를 판별하는 판단이 더 필요하게 되므로, 간소하게 하기 위해 다음과 같이 첫 번째 항만 살린 근사식을 만들었다.

$L = \pi a \left[  1 - \left( \frac{1}{2} \right)^2 \varepsilon^2 \right]$

해를 신속하게 구하기 위해 SageMath를 이용하였다.
(SageMath 대신 WolframAlpha를 이용해도 되나, 해가 복소수로 나오는 등 형태가 다를 수도 있다.)


a,L = var('a,L')
eq = L == pi*a* (  1-((1/2)^2)*(( sqrt(1-(x^2)/(a^2)) )^2)   )
eq
print solve(eq,x)


SageMath를 이용하여 얻어진 해는 다음과 같다.


L == 1/4*pi*a*(x^2/a^2 + 3)
[
x == -sqrt(-3*a^2 + 4*L*a/pi),
x == sqrt(-3*a^2 + 4*L*a/pi)
]



2개의 해가 얻어졌는데, 이 중에서 양수에 해당하는 두 번째 것을 취한다.  이 식을 Julia Code에 집어넣고 사용한다.


* Julia Coding

PyPlot 패키지는 Python 라이브러리 중에서, Matlab과 거의 비슷하게 Plot을 해 주는 MatPlotLib 기능을 Julia에서 사용할 수 있도록 해 주는 라이브러리이다.  따라서 이것은 내부적으로는 Python MatPlotLib가 그대로 동작하며, Julia Code에서 좀 더 사용하기 쉽도록 Matlab 문법과 거의 유사하게 간소화되어 있다.  기계공학도에게 Julia가 Python보다 접근하기 쉬운 점은, 굳이 객체지향 방법으로 코딩하지 않아도 된다는 점이다.  Matlab을 다루듯이 편하게 쓰면 된다.

Interact 패키지는 매우 간단하게 기본적인 GUI를 만들 수 있도록 해 준다.  여기 포함된 @manipulate 매크로를 이용하여, 자유롭게 조절하고 싶은 파라미터들을 설정해 주기만 하면 된다.  내부적으로는 무한루프를 돌리는 간단한 형태다.



#######################################################
# COMBI REDUCER with Planetary & Harmonic Drive
# V05
# 2015.05.18
# Dymaxion.kim
#######################################################
 
using PyPlot
using Interact
 
# Basic Parameter
alpha=[0:0.02:2*pi]
max_n_cs = 300
max_dn_fs = 20
max_dn_ig = 20
max_dn_sg = max_n_cs - max_dn_fs - max_dn_ig
# Making New Figure
f=figure(figsize=(8,8))
# Interact Macro
@manipulate for m = 0.1:0.1:2, # Module of The Gear
    n_cs = 50:1:max_n_cs, # Number of Teeth for Circular Spline
    dn_fs = 1:1:max_dn_fs, # Different Number of Teeth for Flex Spline
    dn_ig = 1:1:max_dn_ig, # Different Number of Teeth for Internal Gear
    dn_sg = 1:1:max_dn_sg # Different Number of Teeth for Sun Gear
    
    withfig(f) do
        grid("on")
        axis("auto")
        title("COMBI REDUCER v05")
        
        # Draw Circular Spline
        r_cs = m*n_cs/2
        plot( r_cs*sin(alpha), r_cs*cos(alpha), linewidth=2, color="Magenta" )
        annotate(["n_cs",int(n_cs)],xy=(0,r_cs),ha="center",va="bottom", color="magenta")
        
        # Draw Flex Spline in Idle Status
        r_fs = m*(n_cs-dn_fs)/2
        plot( r_fs*sin(alpha), r_fs*cos(alpha), linestyle="--", color="cyan" )

        # Draw Internal Gear in Idle Status
        r_ig = m*(n_cs-dn_fs-dn_ig)/2
        plot( r_ig*sin(alpha), r_ig*cos(alpha), linestyle="--", color="cyan" )
        
        # Draw Sun Gear
        r_sg = m*(n_cs-dn_fs-dn_ig-dn_sg)/2
        n_sg = 2*r_sg/m
        if r_sg > 0
            plot( r_sg*sin(alpha), r_sg*cos(alpha), linewidth=2, color="blue" )
            annotate(["n_sg",int(n_sg)],xy=(0,0),ha="center",va="center", color="blue")
        else
            plot( r_sg*sin(alpha), r_sg*cos(alpha), linewidth=4, linestyle="--", color="red" )
            annotate(["n_sg is in minus",int(n_sg)],xy=(0,0),ha="center",va="center", color="red")
        end
        
        # Draw Planet Gears
        t_fs = r_fs-r_ig # Thickness of Flex Spline's Plastic
        r_pg = (r_cs-t_fs-r_sg)/2
        plot( r_pg*sin(alpha), r_pg*cos(alpha)+(r_sg+r_pg), linewidth=2, color="magenta" )
        plot( r_pg*sin(alpha), r_pg*cos(alpha)-(r_sg+r_pg), linewidth=2, color="magenta" )
        n_pg = 2*r_pg/m
        annotate(["n_pg",int(n_pg)],xy=(0,r_sg+r_pg),ha="center",va="center", color="magenta")
        annotate(["Thickness",t_fs],xy=(0,r_sg+2*r_pg),ha="center",va="top", color="blue")
        
        # Draw Flex Spline in assembled
        L_fs = 2*pi*r_fs
        Dl_fs = 2*r_cs
        Ds_fs = sqrt(-3*Dl_fs^2 + 4*L_fs*Dl_fs/pi)
        plot( (Ds_fs/2)*sin(alpha), (Dl_fs/2)*cos(alpha), linewidth=2, color="blue" )
        n_fs = 2*r_fs/m
        annotate(["n_fs",int(n_fs)],xy=(-0.9*r_fs,0),ha="left",va="bottom", color="blue")

        # Draw Internal Gear in assembled
        L_ig = 2*pi*r_ig
        Dl_ig = Dl_fs - 2*t_fs
        #Ds_ig = sqrt(-3*Dl_ig^2 + 4*L_ig*Dl_ig/pi)
        Ds_ig = Ds_fs - 2*t_fs
        plot( (Ds_ig/2)*sin(alpha), (Dl_ig/2)*cos(alpha), linewidth=2, color="blue" )
        n_ig = 2*r_ig/m
        annotate(["n_ig",int(n_ig)],xy=(-0.9*r_ig,0),ha="left",va="top",color="blue")
        
        # Reduction Ratio
        RRp = (n_sg+n_ig)/n_sg
        RRh = n_fs/(n_fs-n_cs)
        RRt = RRp * RRh
        annotate(["Total Reduction Ratio",RRt],xy=(0,-r_cs),ha="center",va="top", color="black")

    end
end




아래 그림은 http://juliabox.org에서 구동한 결과이다.

검증결과 동일한 조건의 파라미터를 입력했을 때 기존 버전과 동일한 결과를 얻을 수 있었다.





2012년 12월 18일 화요일

PyQt GUI에 matplotlib 플랏 삽입하기 (번역)


(원글 출처 : http://www.technicaljar.com/?p=688 )

PyQt GUI에 matplotlib 플랏 삽입하기

admin 씀



Matplotlib는 광범위한 플라팅 툴과 기능성을 제공해 줍니다.
파이썬에서 Matplotlib를 사용하여 플라팅을 하는 것은 전혀 어렵지 않아요~
하지만 간혹 푸쉬버튼이나 텍스트 필드 같은 다른 GUI 요소들에 삽입하고 싶을 때가 있죠.
이 글에서는 PyQt로 GUI를 만들고, 여기에 Matplotlib를 삽입하는 방법을 설명드리겠어요.
일단 QtDesigner를 실행시키고...
File->New 를 해 줘야겠죠.  버튼이 없는 새로운 Dialog를 생성해 줍시다.
(버튼은 곧 직접 넣을 테니깐)
본 예제에서는 푸쉬버튼을 누를 때 새로이 생성되는 랜덤 넘버를 간단한 GUI에 띄워진 Matplotlib 화면에 플랏해 주려고 합니다.
일단 푸쉬버튼 하나를 찝어서 넣어줍시다.
Matplotlib는 PyQt의 일부가 아니기 때문에, Matplotlib를 PyQt상의 위젯이 되도록 만들어줘야 합니다.  일단 컨테이너(Containers)로부터 위젯(Widget)을 선택하고, GUI 위에 올려놔 줍시다.
그럼 이렇게 보일 겁니다.




오른쪽 위에 보이는 객체 탐색기(Object Inspector)를 보면, QWidget의 클래스로 위젯이 설정되어 있는 것을 주목해 볼 수 있어요.
하지만 우리는 Matplotlib를 그리려는 목적을 가지고 있으니깐 변경해 줄 필요가 있습니다.
변경해 줘야 하는 부분은, 구체적으로 위젯의 행동(Behavior)을 변화시켜주는 것입니다.
위젯의 행동을 변화시켜주려면, QWidget이라는 클래스 타입 대신에 Matplotlib를 그릴 수 있도록 타입을 바꿔주면 됩니다.
이런 작업을 승격(Promoting)이라고 합니다.
즉 위젯을 우리가 필요한 타입으로 변경해 주는 승격을 해 준다는 거죠.
승격 방법은 열라 쉬워요.
객체 탐색기(Object Inspector)에서 위젯(widget)을 오른쪽 클릭 해 주고, '다음으로 승격(Promote to)'을 선택해 주면 됩니다.  그리고 다음 그림과 같이 2개의 필드에 똑같이 써 줍시다.




이제 클래스 네임과 헤더파일 네임을 마음대로 쓸 수 있도록 허용된 것입니다.
이렇게 해 줌으로써, matplotlibwidgetFile.py 파일(.py는 써 줄 필요 없음)을 가진 matplotlibWidget이라는 이름의 클래스가, 이 위젯의 행동을 정의(define)해 줄 것이라고 PyQt에게 알려주는 의미가 됩니다.
본 예제에서 사용된 것과 클래스 네임과 헤더파일 네임이 반드시 똑같을 필요는 전혀 없습니다.
뭐 어쨌든 Add 버튼 눌러 주고, 그 다음 Promote 버튼 눌러 줍시다.
객체 탐색기(Object Inspector)에서 위젯의 타입이 변경되었는지 확인해 보시고요.





위젯의 클래스 타입이 matplotlibWidget으로 변경이 어떻게 되었는지 확인해 보고, 승격이 제대로 되었는지도 확인했습니다.
이제 matplotlibwidgetFile.py을 생성해서 위젯의 행동을 정의해 주면 됩니다.
다만 그 전에 먼저, GUI 코드를 파이썬 코드로 변환해 줄 필요가 있습니다.
일단 만들어진 GUI를 PlotGUI.ui 이름으로 저장하면, 아래와 같은 내용의 XML파일로 저장됩니다.



<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>570</width>
    <height>449</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>20</y>
     <width>501</width>
     <height>41</height>
    </rect>
   </property>
   <property name="text">
    <string>Push To Plot</string>
   </property>
  </widget>
  <widget class="matplotlibWidget" name="widget" native="true">
   <property name="geometry">
    <rect>
     <x>40</x>
     <y>90</y>
     <width>501</width>
     <height>321</height>
    </rect>
   </property>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>matplotlibWidget</class>
   <extends>QWidget</extends>
   <header>matplotlibwidgetFile</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>



.py 파일로 변환하려면 아래의 명령어를 터미널에서 쳐 주면 됩니다.
$ pyuic4 PlotGUI.ui > PlotGUI.py
이렇게 변환된 파이썬 파일을 열어보면 아래와 같은 내용이 들어가 있을 것입니다.



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

# Form implementation generated from reading ui file 'PlotGUI.ui'
#
# Created: Thu Jul 26 23:56:29 2012
#      by: PyQt4 UI code generator 4.8.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(570, 449)
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(30, 20, 501, 41))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.widget = matplotlibWidget(Dialog)
        self.widget.setGeometry(QtCore.QRect(40, 90, 501, 321))
        self.widget.setObjectName(_fromUtf8("widget"))

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("Dialog", "Push To Plot", None, QtGui.QApplication.UnicodeUTF8))

from matplotlibwidgetFile import matplotlibWidget



파일의 마지막 라인을 주목해 봅시다.
이 라인의 내용은, matplotlibwidgetFile을 인클루드 해 주고, matplotlibWidget를 임포트 해 주는 것입니다.
임포트되는 matplotlibWidget은 위젯의 행동을 정의해 주는 클래스가 될 것이구요.
아래 두 라인을 봅시다.

self.pushButton = QtGui.QPushButton(Dialog)
self.widget = matplotlibWidget(Dialog)


이 두 줄의 내용은, 우리가 만든 GUI에 있는 2개의 객체(Objects)를 정의하는 내용입니다.
pushButton과 Widget이 각각 자신의 정의함수(identifiers)를 가지게 됨을 알 수 있습니다.
우리는 이 2개의 이름을 가지고 이들에게 억세스 할 수 있게 됩니다.
PyQt GUI를 이제 만들었고, 여기에 푸쉬버튼과 위젯도 추가해 줬습니다.
그럼 이제 위젯의 행동을, matplotlibWidget 클래스를 핸들링해 줘서 설정해 줄 것입니다.
이걸 하려면 이 클래스를 정의(define)해 주기만 하면 됩니다.
방법은 아래와 같이 matplotlibwidgetFile.py 파일을 써서 만들어 주면 되고, 쉬워요.



from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

from matplotlib.figure import Figure

class MplCanvas(FigureCanvas):

    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)

        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)


class matplotlibWidget(QtGui.QWidget):

    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
        self.vbl = QtGui.QVBoxLayout()
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)



이 파일은 핵심적으로 이런 일을 합니다.
그림을 그릴 수 있는 캔버스(canvas)를 만들어주고,
우리가 만든 matplotlibWidget으로 넘겨주는 것입니다.
우리의 플라팅 위젯이 어떻게 핸들링 될 것인지를 정의해 준 것입니다.
이 모든게 그 위에 뭔가를 실제로 그리도록 해 주는 거죠.
이제, 아래에 우리의 메인 프로그램(main.py)이 있습니다.
이것은 푸쉬버튼이 눌러지면 matplotlib에서 랜덤 넘버를 그려주게 될 것입니다.



import sys
from PlotGUI import *
import random

class GUIForm(QtGui.QDialog):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.PlotFunc)

    def PlotFunc(self):
        randomNumbers = random.sample(range(0, 10), 10)
        self.ui.widget.canvas.ax.clear()
        self.ui.widget.canvas.ax.plot(randomNumbers)
        self.ui.widget.canvas.draw()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = GUIForm()
    myapp.show()
    sys.exit(app.exec_())


푸쉬버튼을 누를 때 마다, PlotFunc()이 호출되고, 정수의 랜덤 넘버셋이 그래프 위에 그려질 것입니다.  이 코드의 첫 실행 부분은 아래 부분입니다.


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = GUIForm()
    myapp.show()
    sys.exit(app.exec_())



이 부분은 기본적으로 우리의 GUI 인스턴스를 실행해 주는 QApplication 인스턴스를 생성해 줍니다.  두 번째로, QUIForm 인스턴스를 생성해 줍니다.
이것이 바로 우리의 프로세싱을 수행하고, 데이타를 그림그리는 위젯에 넘겨주도록 하는 우리의 클래스입니다.

우리가 인스턴스를 생성할 때, GUIForm은 초기화 부분(initializer)을 호출하게 됩니다.



    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.PlotFunc)


여기서 먼저 Ui_Dialog 인스턴스를 생성시킵니다.
Ui_Dialog가 PlotGUI.py 안에 있는 클래스의 이름이라는 점을 주목합시다.
(PlotGUI.py는 우리가 미리 만들어둔 GUI파일을 파이썬 포멧으로 변환해 둔 것이죠)
때문에 이 부분은 기본적으로 우리의 GUI 인스턴스를 만들고, 그 다음 setupUi(self)를 호출해서 GUI를 셋업합니다.  마지막 라인은, 우리가 누른 푸쉬버튼 신호를 PlotFunc로 연결해 줍니다.
그 다음에는, GUI가 myapp.show()에 의해 만들어지고 스크린에 뜨게 됩니다.
app.exec_()는, GUI상의 어떤 액션(클릭 따위)이 발생하면 그걸 잡아서 sys.exit()로 연결해 주는 루프를 시동시켜줍니다.  sys.exit()는 GUI를 확실하게 종료시켜 주는 것이구요.
PlotFunc는 명백하게 스스로 설명됩니다.
즉 그림을 만드는 위젯 객체에 억세스하는 것이죠. (이 이름은 PlotGUI.py에서 설정되어 있음을 기억합시다)
결국 푸쉬버튼을 누르면 아래와 같은 장면을 볼 수 있습니다.




이상 PyQt GUI에 matplotlib 그래프를 삽입하는 방법이었습니다.


레퍼런스:
[1] Matplotlib for Python Developers
[2] Introduction to Python Programming and Developing GUI Applications With PyQT

기타 참고 예제는 여기서 : http://eli.thegreenplace.net/2009/01/20/matplotlib-with-pyqt-guis/

2012년 12월 5일 수요일

유용한 python 라이브러리들

* 공학용 파이썬 환경을 구축하기 위한 가이드 : http://openopt.org



* 기본적으로 필요한 것들

(1) iPython ( http://ipython.org/ )
    강력한 파이썬 쉘 (터미널, QT기반 모두 제공)
    웹베이스 노트북 서비스 제공 (코드, 텍스트, 수학표현, 인라인 플랏, 다양한 미디어등도 제공)
    GUI툴킷을 이용하여 인터렉티브한 데이타 비쥬얼라이제이션 가능
    프로젝트에 올릴 수 있는 유연하고 포함가능한 인터프리터
    병렬연산을 하기에 쉽고 파퍼먼스가 좋음

(2) Numpy & Scipy ( http://numpy.scipy.org/ )
    강력한 N차원 오브젝트
    정교한 기능
    C/C++/Fortran 코드와 결합할 수 있는 툴
    선형대수, 푸리에 변환, 난수 등에 유용함

(3) MatPlotLib ( http://matplotlib.org/ )
    2D 플랏팅 라이브러리
    매틀랩 대응



* 추가적으로 유용한 것들

(1) Sympy ( http://code.google.com/p/sympy/ )
    심볼릭 수학을 할 수 있는 라이브러리

(2) Mpmath ( http://code.google.com/p/mpmath/ )
    상이한 정밀도를 가진 부동소수점 연산 라이브러리
    초월함수, 무제한 지수 크기, 복소수, 인터벌 산술계산, 수치 미적분, 근 찾기, 선형대수 등등
    자체 플랏팅 함수도 제공됨 (MatPlotLib로 그려도 됨)
    Sympy,Sage 등이 이 라이브러리에 의존함
    이 라이브러리 자체는 순수 파이썬 코드로 구성되어 있고,
    이것에 선행되는 의존성있는 라이브러리는 불필요

(3) Pyglet ( http://pyglet.org/ )
    GUI 및 멀티미디어 라이브러리
    이것에 선행되는 의존성있는 라이브러리는 없음
    멀티플 윈도우, 멀티 모니터 데스크탑 환경에 적합한 구성을 만들기 좋음
    이미지, 사운드, 뮤직, 비디오 등을 포멧에 별로 구애받지 않고 로딩할 수 있음

(4) Swignac ( http://swiginac.berlios.de/ )
    심볼릭 수학을 위한 라이브러리 (Sympy와는 다른 구현)
    Sympy는 Mpmath 기반이지만, Swignac은 GiNaC 기반임.
    GiNaC은 C/C++ 라이브러리로, 이것을 파이썬에서 그대로 사용하도록 인터페이스해 줌

(5) SDXF ( http://www.kellbot.com/sdxf-python-library-for-dxf/ )
    표준 CAD 파일 포멧의 하나인 DXF 포멧으로 출력해 주는 코드

(6) wxPython ( http://www.wxpython.org/ ) + wxGlade ( http://wxglade.sourceforge.net/ )
    파이썬으로 GUI 쉽게 만들어주는 라이브러리 및 GUI 툴
    wxGlade 가지고 화면 구성, 버튼 구성 뼈대를 만들어 준 후
    Generate하면 파이썬 코드가 생성되는데 거기에 호출함수에 해당 기능을 넣어주면 된다.
    간단하게 뭘 만들기 좋은 것 같다.



* 3D 그래픽 관련

(1) Mayavi2 ( http://code.enthought.com/projects/mayavi/ )
    데이타 비주얼라이제이션을 위한 툴 및 라이브러리
    핵심개발자의 블로그 http://gael-varoquaux.info/blog/?p=141



* 로봇 관련

(1) OpenRave ( http://openrave.org/ )
    테스트, 개발, 모션플래닝 과정을 지원하기 위한 라이브러리
    핵심 촛점은, 모션플랜을 위한 로봇 형상 및 기구학 정보를 시뮬레이션하고 해석하는데 있음
    커맨드라인 툴 위주로 구성되어 있으므로, 현존하는 로봇에 이것으로 구성된 알고리즘을 적용하기가 용이함
    런타임 코어 부분은 로봇제어기 또는 더 큰 프레임웤에 삽입하기에 충분하게 사이즈가 작음
    산업용 로봇 어플리케이션에 대응하는 것이 가장 중요한 목표




2012년 11월 29일 목요일

python 기초 강좌


* 파이썬 마을 http://python.kr/

* 다이빙 파이썬 강좌 http://coreapython.hosting.paran.com/dive/chap02.html

* 왕초보를 위한 PYTHON 2.7 http://wikidocs.net/read/book/136

* The WxPython Linux Tutorial http://wiki.wxpython.org/index.cgi/AnotherTutorial#wx.Window

* FreeCAD Python Script http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=Power_users_hub

* Mayavi ---> 이건 소프트웨어 설치하면 오프라인으로 설명서 제공됨


[Github] Gear 관련 참고할 수 있는 python 오픈소스 모음


(1) https://github.com/phillbaker/non-circular-gears-generator

UC버클리의 제프 스코너라는 학생이 2002년도에 숙제로 해 온 걸 오픈시켜 준 소스.
클리포드 울프의 소스를 참고해서 변형한 것이라고 한다.

발표자료는 프로포절, 중간보고서, 완료보고서로 잘 나와 있다.


(2) https://github.com/TinHead/FreeCAD-scripts

FreeCAD 소프트웨어를 위한 스크립트이다.
스크립트를 돌려보니 잘 그려진다.
다만 너무 간단해서 쓸만한 아웃풋이 나오지는 않는데
대신 FreeCAD 상에서 아주 간단하게 QT기반 GUI 입력창 만들어주고
데이타 뿌려주는데 굉장히 효율적인 것 같다.
FreeCAD에서는 DXF,IGES,STEP 등등 가리지 않고 마음껏 익스포트 시킬 수 있으므로
여기서 기본적인 형상을 그려낸 다음,
다른 상용 CAD에서 임포트시켜 추가 작업을 해도 좋을 것 같다.


(3) https://github.com/cfinch/IGES-File-Reader

2년 전에 중단된 것 같은데,
IGES 파일을 바로 읽어들이도록 python으로 날코딩해서 만들려고 한 것 같다.


(4) https://github.com/nmz787/nanoengineer

'나노캐드(Nanotech CAD)'라길래 뭔가 했더니,
놀랍게도 분자단위의 기계를 가상적으로 구현해 볼 수 있는 설계도구이다.
실제 원자단위, 분자단위로 직접 매니퓰레이팅을 해서
원하는 형상을 마음대로 만들기는 어려우나
AFM 같은 기술이 잘 발달해서 이게 쉽게 된다면
이런 분야의 설계툴이 필요하게 될 지도!!!


(5) https://github.com/elmom/MCAD

OpenSCAD 라는 오픈소스 CAD 툴을 개발하는 프로젝트가 있는 모양인데
이것의 목표는 제대로 된 Parametric 기반으로 만들어보자는 것 같다.
아무튼 여기서 사용할 라이브러리를 구축하는 모양인데
기어 관련 함수들도 python으로 구현되어 포함되어 있다.
gear(), bevel_gear() ....  뭐 이런 식으로 막 호출해서 쓰도록 하나보다.
확장자는 .scad 라고 되어 있긴 한데 열어보니 그냥 python인 듯...




2012년 11월 27일 화요일

python 공학용 환경 구축


현재 사용중인 리눅스 버전은 "리눅스 민트 13 마야 시나몬".
우분투와 거의 발을 맞추고 있으므로,
우분투 저장소에서 제공되는 소프트웨어들도 거의 같을 것이다.

파이썬은 2.7

일단 소프트웨어 저장소에서 다음 것들을 설치해 준다.

(1) python 2.7 : 일단 깔려 있는지 확인.
(2) ipython : 인터액티브 콘솔
(2) numpy : 수치해석용 라이브러리 (행렬등)
(3) scipy : 과학기술용 라이브러리
(4) matplotlib : 플랏팅 라이브러리
(5) mayavi2 : 3D 비주얼라이제이션 라이브러리 및 IDE (?)
(6) sfepy : FEM 모듈

헌데 이중에
(2)~(5)번은 기본 저장소에 등록되어 잘 제공된다.  그냥 선택해서 깔아 주기만 하면 OK.




(6)번 sfepy 소프트웨어는 기본 저장소에서 제공해 주지 않는 것 같다.

http://sfepy.org/doc

여기 가서 튜토리얼 보면서 깔아준다.
의존성 있는 패키지들이 좀 있는데

(1) 필수 : numpy, scipy, cython
(2) sympy 사용시 의존성 있는 것들 : matplotlib, pyparsing, umfpack, pytables
(3) schroedinger.py 사용시 의존성 있는 것들 : pysparse, pexpect, gmsh (2D), tetgen (3D)
(4) log.py (live plotting) 사용시 의존성 있는 것들 : multiprocessing, matplotlib with GTKAgg
(5) isfepy 사용시 의존성 있는 것들 : ipython, matplotlib with WXAgg
(6) postproc.py 사용시 의존성 있는 것들 : mayavi2
(7) 도큐먼트 (재)생성을 위해 필요한 것들 : sphinx, numpydoc, LaTeX

의존성 있는 것들 중 빠진 것들을 볼드체로 표시했다.
우분투 계열 리눅스에서 필수 의존성 패키지들을 포함해서 한꺼번에 까는 명령은


sudo aptitude install python-scipy python-matplotlib python-tables python-pyparsing libsuitesparse-dev python-setuptools mayavi2 python-dev ipython python-sympy cython python-sparse


이렇게 소개되고 있다.
이미 설치되어 있는 패키지는 빼버리고 명령을 줘도 될 것이다.
기타 의존성 있는 것들도 마찬가지로 명령을 주면 될 것이다.

이렇게 준비 한 후,
sfepy 패키지는 tar 패키지로 따로 다운로드 받은 후에
sfepy 디렉토리를 만들어 준비해서 풀어넣어 주고 나서


python setup.py build_ext --inplace


이렇게 해 주면 몇 분 정도 걸려서 컴파일이 된다.


./runTests.py


이후 이걸 실행시켜서 제대로 컴파일이 되었는지 확인하면 됨.

리눅스 말고 윈도우 쪽에서 환경을 구성하는 것은 설명대로 따라가면 될테니
그리 어렵지는 않을 것이라고 생각된다.



한편, (5)번 mayavi2 의 경우 자체적인 환경도 가지고 있는데
여기서 기능점검 같은 걸 해 가면서 하는 것도 좋은 것 같다.
자체적인 튜토리얼도 아주 쉽게 잘 되어 있는 것 같다.


mayavi2 환경에서 IDE(?)를 실행시키는 아이콘이 따로 등록되지 않으므로
터미널상에서 mayavi 명령어를 때려주면 일단 실행이 되고
아이콘 등록해 주고 싶으면 /usr/bin/mayavi 를 아이콘으로 등록해 주면 된다.







































이제 활용을 생각해 보면,


ipython 환경에서 기본적인 것들을 인터액티브하게 연습을 하고,
에디팅은 Geany 에디터 같은 것을 사용하고,
mayavi 띄워서 3D 비주얼라이제이션이나 GUI를 쉽게 만들어 나갈 수 있고,
sfepy를 이용해서 간단한 FEM도 가능해진다.

이것들을 활용해서 필요한 어플리케이션을 구성하는 것이 충분히 가능하다고 생각된다.


최종적으로, 작성된 프로그램을 독립적인 바이너리 패키지로 만들어야 할 텐데
윈도우에서는 py2exe, pyinstall 이나 기타 패키지화 시켜주는 것들이 있을 것이고
리눅스 쪽에서 패키징 해 주는 방법은 아무래도 따로 서칭해 보아야 할 것 같다.

일단 눈에 띄는 것은 cx_Freeze (멀티 플랫폼) 또는 freeze.py (리눅스용) 같은 것들...