다음은 Pythob 2.7.* 에 PyGTK 를 설치하여 실행되는 RPN 계산기 소스이다.

 

#!/usr/bin/env python

# Filename: rpnCalc.py
#           0,3
#
#   RPN Calculator using PyGTK
#   Modified from PyGTK/example/textview-basic.py

import pygtk
pygtk.require('2.0')
import gtk

class TextViewExample:
    def callback(self, widget, data=None):
        print "Hello again - %s was pressed" % data
        if data != None:
            self.textbuffer.insert(self.textbuffer.get_end_iter(), data + "\n")
               
    def enter_callback(self, widget, entry):
        entry_text = entry.get_text()
        print "Entry contents: %s\n" % entry_text
  
    def create_model(self):
        '''create the model - a ListStore'''
        self.store = gtk.ListStore(float)
        return self.store
 
    def create_columns(self, treeView):
        ''' create the columns '''
        rendererText = gtk.CellRendererText()
        rendererText.set_property('xalign', 1.0)   # work for right align
        column = gtk.TreeViewColumn(None, rendererText, text=0)
        column.set_sort_column_id(0)
        column.set_alignment(0.5)   # work for center align

        # append the column
        treeView.append_column(column)

    def reset(self, widget, entry):
        entry.set_text("")

    def calcIt(self, widget, entry):
        CONTINUE_FLAG = 1

        while CONTINUE_FLAG == 1:
            param = entry.get_text()
            tokens = self.tokenize(param)
            token_len = len(tokens)

            self.textbuffer.insert(self.textbuffer.get_end_iter(), "RPN> " + param + "\n")

            for i in range(0, token_len):
                    str = "" + tokens[i]
                    if len(str) == 0:
                        continue

                    a = str[0:1]

                    if a == 'Q' or a == 'q':
                        self.showMessage("Quit")
                        self.clear()
                        CONTINUE_FLAG = 0
                        break

                    if a in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']:
                            self.push(eval(str))
                    elif a == '+':
                            if len(str) > 1:
                                self.push(eval(str))
                            else:
                                self.push(self.pop() + self.pop())
                    elif a == '-':
                            if len(str) > 1:
                                self.push(eval(str))
                            else:
                                op2 = self.pop();
                                self.push(self.pop() - op2)
                    elif a == '*':
                         if str == "**":
                                op2 = self.pop()
                                self.push(pow(self.pop(), op2))
                         else:
                                self.push(self.pop() * self.pop())
                    elif a == '/':
                            op2 = self.pop()
                            if op2 != 0.0:
                                self.push(self.pop() / op2)
                            else:
                                self.showMessage("zero divisor popped")
                    elif a == '^':
                            op2 = self.pop()
                            self.push(pow(self.pop(), op2))
                    elif a == '=' or a == 'p':
                            listmodel = self.listView.get_model()
                            y = listmodel.get_value(listmodel.get_iter_first(), 0)
                            self.showMessage("%s" % y)
                    elif a == 'c':
                            self.showMessage("Clear")
                            self.clear()
                    else:
                            self.showMessage("Unknown Command: " + a)
            CONTINUE_FLAG = 0
            entry.set_text("")


    # push f onto value stack
    def push(self, f):
        self.store.insert(0, [f])

    # pop top value from stack
    def pop(self):
        try:
             listmodel = self.listView.get_model()
             y = listmodel.get_value(listmodel.get_iter_first(), 0)
             self.store.remove(self.store.get_iter_first())
             return y
        except:
             raise "pop error on empty stack"
        return None

    # clear stack
    def clear(self):
        self.store.clear()


    # Tokenize the input string.
    def tokenize(self, s):
        self.len = len(s)
        t = ""
        tokens = []    # list of tokens

        for i in range(0, self.len):
            c = s[i:i+1]
            if c == ' ' or c == '\t' or c == '\r' or c == '\n':
                    if len(t) > 0:
                            tokens.append(t)
                            t = ""
            elif c == '+' or c == '-':
                    if len(t) > 0:
                            tokens.append(t)
                            t = c
                    elif len(t) == 0:
                            t = c
            elif c == '*':
                    if len(t) > 1:
                            tokens.append(t)
                            tokens.append(c)
                            t = ""
                    elif len(t) == 1:
                         if t == "*":
                                tokens.append("**")
                                t = ""
                         else:
                                tokens.append(t)
                                tokens.append(c)
                                t = ""
                    elif len(t) == 0:
                            t = c
            elif c == '/' or c == '^' or c == '=' or c == 'p' or c == 'q' or c == 'Q':
                    if len(t) > 0:
                            tokens.append(t)
                            tokens.append(c)
                            t = ""
                    elif len(t) == 0:
                            tokens.append(c)
            else:
                    t += c

        if len(t) > 0:
                tokens.append(t)
                t = ""
        return tokens


    def showMessage(self, m):
        if m != None:
            self.textbuffer.insert(self.textbuffer.get_end_iter(), "%s\n" % m)


    def close_application(self, widget):
        gtk.main_quit()

    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_resizable(True) 
        window.connect("destroy", self.close_application)
        window.set_title("RPN Calculator")
        window.set_default_size(500, 300)
        window.set_border_width(0)

        box2 = gtk.VBox(False, 10)
        box2.set_border_width(10)
        window.add(box2)
        box2.show()

        hbox1 = gtk.HBox()
        box2.pack_start(hbox1, True, True, 0)
        hbox1.show()


        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        textview = gtk.TextView()
        self.textbuffer = textview.get_buffer()
        sw.add(textview)
        sw.show()
        textview.show()

        hbox1.pack_start(sw, True, True, 10)


        # create a scrollable window and integrate it into the vbox
        sw2 = gtk.ScrolledWindow()
        sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 
        # create a TreeView object which will work with our model (ListStore)
        store = self.create_model()
        self.listView = gtk.TreeView(store)
        self.listView.set_rules_hint(True)
        self.listView.set_headers_clickable(False)
        self.listView.set_property("headers-visible", False)
 
        # add the TreeView to the scrolled window
        sw2.add(self.listView)
 
        sw2.show()
        self.listView.show()

        # create the columns
        self.create_columns(self.listView)
        sw2.set_size_request(150, 300)
        hbox1.pack_start(sw2, False, False, 10)


        # check button to toggle editable mode
        textview.set_editable(False)
        textview.set_cursor_visible(False)
       
        hbox2 = gtk.HBox()
        box2.pack_start(hbox2, False, True, 0)
        hbox2.show()

        entry = gtk.Entry()
        entry.set_max_length(50)
        entry.connect("activate", self.enter_callback, entry)
        hbox2.pack_start(entry, True, True, 10)
        entry.show()

        hbox3 = gtk.HButtonBox()
        hbox2.pack_start(hbox3, False, False, 0)
        hbox3.show()

        btnCalc = gtk.Button("Calculate")
        btnCalc.connect("clicked", self.calcIt, entry)
        hbox3.pack_start(btnCalc, True, True, 5)
        btnCalc.set_flags(gtk.CAN_DEFAULT)
        btnCalc.grab_default()
        btnCalc.show()
       

        btnReset = gtk.Button("Reset")
        btnReset.connect("clicked", self.reset, entry)
        hbox3.pack_start(btnReset, True, True, 5)
        btnReset.set_flags(gtk.CAN_DEFAULT)
        btnReset.grab_default()
        btnReset.show()

        window.show()

def main():
    gtk.main()
    return 0      

if __name__ == "__main__":
    TextViewExample()
    main()

 

프롬프트> python rpnCalc.py

 

 

 

Posted by Scripter

댓글을 달아 주세요

현재 Python 3.3 의 최신 릴리즈는 3.3.5 이고, Python 3.4 의 최신 릴리즈는 3.3.1 이다. 또한 IPython 의 최신 릴리즈는 2.1.0 이다. 

 

여기서는 윈도우용 Python 3.3.5 를 설치한 후 IPython 2.1.0 을 설치하여 사용하는데 문제가 많아 그 한 해결법을 제시한다.'(윈도우용 Python 3.4.1 의 경우에는 IPython 2.1.0 이 무리 없이 잘 설치된다.)

 

이 글에서 IPython 을 포함하여 모든 Python 확장 모듈의 설치는 모두

Unofficial Windows Binaries for Python Extension Packages

의 것을 내려받아 설치하는 것으로 간주한다.

 

우선 Python 3.3.5 인터프리터를 실행해 본다. 

프롬프트> python
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit() 

이번에는 IPython 인터프리터를 실행해본다.  IPython 의 실행파일은 %PYTHONPATH%\Scripts 폴더에 존재하므로 이 폴더를 환경변수 PATH 에 넣어주어야 한다.

프롬프트> ipython
Traceback (most recent call last):
  File "c:\python335\Scripts\ipython-script.py", line 5, in <module>
    from pkg_resources import load_entry_point
ImportError: No module named 'pkg_resources'

 

위의 에러 메시지는 pkg_resources 모듈이 설치되어 있지 않다는 의미이다.

Python 3.4.1 을 설치하여 %PYTHONPATH%\Lib\site_packes 폴더에 있는 pkg_resource.py 파일을 Python 3.3.5 의 해당 폴더에 복사한 후 ipython 릏 다시 실행한다.

프롬프트> ipython
WARNING: Readline services not available or not loaded.
WARNING: Proper color support under MS Windows requires the pyreadline library.
You can find it at:
http://ipython.org/pyreadline.html
Gary's readline needs the ctypes module, from:
http://starship.python.net/crew/theller/ctypes
(Note that ctypes is already part of Python versions 2.5 and newer).

Defaulting color scheme to 'NoColor'
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

 

이번에는 IPython 이 실행은 되었지만 색상이 지원되지않는다. 그래서 PyReadline 을 설치하고 다시 ipython 을 실행한다.


프롬프트> ipython
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

위와 같이 IPython 2.1.0 이 잘 실행되었음을 알 수 있다.

 

64비트용 Python 3,3,5 의 경우에도 위와 같은 방법으러  IPython 2,1,9 을 설치하여 사용할 수 있다.

 

Python 3,4,1 의 경우 IPython 2.1.0 이 설치와 실행은 잘 되지만, 역시 색상은 지둰되지 않는다.

이 경우 PyReadline 을 설치하는 방법은

프롬프트> set PATH=%PYTHTHON341PATH%;%PYTHON341PATH%\Scripts;%PATH%

한 후 pip 명령으로 pyreadline 을 설치한다.

프롬프트> pip ionstall pyreadline

만일 pip 명렬으로 pyreadline 이 설치되지 않으면 Download PyReadline 에서 직법 내려받아 설치해도 된다. (32bit 용 Python 3.4.1 의 경우 이렇게 하여 성공적으로 설치하였다.)

 

참고로, Matplotlib 를 이용하기 위해서는 numpy, python-dateutil, pytz, pyparsing, six, pillow, pycairo, tornado, pyside, pyq 들이 먼저 설치되어 있어야 한다.

이제 Matplotlib 가 잘 설치되었는지 IPython 으로 테스트해 보자.

 

프롬프트> ipython -pylab

 WARNING: `-pylab` flag has been deprecated.
    Use `--matplotlib <backend>` and import pylab manually.
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AM
D64)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
Using matplotlib backend: TkAgg

In [1]: x = randn(10000)

In [2]: hist(x, 100)
Out[2]:
(array([   1.,    0.,    0.,    0.,    0.,    1.,    1.,    3.,    1.,
           2.,    3.,    2.,    2.,    5.,    6.,    4.,    5.,   10.,
           8.,   20.,   27.,   16.,   25.,   34.,   30.,   26.,   51.,
          60.,   70.,   66.,   86.,   97.,   88.,  108.,  118.,  140.,
         151.,  158.,  156.,  175.,  189.,  215.,  220.,  255.,  251.,
         273.,  267.,  260.,  295.,  285.,  314.,  320.,  298.,  285.,
         310.,  327.,  299.,  281.,  246.,  260.,  247.,  277.,  190.,
         199.,  186.,  187.,  206.,  139.,  135.,  131.,  126.,  100.,
         119.,   74.,   71.,   67.,   67.,   42.,   27.,   34.,   29.,
          30.,   24.,   15.,    8.,   13.,   12.,   11.,    3.,    7.,
           4.,    0.,    2.,    2.,    5.,    1.,    2.,    1.,    0.,    1.]),
 array([-3.96240846, -3.8868053 , -3.81120214, -3.73559898, -3.65999581,
        -3.58439265, -3.50878949, -3.43318633, -3.35758317, -3.28198001,
        -3.20637685, -3.13077368, -3.05517052, -2.97956736, -2.9039642 ,
        -2.82836104, -2.75275788, -2.67715471, -2.60155155, -2.52594839,
        -2.45034523, -2.37474207, -2.29913891, -2.22353574, -2.14793258,
        -2.07232942, -1.99672626, -1.9211231 , -1.84551994, -1.76991678,
        -1.69431361, -1.61871045, -1.54310729, -1.46750413, -1.39190097,
        -1.31629781, -1.24069464, -1.16509148, -1.08948832, -1.01388516,
        -0.938282  , -0.86267884, -0.78707567, -0.71147251, -0.63586935,
        -0.56026619, -0.48466303, -0.40905987, -0.3334567 , -0.25785354,
        -0.18225038, -0.10664722, -0.03104406,  0.0445591 ,  0.12016226,
         0.19576543,  0.27136859,  0.34697175,  0.42257491,  0.49817807,
         0.57378123,  0.6493844 ,  0.72498756,  0.80059072,  0.87619388,
         0.95179704,  1.0274002 ,  1.10300337,  1.17860653,  1.25420969,
         1.32981285,  1.40541601,  1.48101917,  1.55662233,  1.6322255 ,
         1.70782866,  1.78343182,  1.85903498,  1.93463814,  2.0102413 ,
         2.08584447,  2.16144763,  2.23705079,  2.31265395,  2.38825711,
         2.46386027,  2.53946344,  2.6150666 ,  2.69066976,  2.76627292,
         2.84187608,  2.91747924,  2.99308241,  3.06868557,  3.14428873,
         3.21989189,  3.29549505,  3.37109821,  3.44670137,  3.52230454,
         3.5979077 ]),
 <a list of 100 Patch objects>)

 

 

 

-pylab 옵션이 deprecate 되었다고 하니 이번에는 옵션--matplotlib 으로 실행해 보자.

프롬프트> ipython --matplotlib
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AM
D64)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
Using matplotlib backend: TkAgg

In [1]: from pylab import *

In [2]: x = randn(10000)

In [3]: hist(x, 100)
Out[3]:
(array([   2.,    1.,    1.,    1.,    1.,    3.,    7.,    5.,    1.,
           4.,   11.,   13.,   15.,   16.,   20.,   21.,   27.,   25.,
          31.,   34.,   47.,   47.,   62.,   70.,   68.,   79.,   98.,
         101.,  123.,  121.,  145.,  142.,  142.,  168.,  172.,  193.,
         212.,  235.,  229.,  227.,  240.,  236.,  296.,  286.,  259.,
         276.,  285.,  274.,  302.,  308.,  284.,  286.,  288.,  255.,
         251.,  234.,  215.,  198.,  216.,  183.,  192.,  175.,  175.,
         156.,  130.,  133.,  102.,  101.,   90.,   95.,   79.,   54.,
          63.,   57.,   50.,   32.,   36.,   33.,   24.,   21.,   23.,
          16.,    9.,    6.,   12.,    7.,    6.,    6.,    5.,    4.,
           1.,    4.,    2.,    2.,    2.,    1.,    3.,    0.,    0.,    1.]),
 array([-3.40718204, -3.33556225, -3.26394247, -3.19232268, -3.1207029 ,
        -3.04908311, -2.97746333, -2.90584354, -2.83422376, -2.76260398,
        -2.69098419, -2.61936441, -2.54774462, -2.47612484, -2.40450505,
        -2.33288527, -2.26126548, -2.1896457 , -2.11802592, -2.04640613,
        -1.97478635, -1.90316656, -1.83154678, -1.75992699, -1.68830721,
        -1.61668742, -1.54506764, -1.47344785, -1.40182807, -1.33020829,
        -1.2585885 , -1.18696872, -1.11534893, -1.04372915, -0.97210936,
        -0.90048958, -0.82886979, -0.75725001, -0.68563023, -0.61401044,
        -0.54239066, -0.47077087, -0.39915109, -0.3275313 , -0.25591152,
        -0.18429173, -0.11267195, -0.04105216,  0.03056762,  0.1021874 ,
         0.17380719,  0.24542697,  0.31704676,  0.38866654,  0.46028633,
         0.53190611,  0.6035259 ,  0.67514568,  0.74676546,  0.81838525,
         0.89000503,  0.96162482,  1.0332446 ,  1.10486439,  1.17648417,
         1.24810396,  1.31972374,  1.39134353,  1.46296331,  1.53458309,
         1.60620288,  1.67782266,  1.74944245,  1.82106223,  1.89268202,
         1.9643018 ,  2.03592159,  2.10754137,  2.17916115,  2.25078094,
         2.32240072,  2.39402051,  2.46564029,  2.53726008,  2.60887986,
         2.68049965,  2.75211943,  2.82373921,  2.895359  ,  2.96697878,
         3.03859857,  3.11021835,  3.18183814,  3.25345792,  3.32507771,
         3.39669749,  3.46831728,  3.53993706,  3.61155684,  3.68317663,
         3.75479641]),
 <a list of 100 Patch objects>)

 

 

 

이제 32비트용 Python 3.4.1 에서 Matplotlib 를 사용해 보자.

32비트용 Python 3.4.1 이 폴더 C:\Python34-32 에 설치된 것으로 간주한다.

먼저 명령 프롬프트에서 환경변수 PATH 를 설정한다.

프롬프트> pythonset PATH=C:\Python34-32;C:\Python34-32\Scripts;%PATH%

Pyhon 인터프리터를 실행하여 간단한 코드

import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()

를 입력한다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
Traceback (most recent call last):
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 111, in <
module>
    import dateutil
ImportError: No module named 'dateutil'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 113, in <
module>
    raise ImportError("matplotlib requires dateutil")
ImportError: matplotlib requires dateutil
>>> plt.plot([1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.ylabel('some numbers')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.show()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> exit()


위의 에러 메시징[서 보다 시피, 모듈 dateutil 이 없다는 에러다.

이번에는 IPython 을 실행해 본다.

프롬프트> ipython
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

IPython 은 정상적으로 잘 실행된다.

pip 명령으로 python-dateutil 을 설치한다.

프롬프트> pip install python-dateutil
Downloading/unpacking python-dateutil
  Running setup.py (path:C:\Users\ph\AppData\Local\Temp\pip_build_ph\python-date
util\setup.py) egg_info for package python-dateutil

Requirement already satisfied (use --upgrade to upgrade): six in c:\python34-32\
lib\site-packages (from python-dateutil)
Installing collected packages: python-dateutil
  Running setup.py install for python-dateutil

Successfully installed python-dateutil
Cleaning up...

 

다시 Pyhon 인터프리터를 실행하여 앞에서 제시했던 간단한 코드를 입력해 본다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
Traceback (most recent call last):
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 125, in <
module>
    import pyparsing
ImportError: No module named 'pyparsing'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 127, in <
module>
    raise ImportError("matplotlib requires pyparsing")
ImportError: matplotlib requires pyparsing
>>> plt.plot([1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.ylabel('some numbers')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.show()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> exit()

 

위의 에러 메시징[서 보다 시피, 이번에는 모듈 pyparsing 이 없다는 에러다.

그래서 pip 명령으로 pyparsing 을 설치한다.

프롬프트> pip install pyparsing
Downloading/unpacking pyparsing
  Running setup.py (path:C:\Users\ph\AppData\Local\Temp\pip_build_ph\pyparsing\s
etup.py) egg_info for package pyparsing

Installing collected packages: pyparsing
  Running setup.py install for pyparsing

Successfully installed pyparsing
Cleaning up...

 

python-dateutil 과 ptparsing 이 설치되었으니 다시 Pyhon 인터프리터를 실행하여 앞에서 제시했던 간단한 코드를 입력해 본다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
[<matplotlib.lines.Line2D object at 0x045BE530>]
>>> plt.ylabel('some numbers')
<matplotlib.text.Text object at 0x047160B0>
>>> plt.show()

위의 명령이 모두 수행되어 아래 처럼 Matplotlib 에 의한 그래프 창이 성공적으로 뜬다.

 


 

이번에는 좌표평면의 네 점 (1, 1), (2, 4), (3, 9), (4, 16) 에 (속이 채워진) 뿕은 색의 굵은 점을 찍어본다.

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4], [1,4,9,16], 'ro')
[<matplotlib.lines.Line2D object at 0x042EE3B0>]
>>> plt.axis([0, 6, 0, 20])
[0, 6, 0, 20]
>>> plt.show()

 

 

 

이번에는 NumPy 모듈을 이용하여, 한 좌표평면의 세 함수 y = x, y = x^2, y = x^3 의 그래프를 그려 보자.

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> t = np.arange(0., 5., 0.2)
>>> plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
[<matplotlib.lines.Line2D object at 0x04716410>, <matplotlib.lines.Line2D object
 at 0x047169F0>, <matplotlib.lines.Line2D object at 0x047160F0>]
>>> plt.show()

 

 

 

* 이 외에도 Matplotlib 튜토리얼의 다른 예제 들도 잘 실행됨을 확인하였다.

 

 

Posted by Scripter

댓글을 달아 주세요

Pytghon 스크립트로 버전을 알아내는 방법 중에 하나는

import sys

sys.version_info

를 이용하는 것이다.

 

* Pyhoin 3.3 의 경우

Python 3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:19:30) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=3, micro=3, releaselevel='final', serial=0)
>>> sys.version_info > (2, 4)
True
>>> sys.version_info >= (2, 4)
True
>>> sys.version_info >= (3, 0)
True

>>> type(sys.version_info)
<class 'sys.version_info'>

 

 

* Python 2.7 의 경우

Python 2.7.5 (default, Oct  2 2013, 22:34:09)
[GCC 4.8.1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)
>>> sys.version_info > (2, 4)
True
>>> sys.version_info > (2, 7)
True
>>> sys.version_info >= (2, 7)
True
>>> sys.version_info >= (2, 8)
False

>>> sys.version_info >= (3, 0)
False

>>> type(sys.version_info)
<type 'sys.version_info'>

 

 

 

Posted by Scripter

댓글을 달아 주세요

* pyqtgraph 내려받기

 

* 예제 소스 (극곡선 r = 2 cos(3 theta) 그리기)

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

# Filename: testPyQtGraph_03.py
# Execute: python testPyQtGraph_03.py


from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

app = QtGui.QApplication([])

win = pg.GraphicsWindow(title="Basic plotting examples")

win.resize(400, 500)
win.setWindowTitle('pyqtgraph example: Plotting')

# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)

p1 = win.addPlot(title="Parametric, grid enabled")
a = 2.0
k = 3.0
theta = np.linspace(0, 2*np.pi, 1000)
x = a*np.cos(theta)*np.cos(k*theta)
y = a*np.sin(theta)*np.cos(k*theta)
p1.plot(x, y)
p1.showGrid(x=True, y=True)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

 

* 실행 결과:

 

 

더 많은 pyqtgraph 예제:

프롬프트> cd %PYTHON27_HOME%\\Lib\site-packages\pyqtgraph

프롬프트> python -m examples

 

 

 

Posted by Scripter

댓글을 달아 주세요

** PySide 설치하기

** QtDesigner 내려받기

** 윈도우즈 용 git 를 설치하기

 

* 다음 소스는 http://qt-project.org/wiki/PySideSimplicissimus_Module_2_CloseButton 에서 볼 수 있는 소스이다.

 

#!/usr/bin/env python

# quitter.py - provide a button to quit this "program"

import sys

from PySide.QtGui import QMainWindow, QPushButton, QApplication
from ui_quitter import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    frame = MainWindow()
    frame.show()   
    app.exec_()

 

프롬프트> python quitter.py
Traceback (most recent call last):
  File "quitter.py", line 8, in <module>
    from ui_quitter import Ui_MainWindow
ImportError: No module named ui_quitter

ui_quitter 모듈이 없다는 에러 메시지이다.

 

* quitter.ui 를 구하기 위한  tuts4pyside 를 내려 받기 (quiter.ui 파일은 QtDesigner 를 이용하여 만든 파일이다.)

프롬프트> git clone https://github.com/OldAl/tuts4pyside

 

* quitter.ui 복사하기 (quittere,ui 파일을 현재 폴더에 복사한다.)

프롬프트> copy .\tuts4pyside\quit_prog\quitter.ui

* quitter.ui 로 부터 ui_quitter.py 를 생성하기 (실행 파일 pyside_uic.exe 는 C:\Python27\Scripts 폴더에 존재한다.)

프롬프트> c:\python27\scripts\pyside-uic quitter.ui -o ui_quitter.py

 

* 실행하기

프롬프트> python quitter.py

 

 

 

 

Posted by Scripter

댓글을 달아 주세요

전개 공식

        (ax + b)(cx + d) = acx^2 + (ad + bc)x + bd

에 기반을 둔 쉬운 곱셉법(일명 카라슈바 곱셈법)이다.

여기서 특히 a == b or a == c or b == d or c == d 인 경우이면

      ad + bc = s(c + d)  or ad + bc = a(b + d)

      or ad + bc = b(s + c) or ad + bc = c(a + b)

로 더 쉬운 곱셈 계산이 가능하다.

 

#!/usr/bin/python
# -*- coding: utf-8 -*-


# Filename: ezMult_02.py
#
# Execute: python ezMult_02.py
#
# See: http://zetcode.com/gui/pyqt4/widgets2/
# See: http://zetcode.com/gui/pyqt4/


import sys
import sys, random
from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
   
    def __init__(self):
        super(Example, self).__init__()
       
        self.ngame = 1
        self.npoint = 0
        self.doneflag = False
       
        self.initUI()
       
    def initUI(self):
        self.rect = QtCore.QRect(0, 30, 300, 220)
        self.xa = random.randint(11, 99)
        self.ya = random.randint(11, 99)
        self.lblXA = QtGui.QLabel(self)
        self.lblYA = QtGui.QLabel(self)
        self.lblYA.setFont(QtGui.QFont('Decorative', 16))
        self.lblXA.setFont(QtGui.QFont('Decorative', 16))
        self.lblXA.setText(str(self.xa))
        self.lblYA.setText(str(self.ya))
        self.lblXA.move(80, 60)
        self.lblYA.move(80, 80)

        self.lblAA = QtGui.QLabel(self)
        self.lblAA.setFont(QtGui.QFont('Decorative', 16))
        self.lblAA.setText("")
        self.lblAA.move(65, 90)

        self.lblBA = QtGui.QLabel(self)
        self.lblBA.setFont(QtGui.QFont('Decorative', 16))
        self.lblBA.setText("")
        self.lblBA.move(105, 110)

        self.lblCA = QtGui.QLabel(self)
        self.lblCA.setFont(QtGui.QFont('Decorative', 16))
        self.lblCA.setText("")
        self.lblCA.move(105, 120)

        self.lblOpa = QtGui.QLabel(self)
        self.lblOpa.setFont(QtGui.QFont('Decorative', 16))
        self.lblOpa.setText("X")
        self.lblOpa.move(40, 80)


        self.x = random.randint(11, 99)
        self.y = random.randint(11, 99)
        self.lblX = QtGui.QLabel(self)
        self.lblY = QtGui.QLabel(self)
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
        self.lblX.move(160, 40)
        self.lblY.move(160, 60)
        self.lblOp = QtGui.QLabel(self)
        self.lblOp.setText("X")
        self.lblOp.move(120, 60)
       
       
        self.lbl = QtGui.QLabel(self)
        self.lbl.move(60, 40)
        self.lbl.setHidden(True)

        self.lblScore = QtGui.QLabel(self)
        self.lblScore.setText("Score:")
        self.lblScore.move(10, 10)

        self.lblMsg = QtGui.QLabel(self)
        self.lblMsg.setText("Your first game")
        self.lblMsg.move(10, 255)

        self.lblScore.setFont(QtGui.QFont('Times New Roman', 12))
        self.lblMsg.setFont(QtGui.QFont('Times New Roman', 12))
       
       
        self.qleA = QtGui.QLineEdit(self)
        self.qleA.setFont(QtGui.QFont('Decorative', 20))
        self.qleA.setMaxLength(4)

        self.qleA.move(165, 90)
        self.qleA.resize(80, 30)

        self.qleB = QtGui.QLineEdit(self)
        self.qleB.setFont(QtGui.QFont('Decorative', 20))
        self.qleB.setMaxLength(3)
       
        self.qleB.move(165, 125)
        self.qleB.resize(60, 30)

        self.qleC = QtGui.QLineEdit(self)
        self.qleC.setFont(QtGui.QFont('Decorative', 20))
        self.qleC.setMaxLength(4)
       
        self.qleC.move(165, 170)
        self.qleC.resize(80, 30)

        if self.isSimple(self.xa, self.ya):
            self.redrawSimpleSubTable()
        else:
            self.redrawSubTable()
           
        if self.isSimple(self.x, self.y):
            self.redrawSimpleTable()
        else:
            self.redrawTable()
           
        self.btnExit = QtGui.QPushButton('Exit', self)
        self.btnExit.move(310, 60)
        self.btnExit.clicked.connect(self.doExit)
        self.btnExit.setEnabled(False)    

        self.btnMore = QtGui.QPushButton('More', self)
        self.btnMore.move(310, 120)
        self.btnMore.clicked.connect(self.moreGame)
        self.btnMore.setEnabled(False)  

        self.btnConfirm = QtGui.QPushButton('Ok', self)
        self.btnConfirm.move(310, 180)
        self.btnConfirm.clicked.connect(self.scoreGame)

        self.btnExit.setFont(QtGui.QFont('Arial', 12))
        self.btnMore.setFont(QtGui.QFont('Arial', 12))
        self.btnConfirm.setFont(QtGui.QFont('Arial', 12))


        self.qleA.textChanged[str].connect(self.onChanged)
       
        self.setGeometry(300, 300, 420, 280)
        self.setWindowTitle('Training Tool for Easy Multiplication')
        self.show()


    def moreGame(self):  
        self.update(self.rect)
          
        self.xa = random.randint(11, 99)
        self.ya = random.randint(11, 99)
        self.lblXA.setText(str(self.xa))
        self.lblYA.setText(str(self.ya))
       
        self.x = random.randint(11, 99)
        self.y = random.randint(11, 99)
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
       
        self.qleA.setText("")
        self.qleB.setText("")
        self.qleC.setText("")
       
        if self.isSimple(self.xa, self.ya):
            self.redrawSimpleSubTable()
        else:
            self.redrawSubTable()
           
        if self.isSimple(self.x, self.y):
            self.redrawSimpleTable()
        else:
            self.redrawTable()

        self.show()
        self.qleA.setFocus(True)    # See: http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html
        self.btnMore.setEnabled(False)  
        self.btnConfirm.setEnabled(True) 

        if self.ngame == 1:
            self.lblMsg.setText("Your first game")
        elif self.ngame == 2:
            self.lblMsg.setText("Your second game")
        elif self.ngame == 3:
            self.lblMsg.setText("Your third game")
        elif self.ngame == 4:
            self.lblMsg.setText("Your fourth game")
        elif self.ngame == 5:
            self.lblMsg.setText("Your fFifh game")
        else:
            self.lblMsg.setText("Your %d-th game" % self.ngame)
        self.lblMsg.adjustSize()


    def scoreGame(self):
        c = int(self.qleC.text())
       
        if self.isSimple(self.x, self.y):
            if c == self.x*self.y:
                 self.npoint += 1
                 self.lblMsg.setText("Right!")
                 if self.npoint == 5 and self.npoint == self.ngame:
                     self.lblMsg.setText("Congratulation!!")
                 self.lblMsg.adjustSize()
            else:
                s3 = "%d -> %d" % (c,  self.x*self.y)
                self.lblMsg.setText("Wrong! (%s)" % s3)
                self.lblMsg.adjustSize()
        else:
            a = int(self.qleA.text())
            b = int(self.qleB.text())
            if a == int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10) and \
                         b == int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10) and \
                         c == self.x*self.y:
                 self.npoint += 1
                 self.lblMsg.setText("Right!")
                 if self.npoint == 5 and self.npoint == self.ngame:
                     self.lblMsg.setText("Congratulation!!")
                 self.lblMsg.adjustSize()
            else:
                s1 = ""
                if a != int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10):
                    s1 = "%d -> %d" % (a,  int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10))
                s2 = ""
                if b !=int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10):
                    if len(s1) > 0:
                        s2 = ", "
                    s2 += "%d -> %d" % (b, int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10))
                s3 = ""
                if c != self.x*self.y:
                    if len(s2) > 0:
                        s3 = ", "
                    s3 += "%d -> %d" % (c,  self.x*self.y)
                self.lblMsg.setText("Wrong! (%s%s%s)" % (s1, s2, s3))
                self.lblMsg.adjustSize()
       
        self.lblScore.setText("Your current score is %d in %d tries," % (20*self.npoint, self.ngame))
        self.lblScore.adjustSize()

        self.ngame += 1

        if self.ngame <= 5:
            self.btnMore.setEnabled(True)   
            self.btnMore.setFocus(True)    
        else:
            self.btnExit.setEnabled(True)  
            self.btnExit.setFocus(True)  
            self.btnMore.setEnabled(False)    
        self.btnConfirm.setEnabled(False)   


    def isSimple(self, x, y):
        if int(x/10) == int(y/10) or x % 10 == y % 10    \
                    or int(x/10) == x % 10 or int(y/10) == y % 10:
            return True
        else:
            return False


    def redrawSimpleSubTable(self):
        self.lblAA.setHidden(True)
        self.lblBA.setHidden(True)
        ca = int(self.xa) * int(self.ya)
        if len(str(ca)) == 3:
            self.lblCA.setText(str(ca))
            self.lblCA.move(72, 109)
            self.lblCA.adjustSize()
        else:
            self.lblCA.setText(str(ca))
            self.lblCA.move(60, 109)
            self.lblCA.adjustSize()


    def redrawSimpleTable(self):
        self.qleA.setHidden(True)
        self.qleB.setHidden(True)
        c = int(self.x) * int(self.y)
        if len(str(c)) == 3:
            self.qleC.setMaxLength(3)
            self.qleC.move(213, 110)
            self.qleC.resize(60, 30)
        else:
            self.qleC.setMaxLength(4)
            self.qleC.move(195, 110)
            self.qleC.resize(80, 30)


    def redrawSubTable(self):
        self.lblAA.setHidden(False)
        self.lblBA.setHidden(False)
        aa = int(self.xa/10) * int(self.ya / 10) * 100 + (self.xa % 10) * (self.ya % 10)
        if len(str(aa)) == 3:
            self.lblAA.setText(str(aa))
            self.lblAA.move(72, 109)
            self.lblAA.adjustSize()
        else:
            self.lblAA.setText(str(aa))
            self.lblAA.move(60, 109)
            self.lblAA.adjustSize()

        ba = int(self.xa % 10) * int(self.ya / 10) +  int(self.xa / 10) * int(self.ya %10)
        if len(str(ba)) == 1:
             self.lblBA.setText(str(ba))
             self.lblBA.move(84, 133)
             self.lblBA.adjustSize()
        elif len(str(ba)) == 2:
             self.lblBA.setText(str(ba))
             self.lblBA.move(72, 133)
             self.lblBA.adjustSize()
        else:
             self.lblBA.setText(str(ba))
             self.lblBA.move(60, 133)
             self.lblBA.adjustSize()

        ca = int(self.xa) * int(self.ya)
        if len(str(ca)) == 3:
             self.lblCA.setText(str(ca))
             self.lblCA.move(72, 164)
             self.lblCA.adjustSize()
        else:
             self.lblCA.setText(str(ca))
             self.lblCA.move(60, 164)
             self.lblCA.adjustSize()


    def redrawTable(self):
        self.qleA.setHidden(False)
        self.qleB.setHidden(False)
        a = int(self.x/10) * int(self.y / 10)
        if len(str(a)) == 1:
            self.qleA.setMaxLength(3)
            self.qleA.move(213, 110)
            self.qleA.resize(60, 30)
        else:
            self.qleA.setMaxLength(4)
            self.qleA.move(195, 110)
            self.qleA.resize(80, 30)

        b = int(self.x % 10) * int(self.y / 10) +  int(self.x / 10) * int(self.y %10)
        if len(str(b)) == 1:
             self.qleB.setMaxLength(1)
             self.qleB.move(235, 145)
             self.qleB.resize(20, 30)
        elif len(str(b)) == 2:
             self.qleB.setMaxLength(2)
             self.qleB.move(213, 145)
             self.qleB.resize(40, 30)
        else:
             self.qleB.setMaxLength(3)
             self.qleB.move(195, 145)
             self.qleB.resize(60, 30)

        c = int(self.x) * int(self.y)
        if len(str(c)) == 3:
            self.qleC.setMaxLength(3)
            self.qleC.move(213, 190)
            self.qleC.resize(60, 30)
        else:
            self.qleC.setMaxLength(4)
            self.qleC.move(195, 190)
            self.qleC.resize(80, 30)


    def paintEvent(self, e):
        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()
       
    def drawLines(self, qp):
        penA = QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.SolidLine)
        qp.setPen(penA)
        if self.isSimple(self.xa, self.ya):
            qp.drawLine(37, 103, 107, 103)
        else:
            qp.drawLine(37, 103, 107, 103)
            qp.drawLine(37, 156, 107, 156)
       
        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
        qp.setPen(pen)
        if int(self.x/10) == int(self.y/10) or self.x % 10 == self.y % 10    \
                    or int(self.x/10) == self.x % 10 or int(self.y/10) == self.y % 10:
            qp.drawLine(170, 100, 270, 100)
        else:
            qp.drawLine(170, 100, 270, 100)
            qp.drawLine(170, 185, 270, 185)

        qp.setFont(QtGui.QFont('Decorative', 20))
        self.lblX.setFont(QtGui.QFont('Decorative', 20))
        self.lblY.setFont(QtGui.QFont('Decorative', 20))
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
        self.lblX.move(230, 40)
        self.lblX.adjustSize()
        self.lblY.move(230, 70)
        self.lblY.adjustSize()
        self.lblOp.setFont(QtGui.QFont('Decorative', 20))
        self.lblOp.move(170, 70)
        self.lblOp.adjustSize()

 

    def onChanged(self, text):

        self.lbl.setText(text)
        self.lbl.adjustSize()       
       
    def doExit(self):
        sys.exit(0)


def main():
        app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

 

실행 중인 창:

 

 

 

Posted by Scripter

댓글을 달아 주세요

* PyQt 내려받기: http://www.riverbankcomputing.co.uk/software/pyqt/download

 (Qt Designer 의실행 파일은 %Python27_HOME%\Lib\site-packages\PyQt4\Designer.exe 이다.)

Qt Designer 는 Visual Studio 의 Visual Basic 개발 환경과 비슷한 Python GUI 개발 도구이다.

다음은 책  Hello World! Second Edition: Computer Programming for Kids and Other Beginners 의 제 20 장에 소개되어 있는 예제를 한국어로 번안한 것이다.

 

Qt Designer 를 실행하여 다음과 같이 "새 폼" 창에서 "Main Window" 를 선택하고 "생성" 버튼을 클릭한다.

 

 

 위젯

  텍스트

 objectName

 Push Button

 Celsius to Fahrenheit >>>

 btn_CtoF

 Push Button

 <<< Fahrenheit to Celsius

 btn_FtoC

 Label

 Celsius

 

 Label

 Fahrenheit

 

 Line Edit

 

 editCel

 Spin Box

 

 spinFahr

* 주의: 폰트 설정 시 한글명 폰트(예: 바탕)를 선택하면 에러가 난다. 

 

위와 같이 디자인된 폼을 파일명 tempconv.ui 으로 저장한다.

 

소스 파일 tempconv.py 의 내용

# -*- encoding: utf-8 -*-

# PyQt 를 이용하는 온도 변환 프로그램

import sys
from PyQt4 import QtCore, QtGui, uic

form_class = uic.loadUiType("tempconv.ui")[0]                 # UI 탑재

class MyWindowClass(QtGui.QMainWindow, form_class):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.btn_CtoF.clicked.connect(self.btn_CtoF_clicked)  # 버튼에 이벤트 핸들러를
        self.btn_FtoC.clicked.connect(self.btn_FtoC_clicked)  #   묶는다.

    def btn_CtoF_clicked(self):                # CtoF 버튼의 이벤트 핸들러
        cel = float(self.editCel.text())         #
        fahr = cel * 9 / 5.0 + 32                 #
        self.spinFahr.setValue(int(fahr + 0.5))  #

    def btn_FtoC_clicked(self):                  # FtoC 버튼의 이벤트 핸들러
        fahr = self.spinFahr.value()             #
        cel = (fahr - 32) / 9.0 * 5
        self.editCel.setText(str(cel))           #

app = QtGui.QApplication(sys.argv)
myWindow = MyWindowClass(None)
myWindow.show()
app.exec_()

 

버튼에 이벤트 핸들러를 묶어 주는 구문은

                  버튼명.clicked.connect(메소드명) 

이다.

 

실행하기:

프롬프트> python convtemp.py

 

 

Posted by Scripter

댓글을 달아 주세요

EditPlus3 의 메뉴에서

   도구(T) -----> 기본 설정(P) ...

을 택하고 기본 설정 창에서 아래와 같이 "사용자 도구" 항목을 지정한다.

 

 

 Python3 용 소스 파일 helloPython3.py 를 아래 처럼 작성하고 저장한 후 Ctrl+1 (숫지 1) 키를 누른다. (파일 저장시에는 BOM 없는 UTF-8 인코딩으로 지정한다.)

 

 

Posted by Scripter

댓글을 달아 주세요

ncurses(또는 curses) 는 Linux/Unix 계열의 환경에서 VT100 등의 터미널과 호환되는 윈도우형 입출력 라이브러이다. 이를 이용하면 윈도우의 임의의 위치에 출력도 하고, 임의의 위치에서 입력을 받을 수도 있다.

* 카라슈바 곱셈 참조

다음은 Linux 나 Cygwin 환경에서 파이썬 2.7.x 로 실행되도록 작성된 소스이다.

 

# Filename: ezMult_003.py
#
#  Execute: python ezMult_003.py
#
#     Date: 2014. 1. 10.

import curses
import curses.textpad
import random


stdscr = curses.initscr()
curses.start_color()   #
curses.nonl()
curses.noecho()
curses.cbreak()
stdscr.keypad(1)

# Initialize few color pairs
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_GREEN)
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_GREEN)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_GREEN)
curses.init_pair(4, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
curses.init_pair(5, curses.COLOR_CYAN, curses.COLOR_BLACK)
curses.init_pair(6, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_WHITE)

x0 = int(random.random()*90) + 10
y0 = int(random.random()*90) + 10
z0 = x0*y0
s01 = int(x0/10)*int(y0/10)
s02 = (x0%10)*(y0%10)
t0 = int(x0/10)*(y0%10) + (x0%10)*int(y0/10)

stdscr.addstr(3, 4, "%4d" % x0)
stdscr.addstr(4, 3, "x%4d" % y0)
stdscr.addstr(5, 3, "-----")
stdscr.addstr(6, 4, "%2d%02d" % (s01, s02))
stdscr.addstr(7, 4, "%3d" % t0)
stdscr.addstr(8, 3, "-----")
stdscr.addstr(9, 4, "%4d" % z0)

x = int(random.random()*90) + 10
y = int(random.random()*90) + 10
z = x*y
s1 = int(x/10)*int(y/10)
s2 = (x%10)*(y%10)
t = int(x/10)*(y%10) + (x%10)*int(y/10)

o1 = 0
o2 = 0
o3 = 0
if s1 < 10:
    o1 = 1
if t < 100:
    o2 = 1
if z < 1000:
    o3 = 1

stdscr.addstr(3, 14, "%4d" % x)
stdscr.addstr(4, 13, "x%4d" % y)
stdscr.addstr(5, 13, "-----")
stdscr.addstr(8, 13, "-----")
stdscr.move(6, 14)
stdscr.refresh()

curses.nl()
curses.noecho()

win4 = curses.newwin(14, 48, 3, 28)
win5 = curses.newwin(2, 78, 21, 0)
   
win4.addstr(0, 0, "Ctrl-A Go to left edge of edit box.")
win4.addstr(1, 0, "Ctrl-B Cursor left.")
win4.addstr(2, 0, "Ctrl-D Delete character under cursor.")
win4.addstr(3, 0, "Ctrl-E Go to right edge of edit box.")
win4.addstr(4, 0, "Ctrl-F Cursor right.")
win4.addstr(5, 0, "Ctrl-G Terminate, returning the box's contents.")
win4.addstr(6, 0, "Ctrl-H Delete character backward.")
win4.addstr(7, 0, "Ctrl-J Terminate if the edit box is 1 line.")
win4.addstr(8, 0, "Ctrl-K Clear to end of line.")
win4.addstr(9, 0, "Ctrl-L Refresh screen.")

win4.refresh()
# win4.getch()

win1 = curses.newwin(1, 5, 6, 14)   # (h,w,y,x)
win2 = curses.newwin(1, 4, 7, 14)   # (h,w,y,x)
win3 = curses.newwin(1, 5, 9, 14)   # (h,w,y,x)
win1.bkgd(curses.color_pair(1))
win2.bkgd(curses.color_pair(1))
win3.bkgd(curses.color_pair(1))
win1.refresh()
win2.refresh()
win3.refresh()
win1.move(0,0)

box1 = curses.textpad.Textbox(win1, insert_mode=True)
box2 = curses.textpad.Textbox(win2, insert_mode=True)
box3 = curses.textpad.Textbox(win3, insert_mode=True)
a1 = box1.edit()
win2.move(0,0)
a2 = box2.edit()
win3.move(0,0)
a3 = box3.edit()

stdscr.move(15, 0)
stdscr.attron(curses.color_pair(6))

try:
    tmp1 = int(a1)
    tmp2 = int(a2)
    tmp3 = int(a3)
    stdscr.addstr(15, 0, "Your answers are")
    stdscr.addstr(16, 0, "            %4d"% int(a1))
    stdscr.addstr(17, 0, "            %3d"% int(a2))
    stdscr.addstr(18, 0, "            %4d"% int(a3))

    stdscr.addstr(15, 20, "Right answers are")
    stdscr.addstr(16, 20, "             %2d%02d"% (s1, s2))
    stdscr.addstr(17, 20, "             %3d"% t)
    stdscr.addstr(18, 20, "             %4d"% z)

    if int(a1) == s1*100 + s2 and int(a2) == t and int(a3) == z:
     stdscr.addstr(20, 0, "Yours are right... ")
    else:
     stdscr.addstr(20, 0, "Yours are wrong... ")

    stdscr.getch()
except:
    stdscr.addstr(15, 0, "Some invalid charactres are found... ")
    stdscr.refresh()
    stdscr.getch()
finally:
    curses.nl()
    curses.nocbreak(); stdscr.keypad(0); curses.echo()
    curses.endwin()

 

Textbox 에서 입력 받을 스트링의 길이가 4인 경우 너비를 4+1 로 잡아야 하므로 배경색(녹색0의 너비가 4+1 로 나오는 것은 어쩔 수 없다. 한 Textbox 에서 입력을 마친 후 다음 Textbox 로 가려면 Enter Ctrl+G, Ctrl+J 키중 하나를 누르면 된다. Ctrl+D 는 커서가 놓인 곳의 글자를 지우는 키이고, Ctrl+H 는 커서 좌측의 글자를 지우면서 좌특으로 커서를 이동하는 키 (즉, Bacpspace 아 같은 역하를 하는 키이다.) Backspace 키는 Textbox 에서 동작하지 않는다. Ctrl+B 또는 키패드의 좌즉 화살표 키는 Textbox 안에서 좌측으로 한 칸씩 이동하는 키이고, Ctrl+F 또는 키패드의 우측 화살표 키는 Textbox 안에서 우측으로 한 칸씩 이동하는 키이다. 커서가 어느 Textbox 를 벗어나면 그 textbox 로는 다시 돌아갈 수 없다. 또 한 Textbox 의 우측 끝에 커서가 위치하면 글자 입력이 되지 않는다.

 

* 실행 결과:

 

 

 

Posted by Scripter

댓글을 달아 주세요

 

Python 언어 소스:

# Filename: testHexView_03.py
#
# Execute: python testHexView_03.py [filename]
# Execute: ipy testHexView_03.py [filename]

import os
import sys

def toHex(b):
    s = ""
    x1 = (b & 0xF0) >> 4
    x2 = b & 0x0F
    if x1 < 10:
        s += chr(x1 + ord('0'[0]))
    else:
     s += chr((x1 - 10) + ord('A'))
    if x2 < 10:
        s += chr(x2 + ord('0'))
    else:
        s += chr((x2 - 10) + ord('A'))
    return s

def toHex8(n):
    s = ""
    x1 = (n & 0xF0000000) >> 28
    x2 = (n & 0xF000000) >> 24
    x3 = (n & 0xF00000) >> 20
    x4 = (n & 0xF0000) >> 16
    x5 = (n & 0xF000) >> 12
    x6 = (n & 0xF0) >> 8
    x7 = (n & 0xF0) >> 4
    x8 = n & 0x0F
    if x1 < 10:
        s += chr(x1 + ord('0'))
    else:
        s += chr((x1 - 10) + ord('A'))
    if x2 < 10:
        s += chr(x2 + ord('0'))
    else:
        s += chr((x2 - 10) + ord('A'))
    if x3 < 10:
        s += chr(x3 + ord('0'))
    else:
        s += chr((x3 - 10) + ord('A'))
    if x4 < 10:
        s += chr(x4 + ord('0'))
    else:
        s += chr((x4 - 10) + ord('A'))
    s += " "
    if x5 < 10:
        s += chr(x5 + ord('0'))
    else:
        s += chr((x5 - 10) + ord('A'))
    if x6 < 10:
        s += chr(x6 + ord('0'))
    else:
        s += chr((x6 - 10) + ord('A'))
    if x7 < 10:
        s += chr(x7 + ord('0'))
    else:
        s += chr((x7 - 10) + ord('A'))
    if x8 < 10:
        s += chr(x8 + ord('0'))
    else:
        s += chr((x8 - 10) + ord('A'))
  
    return s

 

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "Usage: python testHexView_03.py [filename]"
        sys.exit(1)

    fname = sys.argv[1]

    if not os.path.exists(fname):
        print "The file '%s' does not exist.\n" % fname
        sys.exit(1)
    elif os.path.isdir(fname):
        print "%s is a directory.\n" % fname
        sys.exit(1)

    fsize = os.path.getsize(fname)

    if fsize != None:
        print "The size of the file \"%s\" is %d." % (fname, fsize)
        if fsize == 0:
            sys.exit(1)
    print

    try:
        file2 = open(fname, "rb")
        n = 0
        dum = ""
        for i in range(fsize):
            if n % 16 == 0:
                sys.stdout.write("%s: " % toHex8(n & 0xFFFFFFFF))
             
            if n % 16 != 8:
                sys.stdout.write(" ")
            else:
                sys.stdout.write("-")

            a = file2.read(1)
            sys.stdout.write("%s" % toHex(int(ord(a))))
               
            if int(ord(a)) < int(ord(' ')) or int(ord(a)) & 0x80 != 0:
                dum += "."
            else:
                dum += a
               
            if n > 0 and n % 16 == 15:
                sys.stdout.write("  |%s|\n" % dum)
                dum = ""

            n += 1

        if n > 0 and n % 16 > 0:
            for i in range(16 - (fsize % 16)):
                sys.stdout.write("   ")
            sys.stdout.write("  |%s" %dum)
            for i in range(16 - (fsize % 16)):
                sys.stdout.write(" ")
            sys.stdout.write("|\n")
            dum = ""
    except IOError: 
        print "Error: the file \"%s\" cannot be read more." % fname
    finally:
        file2.close()
        print
        print "Read %d bytes\n" % n

 

 

예 1
Python으로 실행하기> python testHexView_03.py temp_1.bin
IronPython으로 실행하기> ipy testHexView_03.py temp_1.bin
Jython으로 실행하기> jython testHexView_03.py temp_1.bin
The size of the file "temp_1.bin" is 12.

0000 0000:  48 65 6C 6C 6F 20 74 68-65 72 65 0A              |Hello there.    |

Read 12 bytes

 

예 2
Python으로 실행하기> python testHexView_03.py myFile.ser
IronPython으로 실행하기> ipy testHexView_03.py myFile.ser
Jython으로 실행하기> jython testHexView_03.py myFile.ser
The size of the file "myFile.ser" is 130.

0000 0000:  AC ED 00 05 73 72 00 06-50 65 72 73 6F 6E 07 31  |....sr..Person.1|
0000 0010:  46 DB A5 1D 44 AB 02 00-03 49 00 03 61 67 65 4C  |F...D....I..ageL|
0000 0020:  00 09 66 69 72 73 74 4E-61 6D 65 74 00 12 4C 6A  |..firstNamet..Lj|
0000 0030:  61 76 61 2F 6C 61 6E 67-2F 53 74 72 69 6E 67 3B  |ava/lang/String;|
0000 0040:  4C 00 08 6C 61 73 74 4E-61 6D 65 71 00 7E 00 01  |L..lastNameq.~..|
0000 0050:  78 70 00 00 00 13 74 00-05 4A 61 6D 65 73 74 00  |xp....t..Jamest.|
0000 0060:  04 52 79 61 6E 73 71 00-7E 00 00 00 00 00 1E 74  |.Ryansq.~......t|
0000 0070:  00 07 4F 62 69 2D 77 61-6E 74 00 06 4B 65 6E 6F  |..Obi-want..Keno|
0000 0080:  62 69                                            |bi              |

Read 130 bytes

 

 

 

Posted by Scripter

댓글을 달아 주세요