2/8 AI클럽 비전공자 대상 파이썬 Flask 웹개발 5주차 모임 후기

안녕하세요! AI클럽(http://aiclub.kr) 운영자 이경용 입니다.
2020년 1월에 시작해서 벌써 5주차 모임이 되었네요. 확실히 5주차가 되니 빈자리 조금씩 보이고 있네요. 남은 분들 남은 2주동안 열심히 열공해 봅시다.

이번주 스터디는 다음과 같이 진행 되었답니다.

1. 반응형 홈페이지 원리 이해하기
1) meta 태그 중에 뷰포트 이해하기
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
반응형 모바일 웹에서는 뷰포트 역할이 필수 이죠. 다양한 해상도에서 동일한 스케일을 유지 시키기 위해 필수

2) 12개의 블럭 개념 이해하기
반응형에서는 100% 비율로 처리되며 12개의 블럭으로 구분해서 하나의 블럭을 100% / 12 = 8.33%로 3개의 블럭 사용시 25%를 사용합니다. 

3) display 속성의 inline, block 과 float의 left, right, position의 reactive, absolute 등의 속성을 잘 활용해야 합니다.

4) 미디어쿼리를 이용해서 화면 해상도에 따라 sytle을 조정해서 PC화면과 모바일 화면에 따라 컨트롤 하는데 매우 중요한 역할이니 꼭 복습하셔서 완벽하게 이해해 보시기 바랍니다.

비전공자 대상 AI클럽 2기 파이썬 Flask 기반 웹프로그래밍 및 데이터 시각화

2. 부트스트랩 (bootstrap)
반응형 모바일 웹을 만드는데 매우 유용한 부트스트랩에 대해 배워 보았습니다.
수업자료 : https://cafe.naver.com/aiclubcafe/67
수업 진행은 https://www.w3schools.com/bootstrap4/default.asp 사이트 내용을 참고 했답니다.
기본 html 태그를 class 이름을 어떻게 지정해 주느냐에 따라 이쁜 모양을 만들어주는 과정을 하나하나 실습해 보았습니다.
시간 관계상 중요한 것들 위주로 해 보았습니다.
꼭, 하나하나 모두 실습해 보시기 바랍니다.

부트스트랩을 이용하기 위한 CDN

<!-- BootStrap CDN --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

열공모드

3. Flask 템플릿 
앞서 템플릿 기능을 조금 학습 하였으나 일부 내용이 남아서 마져 학습 하였답니다.
/templates 폴더에 base.html 파일을 만들어서 자주 사용하는 코드를 별도로 만들어서 템플릿으로 사용하도록 하였습니다.

1) /template/base.html

<!DOCTYPE html>
<html>
    <head>
        <title>BootStrap</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- BootStrap CDN -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
        {% block header %}
        {% endblock %}
    </head>
    <body>
        {% block content %}
        {% endblock %}
    </body>
</html>

템플릿에서 {% block 블럭이름 %} 으로 시작 태그로 사용하고, {% endblock %} 로 끝나는 태그로 사용 합니다.
자주 사용하는 코드는 이렇게 별도의 html 파일을 만들어서 블럭 지정해서 사용하시면 개발 속도 및 유지보수 하기가 용이 합니다.

{% extends "base.html" %}
{% block header %}
<!-- header 블럭에 추가할 내용을 여기에 작성 -->
{% endblock %}
{% block content %}
<!-- content 블럭 영역에 들어갈 내용을 여기에 작성 -->
{% endblock %}

2) /template/bootstrap.html
base.html 템플릿 파일을 불러올 때에는 맨 첫줄에 {% extends “템플릿 파일명” %} 으로 호출 하시면 됩니다. 그리고, {% block 블럭이름 %} ~ {% endblock %} 사이에 원하는 코드를 입력하면 됩니다.
그러면, 접속자는 두개의 파일이 하나로 합쳐진 소스를 받게 됩니다.

부트스트랩 Bootstrap 반응형 웹 실습

4. Flask Request
클라인트 브라우저에서 서버로 데이터를 보내는 방법은 GET, POST 두가지 통신 방식이 있는데 GET은 주소줄 URL에 변수와 값을 붙여서 보냅니다.예) http://aiclub.kr/?name=value반명 post는 form 태그안에 input 태그나 textarea에 값을 사용자로 부터 받아서 서버로 전달하게 됩니다.
request를 실습하기 위해 워드클라우드를 만들어 보았습니다.
워드클라우드는 글자 내용을 분석해서 자주 사용된 단어를 구름 처럼 단어로 표현해 주는 기능 입니다.

1) 나눔 폰트 워드클라우드에서 폰트를 이뿌게 표현해 주기 위해서는 특정 폰트를 사용할 수 있는데 나눔 폰트를 사용해 보겠습니다.
일단, 카페에 강의자료 5주차 첨부 자료에 NanumGothic.zip 파일을 내려 받아서 압축을 푸신후에 /static 폴더에 업로드 하세요!

2) /flask_app.py 먼저 가상환경 콜솔로 가셔서 pip install wordcloud 명령을 실행해서 wordclud 라이브러리를 설치하세요!설치 하는데 많은 시간이 걸릴거에요.matplotlib 등 다양한 라이브러리들이 설치가 될 겁니다.
이제는 flask_app.py에 request 모듈을 추가하고 matplitlib, time 등을 import 합니다.그리고 wordcloud route 함수를 추가 합니다.

from flask import Flask, render_template, request
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import time

app = Flask(__name__)

@app.route('/wordcloud', methods=['GET','POST'])
def wordcloud():
    if request.method == 'GET':
        return render_template('wordcloud.html')
    elif request.method == 'POST':
        content = request.form['content']
        font_path = '/home/aiclub/mysite/static/NanumGothic.ttf'
        wordcloud = WordCloud(font_path=font_path, background_color="white", width=400, height=400)
        wordcloud = wordcloud.generate(content)
        fig = plt.figure(figsize=(6,6))
        plt.imshow(wordcloud)
        plt.axis('off')
        plt.show()
        fig.savefig('/home/aiclub/mysite/static/wordcloud.png')
        return render_template('wordcloud.html', content=content, time=time.time())

route 속성에 methodes=[‘GET’, ‘POST’]를 추가하면 GET, POST 두개의 통신 값을 받겠다는 의미 입니다.
둘중 하나만 명시하도 되지만 저희는 하나의 URL로 사용자 페이지와 데이터를 받는 페이지를 하나로 처리 하기 위해 두개의 값을 추가하도록 했습니다.
현재 접속한 페이지에서 메소드 값을 확인 할 땐 request.method 라고 하면 GET 또는 POST라는 값을 받아올 수 있습니다.
Get인 경우 단순히 reder_template() 함수에서 wordclud.html을 불러와서 출력 합니다. 그러면, 사용자로 부터 입력 받을 수 있는 페이지만 나타 날 것입니다.
만약, method에 POST 값이 넘어오면 넘어온 form내의 사용자 입력값을 얻기 위해서 reqeust.form[‘변수명’]으로 받아올 수 있습니다.
textarea의 name을 “content”로 지정할 예정이니 request.form[‘content’]로 사용자가 입력한 텍스트를 받아와서 content라는 변수에 저장 합니다.

WordCloud() 속성 값
font_path : 폰트의 위치
backgroud_color : 워드크라우드의 이미지 배경색
width/height : 텍스트 작성될 범위

wordcloud.generate(텍스트)
generate 함수는 텍스트 인자를 넘겨 받아서 단순히 반복된 텍스트 갯수를 분석해서 자주 사용한 단어의 크기를 크게 합니다. (초간단 가중치 원리 사용)

pltmatpolit에서 데이터를 시각화 해주기 위한 일종의 그림을 그릴 수 있는 도화지(종이)라고 생각하면 됩니다.
R 프로그램에서 데이터 분석 결과를 시각화해서 보여주는 것처럼 matplit를 이용해서 파이썬에서 데이터를 시각화 하는데 유용하게 활용 됩니다.예) https://cafe.naver.com/aiclubcafe/71

plt.axis(‘off’) 해당 속성은 원래 plt가 데이터를 시각화해서 그래프로 보여주는 것이 기본 속성이라서 디폴트는 눈금자 및 라벨등이 자동으로 출력됩니다. 따라서, off해서 숨기도록 합니다.
plt.show()는 웹에서는 의미가 없습니다.
사용자에게는 이미지와 같은 형태로 보여 줘야 하니 fig.savefig()함수를 이용해서 이미지 파일로 저장합니다.
static 폴더에 저장되어야 사용자에게 보여줄 수 있으니 경로를 static 절대 경로를 지정해 줍니다.

3) /templates/wordcloud.html 템플릿 파일 만들기

{% extends "base.html" %}
{% block header %}
<style>
body { padding:50px; }
h1 { text-align:center; }
</style>
{% endblock %}
{% block content %}
<h1>Word Cloud</h1>
<form action="/wordcloud" method="post" name="frm">
<div class="form-group">
  <label for="comment">News Input :</label>
  <textarea class="form-control" rows="5" name="content">{{content}}</textarea>
</div>
<div class="form-group">
    <input type="submit" class="btn btn-primary btn-block btn-lg">
</div>
</form>
{% if content %}
<div>
    <img src="/static/wordcloud.png?v={{time}}">
</div>
{% endif %}
{% endblock %}

form 태그에서 action 주소를 /wordclud로 해서 나 자신에게 다시 전송하는데 methodpost로 해서 전송 합니다.
textarea의 name변수에 “content”라는 이름으로 전송해서 만약 if content에서 content에 값이 있으면 true 조건이 성립하여 img 태그가 출력되도록 합니다.

이미지 파일 뒤에 {{time}} 표시는 크롬의 캐시 때문에 적용된 content 내용은 바뀌었는데 정작 이미지 파일명은 그대로여서 브라우저가 새로운 이미지를 서버에서 받지 않고 로컬에 저장된 앞전 이미지를 보내 줘서 이미지가 바뀌지 않을 수 있으니 매번 새로운 이미지를 받아올 수 있도록 이미지의 파일명이 자동으로 변경되도록 한 방법입니다. (일명 꽁수)

워드클라우드 텍스트 빈도수에 따라 크기를 구름처럼

http://aiclub.pythonanywhere.com/wordcloud
접속해서 네이버의 기사를 입력후 전송해 보세요!
결과를 보니 명사만으로 처리되지 않아 “올렸다”, “등을” 같은 글자들도 보이게 되는군요.
파이썬에서는 자연어 처리 기능이 있어 좀 더 깔끔하게 처리를 해줄 수 있습니다.강의자료 참고해서 업그레이드 해보시기 바랍니다.

열공중인 문주썜

오늘도 예상보다는 진도를 조금 덜 나갔네요.
수업떄 못다한 내용은 과제로 다시 안내 하도록 하겠습니다.

오늘도 코로나 덕분에 공식 뒷풀이를 갖지 않았는데… 그냥 밥먹으러 왔는데… 이렇게 많이 자리 하셨네요.
점심은 가볍게 떡뽁이로… 그러나 떡뽁이는 더이상 가벼운 음식이 아니라는…ㅋ

역시 스터디 후에는 뒷풀이~ 코로나가 어여 지나가야 할텐데

부경대 레드봉봉 해물 국물 떡볶이

부경대 레드봉봉 치즈 국물 떡볶이

모두 수고 많으셨습니다. 다음주 뵙겠습니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.