My Profile Photo

DongChanS's blog


수학과 학생의 개발일지


SSAFY 스타트 캠프 2주차 - (2)

아래 포스트는 SSAFY 스타트 캠프의 수업내용을 정리한 글입니다.

진자로 조건문 쓰기

진자 : 파이썬코드를 심어줌 -> RENDER

  • 파이썬코드의 핵심 3가지 : 조건문,반복,저장

진자의 if문쓰기

<div>
    {% if True %}
        yay
    {% endif %}
</div>

과제: 오늘이 새해인지 아닌지 말해주는 프로그램 작성

@app.route("/isitfirstday")
def isitfirstday():
    now = datetime.datetime.now()
    day = now.day
    month = now.month
    return render_template('newyear.html',day=day,month=month)
<body>
    <h1>오늘이 새해가 맞는가?</h1>
    {% if day == 1 and month == 1 %}
        <div>맞다</div>
    {% else %}
        <div>아니다</div>
    {% endif %}
</body>

고려해야할 것 : 서버시간이랑 우리 시간이랑 다르다.

form태그

:interaction을 할 수 있음.

  • 안에다 사용자의 입력을 받을 수 있는 input 이라는 태그를 만들 수 있음.

  • 이 input은 엄청나게 많은 타입을 지정할 수 있음.

이걸 이용해서 Fakesearch(우리의 url로 모든 검색엔진을 사용가능???)

@app.route() : 요청에 대해서 어떤걸 할지 길잡이역할을 한다고 보면 됨.

  • @app.route(‘/’)
  • def index():
  • 이런식으로 적는 습관
  1. input태그 - 사용자의 텍스트 인풋을 받는다.

  2. 버튼을 만든다 : submit태그

  3. 입력을 어디론가 보내줄 수 있다(우리 앱이 아니어도됨!!!)

    • action을 통해서

    • 심지어 무언가를 먹여서 보내줄 수도 있다.

    • name=”query”로 정의가능.

<!DOCTYPE html>
<body>
    <h1>Fake Search</h1>
    <form action="https://search.naver.com/search.naver">
        <input type="text" name="query">
        <input type="submit">
    </form>  
</body>

과제 : 네이버 뿐만 아니라 다음, 구글도 만들어라

<br>
    <form id="google" action="https://www.google.com/search">
        <input type="text" name="q">
        <input type="submit">
    </form>
    <br>
    <form id="daum" action="https://search.daum.net/search">
        <input type="text" name="q">
        <input type="submit">
    </form>

텔레그렘에 메세지를 보내는 url을 만들어보아라.

(다른 url에서 메시지를 받고 그걸 텔레그렘으로)

다만 어딘가에 보내는 것이 아니라 우리가 받아서 정제를 해야함.

  • 우리 앱을 나타내는 것 : action=”/sendmsg”
  1. 메세지를 받아서 우리 페이지에 보여주는 것을 먼저 하자

    • 그러기 위해서 url에서 받은 값을 가져오면된다.
  2. 텔레그렘에 메세지를 보내자

    1) 우리 챗봇의 key값을 받아서 저장한다.

    2) key값을 통해서 /getMe(나에 대한 정보) /getUpdates(봇에 대한 상태 정보)

    3)https://api.telegram.org/bot/METHOD_NAME

    4)메시지를 보내는 방법 sendMessage

    • chat_id = ‘나의 아이디’ (getUpdates)
    • text = “내용”

    5)그런데 c9에서 텔레그램을 api.telegrams.org로 가는 요청을 차단했기때문에 리다이렉트를 시켜야함.

from flask import Flask,render_template
import flask
import requests

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/sendmsg')
def sendmsg():
    key = "내 키"
    url = "https://api.hphk.io/telegram/bot%s/"%(key)
    your_id = "내 아이디"
    msg = flask.request.args.get("msg")
    char_url = url + "sendMessage?chat_id=%s&text=%s"%(your_id,msg)
    return render_template('sendmsg.html',msg=msg)
    
app.run()
<!DOCTYPE html>
<body>
    <h1>보낸 메세지</h1>
    <div>{{msg}}</div>
    <h2>다시 보내시려면 이 곳을 누르세요</h2>
    <form action="/">
        <input type="submit">
    </form>  
</body>

vonvon: 전생을 알려주는 사이트 구현

  • fakedata를 만들어야함(직업이 많아서 힘들다고함)

  • -> 페이커

  1. job, name 등등의 fake data를 만들 수 있음.
  2. korean locale도 있음.
from flask import Flask,render_template,request
import requests
from faker import Faker

app = Flask(__name__)
name_job_dict = dict()
# 1. 루트에서 사용자의 이름을 입력 받습니다.
# 2. '/pastlife' : 랜덤으로 생성된 전생직업을 보여준다.
# 3. 조금 더 업그레이드 시켜서,, 검색한 이력이 있다면 처음 매칭된 직업을 보여줄것이고
# 4. 아니면 새로 생성된 이름을 보여줄것이다(딕셔너리)
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/pastlife')
def pastlife():
    name = request.args.get("name")
    fake = Faker('ko_KR')
    if name not in name_job_dict:
        job = fake.job()
        name_job_dict[name] = job
    else:
        job = name_job_dict[name]
    return render_template('pastlife.html',name=name,job=job)
<!--- index.html --->
<!DOCTYPE html>
<body>
    <h1>당신의 전생을 알려드립니다</h1>
    <form action="/pastlife">
        이름을 입력하세요<input type="text" name="name">
        <input type="submit">
    </form>
    
</body>
<!--- pastlife.html --->
<!DOCTYPE html>
<body>
    <h1>{{name}}님의 전생</h1>
    <div>{{job}}</div>
    <h2>다시 돌아가려면 이곳을 누르세요</h2>
    <form action="/">
        <input type="submit">
    </form>
    
</body>

과제 : 이걸 응용해서 궁합앱을 만들어보기

from flask import Flask,render_template
import random
app = Flask(__name__)
fish = {}

@app.route('/')
def landing():
    return render_template('index.html')

@app.route('/match')
def matching():
    # 1. fake 궁합을 알려주고
    # 2. 우리만 알 수 있게 저장한다.
    # - fish 리스트에 저장한다
    # 3. match.html에는 두 사람의 이름과 random으로 생성된
    # 50부터 100사이의 숫자를 함께 보여준다.
    me = request.args.get('me')
    you = request.args.get('you')
    if (me,you) in fish.keys() or (you,me) in fish.keys():
        try:
            num = fish[(me,you)]
        except:
            num = fish[(you,me)]
    else:
        num = str(random.randint(50,100))
        fish[(me,you)] = num
    return render_template('match.html',me=me,you=you,num=num)

@app.route('/admin')
def admin():
    # 낚인 사람들의 명단을 보여줄것임.
    return render_template('admin.html',fish=fish)

<!-- index.html -->
<body>
    <h1>궁합을 알려드려요</h1>
    <form action="/match">
        당신의 이름: <input type="text" name="me">
        그분의 이름: <input type="text" name="you">
        <input type="submit">
    </form>  
</body>
<!-- match.html -->
<body>
    <h1>{{me}}와 {{you}}의 궁합은</h1>
    <div>{{num}} % 입니다.</div>
    <form action="/">
        다시 시도해보기: <input type="submit">
    </form>
</body>
<!-- admin.html -->
<body>
    <h1>당신은 낚였습니다 ㅋㅋㅋㅋ</h1>
    <ul>
        {% for item in fish %}
            <li><div>{{ item[0] }} 과 {{ item[1] }}</div></li>
        {% endfor %}
    </ul>    
</body>

문제점 : 단순하게 리스트상에 저장하니까 서버를 껐다키면 날아간다.

  • 파일을 활용해서 낚인놈들을 파일에다가 쓸거임.

영구적 손실 없이 데이터를 저장하고 싶음

파일 연다

  1. 읽기 2. 쓰기 3. 수정 4. 파일 닫는다

    텍스트 : open(‘names.txt’,’w’,encoding=’utf-8’) : 인코딩 써주는게좋음.

    json : import json

    CSV(comma seperated value) : 아주 간단한 엑셀

    • 대부분의 언어에서 2차원 배열처럼 다뤄지는 경우가 많음.

    • import csv

import csv
f = open('sspy1.csv','w',encoding='utf-8')
re = csv.reader()
wr = csv.writer()
wr.writerow(['a','b','c','d'])
f.close()

DB 열다(connect) -> CRUD

  1. 읽기(create) 2. 쓰기(read) 3. 수정(update) 4. 삭제(delete) 5. db 닫는다(disconnect)

    dictionary(key-value) + 강력한 메소드 추가 = object

    –> ORM(object-relational mapping) : 테크질문에서 질문 많이 받는 개념이라고함.

과제 : pickle을 이용해서 파일을 저장함!

import pickle

app = Flask(__name__)
fake = Faker('ko_KR')

@app.route('/')
def landing():
    return render_template('index.html')

@app.route('/match')
def matching():
    try:
        with open('fish.txt','rb') as f:
            fish = pickle.load(f)
    except:
        fish = {}
        
    me = request.args.get('me')
    you = request.args.get('you')
    if (me,you) in fish.keys() or (you,me) in fish.keys():
        try:
            num = fish[(me,you)]
        except:
            num = fish[(you,me)]
    else:
        num = str(random.randint(50,100))
        fish[(me,you)] = num
        # 매우 비효율적인듯하긴함.
        with open('fish.txt','wb') as f:
            pickle.dump(fish,f)
            
    return render_template('match.html',me=me,you=you,num=num)

@app.route('/admin')
def admin():
    with open('fish.txt','rb') as f:
        fish = pickle.load(f)
    return render_template('admin.html',fish=fish.keys())

pickle말고 json으로도 가능할까??

c9에서도 물론 github으로 업로드 가능하다!

그런데 이상하게도 git push origin master –force를 해야함

start666:~/workspace (master) $ git push origin master

To https://github.com/start6666/C9files
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/start6666/C9files'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details
.
start666:~/workspace (master) $ git push origin master --force

remote: Resolving deltas: 100% (7/7), done.
comments powered by Disqus