Curriculum/AI웹개발자_내일배움캠프

Story 2. 캠프 1주차 주간회고록

작은코딩 2021. 12. 18. 15:19

목차

  • 웹 프로그래밍 A-Z 기초 1
  • 웹 프로그래밍 A-Z 기초 2
  • 웹 프로그래밍 A-Z 기초 3
  • 웹 프로그래밍 A-Z 기초 4
  • 웹 프로그래밍 A-Z 기초 5
  • 1주 차 후기

 


 

1. 웹 프로그래밍 A-Z 기초 1


HTML / CSS / JS


- CSS

< 기본용어 >

배경관련
  background-color
  background-image
  background-size

사이즈
  width
  height

폰트
  font-size
  font-weight
  font-famliy
  color

간격
  margin
  padding

 

< 자주 사용하는 CSS Flex 속성 >

display: flex;
flex-direction: row;
justify-content: center;
align-items: center;

 

display: flex;     / flex 시작

flex-direction:   / 아이템들이 배치되는 축의 방향을 결정하는 속성 (기본값 = row, 행 방향으로 배치)

justify-content: / 메인 축 방향으로 아이템들 정렬 (기본값 = flex-star, 아이템들을 시작점으로 정렬)

align-items:     / 교차축 방향으로 아이템들 정렬 (기본값 = stretch, 아이템들이 교차축 방향으로 끝까지 늘어남)

 

 

< 자주 사용하는 CSS 이미지 배경 속성 >

background-image:linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("여기는 이미지 url 자리!");
background-position: center;
background-size: cover;

 

<웹 페이지 창에서 바로 실행>

alert

 

<콘솔 창에서 실행>

console.log()

 

- Javascript

< 변수 선언 및 for문 사용 >

let a_list = ['사과', '배', '감', '딸기']

for (1. 시작조건; 2. 반복조건; 3. 더하기) {
	4. 매번실행
}

1 -> 2체크하고 -> (괜찮으면) -> 4 -> 3
-> 2체크하고 -> (괜찮으면) -> 4 -> 3
-> 2체크하고 -> (괜찮으면) -> 4 -> 3
-> 2체크하고 -> (괜찮으면) -> 4 -> 3

와 같은 순서로 실행됩니다.
i가 증가하다가 반복조건에 맞지 않으면, 반복을 종료하고 빠져나옵니다.


for (let i =0; i < a_list.length; i++) {
    console.log(a_list[i])

리스트랑 같이 노는게 반복문이다~ (90%) 이런 유형

let scores = [
    {'name': '철수', 'score': 90},
    {'name': '영희', 'score': 85},
    {'name': '민수', 'score': 70},
    {'name': '형준', 'score': 50},
    {'name': '기남', 'score': 68},
    {'name': '동희', 'score': 30},
]

for (let i =0; i < scores.length; i++) {
    console.log(scores[i]['score']
}

나머지 10퍼센트는 이런 유형

let scores = [
    {'name': '철수', 'score': 90},
    {'name': '영희', 'score': 85},
    {'name': '민수', 'score': 70},
    {'name': '형준', 'score': 50},
    {'name': '기남', 'score': 68},
    {'name': '동희', 'score': 30},
]

for (let i =0; i < scores.length; i++) {
    if (scores[i]['score'] > 70) {
        console.log(scores[i]['name'])
        }
}

 

 < 팬명록 만들기 숙제 코드 >

(코드를 보고싶다면 더보기를 눌러주세요!)

더보기
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
    crossorigin="anonymous"></script>
    <title>미니홈피 - 팬명록</title>
    <link href="https://fonts.googleapis.com/css2?family=Dongle:wght@300;700&family=Hi+Melody&display=swap" rel="stylesheet">
    <style>
        * {
            font-family: 'Hi Melody', cursive;
        }
        .mytitle {
            width: 100%;
            height: 300px;

            background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("https://file.mk.co.kr/meet/neds/2019/10/image_readtop_2019_783017_15698844653918925.jpg");
            background-position: top;
            background-size: cover;

            color: white;

            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;

        }
        .mytitle > h1 {
            font-size: xxx-large;
        }
        .mypost {
            max-width: 500px;
            width: 95%;

            margin: 20px auto 20px auto;
            box-shadow: 0 0 3px 0;
            padding: 20px;
        }
        .mybut {
            margin-top: 10px;

            display: flex;
            flex-direction: row;
            justify-content: left;
            align-items: center;
        }
        .card {
            max-width: 500px;
            width: 95%;

            margin: 10px auto 0 auto;
        }
    </style>

</head>

<body>
    <div class="mytitle">
        <h1>악동뮤지션 팬명록</h1>
    </div>
    <div class="mypost">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
            <label for="floatingInput">닉네임</label>
        </div>

        <div>
            <div class="form-floating">
                <textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2"
                          style="height: 100px"></textarea>
                <label for="floatingTextarea2">응원댓글</label>
            </div>
        </div>
        <div class="mybut">
            <button type="button" class="btn btn-dark">응원 남기기</button>
        </div>

    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
</body>

</html>

확실히 파이썬만 하는 것보다 웹 개발쪽을 같이 공부하는게 더 재밌었다. 바로바로 눈으로 결과가 확인되고 머릿속에 구체적으로 이미지가 그려지기에 흥미를 느낄 수 있었다.  (이 흥미가 끝까지 유지되길를!!)

 


 

2. 웹 프로그래밍 A-Z 기초 2


JQuery / JSON / 서버 - 클라이언트 통신이해 / Ajax


- JQuery

<J Query를 이용해서 값 가져오기 >

<div class="form-floating mb-3">
    <input id="url" type="email" class="form-control" placeholder="name@example.com">
    <label>영화URL</label>
</div>

// 크롬 개발자도구 콘솔창에서 쳐보기
// id 값이 url인 곳을 가리키고, val()로 값을 가져온다.
$('#url').val();

 

< 보이기 / 숨기기 >

// id 값이 post-box인 곳을 가리키고, hide()로 안보이게 한다.
$('#post-box').hide();

// show()로 보이게 한다.
$('#post-box').show();

 

 

< API >

  • API : 프로그램들이 서로 상호작용하는 것을 도와주는 매개체
  • 역할

- 서버와 데이터베이스에 대한 출입구 역할을 한다. (허용된 사람에게만 접근성 부여)

- 애플리케이션과 기기가 원활하게 통신할 수 있도록 한다. 

- 모든 접속을 표준화한다.

 

< GET 방식과 POST방식 >

  • GET → 통상적으로! 데이터 조회(Read)를 요청할 때 예) 영화 목록 조회
  • POST → 통상적으로! 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청할 때 예) 회원가입, 회원탈퇴, 비밀번호 수정

 

- Ajax

# 참고! Ajax는 jQuery를 임포트한 페이지에서만 동작 가능합니다.

$.ajax({
  type: "GET", // GET 방식으로 요청한다.
  url: "http://spartacodingclub.shop/sparta_api/seoulair",
  data: {}, // 요청하면서 함께 줄 데이터 (GET 요청시엔 read만 하기때문에 비워둔다.)
  success: function(response){ // 서버에서 준 결과를 response라는 변수에 담음
    console.log(response) // 서버에서 준 결과를 이용해서 나머지 코드를 작성
  }
})

 

< 팬명록에 날씨정보 실시간 반영시키기 숙제 코드 >

(코드를 보고싶다면 더보기를 눌러주세요!)

더보기
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
    crossorigin="anonymous"></script>

    <title>미니홈피 - 팬명록</title>

    <link href="https://fonts.googleapis.com/css2?family=Dongle:wght@300;700&family=Hi+Melody&display=swap" rel="stylesheet">
    <style>
        * {
            font-family: 'Hi Melody', cursive;
        }
        .mytitle {
            width: 100%;
            height: 300px;

            background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("https://file.mk.co.kr/meet/neds/2019/10/image_readtop_2019_783017_15698844653918925.jpg");
            background-position: top;
            background-size: cover;

            color: white;

            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;

        }
        .mytitle > h1 {
            font-size: xxx-large;
        }
        .mypost {
            max-width: 500px;
            width: 95%;

            margin: 20px auto 20px auto;
            box-shadow: 0 0 3px 0;
            padding: 20px;
        }
        .mybut {
            margin-top: 10px;

            display: flex;
            flex-direction: row;
            justify-content: left;
            align-items: center;
        }
        .card {
            max-width: 500px;
            width: 95%;

            margin: 10px auto 0 auto;
        }

        .seoulTemp {
            font-size: x-large;
        }
    </style>
    <script>
        $(document).ready(function(){
            $.ajax({
                type: "GET",
                url: "http://spartacodingclub.shop/sparta_api/weather/seoul",
                data: {},
                success: function (response) {
                    let nowTemp = (response['temp'])

                    $('#temp').append(nowTemp)

                }
            })
        });
    </script>

</head>

<body>
    <div class="mytitle">
        <h1>악동뮤지션 팬명록</h1>
        <p1 class="seoulTemp">현재기온 : <span id="temp"></span>도</p1>
    </div>
    <div class="mypost">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
            <label for="floatingInput">닉네임</label>
        </div>

        <div>
            <div class="form-floating">
                <textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2"
                          style="height: 100px"></textarea>
                <label for="floatingTextarea2">응원댓글</label>
            </div>
        </div>
        <div class="mybut">
            <button type="button" class="btn btn-dark">응원 남기기</button>
        </div>

    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
    <div class="card">
        <div class="card-body">
            <blockquote class="blockquote mb-0">
                <p>새로운 앨범 너무 멋져요!</p>
                <footer class="blockquote-footer">- 고빵맨 <cite title="Source Title"></cite>
                </footer>
            </blockquote>
        </div>
    </div>
</body>

</html>

 


 

3. 웹 프로그래밍 A-Z 기초 3


Python / 웹 스크래핑 / Mongodb


< 로드가 다 되면 실행되는 함수 >

$(document).ready(function(){
  listing();
});

function listing() {
	console.log('화면 로딩 후 잘 실행되었습니다');
}

 

JQury와 JS를 같이 사용

 

- 웹스크래핑

추가 패키지 : bs4

 

< 웹 스크래핑 기본 세팅 >

import requests
from bs4 import BeautifulSoup

# 타겟 URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')

#############################
# (입맛에 맞게 코딩)
#############################

< select / select_one 이용하여 데이터 가져오기 >

# select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr') 

#가져오고 싶은 데이터의 크롬 개발자도구에서 selector 복사를 해온다.

# movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    if a_tag is not None:
        # a의 text를 찍어본다.
        print (a_tag.text)
        
##########################################
#beautifulsoup 내 select에 미리 정의된 다른 방법
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')

soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')

# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')

# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
##########################################

 

- Mongodb

추가 패키지 : pymongo

< pymongo로 db 조작하기 >

from pymongo import MongoClient
client = MongoClient('mongodb+srv://id:<password>@cluster0.bfqfr.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta


'''# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)

# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})

# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))

# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})

# 지우기 - 예시
db.users.delete_one({'name':'bobby'})'''

 

웹 스크래핑의 결과 or post 한 자료 등을 mongodb에 저장하고 저장된 내용을 필요에 따라 불러와서 사용

 

< 지니뮤직 스크래핑 숙제 코드 >

(코드를 보고싶다면 더보기를 눌러주세요!)

더보기
# 크롤링 기본세팅
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

print(soup)

# 순위 / 곡 제목 / 가수 스크래핑
# strip() 연구

musics = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for m in musics:
    a = m.select_one('td.number')
    rank = a.text[:2].strip()
    music = m.select_one('td.info > a.title.ellipsis').text.strip()
    singer = m.select_one('td.info > a.artist.ellipsis').text
    print(rank, music, singer)

 


 

4. 웹 프로그래밍 A-Z 기초 4


Flask 


- Flask

추가 패키지 : flask

< flask 시작 코드 >

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

크롬에서 localhost:5000으로 접속하면 해당 페이지를 볼 수 있다.

 

< 주의사항 >

from flask import Flask, render_template
app = Flask(__name__)

## URL 별로 함수명이 같거나,
## route('/') 등의 주소가 같으면 안됩니다.

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

if __name__ == '__main__':
   app.run('0.0.0.0', port=5000, debug=True)

 

< GET 요청 API 코드 & GET 요청 확인 Ajax 코드 >

#python get요청 api코드
@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
   

#javascript get 요청 확인 Ajax코드
$.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
    }
  })

 

< POST 요청 API코드 & POST 요청 확인 Ajax 코드 >

# python post 요청 api 코드
@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
   
   
# javascript post 요청 확인 Ajax 코드
$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
    }
  })

 

< 팬명록 완성하기 숙제 코드 >

(코드를 보고싶다면 더보기를 눌러주세요!)

더보기

< app.py 코드 >

from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.bfqfr.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta

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

@app.route("/homework", methods=["POST"])
def homework_post():
    fan_nickname_receive = request.form['fan_nickname_give']
    fan_comment_receive = request.form['fan_comment_give']

    doc = {
        'nickname': fan_nickname_receive,
        'comment': fan_comment_receive
    }

    db.homework.insert_one(doc)

    return jsonify({'msg': '작성 완료! 고마워!!'})

@app.route("/homework", methods=["GET"])
def homework_get():
    fans = list(db.homework.find({}, {'_id': False}))

    return jsonify({'fans':fans})

# db.homework.update_one({'nickname':'꿀케미'},{'$set':{'nickname':'환상케미'}})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

 

< index.html 코드 >

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta property="og:title" content="악동뮤지션 팬명록" />
    <meta property="og:description" content="악뮤 노래를 좋아한다면?! 응원한마디하러 GoGo!!" />
    <meta property="og:image" content="https://img2.quasarzone.co.kr/web/editor/1910/1910obj___1247488417.jpg" />

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
            crossorigin="anonymous"></script>

    <title>미니홈피 - 팬명록</title>

    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200;300;400;500;600;700;900&display=swap"
          rel="stylesheet">
    <style>
        * {
            font-family: 'Noto Serif KR', serif;
        }

        .mypic {
            width: 100%;
            height: 300px;

            background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url('https://file.mk.co.kr/meet/neds/2019/10/image_readtop_2019_783017_15698844653918925.jpg');
            background-position: center 30%;
            background-size: cover;

            color: white;

            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
        }

        .mypost {
            width: 95%;
            max-width: 500px;
            margin: 20px auto 20px auto;

            box-shadow: 0px 0px 3px 0px black;
            padding: 20px;
        }

        .mypost > button {
            margin-top: 15px;
        }

        .mycards {
            width: 95%;
            max-width: 500px;
            margin: auto;
        }

        .mycards > .card {
            margin-top: 10px;
            margin-bottom: 10px;
        }
    </style>
    <script>
        $(document).ready(function () {
            set_temp()
            show_comment()
        });

        function set_temp() {
            $.ajax({
                type: "GET",
                url: "http://spartacodingclub.shop/sparta_api/weather/seoul",
                data: {},
                success: function (response) {
                    $('#temp').text(response['temp'])
                }
            })
        }

        function save_comment() {
            let nickname = $('#name').val()
            let comment = $('#comment').val()

            $.ajax({
                type: 'POST',
                url: '/homework',
                data: {fan_nickname_give: nickname, fan_comment_give: comment},
                success: function (response) {
                    alert(response['msg'])
                    window.location.reload()
                }
            })
        }

        function show_comment() {
            $.ajax({
                type: "GET",
                url: "/homework",
                data: {},
                success: function (response) {
                    let rows = response['fans']
                    for (let i = 0; i < rows.length; i++){
                        let nickname = rows[i]['nickname']
                        let comment = rows[i]['comment']

                        let temp_html = `<div class="card">
                                            <div class="card-body">
                                                <blockquote class="blockquote mb-0">
                                                    <p>${comment}</p>
                                                    <footer class="blockquote-footer">${nickname}</footer>
                                                </blockquote>
                                            </div>
                                        </div>`
                        $('#comment-list').append(temp_html)
                    }
                }
            });
        }
    </script>
</head>
<body>
<div class="mypic">
    <h1>악동뮤지션 팬명록</h1>
    <p>현재기온: <span id="temp">36</span>도</p>
</div>
<div class="mypost">
    <div class="form-floating mb-3">
        <input type="text" class="form-control" id="name" placeholder="url">
        <label for="floatingInput">닉네임</label>
    </div>
    <div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="comment"
          style="height: 100px"></textarea>
        <label for="floatingTextarea2">응원댓글</label>
    </div>
    <button onclick="save_comment()" type="button" class="btn btn-dark">응원 남기기</button>
</div>
<div class="mycards" id="comment-list">
</div>
</body>
</html>

 


 

5. 웹 프로그래밍 A-Z 기초 5


AWS 서버 구매하기 / 서버 세팅하기 / nogup 설정하기 / 도메인 연결하기


개인적으로 가장 수월(?) 하고 재밌었던 구간이었다.

가비아에서 도메인을, AWS 서버를 구매해서 서로 연동시켜주고 Filezilla를 통해 그동안 작업하여 완성한 파일들을 보내주니 인터넷에서 접속이 가능한 웹페이지가 만들어졌다.

도메인 가격은. shop 이 붙은 주소를 구매하여 1년에 550원!

나머지는 전부 무료로 이용할 수 있어서 생각보다 투자금 없이 웹을 개발할 수 있었다. (이것도 개발이라고 할 수 있을진 모르겠지만,,)

 

< 숙제 팬명록 주소 >

http://goodvoice.shop/

 

악동뮤지션 팬명록

악뮤 노래를 좋아한다면?! 응원한마디하러 GoGo!!

goodvoice.shop

 

6. 1주 차 후기

커리큘럼 자체가 지식을 전달해주기보다 스스로 과제를 해결해 나가는 방식이다 보니 아무래도 코딩을 처음 시작하는 코린이에겐 친절한 과정은 아니었다. 게다가 3일 차에 실시된 타임어택 구현 테스트는 모두를 혼란에 빠트리게 되었는데 범위가 무려 웹 개발 기초 수업 전체였다. (이 사람들 정말 자비가 없구나,,)

진도가 충분하지 않았던 나는 문제 이해는커녕 pymongo에 회원 가입하는데만 시간의 대부분을 쏟았고 app.py가 뭔지도 모른 체 테스트가 끝나게 되었다. 

 

12월 17일 (금) / 웹 개발 기초과정을 전부 이수하고 어느 정도 자신감을 가진채 타임어택 구현 테스트에 재도전을 하게 되었는데,, 시작부터 오류에 빠져 헤매다가 자신감을 모두 반납한 채 정답을 보게 되었다.

분명 웹 기초가 시험범위랬으면서 배우지 않은게 많이 보였고, 특히 문제의 힌트로 주어졌던 distinct는 distict로 잘못 기재되어 있어서 혼란을 주었다. (이게 진짜 있는 함수인 줄 알고 혼신의 구글링을,,)

구글에 검색해보니 생각보다 자주있는 오타인거 같다.

 

처음부터 헤매던 오류는 정답을 보고 해결되었는데, 회고록을 작성 중에 그 이유를 알게 되었다.

(코드를 보고싶다면 더보기를 눌러주세요!)

더보기

< 오류 코드 >

오류 내용 : Uncaught TypeError: Cannot read properties of undefined (reading 'codes')

#app.py 

@app.route('/dbStock', methods=['GET'])
def recommend_receive():
    codes = list(db.codes.find({}).distinct("group"))
    return jsonify({'codes': codes})
    
 
 
 # index.html
        function recommend() {
            $.ajax({
                type: 'GET',
                url: '/dbStock',
                data: {},
                success: function (response) {
                    console.log(response)['codes']
                }
            })
        }

 

< 정답 코드 > 

#app.py 

@app.route('/dbStock', methods=['GET'])
def recommend_receive():
    codes = list(db.codes.find({}).distinct("group"))
    return jsonify(codes)
    
 
 
 # index.html
 function recommend() {
            $.ajax({
                type: 'GET',
                url: '/dbStock',
                data: {},
                success: function (response) {
                    console.log(response)
                    }

 

< 오류 원인 해결 코드 > 

#app.py 

@app.route('/dbStock', methods=['GET'])
def recommend_receive():
    codes = list(db.codes.find({}).distinct("group"))
    return jsonify({'codes': codes})
    
 
 
 # index.html
 function recommend() {
            $.ajax({
                type: 'GET',
                url: '/dbStock',
                data: {},
                success: function (response) {
                    console.log(response['codes'])
                    }

 

mongodb에서 데이터를 가져올 때 딕셔너리 값으로 리턴을 해줬는데 콘솔에 띄울 때 키값의 위치를 잘못 기재해서 오류가 발생했으며 정답에서는 리스트로 리턴을 해줘서 키값을 입력할 필요가 없었다.

 

♪ 목표 ♪ : 다음 주까지 타임어택 구현 테스트 코드 분석하고 답안지 보지 않고 시간 내 구현하기

 

주간 회고록을 작성하며 느낀건데,, 이게 의외로 시간이 많이 걸린다. 제대로 공부한 내용을 기록하려면 하루종일 해도 모자라지 않을까 싶다. 시간 효율을 따지면 그냥 복습을 하는 게 더 좋은 선택 같지만 데이터가 쌓이면 쌓일수록 내 자산이 되겠지??

 

마지막으로 게더에서 팀원들과 대화하며 공부하는게 생각보다 재밌다. 코딩에 입문한지 2주도 안돼서 모르는 것도 많아 수업 따라가기도 벅찬데 팀원들과 소통하면서 많은 부분을 채울 수 있었고, 타임어택 구현 테스트 등 공부하다 멘탈이 흔들릴 때 팀원들과 대화하면서 refresh 할 수 있었다. (때로는 춤을 추면서~ 게더에서 춤은 Ctrl + z!)

 

3팀 제로 투 원! 다음 한주도 파이팅!!