Django 소개 및 사용법

본 글은 http://tutorial.djangogirls.org/ko/ 의 튜토리얼 을 따라 블로그를 개발하고, 주요 정보들을 요약한 글입니다. 최종 결과물은 http://captainpangyo.pythonanywhere.com/ 에서 확인 가능합니다.

Django 란 무엇인가?

  • Django란 (/ˈdʒæŋɡoʊ/ jang-goh/쟁고/장고) 파이썬으로 만들어진 무료 오픈소스 웹 어플리케이션 프레임워크

Urlresolver

  • 역할 : 웹 서버에 요청이 오면 장고로 전달되고, 장고가 웹 페이지의 주소를 가져와 무엇을 할지 확인한다.
  • 각 URL 에 대해 일일이 확인하기는 비효율적이므로, 패턴으로 일치여부를 판단한다.
  • 일치하는 패턴의 경우 요청을 연관된 함수(view)에 넘긴다.
  • 결론 : urlresolver는 우체국의 우편 배달부 역할을 한다. (편지의 주소를 확인하고 맞으면 집에 전달해주는)

Django 설치

  • 가상환경 (Virtualenv) : 프로젝트 기초 전부를 Python/Django 와 분리시켜준다. 웹사이트가 변경되어도 개발 중인 것에 영향을 미치지 않는다.
  • 가상환경 만들기 : python3 -m venv myvenv myvenv 라는 가상환경을 생성
    • 명명법 : 소문자 / 공백은 없어야함 / 자주 입력해야 하므로 짧게
  • 가상환경 실행 명령어 : source myvenv/bin/activate
  • 가상환경에서 PIP로 장고 설치 : pip install django==1.8
  • 웹서버 실행 명령어 : python manage.py runserver
  • 장고 기본 Database : SQLite3
  • 파이썬 관습 : 던더(dunder; 더블 – 언더스코어 준말)
  • WSGI 프로토콜 : 파이썬을 이용한 웹사이트를 서비스 하기 위한 표준 (PythonAnywhere 에서 지원)

Django 프로젝트 생성

  • 가상환경에서 django-admin startproject mysite . 입력하여 장고 프로젝트 생성
  • 생성된 프로젝트의 초기 구조는
    djangogirls
    ├───manage.py
    └───mysite
          settings.py
          urls.py
          wsgi.py
          __init__.py
    
    • manage.py : 사이트 관리 및 웹 서버 실행
    • settings.py : 웹사이트 설정
    • urls.py : urlresolver 가 사용하는 패턴 목록 포함

Django 배포

  • Git 으로 커밋 및 배포
    [Local]
    - git status
    - git add --all .
    - git commit -m "First Commit."
    - git push
    
    [Server]
    - cd ~/my-first-blog
    - source myvenv/bin/activate
    - git pull
    - python manage.py collectstatic
    

Python 정규표현식

  • ^ : 문자열이 시작할 때
  • $ : 문자열이 끝날 때
  • \d : 숫자
  • + : 바로 앞에 나오는 항목이 계속 나올 때
  • () : 패턴의 부분을 저장할 때
  • 예를 들어, http://www.mysite.com/post/12345/ 와 같은 URL 이 있다고 하자.
  • 뷰마다 모든 글 번호를 작성하는 것은 현실적으로 힘들다.
  • 따라서 정규표현식 ^post/(\d+)/$. 을 이용하여 해당 글 번호를 가진 post 를 접근한다.
  • 위 정규표현식을 아래와 같이 부분 부분 나눠보면
    • ^post : url 시작점에 (오른쪽부터) post/ 가 있다.
    • (\d+) : 숫자가 1개 이상 있다.
    • / : / 뒤에 문자가 존재한다.
    • $ : URL 이 끝이 / 로 끝나야 매칭될 수 있다는 걸 의미
  • 파이썬에서 정규 표현식을 작성할 때는 항상 문자열 앞에 r을 붙입니다

Django View

  • 어플리케이션의 로직 을 넣는 곳
  • 모델의 정보를 받아와서 템플릿 에 전달하는 역할

템플릿 (HTML)

  • 서로 다른 정보를 일정한 형태로 표시할 수 있는 재사용이 가능한 파일
  • HTML : “Hyper Text Markup Language” 의 줄인 말.
  • 하이퍼텍스트(Hyper Text) : 페이지 간에 하이퍼링크를 담을 수 있는 텍스트
  • 마크업(Markup) : 브라우저 문서를 해석하는 표시

Django ORM & QuerySets

  • 쿼리셋 : 전달받은 모델의 객체 목록. 데이터베이스의 데이터를 읽어 필터 및 정렬 가능
  • 사용방법
    from blog.models import Post
    Post.objects.all()
    Post.objects.filter( title__contains = 'title' )
    
  • 쿼리셋은 연결(chaining) 도 가능
    Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    

템플릿의 동적 데이터

  • from 다음의 마침표 .현재 디렉토리 또는 현재 어플리케이션 을 의미
    • from .models import Post : 현재 디렉토리의 models.py 를 접근 (.py 확장자는 붙이지 않아도 됌)
    from django.shortcuts import render
    from django.utils import timezone
    from .models import Post
    
    # `post_list` 라고 정의한 view 함수에서 QuerySet 으로 처리한 데이터를 `posts` 라는 변수로 받는다.
    def post_list(request):
    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    # QuerySet으로 받은 데이터를 posts 라는 이름의 변수에 태워 보낸다
    return render(request, 'blog/post_list.html', {'posts': posts})
    

Django 템플릿

  • 데이터 표현을 위해 template tags 라는 내장된 기능을 사용한다.
  • 장고 템플릿 태그(Django template tags) : 파이썬을 HTML로 바꿔주어, 빠르고 쉽게 동적인 웹사이트를 만들 수 있다.
  • 위에서 정의한 view 함수에서 전달받은 posts 를 다음과 같이 템플릿에 적용하면 동적 데이터를 다룰 수 있다.
    <div>
      <h1><a href="/">Django Girls Blog</a></h1>
    </div>
    
    {% for post in posts %}
      <div>
          published: {{ post.published_date }}
          <h1><a href="">{{ post.title }}</a></h1>
          {{ post.text|linebreaksbr }}
      </div>
    {% endfor %}
    

템플릿 확장하기

  • 서로 다른 페이지에서 HTML의 일부를 동일하게 재사용이 가능
  • post_list.html 에서 base.html 를 참조하는 방법
    <!-- base.html -->
    <div class="row">
      <div class="col-md-8">
      {% block content %}
      {% endblock %}
      </div>
    </div>
    
    <!-- post_list.html -->
    {% extends 'blog/base.html' %}
    
    {% block content %}
      {% for post in posts %}
          <div class="post">
              <div class="date">
                  {{ post.published_date }}
              </div>
              <h1><a href="">{{ post.title }}</a></h1>
              {{ post.text|linebreaksbr }}
          </div>
      {% endfor %}
    {% endblock content %}
    
Advertisements

단순선형회귀법과 다중선형회귀법

Linear Regression (선형회귀법)

  • 스칼라로 표현되는 종속변수 y 와 벡터 형식으로 표현되는 독립변수 X 간의 관계를 표현하기 위한 알고리즘
  • 단순회귀분석 : 독립변수 X가 스칼라 값인 경우 (1차원 벡터)
  • 회귀분석 : 관찰된 변수들에 대해 독립변수와 종속변수 사이의 관계를 나타내는 선형 관계식을 구하는 알고리즘. (독립변수가 바뀜에 따라 종속변수가 어떻게 변하는지를 분석) – 시간과 관계된 데이터, 예측, 인과관계 분석시에 자주 사용

statsmodels.api.OLS

  • Python 라이브러리 statsmodels 의 알고리즘으로 summary 를 제공하며 분석하기 쉽도록 정보를 표시
    import statsmodels.api
    import numpy
    X = [1, 2, 3, 4, 5] # 1
    Y = [2, 3.7, 3.9, 5, 7]
    X = numpy.array(X).T # 2
    X = statsmodels.api.add_constant(X) # 3
    results = statsmodels.api.OLS(Y, X).fit()
    
  • 결과 해석하기 : 회귀분석을 수행하고 나면, 각 독립변수에 대한 계수 (coefficient)P-value 값을 확인할 수 있다.

  • 계수 (coefficient, coef) : 계수가 양이면 해당 변수가 종속변수에 양으로 연관되어 있고, 음이면 음으로 연관되어 있다. 계수 확인은 results.params 를 활용한다.
  • P-value : 각 독립변수가 얼마나 종속변수에 영향을 미치는지 나타낸다. 정확히 말하면, 회귀분석에서 수행하는 테스트에서 P값은 독립변수의 계수가 0일 확률을 나타냅니다. 즉, P값이 작을수록 해당 독립변수가 모델에서 의미를 가지며, P값이 높을수록 해당 독립변수는 종속 변수에 영향을 끼치지 못하게 됩니다. 일반적으로, P값이 0.05 미만일 때 통계적으로 유의하다고 합니다. 확인하는 방법은 results.pvalues

다중선형회귀법

  • 단일선형회귀법은 독립변수 X가 스칼라인 값인 반면, 다중선형회귀법은 여러 차원을 가진 벡터값을 가지는 차이점이 있다.

enumerate

  • 순서가 있는 자료형 (list, tuple, string) 을 입력 받아 인덱스 값을 포함하는 enumerate 객체를 리턴한다.

    for i, name in enumerate(['1','2','3']):
    print (i,name)
    
    # 0 body
    # 1 foo
    # 2 bar
    

Python Numpy Summary

Numpy

  • Python 에서 기본적으로 지원하지 않는 array(배열) 와 matrix(행렬) 의 계산을 도와주는 라이브러리
  • 사용하려면 import numpy 로 라이브러리를 호출해야 한다.

numpy.ndarray

  • n차원 배열을 생성하는 함수
  • 사용법 : numpy.array([[1,2],[3,4]])

numpy.ndarray.shape

  • 배열의 모양을 확인할 수 있다.
    A = numpy.array([[1, 2, 3], [4, 5, 6]])
    print(A.shape) # (2,3)
    

numpy.ndarray.reshape

  • 배열의 모양을 바꿀 수 있다.
    A = numpy.array([[1, 2, 3], [4, 5, 6]])
    print(A)
    # [[1 2 3]
    #  [4 5 6]]
    B = A.reshape((3, 2))
    print(B)
    # [[1 2]
    #  [3 4]
    #  [5 6]]
    

numpy.concatenate

  • 여러 개의 배열을 하나로 합친다
    A = numpy.array([[1, 2], [3, 4]])
    B = numpy.array([[5, 6], [7, 8]])
    C_Y = numpy.concatenate((A, B), axis = 0)
    print(C_Y)
    # [[1 2]
    #  [3 4]
    #  [5 6]
    #  [7 8]]
    C_X = numpy.concatenate((A, B), axis = 1)
    print(C_X)
    # [[1 2 5 6]
    #  [3 4 7 8]]
    

numpy.split

  • 배열을 여러 개의 크기로 나눈다
    A = numpy.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13 ,14 ,15, 16]])
    print(A)
    # [[ 1  2  3  4]
    #  [ 5  6  7  8]
    #  [ 9 10 11 12]
    #  [13 14 15 16]]
    slice_Y_equal_size = numpy.split(A, 2, axis = 0)
    print(slice_Y_equal_size[0])
    # [[1 2 3 4]
    #  [5 6 7 8]]
    print(slice_Y_equal_size[1])
    # [[ 9 10 11 12]
    #  [13 14 15 16]]
    

Numpy 기초 통계처리

numpy.sum

  • 배열에 있는 모든 원소의 합을 구한다
    A = numpy.array([1, 2, 3, 4])
    print(numpy.sum(A)) # 10
    

numpy.mean, median, std, var

  • 통계 처리시 가장 많이 쓰이는 기능 3가지
  • 데이터가 numpy.array 로 주어질 때, 데이터의 평균값, 중간값, 표준 편차, 분산 을 구할 수 있다.
    A = numpy.array([1, 2, 4, 5, 5, 7, 10, 13, 18, 21])
    print(numpy.mean(A)) # 평균 값 8.6
    print(numpy.median(A)) # 중간 값 6.0
    print(numpy.std(A)) # 표준 편차 6.43739077577
    print(numpy.var(A)) # 분산 41.44
    

numpy.ndarray.transpose

  • 전치행렬을 구한다.
    A = numpy.array([[1, 2, 3], [4, 5, 6]])
    print(A.transpose())
    # [[1 4]
    #  [2 5]
    #  [3 6]]
    

numpy.linalg.inv

  • 행렬의 역행렬을 구한다.
    A = numpy.array([[1, 2], [3, 4]])
    print(numpy.linalg.inv(A))
    # [[-2.   1. ]
    #  [ 1.5 -0.5]]
    

numpy.dot

  • 두 행렬의 곱셉, 두 벡터의 내적을 구한다.
    A = numpy.array([[1, 2, 3], [1, 2, 1]])
    B = numpy.array([[2, 1, 3], [-1, 0, 5]])
    C = numpy.dot(A, B) # Error!
    B = B.transpose()
    C = numpy.dot(A, B)
    print(C)
    # [[13 14]
    #  [ 7  4]]
    

행렬 구하는 코드

  • 아래의 코드로 숫자를 입력받아 행렬을 만들 수 있다.
    def get_matrix():
    # 1
    mat = [] # define mat variable
    
    first_line = input().strip() # receice first line
    first_line_splitted = first_line.split(&amp;quot; &amp;quot;) # split line by space &amp;quot; &amp;quot;
    n = int(first_line_splitted[0]) # convert to integer
    m = int(first_line_splitted[1]) # convert to integer
    
    for i in range(n):
      line = input().strip() # receive each line ...
      row = line.split(&amp;quot; &amp;quot;)  # ... and split
      for j in range(m):
          row[j] = int(row[j]) # convert to integer
      mat.append(row)
    
    return numpy.array(mat)
    

Python Basics

함수 (function)

  • 프로그래밍에서 함수는 수학에서의 함수와 동일한 역할
  • 변수를 입력받아, 변수에 대한 명령을 수행하고, 결과를 반환
    def f(x):
    # f(x) = 2x + 1
    return x * 2 + 1
    
    print(f(3))
    

변수 (variables)

  • 프로그램 내에서 사용되는 정보와 그 정보를 저장하는 공간
    x = 5.1
    y = 10 * x
    

리스트 (list)

  • 데이터 구조 (Data Structure) : 데이터를 컴퓨터내에 저장하기 위해 정리하고 조직하는 체계
  • 리스트 (list) : Python에서 가장 기본이 되는 데이터 구조. 데이터를 순차적으로 표현.
  • 대괄호 [] 를 사용한다.
    # 숫자와 문자열 혼용
    students = ["Suin", "Jaewon", "Jungkook", 20121837, 20103811, 0.0]
    
    # 리스트 안에 리스트 포함 가능
    nested_list = ["a", "b", "c"]
    my_list = [1, 2, nested_list, 3]
    
    # 데이터 읽기
    animals = ['cheetah', 'hare', 'reindeer', 'calf']
    print(animals[2])
    
    # 데이터 변경
    animals[1] = 'rabbit'
    
    # 데이터 삭제
    del animals[1]
    
    # 데이터 추가
    animals.append('horse')
    
    # 데이터 존재여부 파악
    my_animal = "calf"
    print(my_animal in animals)
    

튜플 (tuple)

  • 리스트와 비슷하지만 list와 달리 한번 만들면 변경할 수 없다.
  • 소괄호 () 를 사용한다.
    # 아래와 같은 튜플이 있을 때,
    gpu_manufacturers = ('Intel', 'AMD', 'NVidia')
    
    # 아래와 같은 list 접근 법은 허용되지 않는다.
    gpu_manufacturers[1] = 'Matrox'
    del gpu_manufacturers[0]
    gpu_manufacturers.append('3dfx')
    
  • 튜플의 값을 변경하려면 복수 개의 튜플을 조합하여 새로운 튜플 생성이 가능하다.
    current_gpu_manufacturers = ('Intel', 'AMD', 'NVidia')
    old_gpu_manufacturers = ('Matrox', '3dfx')
    gpu_manufacturers = current_gpu_manufacturers + old_gpu_manufacturers
    print(gpu_manufacturers)
    

딕셔너리 (dictionary)

  • 데이터를 순차적으로 저장하는 list 와 tuple 과는 다르게, 자료를 key 와 value 쌍으로 저장
    scores = {
    'Kim': 88,
    'Park': 94,
    'Lee': 91,
    'Choi': 96
    }
    
    # 데이터 읽기
    print(scores['Kim'])
    
    # 데이터 변경
    scores['Lee'] = 89
    
    # 데이터 삭제
    del score['Lee']
    print(scores)
    

조건문 (conditional statements)

  • if, elif, else 의 조건문이 존재
  • and 연산자는 and 이다.

반복문 (loop)

  • forwhile 과 같은 반복문이 존재
  • range(0, 11) 0 과 11 사이의 숫자들을 가진 리스트를 만든다.

Ternary Operators

  • 문법 : True if 컨디션 else False
  • 예제 : True if 1 &gt; 10 else False

range 함수 예시

  • range(10)는 0부터 10 미만의 숫자를 포함하는 range 객체를 만들어 준다.
    sum = 0
    for i in range(1, 11):
    sum = sum + i
    
    print(sum) # 55
    

부울 (Bool)

  • 참과 거짓을 나타내는 자료형
  • 0을 제외한 모든 값은 True / 0과 값이 비어있는 경우 False
    bool(0)   # False
    bool(1)   # True
    bool(92)  # True
    bool([])  # False
    bool('a') # True