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

2019년 4월 14일 일요일

[공부]python의 decorator

https://jupiny.com/2016/09/25/decorator-function/

어떤 함수가 있다.
def plus(a, b):
    return a + b

if __name__ == '__main__':
    plus(1, 2)

그 함수가 일어날 때 마다 어떤 동작 (소요시간 체크, 결과값 확인)이 일어나게 하고 싶다.
def plus(a, b):
    return a + b

import time
def tictoc(func, a, b):
    start_t = time.time()
    ret = func(a, b)
    end_t = time.time()

    print(end_t - start_t)  # 소요시간
    print(ret)                 # 결과값
    return ret

if __name__ == '__main__':
    # plus(1, 2)    tictoc(plus, 1, 2)

tictoc함수에 함수 plus를 인자로 넣어줌으로써 해결하였지만, 문제점이 있다.
함수의 인자가 늘어나면 또 새로운 tictoc함수를 만들어줘야 한다. 

decorator를 사용하면 더 간단하게 해결가능하다.

import time
def tictoc_decorator(func):
    def wrapper(*args, **kwargs):
        start_t = time.time()
        ret = func(*args, **kwargs)
        end_t = time.time()

        print(end_t - start_t)
        print(ret)
        return ret
    return wrapper
@tictoc_decorator
def plus(a, b):
    return a + b

if __name__ == '__main__':
    plus(1, 2)

    help(plus)

그런데 이런 함수형 decorator는 지저분하기에 class형 decorator를 쓰는 것이 더 깔끔하다

class tictoc():
def __init__(self, func):
self.func = func

def __call__(self, *args, **kwargs):
start_t = time.time()
ret = self.func(*args, **kwargs)
end_t = time.time()

print(end_t - start_t)
print(ret)

return ret

   


2018년 11월 20일 화요일

[공부]python에서 class 상속

<참고: http://schoolofweb.net/blog/posts/%ED%8C%8C%EC%9D%B4%EC%8D%AC-oop-part-5-%EC%83%81%EC%86%8D%EA%B3%BC-%EC%84%9C%EB%B8%8C-%ED%81%B4%EB%9E%98%EC%8A%A4inheritance-and-subclass>

class와 inherit(상속)은 Dont' Repeat Yourself (불필요하게 같은 코드를 반복하는 것을 막자) 가 목적.

목적: 기본 클래스(예: Fruit)와 그 서브클래스(예: Apple, Banana)가 있는 경우는 기본 클래스(공통 속성)-서브클래스(개별 속성)로 가는 것이 유지/관리측면에서 좋음.

Fruit과 Apple을 만듬.
class Fruit(object):
    def __init__(self, color):
        self.name = self.__class__.__name__        self.color = color

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))

class Apple(Fruit):
    pass
if __name__ == '__main__':
    apple_1 = Apple('green')
    apple_1.show_status()
    help(Apple)
 # class Apple에서 __init__찾음. 없으니 부모 class인 Fruit에서 __init__찾아서 실행.
name: Apple
color: green

class Apple의 초기화 함수에 Size를 추가해보자.
바보같은 사용법
class Fruit(object):
    def __init__(self, color):
        self.name = self.__class__.__name__        self.color = color

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))

class Apple(Fruit):
    def __init__(self, color, size):
        self.name = self.__class__.__name__        self.color = color
        self.size = size

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))
        print('size: {}'.format(self.size))

if __name__ == '__main__':
    apple_1 = Apple('green', 30)
    apple_1.show_status()
    help(Apple)
목적은 달성했으나, Fruit에 있는 코드들(name, color)이 반복됨. 

멍청한 사용법
class Fruit(object):
    def __init__(self, color):
        self.name = self.__class__.__name__        self.color = color

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))

class Apple(Fruit):
    def __init__(self, color, size):
        Fruit.name = self.__class__.__name__        Fruit.color = color
        self.size = size

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))
        print('size: {}'.format(self.size))

if __name__ == '__main__':
    apple_1 = Apple('green', 30)
    apple_1.show_status()
    help(Apple)

    apple_2 = Apple('red', 10)
    apple_2.show_status()

    apple_1.show_status()
class의 instance가 아닌 class에 값을 대입함.
apple_1의 값 변경은 apple_2의 값도 바뀜. --> 의도하지 않은 결과.

이 경우는 super()함수를 이용하여 부모 클래스의 도움을 받아야 함.

올바른 사용법
class Fruit(object):
    def __init__(self, color):
        self.name = self.__class__.__name__        self.color = color

    def show_status(self):
        print('name: {}'.format(self.name))
        print('color: {}'.format(self.color))

class Apple(Fruit):
    def __init__(self, color, size):
        super(Apple, self).__init__(color)
        self.size = size

    def show_status(self):
        super(Apple, self).show_status()
        print('size: {}'.format(self.size))

if __name__ == '__main__':
    apple_1 = Apple('green', 30)
    apple_1.show_status()
    help(Apple)

위와 같이 사용하면 중복된 코드를 방지할 수 있다.

help(Apple) # Apple class가 이름을 찾는 순서를 보여줌(자기 클래스 namespace, 부모 클래스 namespace, 내장 object namespace).


2018년 11월 19일 월요일

python에서 Enum의 사용

<참고: https://docs.python.org/3/library/enum.html>

from enum import Enum

class Color(Enum):
  RED = 1
  GREEN = 2
  BLUE = 3

Color = Enum('Color', 'RED GREEN BLUE')

위 두가지 타입의 선언법은 동일함.

Enum 라이브러리(모듈)는 심볼릭 멤버에 unique하고 constant인 상수를 부여하여 관리하고, 추가적인 함수를 제공함.
- iteration: for color in Color로 사용가능.
- 비교가능: Color.RED is Color.BLUE -> False 나옴. (is, == 모두 가능)
- 크기비교 불가능

2018년 8월 28일 화요일

python delete variable and free memory

문제: python에서 명시적으로 변수와 그 메모리를 지우자.

답:
python은 기본적으로 garbage collector(gc)를 써서 사용자가 메모리 걱정없이 쓰게 해줌.
그럼에서 위의 것을 명시적으로 하고 싶다면...

del var
# var변수를 지움(그러나 메모리가 지워지지는 않을 수 있음, del은 reference count를 줄이는 일반하고 이게 0이 되어야 release되는 듯)

import gc
if gc.isenabled() is True:
    gc.collect()
# gc를 명시적으로 호출함. 그럼에도 os상황이나 thread상황에 따라 안되는 경우가 있다고 함.




2018년 3월 5일 월요일

python에서 현재시간으로 string만들기

<참조: https://stackoverflow.com/questions/3316882/how-do-i-get-a-string-format-of-the-current-date-time-in-python>

from datetime import datetime

def get_curtime_as_string():
    timestamp = '%d_%d_%d_%d_%d_%d_%d' % (
        datetime.now().year, 
        datetime.now().month, 
        datetime.now().day,
        datetime.now().hour,
        datetime.now().minute,
        datetime.now().second, 
        datetime.now().microsecond
    )
    
    return timestamp

2017년 11월 26일 일요일

python, read txt line-by-line

list = open(FILENAME).read().splitlines()

만약 한글이 있어서,
UnicodeDecodeError: 'cp949' codec can't decode byte 0xa7 in position 55: illegal multibyte sequence
이라면, 다음으로 대체

import codecs
list = codecs.open(FILENAME, 'r', 'utf-8').read().splitlines()

그럼에도 아래와 같은 에러가 생긴다면
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position
다음으로 대체

'utf-8' -> 'euc-kr'

2017년 11월 14일 화요일

python의 list의 append vs extend

문제: python에서 list의 append와 extend의 차이는?

해결:
append는 그냥 추가, extend는 까서 알맹이만 추가.

l = []
l.append([1, 1])
l.append([2, 2])

l은 [[1,1], [2,2]] # 그냥 추가함.



l.extend([1, 1])
l.extend([2, 2])

l은 [1, 1, 2, 2] # 까서 알맹이만 추가함.

2017년 10월 16일 월요일

python random에서 seed없이 사용한다면?

문제
python에서 random을 생성하는 모듈 random을 사용시, seed없이 사용한다면 어떻게 되나?

해결
<참조: https://stackoverflow.com/questions/817705/pythons-random-what-happens-if-i-dont-use-seedsomevalue>

import random as rd

rd.seed()를 하면 seed를 current time에서 가져오면서 random을 생성함.
그런데 위 seed()를 호출하지않고 random number를 생성한다면?

참조에 따르면 random module이 import시에 current time으로 generator를 초기화한다고 함. 즉, seed()를 안불러도 자동으로 부름.

2017년 9월 27일 수요일

[펌]선택한 GPU에만 메모리할당하기

문제: GPU가 여러 개 인경우, 코드가 특정 GPU만 활용하도록 하는 방법

해결:
<참조: http://dongjinlee.tistory.com/73>
참조: https://stackoverflow.com/questions/37893755/tensorflow-set-cuda-visible-devices-within-jupyter)

memory fragmentation으로 기본적으로 모든 GPU를 활용함.
이를 해결하기위해서는 해당코드는 원하는 GPU만 보이게 한다.

즉, terminal에서는 코드 앞에 CUDA_VISIBLE_DEVICE=GPUID를 붙여주고,
python code에서는 다음과 같이 한다.
import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="0"






2017년 9월 20일 수요일

python으로 list를 line-by-line으로 read와 write하자.

문제:
python으로 list를 line-by-line으로 read와 write하자.

해결:
def read_list_linebyline(fname):
    with open(fname) as fid:
        content = fid.readlines()
    content = [item.rstrip('\n') for item in content]

    return content


def write_list_linebyline(fname, thelist):
    fid = open(fname, 'w')

    for item in thelist:
        fid.write('%s\n' % (item))

    fid.close()



2017년 5월 30일 화요일

python에서 matlab을 사용하기

문제
python에서 matlab을 사용하자

해결
1. python에서 matlab 모듈을 읽을 수 있도록 설치 - import matlab이 가능하게 됨.
cd "matlabroot/extern/engines/python"
python setup.py install
<참고: http://kr.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html>

2. matlab엔진 모듈을 불러와서 사용함

# matlab 모듈가져오기
import matlab.engine

# 엔진 시작
eng = matlab.engine.start_matlab()

3. 변수 읽고 쓰기
# python에서 숫자 3을 matlab workspace에 넣고 연산하기
eng.workspace['var'] = 3
a = eng.eval('var + 4')
print(a)
주의: 이때 python에서 var에 matrix형태의 숫자를 대입한 경우는 matlab에서는 cell형태(정수라면 int64로 double과 계산이 안됨)로 들어가기에 적절한 변환이 필요하다.
변환의 예: double(cell2mat(var_fromPy)) in matlab

또한 python에서 matlab의 workspace 변수를 가져온 경우에도 matlab.double type이기에 변환이 필요하다
변환의 예:
var_py = np.array(eng.workspace['var']._data.tolist())
scalar인 경우는 _data.tolist()필요없음.

4. script 및 function call하기
user defined script/function의 경우는
eng.addpath('path', nargout=0)으로 경로 추가 후,
eng.script_name('nargout=0') 로 스크립트를 실행시키고
eng.func(a, b)로 함수를 실행시키면 됨.
스크립트를 실행시키면 생성된 변수들은 eng.workspace에 다 저장되어 추후에 사용가능.

5. 요약하자면 python에서 matlab을 사용하는 경우는, eng이라는 class instance에 workspace라는 내부 변수를 저장하고 matlab 함수들을 멤버함수로 사용하는 형태.


2017년 3월 13일 월요일

Python module.__init__() takes at most 2 arguments (3 given)

문제:
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

해결:
<참조: http://stackoverflow.com/questions/39246994/module-init-takes-at-most-2-arguments-error-in-python>

상속을 class가 아닌 module로 부터 받으려함.

예를 들어 다음과 같은 경우,
folder: datasets
file: datasets/imdb.py
In imdb.py file:
class imdb(object):
   def __init___~~~

dataset.imdb는 모듈임.
dataset.imdb.imdb가 클래스임.

그렇기에 문제가된 class에 dataset.imdb가 아닌 dataset.imdb.imdb를 넣으면 해결됨.

2017년 1월 5일 목요일

Python, with

문제
with란?

해결
block에 진입 및 탈출시 객체 A로 하여금 어떤 프로세싱을 동작케함.
<참고: http://soooprmx.com/wp/archives/4079>
<참고: http://effbot.org/zone/python-with-statement.htm>
with A as B:
  pass
A는 블럭 진입시 A.__enter__()를 수행하고 그 결과를 B에 assign.
블럭내 코드를 수행하고, 탈출시(예외상황 포함) A.__exit__()을 호출함.

with open('file', 'w') as f:
  f.write(~~)
진입시 __enter__()를 호출하고(__enter__()는 open()임) 그 결과를 f에 대입.
탈출시 __exit__()인데 이는 close()로 이를 수행함.

2016년 11월 21일 월요일

python from __future__ 의미

<참조: http://stackoverflow.com/questions/7075082/what-is-future-in-python-used-for-and-how-when-to-use-it-and-how-it-works>

문제
python에서 from __future__ import ~~~가 자주 등장하는데 from __future__ 의미가 무엇일까?

해결
현재 interpreter와 호환되지않는 새로운 특징을 사용하고자할 때 사용하는 pseudo-module.
즉, 현재 나와는 있지만, standard가 아닌 특징들 중 사용하고 싶은 경우 추가해야함.

예:
# / 표준은 다음과 같이 계산
11/4 -> 2

# / 중 다음과 같은 방법도 있음. 하지만 표준은 아님.
from __future__import division
11/4 -> 2.75


2016년 10월 24일 월요일

python 에서 mouse click 하여 image 상 영역 선택하는 함수

참조: http://stackoverflow.com/questions/23596511/how-to-save-mouse-position-in-variable-using-opencv-and-python
참조: http://www.pyimagesearch.com/2015/03/09/capturing-mouse-click-events-with-python-and-opencv/

위 두 참조의 코드를 조합하여 만듬.

함수
class MouseControl:
    def __init__(self):
        # self.points = []        self.refPt = []
        self.cropping = False        self.retRect = []

    # def getPoint(self, event, x, y, flags, params):    #     if event == cv2.EVENT_LBUTTONCLK:    #         self.points = [x, y]
    def click_and_crop(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.refPt = [(x, y)]
            self.cropping = True
        elif event == cv2.EVENT_LBUTTONUP:
            self.refPt.append((x, y))
            self.cropping = False
            #   left, top, right, bottom            self.retRect = [mousectrl.refPt[0][1], mousectrl.refPt[0][0], mousectrl.refPt[1][1], mousectrl.refPt[1][0]]
            self.refPt = []

        return self.retRect


실제사용

# if mouse has an input,cv2.namedWindow('img1')
cv2.setMouseCallback('img1', mousectrl.click_and_crop)

# for t in range(2):while(1):
    cv2.imshow('img1', img1)
    k = cv2.waitKey(20) & 0xFF    # print mousectrl.refPt    if k == ord('n'):
        break    if len(mousectrl.retRect) == 4:
        break
mousectrl.retRect[0] << left
mousectrl.retRect[2] << right
mousectrl.retRect[1] << top
mousectrl.retRect[3] << bottom

mousectrl.retRect = []

2016년 10월 13일 목요일

MDB_MAP_FULL: Environment mapsize limit reached 해결방법

MDB_MAP_FULL: Environment mapsize limit reached


lmdb를 더 큰 mmap size로 열어야 함.

참고로 lmdb.open(filename, map_size = ABCD)에서 ABCD는 byte 단위임.
1e10 = 1 x 10^10 = 10GB


<참조: https://github.com/clibs/lmdb/issues/1>

2016년 7월 20일 수요일

python library / module 설치하기 (pip vs apt-get)

python을 실행했는데 No moudle named 'ABC' 이면 ABC라는 라이브러리가 없다는 의미이다.

In linux

리눅스에서는 아래와 같이 하면 된다.
<참조: https://docs.python.org/3.6/installing/index.html>
일반적인 경우,
ctrl + art + t -> terminal open

sudo apt-get install python-pip python-dev

sudo pip install SomePackage
or
sudo apt-get install SomePackage

참고: pip vs apt-get
pip은 PyPI(Pyhon Package index - pyhon module reposiory)로부터 바로 다운로드 및 설치하는 방법, Python Software Foundation이 관리.
apt-get은 Ubunu repository에서 다운로드 및 설치하는 방법. Canonical(?)이 관리.
pip이 apt-get보다 제공하는 모듈이 더 많음.
pip을 이용하면 과거버전도 다운받을 수 있음.
pip을 이용하면 virtualenv에 설치가능. apt-get은 불가능하여 모든 환경에 설치됨.

버전 제한을 두는 경우,
sudo pip install SomePackage==1.0.4    # specific version
sudo pip install "SomePackage>=1.0.4"  # minimum version

업그레이드를 하는 경우,
sudo pip install --upgrade SomePackage

혹시 안되면 sudo 대신 python -m을 써볼 것.

In windows

윈도우에서는 아래와 같이 하면 된다.
<참조: http://stackoverflow.com/questions/1449494/how-do-i-install-python-packages-on-windows>

1. curl을 다운받고 설치한다.
https://curl.haxx.se/download.html (임시)
http://winampplugins.co.uk/curl/ (here)

2. setuptools를 설치한다.(curl이 설치된 폴더에서 해야됨, 혹은 경로설정 후).
curl https://bootstrap.pypa.io/ez_setup.py | python

3. pip를 설치한다.
curl https://bootstrap.pypa.io/get-pip.py | python

4. 리눅스와 같은 방식으로 다운받는다. 혹은 5번 방법을 이용한다.

5. 참고로 windows에서 64bit os의 경우, 지원하지 않는 라이브러리들이 있다. 이 경우, 다음에서 비공식버전을 찾을 수 있다.
<http://www.lfd.uci.edu/~gohlke/pythonlibs/>
5.1. 먼저 위 사이트에서 원하는 lib를 다운받는다(확장자가 whl임).
5.2. 다운받은 파일의 위치로 가서 python -m pip install [파일명.whl]을 입력한다. 그럼 설치가 됨.



2016년 2월 26일 금요일

python exit code 139

caffe를 사용해서 모델을 학습할 때, 중간중간에 snapshot을 찍도록 되어있다.

그런데 snapshot을 찍을 때, Process finished with exit code 139를 띄우며 죽는 경우가 있는데, 이때 snapshot으로 생긴 파일크기는 0.

참고: http://stackoverflow.com/questions/23704040/exit-code-139-when-perfroming-image-subtraction

이 문제의 원인은...
"attempt to access a virtual address which is not in your address space" 이라고 한다.
즉, out of memory.

해결책은...
메모리 사용량을 줄이는 수 밖에 없다.


2016년 2월 16일 화요일

pycaffe로 logging하기

https://github.com/BVLC/caffe/pull/89 참고

1. 러닝시 발생하는 log를 파일로 가도록 redirection.
GLOG_logtostderr=1 ./build/examples/train_net.bin solver.prototxt 2> caffe.log
혹은 python 창에 뜨는 log를 copy & paste하여 파일에 저장함.(caffe.log)
단 이때, 저장되어야 할 log는 'I0217 ~~~'로 시작하는 caffe에서 발생한 log여야함. 다른 print로 발생한 log는 삭제해야됨.

2. 파일을 parsing하여 tr data의 loss와 vl data의 acc로 별도 파일로 만들어 냄.
parse_log.sh caffe.log [init_iter=0] [test_interval=1000]
위의 것을 써도 되고 혹은 python버전을 사용
https://github.com/BVLC/caffe/blob/master/tools/extra/parse_log.py

아님 caffe/tools/extra에 있음.

3. 각 파일을 draw
plot_training_log.py.example을 사용하면 됨.

결론:
1.번을 수행 후, caffe/tools/extra/plot_training_log.py.example을 사용하면 됨.

2015년 12월 23일 수요일

python, PIL과 opencv에서 image read시 RGB순서

cv = [15, 23, 22], [14, 22, 21]...
PIL= [22, 23, 15], [21, 22, 14]...

PIL은 RGB 순으로, cv는 BGR순으로 읽는다.