2020년 9월 23일 수요일

Chardet 문자열 판단하는 패키지

 python을 사용하다보면, 문자열로 고생하는 경우들이 있다. 

 

주로 UTF-8과 cp949 , 하나는 리눅스에서 사용하는 한글이고, 하나는 windows에서 사용하는 한글 포맷인데, 

예를 들면 아래와 같이 사용할 경우 

 

with open('filename.txt','r', encoding='utf-8') as f:
  _s = f.read()

 

위와 같이 사용하는 경우 실제 파일이 cp949인 형태 (또는 반대) 의 경우 Fail을 내면서 

죽어버리는 경우가 있다. 

 

그래서 이때 사용하기 위한 solution이 chardet 패키지 이다. 

이것은 미리 문자열 셋을 판단해주는 패키지 이다. 

 

위의 코드를 아래와 같이 할 경우, utf-8이던 cp949이던 상관없이 read가 가능하게 된다. 

import chardet

rawdata = open(file, "r").read()
result = chardet.detect(rawdata)
charenc = result['encoding']

#with open('filename.txt','r', encoding='utf-8') as f:
with open('filename.txt','r', encoding=charend) as f:
  _s = f.read()
  
  

2020년 2월 12일 수요일

Python f-string (3.6이상), 문자열 보간, 소수점 추가


formatted string을 이용할 때 대략 세가지 정도의 방법이 있습니다.

첫번째가 c-style string format인 %-formatting ,
두번째, string format 이 기존에 제공되었던 방법이라면
세번째, python 3.6 부터는 f-string 이란 것을 제공합니다.

오늘 이야기 드릴 것은 f-string입니다. 이것 정말 편합니다
아래는 예제입니다.

name = "Alice"
score = 0.12345
print (f'Name : {name} / Score : {score:.2%}')
# Name : Alice / Score : 12.35%
a = 2
b = 3
print (f'{a} + {b} = {a+b}')
# 2 + 3 = 5
# 개별값도 출력가능하고 계산값도 출력가능 
# {} 안에는 위와 같이 expression이 들어가도 됨..


이런식으로 inline으로 문자를 치환하는 방식을 string interpolation 이라고도 이야기합니다.
이게 문자열 보간이라고 번역이 되어서, 문자열 보간이라는 용어도 사용합니다.

python에서는 Jinja2, mako 같은 template engine들이 이런 기능을 제공하고 있었는데,
더 간결하게 지원을 합니다.

이것은 어찌보면 간단한 template을 내장한 형태인데, 간결하면서도
굉장히 편리합니다.

C-style인 %-formatting에서는 %2d와 같은 형태로 지원하기때문에  기본적으로 줄맞추기가 굉장히 수월합니다. 이런 부분 역시, {aaa:2d} 와 같은 형태로 :(콜론)을 가지고 자리수를 맞추는 기능도 지원이 됩니다.

f-string은 mustache 를 사용하는 template들과 비슷하기도 합니다
게다가 scope상의 variable들이 인자가 되어서, 따로 변수들을 입력할 필요가 없이 동작합니다.

그 결과 template에 기본적으로 들어가는 if branch 구문이나, for loop 같은 건 없지만,
굉장히 편리하면서도 사용하기 용이합니다.

물론 대규모시스템의 MVC같은 형태로 template과 로직을 분리해서 하는 것과 비교하면
좀 안맞을 수도 있지만, 효율성이 시스템을 압도하는 케이스로 만들어 버린 것 같습니다.

이 기능은 처음엔 낮설지만 사용하다 보면, print관련해서 이것만큼 편리한 기능은 없어 보입니다. python 3.6 이상 사용하시면, 별도 템플릿 엔진을 사용하지 않더라도, 거의 템플릿엔진 수준으로 사용 가능하니,  꼭 활용 하시는 것 추천 드립니다.

아래는 좀더 예제를 보강합니다


정수, 16진수, 2진수 정렬

많이들 사용하는 정수 , 16진수, 2진수에 대한 예제들입니다. 

score1 = 240
print (f'Score (hex) : {score1:x}') # hex 소문자
print (f'Score (hex) : {score1:X}') # hex 대문자
print (f'Score (dec) : {score1:d}') # dec
print (f'Score (bin) : {score1:b}') # binary

print (f'Score (hex) : {score1:4x}') # 4자리 hex : default는 오른쪽 정령
print (f'Score (dec) : {score1:4d}') # 4자리 dec : 빈칸은 놔두고 오른쪽 정렬
print (f'Score (bin) : {score1:12b}')  # 12자리 bin : default는 오른쪽 정렬
print (f'Score (bin) : {score1:<12b}') # 12자리 bin : 왼쪽정렬

print (f'Score (hex) : {score1:04x}') # 4자리 hex : 빈자리는 0으로 채움
print (f'Score (dec) : {score1:04d}') # 4자리 dec : 빈자리는 0으로 채움
print (f'Score (bin) : {score1:012b}') # 12자리 bin : 빈자리는 0으로 채움

결과 : 

Score (hex) : f0
Score (hex) : F0
Score (dec) : 240
Score (bin) : 11110000
Score (hex) :   f0
Score (dec) :  240
Score (bin) :     11110000
Score (bin) : 11110000    
Score (hex) : 00f0
Score (dec) : 0240
Score (bin) : 000011110000

소수점자리 지정 및 자리지정

formatting하는건 string formatter와 비슷합니다.


score1 = 0.12345
score2 = -0.34567
print (f'Score1 : {score1:x%}')
print (f'Score2 : {score1:.3f}')
# Score1 : 12.35%
# Score2 : 0.123


score1 = 24
score2 = 23
print (f'Score1 : {score1:x}')
print (f'Score2 : {score1:x}')
# Score1 : 12.35%
# Score2 : 0.123

자리 정렬 (alignment)

정렬의 경우 아래와 같이 왼쪽, 오른쪽, 가운데 정렬을 합니다. 아래와 같이 직관적입니다.
score1 = 0.12345
print (f'left   : |{score1:<10.2f}|')
print (f'right  : |{score1:>10.2f}|')
print (f'center : |{score1:^10.2f}|')

#left   : |0.12      |
#right  : |      0.12|
#center : |   0.12   |



2020년 2월 4일 화요일

파이썬 삼항 연산자


보통 C나 예전 언어들 보면 Ternary operator라고 삼항 연산자라는게 있다.

형식이 대략 아래와 같은데,
A ? B : C


파이썬에서는 위와 같이 ?(물음표)를 사용하지 않고

B if A else C


와 같은 형태로 guide를 하고 있다.

근데 이건 다른 언어들이랑 다르고 줄세우기 할때 가독성도 떨어지는데,,
아래와 같은 방법으로도 가능하다.

(C,B)[A]

튜플을 이용한 방법인데 참이면 1이므로 B, 거짓이면 0이므로 C를 선택하는 것이다.

그외에  A and B or C와 같이 short circuit구문을 이용하는 방법도 있는데,
이게 기존 다른언어의 삼항연산자들과 순서가 맞긴하다.

다만 이건 판정중에, B의 실제 값이 0인 경우 그 항이 False가 되면서
C가 실행되는 점이 있어서, 추천하지는 않는다.





2020년 1월 28일 화요일

Python itertools product (Catesian product, 카티젼곱, 데카르트 곱)

집합론의 데카르트의 곱이라는 함수가 python에는  itertools안에 product라고 존재한다.

from itertools import product
list_a = ['A','B','C','D']
list_b = ['1','2']
list_result = []
for x in list_a:
  for y in list_b:
    list_result.append((x,y))
print (list_result)
# [('A', '1'), ('A', '2'), ('B', '1'), ('B', '2'), ('C', '1'), ('C', '2'), ('D', '1'), ('D', '2')]

print (list(product(list_a,list_b)))
# [('A', '1'), ('A', '2'), ('B', '1'), ('B', '2'), ('C', '1'), ('C', '2'), ('D', '1'), ('D', '2')]




이건 우리 프로그램을 하다보면 보통 중첩 for문을 돌리는 경우가 있는데,
위와 같이 간단하게 한문장으로 해결되는 경우가 있다.

그것도 수학적 개념과 동일하게 ,

확률론의 순열과도 비슷한 개념이므로
이것 역시 모든 경우의 수를 나열할때 용이하게 사용된다.


2020년 1월 21일 화요일

우분투 tesseract-ocr 설치

OCR 프로그램 중 유명한건
러시아제인 ABBYY와 open source project인 Tesseract가 있는데,
tessaract가 구글 후원받아서 진행되고 있고 , 최신이 5.0으로 2019년 10월에 업데이트가 되었다. 최신버젼은 홈페이지들어가서 다운받거나 하고,

일단 우분투를 기준으로는

sudo apt-get install tesseract-ocr
sudo apt-get install libtesseract-dev
하면 현재 stable한 4.1 버젼이 설치가 된다.

여기서 tesseract는 언어별로 추가 패키지를 설치할수 있고,

sudo apt-cache seach tesseract
하면 패키지 들이 주르를 나오는데 이중에서  원하는 언어 패키지를
apt-get intstall명령어로 깔면된다.

OCR같은 언어인식 프로그램은 어떻게 보면 인공지능의
Pattern recognition 부분에서 파생되나간부분인데,
요즘 머신러닝이란 이름으로 잘팔리니,, 좋은일이다.

일단 머신러닝보다는 사용법만 기술한다.

 아주단순하게는,

tesseract input.bmp output[.txt]
 이렇게하면 그림이 text로 바뀌어 나온다.

여기서 한글 인식을 위해서는 추가 패키지를 설치해서

tesseract -l kor input.bmp output[.txt]
 이렇게하면 된다,.


한글인식이 잘되지 않는 경우에는 기계학습을 통해서 데이터를 축적시켜줘야되는데,
한글 부분은 일단 패스한다. 영어나 숫자 같은 경우는 쉽게 인식이 되고,

이 모델이 현재 최신 머신러닝 알고리즘으로 시간이 지나면서
계속 업데이트가 되고 있기때문에, 주기적으로 관심을 가지고 보면 좋을듯하다.








2020년 1월 14일 화요일

Python collections namedtutple

Namedtuple

Collection의 Namedtuple함수는 생각보다 요긴한데가 많다..

일반적인 튜플의 경우는 index만 가지고 처리를 하지만, namedtuple의 경우에는 Dictionary처럼 key를 가지고 처리한다.

보통 이렇게 많이 사용하는 데이터 형식이 있다.
2d형태의 엑셀이라든지, csv, sql같은 형태가 이런식의 데이터형태가 많기때문에,

index도 사용할 수 있고, key값으로도 할 수 있는 형태가
유용하게 사용될 수 있는 형태이다.

from collections import namedtuple
Unit = namedtuple('Knight','name','age','hp')
u1 = Unit('klas','23','98')
print (u1.name) # klas
print (u1.hp) # 98