2017년 7월 17일 월요일

[python][django] RuntimeWarning: DateTimeField received a naive datetime 에러

DateTimeField에 날짜를 테스트하려 할 때 문제가 발생했다.
from datetime import datetime
AA.objects.create(my_date=datetime.now())
장고는 날짜에 Timezone을 추가해서 사용한다. timezone을 함께 넣어주던가
사용하지 않는다고 명시하던가 해야한다.
from django.utils import timezone
AA.objects.create(my_date=timezone.now())

[python][django] Model 테이블의 이름을 변경하려면 어떻게 해야 할까?

makemigrations 손보기

ORM에 대해서 많이 들어보고 그냥 쓰면 좋다는 생각에..
그리고 장고를 사용하면 자연스럽게 쓸 수밖에 없기에 그 편리함에 놀라워했다

makemigrations와 migrate만 알면 전부 다 될 줄 알았다. 하지만 이제 알겠다.
편리하기 위해선 많이 배워야 함을... 어쩌면 한 번도 사용한 적이 없어서일지도 모르겠다.
여하튼
단순히 Model명을 변경하고 makemigrations를 하면 에러가 난다.
장고는 내 맘과 같지 않아서, 이 모델이 rename된건지 확신하지 못하는 것같다.
그러면 내가 확신을 가지도록 명시해줘야 한다.
일단 원래대로 돌려놓고
python manage.py makemigrations --empty <앱이름>
이렇게 하면 makemigrations의 빈 통이 보인다. 다른건 보지말고 얘만 보자.
...
operations = [
]
이 안에다가 무슨일을 한 건지 적어준다.
operations = [
  migrations.RenameModel(
    old_name='Pattern',
    new_name='MessagePattern',
    ),
]
이후 Model명을 바꾸고 사용하고 있는 다른 파일들 모델명을 전부 바꾼다.

출처: 이것저것 바꾸다가 makemigrations 스키마가 이런걸 사용하는 것을 확인. python 도큐먼트를 뒤늦게 확인

[python] 파이썬 디렉터리 삭제하기

os.removedirs, shutil.rmtree

단순히 디렉터리를 삭제할 때는 os.removedirs를 사용하는 것으로 가능하다.
import os

os.removedirs(some_path)
하지만 디렉터리 안에 파일이 있다면 삭제되지 않는다. 그럴땐
import shutil
shutil.rmtree(some_path)
이렇게 삭제하자

2017년 7월 7일 금요일

[python] eval 악마와의 계약

eval()을 사용해보자

후위표현식 AB+를 A+B로 변환해서 산술연산하는 함수를 만들자.
def postfix_eval(expr):
    operand_stack = []
    token_list = postfix_expr.split()

    for token in token_list:
        if token in '0123456789':
            operand_stack.append(int(token))
        else:
            operand2 = operand_stack.pop()
            operand1 = operand_stack.pop()
            result = do_math(token, operand1, operand2)
            operand_stack.append(result)
    return operand_stack.pop()

def do_math(op, op1, op2):
    if op == "*":
        return op1 * op2
    elif op == "/":
        return op1 / op2
    elif op == '+':
        return op1 + op2
    else:
        return op1 - op2
실행
print(postfix_eval('7 8 + 3 2 + /'))
여기서 주목할 것은 do_math
여기 do_math의 내용을 이렇게 바꾼다면
def post_math(op, op1, op2):
    return eval(op1 + op + op2)
테스트를 해보자.
post_math('+', '1', '2')
3
문자열을 그대로 맘대로 합쳐서 그 문자열 자체를 평가
이런 것에 대한 엄청난 효과를 볼 수 있는 것은 리스프 형태일 것 같다.
다음엔 python 리스트 형태 언어인 hy로도 조금씩 적어봐야겠다.

2017년 7월 4일 화요일

Extra Long Factorials python3

사실 푼 것도 아님. 그런데 너무 빨라서... 널 쓸 수 밖에 없었단다...
#!/bin/python3
import sys
from math import factorial

n = int(input().strip())

print(factorial(n))

2017년 7월 1일 토요일

[python][트리] 백준 알고리즘 1991번

테스트를 위해 인풋을 파일로 만들었음.
할일
  1. 파일을 읽어온다.
  2. 파일을 정재하여 리스트에 넣는다.
  3. 간단한 트리구조로 변환할 함수를 만든다
  4. 트리의 루트를 글로벌로 하나 생성한다.
  5. 트리구조의 리스트로 변환한다
  6. 전위, 후위, 중위 탐색을 함수를 만든다.
  7. 출력한다.
1. 파일을 읽어온다. 2. 파일을 정재하여 리스트에 넣는다.
def readFile(filename):
  with open(filename) as file:
    return [ x.strip('\n').replace(' ','') for x in file.readlines()]
list_ = readFile('1991.txt')

3. 간단한 트리구조로 변환할 함수를 만든다. 4. 트리의 루트를 글로벌로 하나 생성한다.
def my_tree(r):
    return [r, [], []]
root = None

5. 트리구조의 리스트로 변환한다.
def add(data, left, right):
    global root
    if root is None:
        if data != '.':
            root = my_tree(data)
        if left != '.':
            root[1] = my_tree(left)
        if right != '.':
            root[2] = my_tree(right)
        return root
    else:
        return search(root, data, left, right)

def search(root, data, left, right):
    if root is None or root == []:
        return root
    elif root[0] == data:
        if left != '.':
            root[1] = my_tree(left)
        if right != '.':
            root[2] = my_tree(right)
        return root
    else:
        search(root[1], data, left, right)
        search(root[2], data, left, right)


for l_ in list_[1:]:
    add(l_[0],l_[1],l_[2])

6. 전위 후위 중위 탐색 함수를 만든다.
def preorder(root):
    if root:
        print(root[0], end='')
        if root[1]:
            preorder(root[1])
        if root[2]:
            preorder(root[2])

def inorder(root):
    if root:
        if root[1]:
            inorder(root[1])
        print(root[0], end='')
        if root[2]:
            inorder(root[2])

def postorder(root):
    if root:
        if root[1]:
            postorder(root[1])
        if root[2]:
            postorder(root[2])
        print(root[0], end='')

7. 출력한다.
preorder(root)
print()
inorder(root)
print()
postorder(root)
print()