<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>codename_suding.log</title>
        <link>https://velog.io/</link>
        <description>웹개발자가 되고 싶은 수딩의 코딩 일지 </description>
        <lastBuildDate>Sat, 19 Nov 2022 14:49:49 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>codename_suding.log</title>
            <url>https://velog.velcdn.com/images/codename_suding/profile/55b4ae98-fff6-4da0-b26d-5b1cb9355105/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. codename_suding.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/codename_suding" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[TIL_JavaScript 22년 11월 18일]]></title>
            <link>https://velog.io/@codename_suding/TILJavaScript-22%EB%85%84-11%EC%9B%94-18%EC%9D%BC-kn4bd9mo</link>
            <guid>https://velog.io/@codename_suding/TILJavaScript-22%EB%85%84-11%EC%9B%94-18%EC%9D%BC-kn4bd9mo</guid>
            <pubDate>Sat, 19 Nov 2022 14:49:49 GMT</pubDate>
            <description><![CDATA[<p>오늘 공부내용: 프로그래머스 알고리즘 문제 풀기.</p>
<p>내개 생각한 알고리즘 문제 풀이 법</p>
<p>1) 문제, 예제, 조건을 읽고 규칙과 사용가능한 메소드를 생각해본다.
2) 손으로 공책에 문제를 그려보면서 규칙을 찾고 코드의 뼈대를 잡아본다
3) 코드를 만들기 시작했는데 아, 근데 이거 어떻게 하지? 여기서 막히면 MDN에가서 내가 사용하려 했던 객체를 찾아보고 예시를 보고 적용가능한지 코드를 돌려본다 
<em>** 여기서 주의! 문제 전체를 구글링하면 답이 나올수 있으니 최대한 내가 찾고자 하는 객체만 찾아보자.</em>
4) 이것도 해보고 저것도 해봤는데 진쨔 모르겠다 하면, 지금까지 풀이를 정리하고 다음 문제로 넘어가고 도움을 요청하자
5) 답지를 보는건 최대한 보류</p>
<p>고수들은 알고리즘을 어떻게 푸는지 유트브도 좀 찾아보고 기술매니저님이랑 달리기반에 있는 분들에게도 조언을 구해야겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_JavaScript 22년 11월 18일]]></title>
            <link>https://velog.io/@codename_suding/TILJavaScript-22%EB%85%84-11%EC%9B%94-18%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILJavaScript-22%EB%85%84-11%EC%9B%94-18%EC%9D%BC</guid>
            <pubDate>Fri, 18 Nov 2022 13:46:00 GMT</pubDate>
            <description><![CDATA[<aside>
 💡 JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ? 

</aside>

<h3 id="느슨한-타입loosely-typed의-동적dynamic-언어">느슨한 타입(loosely typed)의 동적(dynamic) 언어</h3>
<ul>
<li>JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당)이 가능하다</li>
</ul>
<pre><code class="language-jsx">let foo = 45 // foo는 숫자
foo =&#39;age&#39; // 이제 foo 는 문자가 된다 
foo = true // boolean 이 된다, 출력하면 true 가 나온다 </code></pre>
<ul>
<li>JavaScript 기본적인 자료형</li>
</ul>
<pre><code>숫자형 – 정수, 부동 소수점 숫자 등의 숫자를 나타낼 때 사용합니다. 정수의 한계는 ±253 입니다.
bigint – 길이 제약 없이 정수를 나타낼 수 있습니다.
문자형 – 빈 문자열이나 글자들로 이뤄진 문자열을 나타낼 때 사용합니다. 단일 문자를 나타내는 별도의 자료형은 없습니다.
불린형 – true, false를 나타낼 때 사용합니다.
null – null 값만을 위한 독립 자료형입니다. null은 알 수 없는 값을 나타냅니다.
undefined – undefined 값만을 위한 독립 자료형입니다. undefined는 할당되지 않은 값을 나타냅니다.
객체형 – 복잡한 데이터 구조를 표현할 때 사용합니다.
심볼형 – 객체의 고유 식별자를 만들 때 사용합니다.</code></pre><h3 id="javascript-형변환-type-conversion">JavaScript 형변환 (type conversion)</h3>
<ul>
<li>함수와 연산자에 전달되는 값은 대부분 적절한 자료형으로 자동 변환되는 것을 형변환이라고 한다</li>
<li>전달받은 값을 의도를 갖고 원하는 타입으로 변환(명시적 변환)해 주는 경우도 형 변환이라고 할 수 있다</li>
</ul>
<pre><code>alert (100) // 100 은 문자로 변환된다 
alert (Number(&#39;100&#39;)) // 100은 숫자로 변환된다 
alert (boolean(100)) // true 가 출력 된다 </code></pre><ul>
<li>문자형 변환은 무엇을 출력할때 주로 일어남</li>
<li>숫자형으로 변환할 때 적용되는 규칙 , 연산시 주로 일어남</li>
</ul>
<pre><code>| 전달 받은 값 | 형 변환 후 |
| --- | --- |
| undefined | NaN |
| null | 0 |
| true and false | 1 and 0 |
| string | 문자열 처음과 끝의 공백은 제거됨
공백후 남아있는 문자열이 없다면 0
그렇지 않다면 숫자를 읽고 변환
변환에 실패하면 NaN |</code></pre><ul>
<li>불린형으로 변환할 때 적용되는 규칙</li>
</ul>
<pre><code>| 전달 받은 값 | 형 변환 후  |
| --- | --- |
| 0, undefiend, null, NaN, ““ | false, ” &quot;는 빈 문자열이기 때문에 false |
| 그 외의 값 | true, ”0” 문자열 0은 값이 있기 때문에 true 공백이 있는 문자열도 비어있지 않기 때문에 true  |</code></pre><ul>
<li><a href="https://www.notion.so/11-18-47bc709864fb421db9bd0af6012dfc77">https://www.notion.so/subinbaek/11-18-47bc709864fb421db9bd0af6012dfc77#5c420ab048f5423e8ac19d859792400d</a></li>
</ul>
<h3 id="비교-연산자와-의-차이에-대해-알아보자">비교 연산자와 ==,===의 차이에 대해 알아보자</h3>
<p>== (동등연산자) </p>
<ul>
<li>비교하는 자료형의 값이 숫자가 아니면 자바스크립트는 숫자로 변환하여 비교한다</li>
<li>0 과 false 를 구분하지 못한다</li>
<li>느슨한 비교</li>
<li>==의 특성에 대해 추가로 알아보기:<ul>
<li>== 은 undefined 나 null을 숫자로 변환하지 않는다</li>
</ul>
</li>
</ul>
<p>=== (일치연산자)</p>
<ul>
<li>엄격한 동등연산자로 문자를 숫자로 변환하지 않는다 따라서 버그를 피하기 위해 일치 연산자를 사용해야 한다</li>
<li>null === undefined를 비교시 두 값의 타입이 다르기 때문에 false 이다</li>
</ul>
<pre><code class="language-jsx">alert(0 == false); // true를 출력한다 false 가 숫자 0으로 변환되기 때문
let a = &#39;3&#39;
let b= 3
alert(a === b) // false 
alert(a ==b) // true</code></pre>
<h3 id="느슨한-타입loosely-typed의-동적dynamic-언어의-문제점은-무엇이고-보완할-수-있는-방법에는-무엇이-있을지-생각해보세요">느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점은 무엇이고 보완할 수 있는 방법에는 무엇이 있을지 생각해보세요.</h3>
<ul>
<li>느슨한 타입의 언어는 변수값을 변환시킬수 있고 런타임시 변수 타입이 결정되는 특성이 있다.  이러한 특성은 자바스크립트가 개발자를 편하게도 해주지만 오류 발생이 잦아 단점으로 꼽히기도 한다. 위에서 ==느슨한 비교시과 ===을 비교한것 처럼 이런 오류를 방지하기위해 use strict type 을 사용 하기도한다.</li>
<li>나아가 자바스크립트의 동적언어의 단점을 커버하기 위해 type script를 사용하기도 한다</li>
</ul>
<h3 id="undefined-와-null-의-미세한-차이-비교">undefined 와 null 의 미세한 차이 비교</h3>
<ul>
<li>자바스크립트에서 null 은 존재하지 않는값, 비어있음을 뜻한다</li>
<li>undefined은 변수는 선언했지만 값이 설정되지 않은 상태를 나타낸다</li>
<li>null 과 undefined를 숫자형으로 변환하면 null =0 , undefined = NaN 이 된다</li>
</ul>
<aside>
💡 JavaScript 객체와 불변성이란 ?

</aside>

<h3 id="객체란">객체란?</h3>
<p>객체는 8개의 자료형 중에 하나이지만 문자와 숫자만 담을수 있는 원시형이 아니기 때문에 다양한 데이터를 담을 수 있다 </p>
<p>코드</p>
<pre><code class="language-jsx">let user = {
name: &#39;dora&#39;,
age: 7,};</code></pre>
<p>폴더 예시</p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/007bae02-a53f-43f5-ba42-4a574dd5c482/Screen_Shot_2022-11-18_at_3.19.07_PM.png" alt="Screen Shot 2022-11-18 at 3.19.07 PM.png"></p>
<p>폴더로 예시 설명</p>
<ul>
<li><p>객체 = 폴더 = user</p>
</li>
<li><p>property = 파일  </p>
</li>
<li><p>객체 key = 파일명 = name, age </p>
</li>
<li><p>객체 value = 파일에 담긴 데이터 = dora , 7</p>
</li>
</ul>
<h3 id="데이터-타입의-종류-기본형-데이터와-참조형-데이터">데이터 타입의 종류: 기본형 데이터와 참조형 데이터</h3>
<table>
<thead>
<tr>
<th>비교 값</th>
<th>기본형 타입(Primitive Type)</th>
<th>참조형 타입(Reference Type)</th>
</tr>
</thead>
<tbody><tr>
<td>데이터 종류</td>
<td>숫자(Number), bigInt,문자열(String),불리언(Boolean), null, undefined, 심볼(Symbol)</td>
<td>객체(Object),배열(Array),함수(Function),날짜(Date),정규표현식(RegExp),Map,WeakMapSet,WeakSet</td>
</tr>
</tbody></table>
<h3 id="불변-객체를-만드는-방법">불변 객체를 만드는 방법</h3>
<p>레퍼런스: <a href="https://spiderwebcoding.tistory.com/8">https://spiderwebcoding.tistory.com/8</a></p>
<ul>
<li>const 로 객체를 만들면 객체는 변할수 없지만 안에 담겨진 프로퍼티는 바뀔 수 있다.<ul>
<li>상수로 선언된 user 라는 객체는 객체 이름을 바꿀수 없지만 안에 담긴 자료는 바뀔수 있다.</li>
</ul>
</li>
<li>object.freeze() 는 객체안에 새로운 속성을 넣지 못하게 하는 메서드<ul>
<li>다만 변수로 선언된 객체는 재할당이 가능하여 속성 값이 바뀔 수 있다</li>
</ul>
</li>
<li>const 의 재할당 불가 + object.freeze의 객체 속성 변경 불가를 합치면 불변 객체를 만들 수 있다</li>
</ul>
<pre><code class="language-jsx">const test = {         //const 로 객체를 재할당하지 못하게 한다 
    &#39;name&#39; : &#39;jung&#39;
};

Object.freeze(test);  // object freeze로 test 의 속성을 수정하지 못하게 한다 </code></pre>
<ul>
<li>얕은 복사와 깊은 복사</li>
</ul>
<p>레퍼런스: <a href="https://velog.io/@th0566/Javascript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC">https://velog.io/@th0566/Javascript-얕은-복사-깊은-복사</a></p>
<aside>
💡 호이스팅과 TDZ는 무엇일까 ?

</aside>

<p>스코프</p>
<ul>
<li><p>자바스크립트가 코드를 읽어오는 구역</p>
<p>호이스팅</p>
</li>
<li><p>변수나 함수를 선언하면 코드가 실행되기 이전에, 스코프 상단 선언이 끌어 올려 지고 메모리에 선언이 저장되는 현상이다</p>
</li>
</ul>
<p>TDZ</p>
<ul>
<li>일시적인 사각지대라는 뜻으로 let 과 const 의 경우 변수가 선언됬을때 TDZ에 속하기 때문에 호이스팅이 되지 않는것 처럼 보이지만 실제로 호이스팅이 된다.</li>
</ul>
<p>레퍼렌스: <a href="https://noogoonaa.tistory.com/78">https://noogoonaa.tistory.com/78</a></p>
<aside>
💡 *나중에 조금더 알아보기*

</aside>

<ul>
<li><p>얕은 복사와 깊은 복사</p>
<p>  레퍼런스: <a href="https://velog.io/@th0566/Javascript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC">https://velog.io/@th0566/Javascript-얕은-복사-깊은-복사</a></p>
</li>
<li><p>함수 선언문과 함수 표현식에서 호이스팅 방식의 차이</p>
</li>
<li><p>여러분이 많이 작성해온 let, const, var, function 이 어떤 원리로 실행되는지 알 수 있어요.</p>
</li>
<li><p>실행 컨텍스트와 콜 스택</p>
</li>
<li><p>스코프 체인, 변수 은닉화</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[미니프로젝트 TIL 22년 14~17일]]></title>
            <link>https://velog.io/@codename_suding/%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-TIL</link>
            <guid>https://velog.io/@codename_suding/%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-TIL</guid>
            <pubDate>Thu, 17 Nov 2022 13:03:10 GMT</pubDate>
            <description><![CDATA[<p>회고록</p>
<p><strong>느낀점</strong></p>
<p>우선 4일간 프로젝트를 진행하며 배운점은 아직 내가 구상한 아이디어를  코딩으로 구현해내는걸 자유롭게 하지 못한다는걸 깨닳았다. </p>
<p>그 부분에서 실제 내가 맡은 기능을 구현할때 막히는 부분이 상당히 많았고 기획한 서비스를  구현하려면 당연히 알고리즘을 짜고 기능 구현을 해야겠지만 유저 플로우, 화면간의 연결, 디비구조, 보안 등의 실제 서비스를 만들때 고려해야할 부분들을 생각하게 되는 계기가 되었다. </p>
<p><strong>배운점</strong></p>
<p>사실 기능구현 보다는 기획이나 회의에 시간을 너무 많이 쏟은것 같아서 이부분은 다음 프로젝트때 참고하여 최대한 코딩에 집중하는 시간을 갖도록 해야겠다. </p>
<p>우선 에러들을 정말 많이 마주했는데 대부분 내가 자바스크립트의 문법, 자료구조 등이 아직 미숙해서 그랬던것 같다. 자바스크립트 문법 배우는것도 중요하지만 자바스크립트가 동작하는 구조, 특성들 프레임워크라고하나? 이런것들을 더 많이 접해보고 배워야할것 같다. </p>
<p>이번 협업을 통해서 깃과 깃헙을 처음 사용하게 됬고 사용법을 조금이나마 숙지한것 같다. 내 프로젝트를 진행할때도 버전관리를 위해서 앞으로 깃을 이용해야겠다. 실제 취업시장에서 깃을 못하는 개발자는 설자리가 없다고 하니 잘 배워둬야겠다.</p>
<p>추가로 이번에 파이참 세션 기능을 사용해서 한 파일에서 같이 코딩을 진행하는 신기한 경험을 해봤는데 실제로 개발자들이 원격근무를 많이 하다보니 이렇게 프로그램을 잘 이용할줄 알면 협업에 많은 도움이 될것 같다.</p>
<p>정말 어려웠던 점은 나도 아직 내가 할 일을 끝내지 못했는데 다른 팀원들이 질문을 던진다거나 로직에 대해서 수정이 필요한점을 말했을 때 시간관리를 잘 하지 못해서 코딩에 집중하는 시간이 부족했던것 같다. 그리고 정말 도와주고 싶지만 몰라서 돕지 못했던 점도 있어 부담감을 느끼기도 했는데 사실 남이 모르는거 나도 모를 경우가 크니 시간적 여유가 있었다면 같이 찾아보고 공부하는 시간을 가졌을것 같다.</p>
<p><strong>시도해볼것</strong></p>
<p>내가 구현하지 못했던 캘린더 조회시 모달창으로 데이터 보여주기를 완성해봐야겠다. 그리고 코드의 재사용 가능성을 고려해서 노가다로 1일 부터 7일 까지의 기능을 구현하기 위해 각각의 코드를 짜지 않고 하나의 기능을 재사용할수 있게 코드를 수정해보고 싶다. </p>
<p>프런트에서 캘린더 이름을 DB에서 조회 요청을하면 서버는 몽고디비에서 해당 조건을 갖은 데이터를 찾아서 jsonify하여 전달해주는 개념과 로직은 이해 했는데 캘린더 이름을 강제로 코드에 박아두지 않고 쿠키나 디비에서 불러와서 서버에게 GET 요청을 할수 있을지 고민이 필요하고 기술 매니저님께도 한번 문의 드리면 좋겠다. </p>
<p>추가로 연산작업이나 알고리즘을 백엔드에서 구현하는게 좋다고 여러번 들었지만 어떻게 구현해야할지 막막했던 부분이 있었는데 어떻게 하면 될지 해결방안까지 찾아서 프로젝트를 완성하고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GIT 연결하기, 브랜치 생성하기 ]]></title>
            <link>https://velog.io/@codename_suding/GIT-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@codename_suding/GIT-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 15 Nov 2022 02:41:22 GMT</pubDate>
            <description><![CDATA[<h4 id="레퍼렌스-httpsifuwannatistorycom283">레퍼렌스: <a href="https://ifuwanna.tistory.com/283">https://ifuwanna.tistory.com/283</a></h4>
<hr>
<h3 id="vs-code-에-깃-연결하기">VS code 에 깃 연결하기</h3>
<p>(팀에서 먼저 깃헙에 repository를 만들어주셔서 깃헙 html 주소를 받아왔다)</p>
<p>vscode 열기 -&gt; repository clone -&gt; 로컬에 repository 저장소 설정 -&gt; 저장 </p>
<h3 id="브랜치-만들기">브랜치 만들기</h3>
<p>깃에서 main 브랜치는 프로젝트에 적용할 파일들을 업로드하는 메인 브랜치이다. 
(여기에 만들어진 폴더랑 파일들을 내 로컬에 클론해 두었다.)</p>
<p>내가 만든 파일들의 버전관리와 팀과 공유를 위해 내 브랜치를 만들었다. 
vscode -&gt; sorce control -&gt; repository 에서 branch -&gt; create branch -&gt; branch 이름 입력-&gt; 완료</p>
<p>내가 생성한 tree 브랜치를 remote 연결했더니,이미 remote origin에 연결되었다 
git remote add origin (git html) </p>
<h3 id="브랜치-push-하기">브랜치 push 하기</h3>
<p>git push origin (브랜치명) 
완료하면 깃헙에 내 브랜치가 생성된걸 볼수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[git error]]></title>
            <link>https://velog.io/@codename_suding/git-error</link>
            <guid>https://velog.io/@codename_suding/git-error</guid>
            <pubDate>Mon, 14 Nov 2022 15:23:47 GMT</pubDate>
            <description><![CDATA[<p>11/14일
에러코드 
fatal: The current branch calendarstree has no upstream branch.
To push the current branch and set the remote as upstream, use
    git push --set-upstream origin calendarstree</p>
<p>원인
내가 생성하고자 하는 calendarstree 브랜치의 상위 브랜치가 없어서
해결방법
git push --set-upstream origin calendarstree 실행 </p>
<p>11/15일
오류
깃저장소가 잘못 설정되어있었던걸 확인했다. 
원인
repository 가 두개가 만들어져있었는데 모두 삭제하고 새로 생성했다. 
해결방법
순서: vscode 열기 -&gt; repository cloning -&gt; git html 입력 -&gt; 저장소 설정 (내 로컬파일 폴더) -&gt; 완료! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_mini project 22년 11월 14일]]></title>
            <link>https://velog.io/@codename_suding/TILmini-project-22%EB%85%84-11%EC%9B%94-14%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILmini-project-22%EB%85%84-11%EC%9B%94-14%EC%9D%BC</guid>
            <pubDate>Mon, 14 Nov 2022 15:18:57 GMT</pubDate>
            <description><![CDATA[<h1 id="1주차-풀스택-미니-프로젝트-팀플-1개">1주차 풀스택 미니 프로젝트 (팀플 1개)</h1>
<p>설명: 파이썬, 몽고디비, 자바스크립트 활용하여 4일만에 미니프로젝트 만들기 </p>
<h2 id="메인-이벤트">메인 이벤트</h2>
<p>D1 - 프로젝트 기획, github repository만들기, 기술매니저 면담 </p>
<p>D2 - 프로젝트 디벨롭</p>
<p>D3 - 프로젝트 디벨롭, 기술매니저 면담</p>
<p>D4 - 프로젝트 제출, 발표 </p>
<h2 id="프로젝트-기획서">프로젝트 기획서</h2>
<p><a href="https://www.notion.so/S-A-706d78f9b03c4483a2e8f0ceb56575c7">S.A </a></p>
<h2 id="회고록">회고록</h2>
<ul>
<li><p>D1 회고록</p>
<ul>
<li><p>셀프 평가</p>
<ul>
<li>팀프로젝트 스타트를 잘 끊었다. 프로젝트 주제도 내 아이디어가 채택되었고 오늘 기술매니저님께 프로젝트 설명 발표도 나서서 진행했다. 나는 원래 발표를 싫어하는데, 내 아이디어로 시작된 프로젝트라서 내가 적극적으로 참여하게 됐다.</li>
</ul>
</li>
<li><p>잘한 점</p>
<ul>
<li>팀장님이 발표를 어려워 하셔서 내가 나서서 기술 매니저님께 프로젝트 설명을 진행했다</li>
<li>아이디어 선정할때 회의를 주도해서 아이디어선정, 프로젝트명 결정을 내렸다</li>
<li>기술매니저님 면담 내용 회의록을 작성해서 팀에 공유했고 이를 바탕으로 Starting Assignment 문서를 수정했다</li>
</ul>
</li>
<li><p>개선할 점</p>
<ul>
<li>나와 민욱님이 깃과 깃헙이 아직 능숙하지 않았어서 한울님이 고생하셨다. 친절하게 터미널창에서 git push 하는것도 알려주셨다. 깃 사용법을 숙지하자</li>
</ul>
</li>
<li><p>내일 시도해볼 것</p>
<ul>
<li><p>깃강의 듣기, 한울님이 공유한 깃 자료 읽기</p>
<ul>
<li><a href="https://overcome-the-limits.tistory.com/6">https://overcome-the-limits.tistory.com/6</a></li>
</ul>
</li>
<li><p>왜 내 파일을 실행하면 주소창에 로컬호스트로 연결되지 않고 내 컴퓨터의 파일경로가 뜨는지 이유를 확인하고 해결하기</p>
<ul>
<li><p>내 생각에는 상위 브랜치가 origin master 으로 설정되지 않고 calendarstree 로 생성이 된게 문제 일까?</p>
</li>
<li><p>브랜치 생성하고 push 할때 발생했던 오류</p>
<pre><code class="language-jsx">fatal: The current branch calendarstree has no upstream branch.
To push the current branch and set the remote as upstream, use
  git push --set-upstream origin calendarstree</code></pre>
</li>
</ul>
</li>
<li><p>내일 내가 구현해야하는 기능, 화면 기획하기 (어떻게 만들지 우선 구도를 짜고 그다음에 코딩을 하자)</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_javascript 22년 11월 12일]]></title>
            <link>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%94-12%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%94-12%EC%9D%BC</guid>
            <pubDate>Sat, 12 Nov 2022 16:59:03 GMT</pubDate>
            <description><![CDATA[<h3 id="학습-목표">학습 목표</h3>
<ul>
<li><input disabled="" type="checkbox"> 챕터 3,4, 예제 복습하기</li>
<li><input checked="" disabled="" type="checkbox"> 챕터 5-1 복습하기</li>
<li><input checked="" disabled="" type="checkbox"> 프로그래머스 예제 풀어보기</li>
<li><input checked="" disabled="" type="checkbox"> 잘한점, 개선할점, 새로 시도해볼점 기록하기</li>
</ul>
<h3 id="회고록">회고록</h3>
<ul>
<li>셀프 평가<ul>
<li>이번 챕터는 어려웠다. 아직 모르는 호이스팅의 개념이 잘 머리에 입력되어있어야 하는데 키워드를 들었지만 자세하게 확인해보지 않아서 계속해서 키워드가 나와도 정확하게 이해하지 못했던것 같다. 매번 정리하기 어렵겠지만 키워드를 모아 두었다가 정리하는 시간을 갖으면 도움이 될것 같다</li>
</ul>
</li>
<li>잘한 점<ul>
<li>프로그래머스 문제 오류를 직접 해결했다. 다른 사람이 푼 답지를 보지 않고 우선 내가 짠 코드에서 뭘 바꾸면 답이 나올지 계속 디버깅하면서 답을 찾아갔다. 어떻게든 구현해야하는 답을 구현해 보는 경험을 하게 됬다.</li>
</ul>
</li>
<li>개선할 점<ul>
<li>구글링을 잘 해서 만들어진 모듈을 활용하는 것도 실력이다!</li>
</ul>
</li>
<li>내일 시도해볼 것<ul>
<li>호이스팅이라는 키워드가 튜터님과 수현님이 계속 반복해서 언급하는데 알아봐야겠다.</li>
<li>동기, 비동기 (동기화) 키워드 배우기</li>
</ul>
</li>
</ul>
<h3 id="새로운-개념">새로운 개념</h3>
<p>5-1:</p>
<ul>
<li><p>콜백함수 (callback function)</p>
<ul>
<li><p>함수는 하나의 자료형이기 때문에 매개변수로 전달할수 있다.</p>
</li>
<li><p>매개변수로 전달하는 함수를 콜백함수라고 한다</p>
<pre><code class="language-jsx">function callThreeTimes (callback){
  for (let i=0; i&lt;3; i++){
  callback(i)
  }
}
function print(i){
  console.log(`${i} 번째 함수 호출`)
}
callThreeTimes(print)

//callThreeTimes() 는 print()함수를 매개변수로 받아 3번 호출한다 
// callThreeTimes() 함수의 내부에는 callback(i)로 함수를 호출하고 있다.
//print() 함수가 print(0), print(1),print(2)로 차례대로 호출되어 콘솔에 찍힌다

&gt; 0번째 함수 호출
  1번째 함수 호출
  2번째 함수 호출
</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="오답노트">오답노트</h3>
<p>콜백함수 코드 처리 순서가 햇갈렸고 팀원들과 토론후  내가 이해한 대로  다시 설명해보겠다.</p>
<ul>
<li>자바스크립트의 호이스팅 때문에 변수, 함수가 제일 최상위로 선언된다.<ul>
<li>그래서 function callThreeTimes (print) 함수는 print () 함수를 callThreeTimes함수의 매게변수로 받는 콜백 함수라는걸 컴퓨터가 알게 된다.</li>
</ul>
</li>
<li>print(i) 함수는 실행하면 콘솔에 i번째 함수 호출이 찍히는것을 컴퓨터가 메모리에 입력하게 된다</li>
<li>callThreeTime 함수는 아래의 반복문 작업 코드를 실행하는데 , i를 print() 함수의 매개로 호출이 되고 콘솔에 i번째 함수 호출 이 찍히게 된다<ul>
<li>print는 console.log(<code>${i}번째 함수 호출</code>) callback(i) 함수로 호출되어서</li>
<li>for 문이 돌면서 i는  0,1,2 라는 값이 처리되고 i 값을 print(i) 넣어서 콘솔로 찍으면</li>
<li>0번째 함수 호출…2번째 함수 호출을 실행하게 된다</li>
</ul>
</li>
</ul>
<p>선언적 함수와 익명 함수의 조합: 익명함수가 호출되는지 이해가 안됨</p>
<pre><code class="language-jsx">함수 = function (){
    console.log(&#39;익명함수&#39;)
}

function 함수() {
    console.log(&#39;선언적함수&#39;)
}

함수 ()
&gt; 익명함수가 실행 된다 </code></pre>
<p>결국 호이스팅을 이해해야 하는데.. (또 나왔네?)</p>
<p>우선 예제 문제로만 봤을 때, 선언적 함수가 먼저 생성되고 → 컴퓨터가 코드 순으로 익명 함수를 실행하게 되는데, 익명함수와 선언적 함수의 이름이 함수()로 같기 때문에 컴퓨터는 선언적 함수가 익명 함수로 바뀐걸로 인식하고 익명함수의 콘솔을 실행한다. </p>
<ul>
<li>익명 함수는  코드가 순차적으로 실행</li>
<li>선언적 함수는 순차</li>
<li>적인 코드 실행 이전에 생성 (호이스팅)</li>
</ul>
<p>프로그래머스 문제 :</p>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/120899">https://school.programmers.co.kr/learn/courses/30/lessons/120899</a></p>
<ul>
<li><p>내 오류: 문제에서 요구하는 최대값의 인덱스와 최대값을 구하시오를 무시하고 최대값만 먼저 찾았더니 정답을 입력했을때 정답의 형식에 맞지 않아서 답이 틀리게 됬다</p>
</li>
<li><p>해결 방법:</p>
<pre><code class="language-jsx">  //내 해결 방법
  function solution  (array) {
      let output = array[0];
      for (const item of array){
          if (output &lt; item){
              output =item
          }
        }

      return [output,array.indexOf(output)]

  }
  const arrayExample= [1,8,3]
  console.log(solution(arrayExample))

  &gt;[8,1] // 8은 최대값, 1은 최대값의 인덱스

  // math 메소드 사용하여 max 값 구하는 방법

  function solution2(array) {
    let max = Math.max(...array);
    return [max, array.indexOf(max)];
  }
  console.log(solution2([1, 2, 3, 4]))</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_javascript 22년 11월11일]]></title>
            <link>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%9411%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%9411%EC%9D%BC</guid>
            <pubDate>Fri, 11 Nov 2022 14:50:11 GMT</pubDate>
            <description><![CDATA[<h3 id="학습-목표">학습 목표</h3>
<ul>
<li><input checked="" disabled="" type="checkbox"> 챕터 5-1 학습, 예제 풀기</li>
<li><input checked="" disabled="" type="checkbox"> 챕터 4 복습</li>
<li><input checked="" disabled="" type="checkbox"> 셀프 평가, 잘한점, 개선할점, 내일 시도할 것 기록하기</li>
</ul>
<h3 id="회고록">회고록</h3>
<ul>
<li>셀프 평가<ul>
<li>어려운 문제들이 나오니 마치 고딩시절 수학공부할때 느꼈던 답답함이 떠올랐다. 그래도 수학은 계산을 내가 해내야만 했지만 코딩은 컴퓨터가 하니까 조금더 수월하다고 생각하자;; 화이팅!</li>
<li>책으로 본 내용이 이해가 안되서 동영상 강의도 다시 돌려보고 다른 유트브 해설도 찾아봤다. 붙잡고 있지말고 해설을 빨리 보자.</li>
<li>팀원들의 강점을 파악한거 같다.<ul>
<li>수현님은 설명을 잘해주신다, 코딩을 1년간 공부하셨다고.</li>
<li>진솔님은 논리적으로 접근을 잘 하신다 그리고 팀원들이 헷갈리는 내용들을 책어디에 있는지 빨리 잘 캐치하고 알려주신다.</li>
<li>나의 강점은 무엇일까? 협업을 위한 분위기 형성, 아이디어 제공?</li>
</ul>
</li>
</ul>
</li>
<li>잘한 점<ul>
<li>학습한 내용을 복습하기위해 프로그래머스에서 알고리즘을 풀어보는게 좋을지 팀에게 물어봤고 이야기를 하다 내일 모임시간에 프로그래머스에서 문제를 하나 풀어보기로 했다!</li>
<li>오늘 이해하지 못했던 예제 문제를 팀에게 설명 부탁하고 내가 이해한것을 다시 한번 설명하는 방법을 거쳤다.</li>
</ul>
</li>
<li>개선할 점<ul>
<li>복습하는 시간은 3-9 시간에 넣지 말아야겠다. 진도가 밀린다.</li>
</ul>
</li>
<li>내일 시도해볼 것<ul>
<li>내가 배운내용을 설명하는 습관을  만들어야겠다</li>
<li>복습은 오전에 9-12에 하자!</li>
</ul>
</li>
</ul>
<h3 id="새로운-개념">새로운 개념</h3>
<p>챕터5-1 함수</p>
<ul>
<li><p>함수의 기본 형태 (익명 vs 선언 함수)</p>
<pre><code class="language-jsx">  function () {}</code></pre>
<ul>
<li><p>익명 함수  (anonymous function)</p>
<ul>
<li><p>함수를 출력할 때 이름이 붙지 않는다</p>
<p>```jsx
const 함수 = function () {
  console.log(&#39;함수 내부의 코드입니다...1&#39;)
console.log(&#39;함수 내부의 코드입니다...2&#39;)
console.log(&#39;함수 내부의 코드입니다...3&#39;)
console.log(&#39;&#39;)
}</p>
<p>함수()
console.log(함수)
//함수를 출력하면 함수에 이름이 붙지 않는다 </p>
</li>
<li><p><em>ƒ (){
   console.log(&#39;함수 내부의 코드입니다...1&#39;)
   console.log(&#39;함수 내부의 코드입니다...2&#39;)
   console.log(&#39;함수 내부의 코드입니다...3&#39;)
   console.log(&#39;&#39;)
}*</em></p>
<pre><code></code></pre></li>
</ul>
</li>
<li><p>선언적 함수</p>
<ul>
<li><p>함수를 출력하면 이름이 붙는다</p>
<p>```jsx
function 함수 () {
  console.log(&#39;함수 내부의 코드입니다...1&#39;)
  console.log(&#39;함수 내부의 코드입니다...2&#39;)
  console.log(&#39;함수 내부의 코드입니다...3&#39;)
  console.log(&#39;&#39;)
}
함수()
console.log(함수)
//함수를 출력하면 함수에 &#39;함수&#39;라는 이름이 붙는다 </p>
</li>
<li><p><em>ƒ (함수){
   console.log(&#39;함수 내부의 코드입니다...1&#39;)
   console.log(&#39;함수 내부의 코드입니다...2&#39;)
   console.log(&#39;함수 내부의 코드입니다...3&#39;)
   console.log(&#39;&#39;)
}*</em></p>
<pre><code></code></pre></li>
</ul>
</li>
</ul>
</li>
<li><p>숫자 계산하기</p>
<pre><code class="language-jsx">  function 함수 (매개변수){
      let output = 초기 값
      코드가 처리 된다
      return output
  }

  최소 값 구하기 
  // 함수 min 으로 선헌하기 매개변수에 배열 넣어 주기 

  function min (array){

  // 초기 값은 배열의 0번째 인덱스 
      let output = array[0]

  // for of 반복문 사용하여 items안에 item(요소)과 output을 하나씩 비교해본다
  // item이 output 보다 작으면 output= item (최소값) 으로 선언한다
  // 배열에 마지막 요소 까지 비교해서 최종적으로 최소값을 리턴한다 
      for (const item of array) {
          if (output &gt; item) {
          output= item 
          }
      }

  //최소값을 리턴한다    
  return output
  }
  const inputArray = [10,3,5,2,1] 
  console.log(min(inputArray))
  &gt; 1</code></pre>
</li>
<li><p>나머지 매개 변수를 사용한 min() 함수</p>
<pre><code class="language-jsx">  // min의 매개변수는 53, 40,1,-3,100인데 이걸 매개변수를 하나씩 찍어주기 귀찬다 
  // min(...items) 라고하면 매개변수들이 items라는 배열안에 들어간다
  function min(...items){
      // 배열의 첫번쩨 인덱스를 최초 값으로 정한다 
      let output = items[0] //53 이 최초값이 된다 
      // output과 배열안에 있는 요소를 비교하기위한 for of 반복문 사용
      for (const item of items){
          // 53과 40 비교했을때 40이 더 작다, 그러니까 40이 outputd이 된다, 마지막 요소까지 비교해서 최소값을 구한다
          if (output &gt; item){
          output = item 
          } 
      }
  // -3가 최소값이 된다 
  return output
  }
  console.log(min(53,40,1,-3,100))
  &gt; -3</code></pre>
</li>
<li><p>전개 연산자 (spread operator)</p>
<ul>
<li><p>전개 연산자를 사용하지 않는 경우 배열이 매개변수로 들어온다</p>
</li>
<li><p>전개 연산자를 사용하는 경우 숫자가 하나하나 전개되어 매개변수로 들어 온다</p>
<pre><code class="language-jsx">//매개변수를 모두 출력하는 함수 
function sample(...items){
  console.log(items)
}

const array= [1,2,3,4]

console.log(sample(array)) //전개연산자를 사용 하지 않을 때 [Array(4)] 또는 [[1,2,3,4,]]
console.log(sample(...array)) // 전개연사잔 사용 할때  [1,2,3,4] </code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="오답노트">오답노트</h3>
<p>매개변수의 자료형에 따라 다르게 작동하는 min () 함수 이해하기가 어려웠다.</p>
<ul>
<li>오늘 팀과 튜터님과 배운 내용을 바탕으로 내가 다시 설명해보겠다</li>
<li>Array.isArray() 는 object type이 배열인지 확인 할때 쓰는 메소드</li>
<li>typeof () 는 object의 자료 형태를 확인할때 쓴다</li>
</ul>
<pre><code class="language-jsx">function min(first...rests){   

 //최소값 구하기 for of 반복문을 함수를 사용하기 위해 output과 items 변수 선언해준다 
    let output
    let items

// 매개변수의 자료형에 따라 조건 분기하기 
// 매개변수의 자료형이 배열이면, 0번째 인덱스 값을 아웃풋이라고 한다. output=100
if (Array.isArray(first)){
    output=first[0]
    items= first // items는 배열이 된다 [100,30,1,34] if 조건이 true기 때문에 최소값을 찾는 함수로 넘어간다

} else if (typeof(first) === &#39;number&#39;){
//first의 자료형이 숫자면, first 매개변수 100을 최초값 output으로 선언한다 
// ...rests는 배열이 되기 때문에 나머지 매개변수가 items에 들어간다 [30,1,34]
// else if 조건에 맞춰 최소값을 처리한다 
    output= first
    items= rests
}
// 최소값 구하는 반복문 사용
for (const item of items){
    if (output &gt; item) {
    output = item 
        }
    } 
//최소값 추출
return output
}

console.log (`배열: ${min([100,30,1,34])}`) // 배열: 1
console.log (`숫자: ${min(100,30,1,34)}`) // 숫자: 1</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_javascript 22년 11월10일]]></title>
            <link>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%9410%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%9410%EC%9D%BC</guid>
            <pubDate>Thu, 10 Nov 2022 13:40:47 GMT</pubDate>
            <description><![CDATA[<h3 id="4일차-스터디-목표">4일차 스터디 목표</h3>
<ul>
<li><input checked="" disabled="" type="checkbox"> 어제 배운내용 복습하기</li>
<li><input checked="" disabled="" type="checkbox"> 챕터 4완강, 확인 문제 풀기, 오답 정리 하기</li>
<li><input checked="" disabled="" type="checkbox"> 책에 나온 손코드 따라하기 배운 내용으로 내가 직접 코딩 짜보기</li>
<li><input checked="" disabled="" type="checkbox"> 셀프 평가, 잘한점, 개선할점, 내일 시도할 것 기록하기</li>
</ul>
<h3 id="회고">회고</h3>
<ul>
<li>셀프 평가:<ul>
<li>오늘 학습은 책으로 새로운 개념을 훑고 유트브 강의를 다시 봤더니 학습진도가 훨신 빨랐다.</li>
</ul>
</li>
<li>잘한 점<ul>
<li>입과 시험에서 짠 코드리뷰를 하자고 제안했다.<ul>
<li>팀원들이 전부 다른 코드를 썼는데 전반적으로 클라이언에서 가격 계산을 시키는것과 서버에서 계산한 값을 저장해서 클라이언트로 값을 보내주는 방법으로 나뉘었다.</li>
<li>나는 클라이언트에 기능을 구현을 했는데 서버에 구현한 팀원의 코드를 보고 아 서버에서 계산해서 DB에 가격 데이터를 넣어줄수 있고 나중에 데이터 활용에 더 유용하고 안전한 코드구나 하고 깨닳았고 후자가 더 좋은 코드 같다고 피드백을 했다.</li>
</ul>
</li>
<li>튜터님께도 코드리뷰 제안을 했고 개발자의 마인드로 벌써부터 임한다고 칭찬을 받았다. 실전 프로젝트를 진행하는 8~13주차 때에 가도 어디서부터 어디까지가 프론트, 백의 영역인지 구분하기 어려울텐데 0주차에서 부터 고민을 하는 3조에 감탄하셨다.</li>
<li>3조가 협업을 적극적으로 하고 있다는 피드백을 받았다.</li>
</ul>
</li>
<li>개선할 점<ul>
<li>오류가 생기면 오타부터 확인하자 !</li>
</ul>
</li>
<li>내일 시도 해볼 것<ul>
<li>챕터 3,4 문제 해답안보고 풀어보기</li>
</ul>
</li>
</ul>
<h3 id="새로배운-개념-기능">새로배운 개념, 기능</h3>
<ul>
<li><p>배열 splice() 메소드 사용 예시</p>
<ul>
<li><p>배열의 특정 요소를 제거 하는 경우</p>
<ul>
<li><p>array.splice(index, number of deleting element )</p>
<pre><code class="language-jsx">const alphabet = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;]
alphabet.splice(2,1) 
&gt; 
[&#39;c&#39;]
&gt;alphabet
(3) [&#39;a&#39;,&#39;b&#39;,&#39;d&#39;]</code></pre>
</li>
</ul>
</li>
<li><p>값으로 요소 제거하는 경우</p>
<ul>
<li><p>indexof(element) 메소드 사용</p>
</li>
<li><p>index를 const index = array.indexof(element) 로  지정해 주고</p>
</li>
<li><p>index의 번호를  array.splice(index, number of deleting element) 에 넣어서 돌리면 된다</p>
<p>```jsx
const alphabet = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;]
const index = alphabet.indexof(&#39;c&#39;)</p>
<blockquote>
<p>index 
2 
alphabet.splice(index,1)</p>
</blockquote>
<p>&#39;c&#39;</p>
<blockquote>
<p>alaphbet
[&#39;a&#39;,&#39;b&#39;,&#39;d&#39;]
alphabet.indexof(&#39;c&#39;)</p>
</blockquote>
</li>
<li><p>1 // 배열에 없는 값을 호출하면 -1을 리턴한다 </p>
<pre><code></code></pre></li>
</ul>
</li>
<li><p>배열에 내부에서 특정 값을 가진 모든 요소를 제거 할때</p>
<ul>
<li><p>filter () 메소드 사용</p>
</li>
<li><p>필터에 맞지 않는 조건을 출력한다</p>
<pre><code class="language-jsx">const fruits = [&#39;apple&#39;, &#39;pear&#39;, &#39;banana&#39;] 
fruits.filter((fruit)=&gt; fruit !== &#39;pear&#39;)
&gt; (2) [&#39;apple&#39;,&#39;banana&#39;]</code></pre>
</li>
</ul>
</li>
<li><p>배열의 요소 중간에 특정 요소를 넣을 경우</p>
<ul>
<li><p>array.splice(index,0,element)</p>
</li>
<li><p>splice 메소드의 2번째 매개변수에 0을 입력하면 아무것도 제거하지 않고 3번째 매게면수에 추가하고 싶은 요소를 입력하게 된다 (fruits 배열의 2번째 인덱스 사이에 ‘kiwi’를 추가하라)</p>
<pre><code class="language-jsx">const fruits = [&#39;apple&#39;, &#39;pear&#39;, &#39;banana&#39;] 
fruits.splice(2,0,&#39;kiwi&#39;)
&gt; (4) [&#39;apple&#39;, &#39;pear&#39;, &#39;kiwi&#39;, &#39;banana&#39;]</code></pre>
</li>
</ul>
</li>
<li><p>영문 이름 짚고 넘어가기:</p>
<ul>
<li>배열 = array 한글= [ ㄱ,ㄴ,ㄷ]</li>
<li>요소 = element ‘ㄱ’, ‘ㄴ’, ‘ㄷ’</li>
<li>요소의 순서= index [ 0번째, 1번째, 2번째]</li>
</ul>
</li>
</ul>
</li>
<li><p>메소드의 파괴적 처리 vs 비파괴적 처리 이해하기</p>
<ul>
<li>파괴적 처리 : 처리 후 원본 내용이 변경 됨<ul>
<li>ex) array.push() 처리 후 array 안에 새로운 요소가 추가 됨</li>
</ul>
</li>
<li>비파괴적 처리: 처리 후 원본이 변경되지 않음<ul>
<li>ex) const a = ‘안녕’, const b= ‘하세요’ const c = a +b // ‘안녕하세요’ 출력  a 와 b의 값은 변경되지 않음</li>
</ul>
</li>
</ul>
</li>
<li><p>for in, for of, for 반복문 차이첨 이해하기</p>
<ul>
<li><p>for in : 반복변수에 요소의 인덱스가 들어 간다 (for in= 인덱스 )</p>
<pre><code class="language-jsx">  const orders = [&#39;skirt&#39;,&#39;tshirt&#39;,&#39;pants&#39;,&#39;sweater&#39;]
  for (const i in orders) {
      console.log(`${i}번째 주문은 ${orders[i]}입니다`)}
  &gt; 
  0번째 주문은 skirt입니다
  1번째 주문은 tshirt입니다
  2번째 주문은 pants입니다
  3번째 주문은 sweater입니다
  // 요소의 인덱스 값을 과 요소를 알려준다 </code></pre>
</li>
<li><p>for of: 반복변수에 요소가 들어간다 (for of= 요소)</p>
<pre><code class="language-jsx">  const orders = [&#39;skirt&#39;,&#39;tshirt&#39;,&#39;pants&#39;,&#39;sweater&#39;]
  for (const order of orders) {
      console.log(`주문된 아이템은 ${order}입니다`)}
  &gt;
  주문된 아이템은 skirt입니다
  주문된 아이템은 tshirt입니다
  주문된 아이템은 pants입니다
  주문된 아이템은 sweater입니다
  //배열에 있는 요소를 알려준다 </code></pre>
</li>
<li><p>for: 특정 횟수 만큼 반복한다</p>
<ul>
<li><p>for (let i=0; i&lt; 반복회수 ; i++){ 문장}</p>
<pre><code class="language-jsx">const orders = [&#39;skirt&#39;,&#39;tshirt&#39;,&#39;pants&#39;,&#39;sweater&#39;]
for (let i = 0; i &lt; 2 ; i++){
  console.log(`주문 번호는 ${i} 입니다`)}
&gt;
주문 번호는 0 입니다
주문 번호는 1 입니다
// 0부터 시작해서 2 미만이면 반복한다, 1번째 인덱스값 까지만 출력한다 

//1부터 N까지 더하기 (100번째 까지)
let output =0 
for (let i=0; i &lt;= 100; i++) {
  output += i } // i가 1부터 시작해야 하니가 += 를 사용해서 i의 값을 1로 만들어 준다
console.log(`1~100까지 더하면 ${output}입니다`)

//배열 사용하기 
const orders = [&#39;skirt&#39;,&#39;tshirt&#39;,&#39;pants&#39;,&#39;sweater&#39;]
for (let i=0; i&lt;orders.length; i++){
  console.log(`${i}번째 주문은 ${orders[i]} 입니다`)
}
&gt;
0번째 주문은 skirt입니다
1번째 주문은 tshirt입니다
2번째 주문은 pants입니다
3번째 주문은 sweater입니다

//배열을 반대로 출력하기 
const orders = [&#39;skirt&#39;,&#39;tshirt&#39;,&#39;pants&#39;,&#39;sweater&#39;]
for (let i=orders.length -1; i&gt;=0; i--){
  console.log(`${i}번째 주문은 ${orders[i]} 입니다`)
}
&gt;
3번째 주문은 sweater 입니다
2번째 주문은 pants 입니다
1번째 주문은 tshirt 입니다
0번째 주문은 skirt 입니다
</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p>while 반복문과 break , continue</p>
<ul>
<li><p>while 반복문은 조건에 큰 비중이 있을 때 사용한다</p>
<ul>
<li>특정 시간까지</li>
<li>결과가 나올 때 까지</li>
<li>파일을 읽으며 특정 단어를 찾을 때 까지</li>
</ul>
</li>
<li><p>break 키워드 사용 예시</p>
<ul>
<li><p>while 반복문은 불표현식이 true 면 무한 반복이 될 수 있기 때문에 break를 사용해서 무한반복을 벗어나야 한다</p>
<pre><code class="language-jsx">for (let i=0; true; i++){
  alert(i + &#39;번째 반복입니다&#39;)
const isContinue= confirm(&#39;계속 하시겠습니까?&#39;)
if (!isContinue){
  break
  }
}
alert (&#39;프로그램 종료&#39;) 

//confirm() 을 사용해서 &quot;확인&quot; 를 누르면 true, &quot;취소&quot; 누르면 false 리턴하기
// break 키워드로 false 면 반복문에서 빠져나오고 프로그램 종료 알럿을 보낸다</code></pre>
</li>
</ul>
</li>
<li><p>continue 사용 예시</p>
<ul>
<li><p>반복문 안의 반복작업을 멈추고 반복문의 처음으로 돌아가게 한다</p>
<pre><code class="language-jsx">//1~10까지 짝수의 합을 구할때 
//변수 선언
let output=0
//반복문
for (let i=0; i&lt;=10; i++){
  //조건문
  if (i%2 ===1){
  //홀수면 반복을 중지하고 다음 반복을 수행
      continue}
  output += i 
}
// 출력
alert(output)
&gt;30</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p>VS Code 기능</p>
<p>  문제점: 파이참을 사용하다 VS Code를 사용하려니 여러 시행착오가 발생했다 </p>
<ol>
<li><p>node 패키지를 다운 받아서 토이프로젝트 때도 썼는데, 왜 갑자기  js 파일이 node 로 명령했을 때 실행되지 않는 걸까? </p>
<pre><code class="language-jsx"> node:internal/modules/cjs/loader:959
 throw err;
 ^

 Error: Cannot find module &#39;/Users/subinbaek/sparta/hello.js&#39;
 at Function.Module._resolveFilename (node:internal/modules/cjs/loader:956:15)
     at Function.Module._load (node:internal/modules/cjs/loader:804:27)
     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
     at node:internal/main/run_main_module:17:47 {
   code: &#39;MODULE_NOT_FOUND&#39;,
   requireStack: []</code></pre>
</li>
</ol>
</li>
</ul>
<pre><code>구글링을 하다보니 path 설정에 문제가 있었다. 내가 열려는 hello.js 파일이 담긴 폴더를 먼저 vscode에서 열고 그담에 파일을 열어야 했다. 

```jsx
[Running] node &quot;/Users/subinbaek/Desktop/bookprac/prac.js&quot;
```

1. html 파일을 크롬에서 실행하려는데 에러코드가 났다. 왜 또… 이런 시련이;; 구글링해서 vs code 에 파일 실행을 위한 패키지들을 설치하고 세팅에서 chrome 으로 html을 열수 있도록 설정했다 

[레퍼런스](https://www.youtube.com/watch?v=q9KWvNmM2QU)</code></pre><h3 id="튜터-질문">튜터 질문</h3>
<p>챕터3 switch 조건문 사용하기 손코딩</p>
<ul>
<li>input을 입력하지 않아도 default break 되지 않고 case 0가 실행되는 이유는?</li>
<li>숫자가 아닌 input이 들어가면 default 가 진행되지만 alert는 뜨지 않는다</li>
<li>이걸 보완하려면 어떻게 코딩을 수정하면 좋을까?<pre><code class="language-jsx">&lt;script&gt;
</code></pre>
</li>
</ul>
<p>const input = Number(prompt(&#39;enter a number&#39;,&#39;&#39;))</p>
<p>switch (input %2 ) {
    case 0: 
        alert (&#39;even number&#39;)
        break
    case 1: 
        alert(&#39;odd number&#39;)
        break
    defualt:
        alert(&#39;not a number&#39;)
        break
}</p>
<p>//빈값을 입력하면 &#39;&#39; 빈 문자열이 입력된다, 빈문자열은 숫자변환 하면 0, 0%2 =0 그래서 짝수입니다가 출력됨 
// 문자를 넣어도 default 알럿이 안뜬 이유는 default 에 오타가 있어서!
// input 값이 없을때 입력하세요 라른 알럿을 띄우려면 
const input = prompt(&#39;enter a number&#39;,&#39;&#39;) // 인풋값이 숫자가 아닐때를 검증하기 때문에 Number를 지워준다
if (input ===&#39;&#39;) {
    alert(&#39;enter a number&#39;)
} else{
switch (Number(input) %2 ) {. // Number () 안에 input을 넣어서 input값은 숫자라고 알려준다
    case 0: 
        alert (&#39;even number&#39;)
        break
    case 1: 
        alert(&#39;odd number&#39;)
        break
    defualt:
        alert(&#39;not a number&#39;)
        break
}
}
</script></p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_javascript 22년 11월9일]]></title>
            <link>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%949%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TILjavascript-22%EB%85%84-11%EC%9B%949%EC%9D%BC</guid>
            <pubDate>Thu, 10 Nov 2022 13:36:12 GMT</pubDate>
            <description><![CDATA[<h2 id="오늘은-입과시험이-있었다">오늘은 입과시험이 있었다..!</h2>
<h3 id="학습-목표">학습 목표</h3>
<ul>
<li><input checked="" disabled="" type="checkbox"> 입과 시험 치르기</li>
<li><input checked="" disabled="" type="checkbox"> 밍글데이 참여하기</li>
<li><input disabled="" type="checkbox"> 챕터 3 연습문제 다시 풀어보기</li>
</ul>
<h3 id="새로운-개념">새로운 개념</h3>
<p><strong>HTTP 와 HTTPS의 차이</strong> </p>
<p>HTTP란?</p>
<ul>
<li>서버에서 브라우저로 데이터를 연결해줄 때 사용된다</li>
<li>서로 다른 시스템들 사이에서 통신을 주고 받을 수 있게 해주는 프로토콜</li>
<li>Hypertext Transfer Protocol의 약자</li>
<li>기존 버전</li>
</ul>
<p>HTTPS 란?</p>
<ul>
<li>HTTP의 보안을 강화시킨 버전, 서버에서 브라우저로 전송되는 데이터가 암호화 된다</li>
<li>SSL(보안 소켓 계층)을 사용해서 데이터 도난 방지</li>
<li>TLS (전송 계층 바안)을 사용해서 데이터가 전송중 수정되거나 손상되는 것을 방지하고 사용자에게 사용자가 의도한 웹사이트와 통신하고 있다는걸 입증 해준다</li>
<li>Hypertext Transfer Protocol Secured의 약자</li>
<li>업데이트 버전 (구글 권장, SEO 최적화에도 장점이 있음)
<a href="https://yozm.wishket.com/magazine/detail/130/">레퍼런스</a></li>
</ul>
<h3 id="오답노트">오답노트</h3>
<p>문제점: </p>
<p>내가 만든 웹사이트를 EC2 instance 연결했고 inbound security 설정에 5000,80, 27017 포트를 모두 열어줬는데도 내 public ip 주소를 크롬에서 실행했을때 로딩이 되지 않는 문제가 생겼다. </p>
<p>해결방법: </p>
<p>과연 설정에 오류인가.. 오류가 없는데 왜그러지? 모바일로 내 ip주소로 크롬에서 접속해봤다.</p>
<p>결과는 문제 없음!! 그렇다면 모바일과 데스크탑에서 크롬 브라우저에 차이점이 뭐가 있을까???</p>
<p>주소를 잘 살펴보니 내 맥에서 사용하는 크롬 브라우저는 https 를 사용하고 있었다. </p>
<p>http로 다시 접속해보니 이상무!! </p>
<p>배운점: </p>
<p>https 는 보안이 강화된 버전이고 내 웹사이트가 그에 맞는 설정을 하지 않았기 때문에 내 웹이 열리지 않았나보다.</p>
<h3 id="회고록">회고록</h3>
<ul>
<li>셀프 평가<ul>
<li>입과 시험 기술 구현 하기 무난하게 해결했다</li>
<li>어려움을 겪은 부분:<ul>
<li>ec2 연결하기 private key chain 에러 발생, 인스턴스를 다시 만들어서 해결 함 ㅠㅠ</li>
<li>인스턴스 연결, nohub 설정하여  ssh 종료해도 서버가 작동하게 설정했으나 ip 주소로 접속시도시  도무지 작동하질 않았다…</li>
<li>원인은 chrome 브라우저가 https로 실행되어서 였다, http로하니 이상없어 과제 제출 완료!</li>
</ul>
</li>
</ul>
</li>
<li>잘한 점<ul>
<li>http 와 https 개념을 이해하고 넘어 갔다</li>
</ul>
</li>
<li>개선할 점</li>
<li>내일 시도해볼 것</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_ java script 22년 11월 8일]]></title>
            <link>https://velog.io/@codename_suding/TIL-java-script-22%EB%85%84-11%EC%9B%94-8%EC%9D%BC</link>
            <guid>https://velog.io/@codename_suding/TIL-java-script-22%EB%85%84-11%EC%9B%94-8%EC%9D%BC</guid>
            <pubDate>Tue, 08 Nov 2022 13:28:36 GMT</pubDate>
            <description><![CDATA[<h3 id="2일차-스터디-목표">2일차 스터디 목표</h3>
<ul>
<li><input checked="" disabled="" type="checkbox"> 어제 배운내용 복습하기</li>
<li><input checked="" disabled="" type="checkbox"> 챕터 3 완강, 확인 문제 풀기, 오답 정리 하기</li>
<li><input checked="" disabled="" type="checkbox"> 책에 나온 손코드 따라하기 배운 내용으로 내가 직접 코딩 짜보기</li>
<li><input checked="" disabled="" type="checkbox"> 셀프 평가, 잘한점, 개선할점, 내일 시도할 것 기록하기</li>
</ul>
<h3 id="새로배운-개념">새로배운 개념</h3>
<p>03-2:</p>
<ul>
<li>조건부 연산자</li>
</ul>
<pre><code class="language-jsx">const input =prompt(&#39;input number&#39;,&#39;&#39;)
const number = Number(input)

const result = (number &gt;= 0) ? &#39;number is greater than 0&#39;:&#39;number is less than 0&#39;
alert(result)
// 불 표현식 ? 참일 때 결과: 거짓일 때 결과 
//number= 7,  7 &gt;= 0 result= true , &#39;number is greater than 0&#39; 출력 
//number= -5, -5 &gt;= 0 result= false, &#39;number is less than 0&#39; 출력</code></pre>
<ul>
<li>짧은 조건문</li>
</ul>
<pre><code class="language-jsx">true || console.log (&#39;good&#39;) // 좌변이 참이면 우변 실행 하지 않는다 &gt; true 출력 
false || console.log(&#39;good&#39;) // 좌변이 거짓이면 우변 실행 &gt; good 출력 
false || 불 표현식이 거짓일 때 실행할 문장 

true &amp;&amp; console.log (&#39;good&#39;) // 양변이 모두 참이여야 true &gt; true 
false &amp;&amp;
</code></pre>
<h3 id="오답노트">오답노트</h3>
<p>prompt 가  실행이 안된다 그래서 구글링을 했더니 prompt-sync 패키지를 설정하고 prompt 를 require 하라고 했다. </p>
<pre><code class="language-jsx">const prompt=require(&quot;prompt-sync&quot;)({sigint:true});

var name = prompt(&quot;What&#39;s your name&quot;);
console.log(&quot;hello&quot;+name+&quot;!&quot;);</code></pre>
<p>레퍼런스: <a href="https://www.geeksforgeeks.org/javascript-is-showing-reference-error-prompt-is-not-defined/">https://www.geeksforgeeks.org/javascript-is-showing-reference-error-prompt-is-not-defined/</a></p>
<p>근데도 크롬 브라우저에서  require is not defined 에러 메세지가 떴다. </p>
<p>나는 지금 브라우저에서 prompt를 실행하려고 하는거니까 require 코드가 필요 없었던 것이다.  인터넷에서 찾았던 코드를 삭제하고  const number = prompt(’message’,’ ‘) 이렇게 다시 변경했더니 브라우저에서 prompt가 잘 실행됬고 하기 조건문에 맞게 알럿이 잘 떴다. </p>
<pre><code class="language-jsx">const number = prompt(&#39;enter a number&#39;, &#39;&#39;)
if (number &gt; 0) {
    alert(&#39;positive number&#39;)
} else {
    if (number &lt;0) {
        alert (&#39;negative number&#39;)
    }
}</code></pre>
<p>인터넷에서 찾은 오류 해결법을 적용하기전에 내가 코드를 실행하는 목적은 무엇인지, 내 코드는 어디서 실행되는지  먼저 확인해 보고 적용해보는 습관이 필요하다. </p>
<p>03-1 확인문제 6번 : 월을 입력하면 계절을 구분하는 프로그램 </p>
<ul>
<li>입력값이 음수이면 에러 알럿 띄우기</li>
<li>겨울: 12, 1, 2</li>
<li>봄: 3,4,5</li>
<li>여름: 6,7,8</li>
<li>가을: 9,10,11</li>
<li>계절 구분이 안됨 ㅠㅠ 조건을 어떻게 하면 바뀔까? 잘 모르겠다<ul>
<li>현재 코드에서는 3을 입력하면 겨울이 나와야하는데 봄이 나온다</li>
</ul>
</li>
</ul>
<pre><code class="language-jsx">const month = prompt(&#39;enter the number of a month&#39;, &#39;&#39;)
if (month &lt;0) {
    alert (&#39;not a vailid entry, enter postive number&#39;)
} else {
    if ( month &lt; 6) {
    alert(&#39;spring&#39;)
} else if ( month &lt;9 ) {
    alert (&#39;summer&#39;) 
} else if ( month &lt; 11){
    alert (&#39;fall&#39;)
} else{
    alert (&#39;winter&#39;)
}
}</code></pre>
<p>오류 해결</p>
<ul>
<li>if 사용할 경우 중첩 조건문을 사용해야 하고, 봄을 예로 들면 봄이 되려면 month 는 3보다 크거나 같고 6보다 작아야 한다 라고 코드를 짜야한다</li>
</ul>
<pre><code class="language-jsx">if ( month &lt;= 3) {
    if (month &lt; 6){
        alert (&#39;spring&#39;)   
    }
}

if (month &lt;= 6){
    if (month &lt;9){
        alert(&#39;summer&#39;)
    }
}
if (month &lt;= 9){
    if (month &lt;12){
        alert(&#39;fall&#39;)
    }
} else {
    alert(&#39;winter&#39;)
}</code></pre>
<ul>
<li>챕터 진도를 나가보니 &amp;&amp; (논리곱 연산자)를 사용하면 코드를 깔끔하게 만들 수 있는 법을 배워서 적용해 봤는데 sytext error:  Unexpected token &#39;&lt;’ 에러가 발생했다</li>
<li>해결: &amp;&amp; 뒤에 month를 입력해줘야 한다</li>
</ul>
<pre><code class="language-jsx">const month = prompt(&#39;enter the number of a month&#39;, &#39;&#39;)
if (month &lt;0) {
    alert (&#39;not a vailid entry, enter postive number&#39;)
} else {
    if ( 3 &lt;=  month &amp;&amp; month &lt; 6) {
    alert(&#39;spring&#39;)
    } else if ( 6 &lt;= month &amp;&amp; month&lt;9 ) {
        alert (&#39;summer&#39;) 
    } else if ( 9 &lt;= month &amp;&amp; month &lt; 12){
        alert (&#39;fall&#39;)
    } else {
        alert (&#39;winter&#39;)
    }
}</code></pre>
<h3 id="회고">회고</h3>
<ul>
<li>셀프 평가:<ul>
<li>오류해결을 위해 구글링해서 해결방법을 시도해보는것은 좋은 습관이지만 내 코드에 맞는 해결책인지 내 코드의 목적과 내 코드가 실행되는 환경등을 생각해보는 습관도 필요하다.</li>
</ul>
</li>
<li>잘한 점<ul>
<li>오류해결 하기 위해 기술매니저님과 질의응답 했고, 답지를 배끼지 않고  결국 내 손으로 직접 코드를 다시 짜보고 오류를 해결했다!</li>
</ul>
</li>
<li>개선할 점<ul>
<li>문제 풀때 막히면 계속 붙잡고 있지말고 답지를 찾아보자, 오늘은 시간 분량 실패 챕터 3 전체 문제를 풀지 못하고 그룹스터디에 들어가서 아쉬웠다</li>
</ul>
</li>
<li>내일 시도 해볼 것<ul>
<li>내일은 시험보는 날이고 밍글데이가 있으니까 밍글데이 이전, 이후에 여유가 있으면 챕터 2, 3 복습하기</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ TIL_java script  22년11월7일]]></title>
            <link>https://velog.io/@codename_suding/TILjava-script</link>
            <guid>https://velog.io/@codename_suding/TILjava-script</guid>
            <pubDate>Mon, 07 Nov 2022 13:18:29 GMT</pubDate>
            <description><![CDATA[<h3 id="1일차-스터디-목표">1일차 스터디 목표</h3>
<ul>
<li><input checked="" disabled="" type="checkbox"> 챕터2 연습문제 풀기, 오답 정리하기</li>
<li><input checked="" disabled="" type="checkbox"> 오늘 스터디 하면서 느낀점, 내일 어떻게 더 잘 할 수 있을지 정리하기</li>
<li><input checked="" disabled="" type="checkbox"> 오늘 스터디 하면서 잘 한점 정리하기</li>
</ul>
<h3 id="새로-배운-개념">새로 배운 개념</h3>
<p><strong>02-1 기본자료형:</strong></p>
<ul>
<li><p>이스케이프 문자 : 특수한 기능을 수행한다</p>
<ul>
<li>문자열 안에 따옴표를 쓰고 싶을 때 == ‘this is \’string’\’</li>
<li>\n = 줄바꿈</li>
<li>\t = tap</li>
<li>\= 역슬래시 \ , “\\\” 는 \\를 출력한다</li>
</ul>
</li>
<li><p>연산자</p>
<ul>
<li><p>=== 양쪽이 같다</p>
</li>
<li><p>! == 양쪽이 다르다</p>
</li>
<li><p>&amp;&amp; 논리곱 연산자로, 양쪽변의 모든 조건이 true 여야 true , 한국어로 하면 “그리고”</p>
</li>
<li><p>|| 논리합 연산자로, 양쪽변의 조건이 하나만 true 여도  true , 한국어로 하면 “또는”</p>
<p>문자열 자료형은 사전적 앞쪽에 있을 수록 값이 적다 </p>
</li>
<li><p>‘가나다’ &gt; ‘마바사’ = false</p>
</li>
</ul>
</li>
</ul>
<p><strong>02-3 자료형 변환:</strong></p>
<ul>
<li>!! 를 사용하면 Boolean() 함수를 사용하지 않고도 자료형 변환 가능<ul>
<li>빈 문자열, null, undefined 가 아닌경우 boolean() 바꾸면 true 로 변환된다</li>
<li>true 는 1, false 는 0 이다</li>
<li>!! 100 = true 가 된다</li>
<li>!! 안녕세요 = true</li>
<li>!!0 = false</li>
<li>!! ‘ ‘ = false</li>
</ul>
</li>
</ul>
<h3 id="오답노트">오답노트</h3>
<pre><code class="language-jsx">//02-2 확인문제 4번 증감 연산자 오답
let number =10
    alert(++number) //정답 11
    alert(number++) //오답 12, 정답 11
    alert(++number) //정답 13 
    alert(number--) //오답12, 정답 13</code></pre>
<p><strong>내 오답풀이</strong> </p>
<p>number = 10 </p>
<p>(++number) 1+ 10 = 11</p>
<p>(number ++)  10 +1 = 11</p>
<p>(++number) 왜 13인지 모르겠음 (1+10, 11+1, 1+12) 그래서 13?</p>
<p>(number—) 이후 실행되는 코드가 없으니까 이전 코드인 13이 그대로 출력됨 ?</p>
<ul>
<li>개념을 잘못 이해했는데, 팀과 함께 풀이하고 확실하게 이해 했다!</li>
</ul>
<p><strong>팀 오답풀이</strong> </p>
<ul>
<li>(++number) 는 1+ 이 코드가 실행되기 이전에 반영</li>
<li>(number ++) 는 코트가 실행된 후 반영</li>
</ul>
<pre><code class="language-jsx">let number =10
    alert(++number) // 10 + 1 이 여기서 실행됨, 정답 11
    alert(number++) // 11 + 1 은 다음 코드에서 실행됨, 정답 11
        //alert(number) // 위의 코드에서 number +1 가 여기서 실행이 됨, number = 12 
    alert(++number) // 12 + 1, 정답 13
    alert(number--) // 13 -1 은 다음 코드에서 실행 됨, 정답 13
        //alert(number) // number에서 -1 여기서 실행되어 number = 12 </code></pre>
<h3 id="회고록">회고록</h3>
<p>셀프평가</p>
<ul>
<li>책에서 많은 내용을 담다보니 넘어가는 내용들도 있다. 그러니 복습하는 습관이 필요할것 같다</li>
</ul>
<p>잘한점</p>
<ul>
<li>오늘 학습 목표를 세웠고, 목표한 학습량을 달성 했다</li>
<li>팀에게 적극적으로 모르는 부분을 질문하고 해답을 얻었다</li>
</ul>
<p>개선할점 </p>
<ul>
<li>책에 손코드 그냥 읽고 넘어가지 말고 직접 코드를 쳐볼 것</li>
</ul>
<p>내일 시도할 점 </p>
<ul>
<li>손코드 쳐본것 내 방식으로 다시 만들어 보자</li>
<li>새로 배운 문법, 헷갈리는건 내가 직접 코드를 쳐보자 그리고 에러가 나면 왜 에러가 났는지 리뷰해보자</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[토이프로젝트_(4단계 프론트 만들기)]]></title>
            <link>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B84%EB%8B%A8%EA%B3%84-%ED%94%84%EB%A1%A0%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B84%EB%8B%A8%EA%B3%84-%ED%94%84%EB%A1%A0%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 05 Nov 2022 07:14:29 GMT</pubDate>
            <description><![CDATA[<p>백엔드단의 준비 (서버세팅, db 연결, api)가 끝났으니 이제 클라이언트 사이드 화면을 만들어 준다. </p>
<p>ejs는 nodes에서 html에 데이터를 입력시킬수 있게 도움을 주는 템플릿 엔진이다. 앞서 main.js 파일에 ejs template engine 세팅을 했다. 
우리가 만들어둔 uploades 폴더는 퍼블릭한 폴더가 아니기때문에 웹브라우저가 접근할수 없다. 그래서 이 폴더를 static 으로 바꿔줘야 웹브라우저에서 이미지가 디스플레이 된다.  </p>
<pre><code class="language-jsx">//set template engine
const express = require(&#39;express&#39;);
app.set(&#39;view engine&#39;, &#39;ejs&#39;);
// uploads 폴더를 static 으로 바꿔주서 웹브라우저가 요청하면 접근할수 있게 해준다
var path = require(&#39;path&#39;)
app.use(express.static(path.join(__dirname,&#39;uploads&#39;)));</code></pre>
<p>포토앨범 페이지의 뼈대 코드는 html로 만들어 놨고, views 폴더안에 index.ejs 파일로 붙여 넣기 했다. 프론트 단 보여지는 코드는 index.ejs 파일에다 입력한다. </p>
<h3 id="1-파일-업로딩을-위한-multipartform-data-만들기">1. 파일 업로딩을 위한 multipart/form-data 만들기</h3>
<p>만들어둔 인풋박스를  multippart/form-data를 form 으로 감싼다. </p>
<ul>
<li>form action = &quot;/&quot; <em>로컬호스트 5000에서 실행</em></li>
<li>method=&quot;post&quot; <em>POST api 형식으로 데이터를 저장</em></li>
<li>enctype=&quot;multipart/form-data&quot; <em>파일업로드 기능을 제공한다</em></li>
<li>type=&quot;file&quot; <em>choose file 버튼을 누르면 파일 찾기 기능이 실행된다</em></li>
<li>acept=&quot;image/jpeg, image/png, image/jpg&quot;  <em>첨부가능한 파일은 이미지 형태 png, jpg, jpeg으로 한정한다.</em></li>
<li>name = “username, image, comment” 인풋의 이름을 지정해준다, GET으로 데이터를 ejs로 불러올때 사용한다</li>
</ul>
<pre><code class="language-jsx">//파일 업로드 기능을 제공하는 form 뼈대 
&lt;form action=&quot;/&quot; method=&quot;post&quot; id=&quot;add-form&quot; enctype=&quot;multipart/form-data&quot;&gt;
        &lt;div class=&quot;input-group mb-3&quot;&gt;
            &lt;span class=&quot;input-group-text&quot; id=&quot;basic-addon1&quot;&gt;@&lt;/span&gt;
            &lt;input type=&quot;text&quot; name=&quot;username&quot; class=&quot;form-control&quot; placeholder=&quot;Username&quot; aria-label=&quot;Username&quot; aria-describedby=&quot;basic-addon1&quot; required/&gt;

        &lt;/div&gt;
        &lt;div class=&quot;mb-3&quot;&gt;
            &lt;label for=&quot;formFileMultiple&quot; class=&quot;form-label&quot;&gt;&lt;/label&gt;
            &lt;input class=&quot;form-control&quot; type=&quot;file&quot; name=&quot;image&quot; id=&quot;upload-file&quot; accept = &quot;image/jpeg, image/png&quot; &gt;
        &lt;/div&gt;
        &lt;div class=&quot;mb-3&quot;&gt;
            &lt;label for=&quot;comment&quot; class=&quot;form-label&quot;&gt; 자랑하기 &lt;/label&gt;
            &lt;textarea class=&quot;form-control&quot; name=&quot;comment&quot; id=&quot;comment&quot; rows=&quot;3&quot;&gt;&lt;/textarea&gt;
        &lt;/div&gt;
        &lt;div class=&quot;mybutton&quot;&gt;
            &lt;div class=&quot;d-grid gap-2 d-md-block&quot;&gt;
                &lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;자랑하기&quot;class=&quot;btn btn-dark&quot;/&gt;
            &lt;/div&gt;
        &lt;/div&gt;
&lt;/form&gt;</code></pre>
<h3 id="2-ejs-사용해서-username-image-comment-데이터를-포토앨범-html-코드에-붙여서-이미지카드-디스플레이-하기">2. ejs 사용해서 username, image, comment 데이터를 포토앨범 html 코드에 붙여서 이미지카드 디스플레이 하기</h3>
<ul>
<li>db에 인풋박스에 입력한 데이터가 성공적으로 저장되면, 성공 메세지 알럿을 보내기 </li>
<li>db 안에 파일이 있으면 username, image, comment에 맞는 데이터를 찾아서 html에 붙여주기 </li>
<li>db 안에 파일을 찾아서 업로드된 파일이 없으면 알럿 보내기</li>
</ul>
<p>if 문을 사용해서 시나리오에 맞는 코드를 실행시킨다. </p>
<pre><code class="language-jsx">//db에 등록된 file이 없으면 ejs로 지정한 html 코드에 알럿 메세지를 보여준다
&lt;script src=&quot;ejs.js&quot;&gt;&lt;/script&gt;
    &lt;div class=&quot;photo-display&quot;&gt;
        &lt;% if(message) { %&gt; 
            &lt;div class=&quot;alert alert-dismissable fade show alert- &lt;%= message.type %&gt;&quot;
                role=&quot;alert&quot;&gt;
                &lt;button class=&quot;btn-close&quot; type=&quot;button&quot; data-bs-dismiss=&quot;alert&quot;
                aria-label=&quot;close&quot;&gt;&lt;/button&gt;
                &lt;strong&gt; &lt;%= message.message%&gt;&lt;/strong&gt;
            &lt;/div&gt;
        &lt;% } %&gt; 

//db안에 등록된 file 있으면, loop를 사용해서 저장된 파일을 찾아서, 
&lt;%= row.name%&gt; 으로 데이터를 html 코드에 붙여서 화면에 보여준다

 &lt;div class=&quot;row row-cols-1 row-cols-md-3 g-4&quot;&gt;
        &lt;% if(files !=&#39;&#39;) { %&gt; 
            &lt;% files.forEach((row, index) =&gt; { %&gt;

                &lt;div class=&quot;col&quot;&gt;
                    &lt;div class=&quot;card&quot;&gt;
                            &lt;img src=&quot;&lt;%= row.image %&gt;&quot; width=&quot;300&quot; class=&quot;card-img-top&quot;/&gt;
                            &lt;div class=&quot;card-body&quot;&gt;
                              &lt;h5 class=&quot;card-title&quot;&gt; &lt;%= row.username %&gt;&lt;/h5&gt;
                              &lt;p class=&quot;card-text&quot;&gt; &lt;%= row.comment %&gt;&lt;/p&gt;
                            &lt;/div&gt;
                    &lt;/div&gt;
                    &lt;/div&gt;
        &lt;% }) %&gt;
    &lt;/div&gt;

        &lt;% } else { %&gt; 
            &lt;h2 class=&quot;text-center text-secondary mt- 5&quot;&gt; no files found in the database&lt;/h2&gt;
        &lt;% } %&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;/script&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[토이프로젝트_ 포토앨범 (3단계 router 세팅, GET POST api 생성, multer storage 세팅)]]></title>
            <link>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-3%EB%8B%A8%EA%B3%84-Express%EB%A1%9C-rest-API-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-3%EB%8B%A8%EA%B3%84-Express%EB%A1%9C-rest-API-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 05 Nov 2022 05:35:08 GMT</pubDate>
            <description><![CDATA[<p>routes 디렉토리, routes.js 파일에 multer로 업로드된 파일과 텍스트의 데이터를 POST와 GET 형식으로 서버와 클라이언트가 주고 받을 수 있도록 세팅해준다. </p>
<p>ulpoads 라는 디렉토리도 미리 생성해준다 (앞으로 multer를 통해 업로드된 이미지가 저장될 경로) </p>
<h3 id="1-multer-로-업로드한-데이터드를-저장할수-있는-storage를-세팅한다">1. multer 로 업로드한 데이터드를 저장할수 있는 storage를 세팅한다</h3>
<ul>
<li>uploads 폴더를 업로드한 image 저장하는 경로로 만들기  </li>
<li>image는 fieldname+날짜+오리지널파일명 으로 저장하기 </li>
</ul>
<pre><code class="language-jsx">const express = require(&#39;express&#39;);
const multer = require(&#39;multer&#39;);
const files = require(&#39;../models/files&#39;);

//uploads 폴더로 multer를 사용해 업로드 된 이미지 파일을 담는 storage를 만든다.

var storage = multer.diskStorage ({
    destination: function (req, file, cb) {
        cb (null, &#39;./uploads/&#39;);
    },
    filename: function (req, file, cb) {
        cb (null, file.fieldname+&quot;_&quot;+Date.now()+&quot;_&quot;+file.originalname);
    },

});

var upload = multer({
    storage: storage,
}).single(&#39;image&#39;);</code></pre>
<h3 id="2-router-만들어-주기">2. router 만들어 주기</h3>
<pre><code class="language-jsx">const router = express.Router();
const File = require(&#39;../models/files&#39;);

router.get(&#39;/&#39;, (req, res)=&gt; {
    res.render(&#39;index&#39;, {title: &#39;Photo Album&#39;});
});

module.exports = router;</code></pre>
<h3 id="3-rest-api-get-post-routes-만들어-주기">3. rest api GET, POST routes 만들어 주기</h3>
<ul>
<li>POST: multer로 업로드한 데이터를 연결해둔 mongodb로 저장하기 </li>
<li>GET: mongdb에 있는 데이터를 불러오기 (포토앨범 디스플레이)</li>
</ul>
<pre><code class="language-jsx">// POST 설정: 인풋박스 데이터 db에 저장하기, 오류있으면 알럿 생성하기 
router.post(&#39;/&#39;, upload, (req,res)=&gt; {
    const file = new File({
        username: req.body.username,
        comment: req.body.comment,
        image: req.file.filename,
    });
    file.save((err)=&gt; {
        if(err){
            res.json({message: err.message, type: &#39;danger&#39;});
        }else{ 
                req.session.message = {
                    type: &#39;success&#39;,
                    message: &#39;file added successfully&#39;
                };
                res.redirect(&#39;/&#39;);
            }
        });

    });

//GET 설정: db에 저장되어있는 데이터 찾아서 로컬호스트 5000으로 불러오기 
router.get(&quot;/&quot;, (req, res)=&gt; {
    File.find().exec((err,files)=&gt; {
        if(err){
            res.json({message: err.message});
        }else{
            res.render(&#39;index&#39;, {
                title: &#39;Phote Album&#39;,
                files: files,
            });
        }
    })
});</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[토이프로젝트_포토앨범(2단계 mongoose로 document의 schema 생성하기)]]></title>
            <link>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%942%EB%8B%A8%EA%B3%84-mongoose%EB%A1%9C-document%EC%9D%98-schema-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%942%EB%8B%A8%EA%B3%84-mongoose%EB%A1%9C-document%EC%9D%98-schema-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 05 Nov 2022 04:02:15 GMT</pubDate>
            <description><![CDATA[<p>업로드한 이미지와 텍스트를 mongodb에 저장하게 될텐데 mongodb는 schema가 없는 noSQL document 데이터베이스이기 때문에 mongoose를 사용해서 document의 structure을 잡아준다. 
(database &gt; collection &gt; document)</p>
<h3 id="1-업로드된-파일의-데이터를-db에-저장하는-규칙-선언하기">1. 업로드된 파일의 데이터를 db에 저장하는 규칙 선언하기</h3>
<p>(username, comment, image로 데이터를 string 형식으로 저장하자는 규칙이다)</p>
<pre><code class="language-jsx">    const mongoose = require(&#39;mongoose&#39;);
    const fileSchema = new mongoose.Schema({
        username: {
            type: String,
            required: true,
        },
        comment: {
            type: String,
            required: true,
        },
        image: {
            type: String,
            required: true,
        }
    });</code></pre>
<h3 id="2-컬렉션-생성하기-schema-등록하기">2. 컬렉션 생성하기, schema 등록하기</h3>
<pre><code class="language-jsx">module.exports = mongoose.model(&#39;Files&#39;,fileSchema);</code></pre>
<p>Files 라는 컬렉션이름이 만들었다 (db 에서 보면 files 라는 컬랙션이 생성된다) </p>
<p>fileSchema가 등록되어 앞으로 컬렉션에 저장되는 데이터들은 schema 조건을 충족하는지 검사가 이뤄 진다. </p>
<p>module.exports 를 통해 model 을 호출할수 있게 되었다.</p>
<p>routes.js 파일에서 Files를 require 해준다. 이렇게 하면, fileSchema가 등록된가 
model file이 호출 될때마다 DB 작업이 이뤄질때 schema에 맞춰 검사가 이뤄 진다.</p>
<hr>
<p>레퍼런스: 
<a href="https://www.zerocho.com/category/MongoDB/post/59a1870210b942001853e250">https://www.zerocho.com/category/MongoDB/post/59a1870210b942001853e250</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토이 프로젝트_ 포토앨범 (1단계 서버 세팅, DB 연결)]]></title>
            <link>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-1%EB%8B%A8%EA%B3%84-%EC%84%9C%EB%B2%84-%EC%84%B8%ED%8C%85-DB-%EC%97%B0%EA%B2%B0</link>
            <guid>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-1%EB%8B%A8%EA%B3%84-%EC%84%9C%EB%B2%84-%EC%84%B8%ED%8C%85-DB-%EC%97%B0%EA%B2%B0</guid>
            <pubDate>Fri, 04 Nov 2022 13:02:27 GMT</pubDate>
            <description><![CDATA[<h3 id="프로젝트-구조">프로젝트 구조:</h3>
<p>우선 VS code에 프로젝트 구조를 아래와 같이 설계했다. 그리고 필요한 프로그램들을 express, multer, mongodb, mongoose, ejs, env, nodemon 등을 설치했다. </p>
<p><img src="https://velog.velcdn.com/images/codename_suding/post/223f55fb-d2ba-4498-973c-bab09e382439/image.png" alt=""></p>
<h3 id="1-env-파일에-db-정보-입력하기">1. env 파일에 DB 정보 입력하기</h3>
<p>(env 파일은 비공개 파일로 주로 민감한 정보를 저장하는데 쓴다). </p>
<pre><code class="language-jsx">//.env 파일에 포트와 DB_URI 정보를 입력한다. 
PORT = 5000
DB_URI = mongodb://localhost:27017/photo_album</code></pre>
<h3 id="2-서버-세팅과-설치한-프로그램-import-하기">2. 서버 세팅과 설치한 프로그램 import 하기</h3>
<p>main.js에 서버를 세팅하고 파일업로드, DB 연결, ejs 템플릿 셋업을 한다.nodes 에서는 require () 을 사용해서 설치해둔 프로그램들을 import 한다.  </p>
<pre><code class="language-jsx">// main.js 서버 파일 
// imports 
var require
require(&#39;dotenv&#39;).config();
const express = require(&#39;express&#39;);
const mongoose = require(&#39;mongoose&#39;);
const session = require(&#39;express-session&#39;);</code></pre>
<h3 id="3-express-를-사용해서-서버를-5000포트로-연결시킨다">3. express 를 사용해서 서버를 5000포트로 연결시킨다.</h3>
<pre><code class="language-jsx">    const app = express();
    const PORT = process.env.PORT || 4000;

    app.listen(PORT, ()=&gt; {
        console.log(`server started at http://localhost:${PORT}`);
    });</code></pre>
<h3 id="4-mongoose를-사용해서-내-어플리케이션과-db를-연결한다">4. mongoose를 사용해서 내 어플리케이션과 db를 연결한다.</h3>
<p>.connect () 를 사용해서 env 파일에 저장해둔 내 DB_URI를 연결해준다. db가 성공적으로 연결되면 console로 성공 메세지를 보내주고, 에러가 생기면 에러 메세지를 보내준다.</p>
<pre><code class="language-jsx">    //database connection
    mongoose.connect(process.env.DB_URI, 
    {useNewUrlParser: true, useUnifiedTopology: true});
    const db = mongoose.connection;
    db.on(&quot;error&quot;, (error)=&gt; console.log(error));
    db.once(&quot;open&quot;, () =&gt; console.log(&quot;connection success&quot;) );</code></pre>
<h3 id="5-세션-암호화하기">5. 세션 암호화하기</h3>
<p>express session을 사용해서 보안을 위해 세션을 암호화 한다 (잘 이해가 안간다,, 유트브 강의 따라 하게 된 작업)</p>
<pre><code class="language-jsx">    //middlewares 
    app.use(express.urlencoded({extended: false}));
    app.use(express.json());

    app.use(session({
        secret: &#39;my secret key&#39;,
        saveUninitialized: true,
        resave: false,
    })
    );

    app.use((req,res,next)=&gt; {
        res.locals.message= req.session.message;
        delete req.session.message;
        next();
    });</code></pre>
<h3 id="6-ejs-templates-셋업">6. ejs templates 셋업</h3>
<p>ejs 는 html에 다이나믹한 컨텐츠를 엠베드 시켜준다.db에 저장한 파일을 애플리케이션에 불러올때 필요하다. </p>
<pre><code class="language-jsx">    //set template engine
    app.set(&#39;view engine&#39;, &#39;ejs&#39;);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[토이 프로젝트_ 포토앨범 (완성작) ]]></title>
            <link>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-%EC%99%84%EC%84%B1%EC%9E%91</link>
            <guid>https://velog.io/@codename_suding/%ED%86%A0%EC%9D%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%AC%ED%86%A0%EC%95%A8%EB%B2%94-%EC%99%84%EC%84%B1%EC%9E%91</guid>
            <pubDate>Fri, 04 Nov 2022 11:55:07 GMT</pubDate>
            <description><![CDATA[<p>사전스터디 팀과 함께 반려동물 여행시 유용한 웹사이트를 만들었고 그중 여행의 추억을 기록할수 있는 포토앨범 기능은 구현했다.</p>
<p>파일 업로드 기능은 사전스터디 기간에 배운 내용이 아니지만, 뉴욕 버켓리스트 프로젝트 할때 만들어 보고 싶었던 기능이여서 구글링과 수많은 유트브 강의를 찾아가면서 일단 무작정 만들어 봤다. 내가 사용한 기술들이 정확하게 어떤 기능을 하는지 사용하는 목적이 무엇인지 최대한 이해한 대로 정리해 봤다. 부트캠프가 끝나고 다시 되돌아 보면 어느정도 맞췄는지 알수 있겠다. ㅎㅎ </p>
<p>그리고 이 프로젝트를 끝내고 주특기는 node js 로 정하게 되었다!</p>
<p>*<em>사용한 기술: *</em>
    - node js
    - express
    - multer
    - mongodb 
    - mongoose
    - ejs 
    - bootstrap </p>
<p><strong>기능의 플로우와 사용된 기술:</strong>
<img src="https://velog.velcdn.com/images/codename_suding/post/70545c4c-32b7-4762-b227-18f831b78406/image.jpg" alt=""></p>
<p><strong>완성 작품</strong></p>
<p>인풋 박스 
<img src="https://velog.velcdn.com/images/codename_suding/post/3b4d19cd-e396-4f00-a5d0-578ccfb9e404/image.png" alt="">
디스플레이 
<img src="https://velog.velcdn.com/images/codename_suding/post/1ccd6bb8-bc84-4870-b823-42f7f0de6724/image.png" alt=""></p>
<p>DB
<img src="https://velog.velcdn.com/images/codename_suding/post/b34a4839-681f-4e58-9d80-ca0c30a15e34/image.png" alt=""></p>
<p><strong>레퍼런스</strong></p>
<ul>
<li><a href="https://www.youtube.com/playlist?list=PL6u82dzQtlfvJoAWdyf5mUxPQRnNKCMGt">https://www.youtube.com/playlist?list...</a></li>
<li><a href="https://www.bezkoder.com/node-js-upload-store-images-mongodb/">https://www.bezkoder.com/node-js-upload-store-images-mongodb/</a></li>
<li><a href="https://codedec.com/tutorials/image-uploading-to-mongodb-in-nodejs/">https://codedec.com/tutorials/image-uploading-to-mongodb-in-nodejs/</a> </li>
<li>외 수많은 stack overflow 와 github 자료들 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[GIT HUB - 이해하기 ]]></title>
            <link>https://velog.io/@codename_suding/GIT-HUB-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@codename_suding/GIT-HUB-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 20 Oct 2022 22:25:56 GMT</pubDate>
            <description><![CDATA[<p>곧 있으면 항해 99 사전스터디 그룹과 토이프로젝트를 진행하게된다.
토이프로젝트 진행시 협업이 필수기 때문에 깃헙을 셋업하고 사용법을 숙지 해보려 한다. </p>
<p>레퍼렌스: 생활코딩의 깃헙강의를 참고했다. </p>
<h2 id="깃헙의-3대-목적">깃헙의 3대 목적</h2>
<h3 id="1-버전관리">1. 버전관리</h3>
<h3 id="2-백업">2. 백업</h3>
<h3 id="3-협업">3. 협업</h3>
<h3 id="깃헙-용어">깃헙 용어</h3>
<p>GIT (데스크탑 버전): 버전을 관리하는 컴퓨터 프로그램
Repository : 저장소 
local repository: 로컬 (내컴퓨터) 저장소
remote repository: 원격 저장소 (깃허브)
commit: 변경 저장하기 
push: 원격 저장소에 저장하기 
pull: 원격 저장소에서 끌어오기 </p>
<h3 id="버전관리">버전관리</h3>
<p>내 컴퓨터에 저장된 파일을 깃헙 저장소에도 저장시켜서 문서의 변화를 추적할 수 있다. 이전 버전으로 돌아갈수도 있다. </p>
<h3 id="백업하기">백업하기</h3>
<p>내 컴퓨터와 가상의 컴퓨터를 연결해서 파일을 복제한다. 내 저장소에 있는 파일을 원격 저장소에 push 하면 같은 파일이 저장된다. 원격 저장소에 있는 파일을 내 컴퓨터로 pull 하면 원격 저장소에 있던 파일이 불려온다. (이전버전을 복원 할 수 있다)</p>
<h3 id="협업하기">협업하기</h3>
<p>협업 시나리오:</p>
<ul>
<li>내가 작성한 파일을 원격 저장소에 푸시 한다</li>
<li>나와 협업하는 사람이 원격 저장소에서 내 파일을 풀 한다</li>
<li>파일 작업을 하고 원격 저장소에 다시 푸시 한다 </li>
<li>내가 다시 작업할때, 협업자가 업로드한 파일을 내 컴퓨터로 풀 해서 작업한다</li>
</ul>
<p>협업 할때 발생 가능한 에러 사항들을 깃헙이 알아서 잘 교통정리 해준다
예시: </p>
<ul>
<li>남의 파일 덮어 쓰기 </li>
<li>같은 파일, 같은 행 수정하기 등 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Weekly I Learned- 웹개발 종합반 미니프로젝트 ]]></title>
            <link>https://velog.io/@codename_suding/Weekly-I-Learned-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@codename_suding/Weekly-I-Learned-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 18 Oct 2022 16:05:41 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="미니프로젝트-완성본-바로가기">미니프로젝트 완성본 바로가기:</h2>
<p><a href="http://subin-100.shop/">http://subin-100.shop/</a></p>
<h2 id="step-1_기획안--만들기">Step 1_기획안  만들기</h2>
<p>본격적인 웹페이지 개발에 앞서 기획안을 작성하여 페이지의 목적, 타켓유저, 구현할 기능을 정의 했다.</p>
<aside>
💡 **기획안**

<p>웹페이지의 목적: </p>
<ul>
<li>여행 버켓리스트 기록하기, 완료한 리스트 트레킹 하기</li>
<li>여행 시 필요한 현지 정보 위젯으로 쉽게 확인하기 (날씨, 환율)</li>
<li>여행 일정 관리 및 방문한 장소 기록하기</li>
</ul>
<p>타겟 유저: </p>
<ul>
<li>해외 여행을 앞두거나 여행중인 유저</li>
</ul>
<p>구현할 기능: </p>
<ul>
<li>Flask 사용하여 restful api 구현하기 (GET, POST)</li>
<li>mongodb 사용하여 웹사이트의 버켓리스트 데이터 기록하고 조회하기</li>
<li>api로 날씨, 환율 위젯  웹 페이지에 불러오기</li>
<li>iframe 사용하여 구글 캘린더, 구글 맵 embed 하기</li>
<li>하이퍼링크 사용하여 버켓리스트 아이템 관련 웹사이트로 랜딩하기</li>
</ul>
</aside>

<h2 id="step-2_template-만들기">Step 2_template 만들기</h2>
<p>이후, 기획안을 가장 잘 표현할수 있는 웹디자인을 구글링하여 선정하고 필요한 기능들을 구현할수 있도록 코드를 수정하고 웹페이지의 뼈대를 구축했다. </p>
<aside>
💡 활용한 tools:

<ul>
<li>bootstrap 활용한 CSS 기능: form, button, table</li>
<li>사용한 w3css 의 템플릿: <code>[https://www.w3schools.com/w3css/4/w3.css](https://www.w3schools.com/w3css/4/w3.css)</code></li>
<li>날씨 위젯: <a href="https://openweathermap.org/">https://openweathermap.org/</a></li>
<li>환율 위젯: <a href="https://www.exchangerates.org.uk/">https://www.exchangerates.org.uk/</a></aside>

</li>
</ul>
<h2 id="step-3_-코딩하기">Step 3_ 코딩하기</h2>
<p>스파르타 코딩의 웹종합개발 강의 과제들을 참고하여 필수 기능들을 구현했다 </p>
<h3 id="파이썬--flask-post-get">파이썬:  Flask, POST, GET</h3>
<pre><code class="language-python"># 파이썬 참고한 숙제 코드

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

from pymongo import MongoClient
import certifi

ca = certifi.where()
client = MongoClient(&#39;mongodb+srv://test:sparta@cluster0.v0amks8.mongodb.net/?retryWrites=true&amp;w=majority&#39;,tlsCAFile=ca)
db = client.dbsparta

@app.route(&#39;/&#39;)
def home():
   return render_template(&#39;bucket.html&#39;)

@app.route(&quot;/bucket&quot;, methods=[&quot;POST&quot;])
def save_bucket():
    bucket_receive = request.form[&#39;bucket_give&#39;]
    count = list(db.bucket.find({},{&#39;_id&#39;:False}))
    num = len(count)+1
    done = 0
    doc = {
        &#39;bucket&#39;: bucket_receive,
        &#39;num&#39;: num,
        &#39;done&#39;: done
    }
    db.bucket.insert_one(doc)
    return jsonify({&#39;msg&#39;: &#39;저장 완료!&#39;})

@app.route(&quot;/bucket/done&quot;, methods=[&quot;POST&quot;])
def done_bucket():
    num_receive = request.form[&#39;num_give&#39;]
    db.bucket.update_one({&#39;num&#39;: int(num_receive)}, {&#39;$set&#39;: {&#39;done&#39;: 1}})
    return jsonify({&#39;msg&#39;: &#39;완료!&#39;})

@app.route(&quot;/bucket&quot;, methods=[&quot;GET&quot;])
def show_bucket():

    bucket_list = list(db.bucket.find({},{&#39;_id&#39;:False}))
    return jsonify({&#39;buckets&#39;: bucket_list})

if __name__ == &#39;__main__&#39;:
   app.run(&#39;0.0.0.0&#39;, port=5000, debug=True)
</code></pre>
<h3 id="클라이언트-html-js-css">클라이언트: HTML, JS, CSS</h3>
<pre><code class="language-jsx">//html, css, JS 참고한 숙제 코드 

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;

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

&lt;link href=&quot;https://fonts.googleapis.com/css2?family=Gowun+Dodum&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;

&lt;title&gt;인생 버킷리스트&lt;/title&gt;

&lt;style&gt;
* {
font-family: &#39;Gowun Dodum&#39;, sans-serif;
}
.mypic {
width: 100%;
height: 200px;

background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(&#39;https://images.unsplash.com/photo-1601024445121-e5b82f020549?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=1189&amp;q=80&#39;);
background-position: center;
background-size: cover;

color: white;

display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mypic &gt; h1 {
font-size: 30px;
}
.mybox {
width: 95%;
max-width: 700px;
padding: 20px;
box-shadow: 0px 0px 10px 0px lightblue;
margin: 20px auto;
}
.mybucket {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}

.mybucket &gt; input {
width: 70%;
}
.mybox &gt; li {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;

margin-bottom: 10px;
min-height: 48px;
}
.mybox &gt; li &gt; h2 {
max-width: 75%;
font-size: 20px;
font-weight: 500;
margin-right: auto;
margin-bottom: 0px;
}
.mybox &gt; li &gt; h2.done {
text-decoration:line-through
}
&lt;/style&gt;
&lt;script&gt;
$(document).ready(function () {
show_bucket();
});
function show_bucket(){
    $.ajax({
        type: &quot;GET&quot;,
        url: &quot;/bucket&quot;,
        data: {},
        success: function (response) {
            function show_bucket(){
    $(&#39;#bucket-list&#39;).empty()
    $.ajax({
        type: &quot;GET&quot;,
        url: &quot;/bucket&quot;,
        data: {},
        success: function (response) {
            let rows = response[&#39;buckets&#39;]
            for (let i = 0; i &lt; rows.length; i++) {
                let bucket = rows[i][&#39;bucket&#39;]
                let num = rows[i][&#39;num&#39;]
                let done = rows[i][&#39;done&#39;]

                let temp_html = ``
                if (done == 0) {
                    temp_html = `&lt;li&gt;
                                    &lt;h2&gt;✅ ${bucket}&lt;/h2&gt;
                                    &lt;button onclick=&quot;done_bucket(${num})&quot; type=&quot;button&quot; class=&quot;btn btn-outline-primary&quot;&gt;완료!&lt;/button&gt;
                                &lt;/li&gt;`
                } else {
                    temp_html = `&lt;li&gt;
                                    &lt;h2 class=&quot;done&quot;&gt;✅ ${bucket}&lt;/h2&gt;
                                &lt;/li&gt;`
                }
                $(&#39;#bucket-list&#39;).append(temp_html)
            }
        }
    });
}
function save_bucket(){
    let bucket = $(&#39;#bucket&#39;).val()
    $.ajax({
        type: &quot;POST&quot;,
        url: &quot;/bucket&quot;,
        data: {bucket_give: bucket},
        success: function (response) {
            alert(response[&quot;msg&quot;])
            window.location.reload()
        }
    });
}
function done_bucket(num){
    $.ajax({
        type: &quot;POST&quot;,
        url: &quot;/bucket/done&quot;,
        data: {num_give: num},
        success: function (response) {
            alert(response[&quot;msg&quot;])
            window.location.reload()
        }
    });
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;mypic&quot;&gt;
&lt;h1&gt;나의 버킷리스트&lt;/h1&gt;
&lt;/div&gt;
&lt;div class=&quot;mybox&quot;&gt;
&lt;div class=&quot;mybucket&quot;&gt;
&lt;input id=&quot;bucket&quot; class=&quot;form-control&quot; type=&quot;text&quot; placeholder=&quot;이루고 싶은 것을 입력하세요&quot;&gt;
&lt;button onclick=&quot;save_bucket()&quot; type=&quot;button&quot; class=&quot;btn btn-outline-primary&quot;&gt;기록하기&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;mybox&quot; id=&quot;bucket-list&quot;&gt;
&lt;li&gt;
&lt;h2&gt;✅ 호주에서 스카이다이빙 하기&lt;/h2&gt;
&lt;button onclick=&quot;done_bucket(5)&quot; type=&quot;button&quot; class=&quot;btn btn-outline-primary&quot;&gt;완료!&lt;/button&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 class=&quot;done&quot;&gt;✅ 호주에서 스카이다이빙 하기&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;✅ 호주에서 스카이다이빙 하기&lt;/h2&gt;
&lt;button type=&quot;button&quot; class=&quot;btn btn-outline-primary&quot;&gt;완료!&lt;/button&gt;
&lt;/li&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h2 id="step-4_-서버-배포하기">Step 4_ 서버 배포하기</h2>
<ol>
<li>가비아에서 도메인 구입 (내 프로젝트 웹사이트의 주소) </li>
<li>AWS에 서버 컴퓨터 (EC2)를 구매해서 서버와 연결하기 </li>
</ol>
<ul>
<li>SSH 접속하여 내 가상 컴퓨터에 리눅스 명령어를 사용하여 필요한 프로그램을 설치한다<ul>
<li>flask, pymongo, dnspython 설치</li>
</ul>
</li>
</ul>
<ol>
<li>FileZilla에 내 컴퓨터와 가상의 컴퓨터 (EC2)를 연결해서 파이썬 파일과 static, templates 폴더를 업로드 한다 </li>
</ol>
<ul>
<li>SSH 에서 파이썬 파일을 실행해서 파일이 잘 작동하는걸 확인한다</li>
</ul>
<ol>
<li>EC2에 포트 포워딩 세팅을 해준다 </li>
</ol>
<ul>
<li>우리 서버는 포트 5000으로 실행되지만 http 기본요청 포트 80이기 때문에 이를 5000으로 변환해주는 작업이 필요하다</li>
</ul>
<ol>
<li>no hub 설정 </li>
</ol>
<ul>
<li>ssh 접속이 끊겨도 서버가 계속 돌수 있도록 명령어를 입력해주자<ul>
<li>nohub python <a href="http://db.py">db.py</a> &amp;</li>
</ul>
</li>
</ul>
<ol>
<li>도메인에 IP 주소 연결하기 </li>
</ol>
<h2 id="step-5_-완성코드">Step 5_ 완성코드</h2>
<p>완성코드 </p>
<pre><code class="language-python">from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

from pymongo import MongoClient
import certifi

ca = certifi.where()
client = MongoClient(&#39;mongodb+srv://test:sparta@cluster0.v0amks8.mongodb.net/?retryWrites=true&amp;w=majority&#39;,tlsCAFile=ca)
db = client.dbsparta

@app.route(&#39;/&#39;)
def home():
   return render_template(&#39;index.html&#39;)

@app.route(&quot;/nycBucket&quot;, methods=[&quot;POST&quot;])
def save_bucket():

    count = list(db.nycBucket.find({}, {&#39;_id&#39;: False}))
    num = len(count)+1
    done = 0
    category_receive = request.form[&#39;category_give&#39;]
    bucketItem_receive = request.form[&#39;bucketItem_give&#39;]
    links_receive = request.form[&#39;links_give&#39;]
    memo_receive = request.form[&#39;memo_give&#39;]

    doc = {
        &#39;num&#39;: num,
        &#39;done&#39;: done,
        &#39;category&#39;: category_receive,
        &#39;bucketItem&#39;: bucketItem_receive,
        &#39;links&#39;: links_receive,
        &#39;memo&#39;: memo_receive
    }

    db.nycBucket.insert_one(doc)

    return jsonify({&#39;msg&#39;: &#39;List Saved!&#39;})

@app.route(&quot;/nycBucket/done&quot;, methods=[&quot;POST&quot;])
def done_bucket():
    num_receive = request.form[&#39;num_give&#39;]
    db.nycBucket.update_one({&#39;num&#39;: int(num_receive)}, {&#39;$set&#39;: {&#39;done&#39;: 1}})
    return jsonify({&#39;msg&#39;: &#39;completed!&#39;})

@app.route(&quot;/nycBucket&quot;, methods=[&quot;GET&quot;])
def show_bucket():
    items_list = list(db.nycBucket.find({}, {&#39;_id&#39;:False}))
    return jsonify({&#39;items&#39;: items_list })

if __name__ == &#39;__main__&#39;:
   app.run(&#39;0.0.0.0&#39;, port=5000, debug=True)</code></pre>
<pre><code class="language-jsx">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Subin&#39;s NYC Bucket List and Travel Manager&lt;/title&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
    &lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot;
          integrity=&quot;sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC&quot; crossorigin=&quot;anonymous&quot;&gt;
    &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js&quot;
            integrity=&quot;sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM&quot;
            crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Gowun+Dodum&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://www.w3schools.com/w3css/4/w3.css&quot;&gt;

&lt;style&gt;

    body {
        font-family: &quot;Times New Roman&quot;, Georgia, Serif;
    }

    h1, h2, h3, h4, h5, h6 {
        font-family: &quot;Playfair Display&quot;;
        letter-spacing: 5px;
    }

    .header_image {
        width: 100%;
        height: 500px;

        background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(&#39;https://s.yimg.com/ny/api/res/1.2/OucfyjfjqKoqZ_mXwtPDTw--/YXBwaWQ9aGlnaGxhbmRlcjt3PTk2MDtoPTU0MDtjZj13ZWJw/https://s.yimg.com/uu/api/res/1.2/4cTCbzGMlV8IqExbyzpiVw--~B/aD0xMDgwO3c9MTkyMDthcHBpZD15dGFjaHlvbg--/https://media.zenfs.com/en/gobankingrates_644/c598b71abc0b5732623a999fde50a539&#39;);
        background-position: center;
        background-size: cover;
        color: white;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .about-section {
      width: 100%;
      height: 800 px;
      background-position: center;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin-top: 20 px;
      margin-bottom: 20 px;
      text-align: center;

    }

    .bucket-section {
      background-position: center;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;

    }

    .box-image {
        width: 1000px;
        height: 300px;
        background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(&#39;https://media.timeout.com/images/103547775/1372/772/image.jpg&#39;);
        background-position: center;
        background-size: cover;
        color: white;
        display: flex;
        justify-content: center;
        align-items: center;

    }

    .box-image &gt; button {
        width: 200px;
        height: 50px;
        background-color: transparent;
        color: white;
        border-radius: 50px;
        border: 1px solid white;
        margin-top: 10px;

    }

    .box-image &gt; button:hover {
        border: 2px solid white;
    }

    .mypost {
        width: 95%;
        max-width: 1000px;
        margin: 20px auto 0px auto;
        padding: 20px;
        box-shadow: 0px 0px 3px 0px gray;
        display: none;

    }

    .mybutton {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin-top: 20px;

    }

    .mybutton &gt; button {
        margin-right: 10px;
    }

    .mybox {
      width: 95%;
      max-width: 1000px;
      padding: 20px;
      box-shadow: 0px 0px 10px 0px grey;
      margin: 20px auto 0px auto;
      margin: 20px auto;
      margin-top: 100px;
      margin-bottom: 100px;
    }

    .done {
        text-decoration:line-through
    }

    .travel-section {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;
      margin-top: 20px;
      margin-bottom: 20px;
    }

    .currency {
      margin-top: 20px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;
    }

    .map-section {
        margin-top: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .contact-section {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
&lt;/style&gt;

&lt;script&gt;

  function open_box() {
    $(&#39;#post-box&#39;).show()
  }
  function close_box() {
    $(&#39;#post-box&#39;).hide()
  }

  $(document).ready(function () {
    show_bucket();
    $(&#39;#list-box&#39;).empty()
  });

  function show_bucket() {
    $.ajax({
      type: &#39;GET&#39;,
      url: &#39;/nycBucket&#39;,
      data: {},
      success: function (response) {
        let rows = response[&#39;items&#39;]
        for (let i = 0; i &lt; rows.length; i++) {
              let category = rows[i][&#39;category&#39;]
              let bucket_Item = rows[i][&#39;bucketItem&#39;]
              let links = rows[i][&#39;links&#39;]
              let memo = rows[i][&#39;memo&#39;]
              let num = rows[i][&#39;num&#39;]
              let done = rows[i][&#39;done&#39;]
              let temp_html = ``
              if (done == 0) {
                  temp_html = `&lt;tr&gt;
                                                      &lt;td&gt; &lt;button onclick=&quot;done_bucket(${num})&quot; type=&quot;button&quot; class=&quot;btn btn-outline-secondary&quot;&gt; ✔  &lt;/button&gt; &lt;/td&gt;
                                                      &lt;td&gt;${category}&lt;/td&gt;
                                                      &lt;td&gt;${bucket_Item}&lt;/td&gt;
                                                      &lt;td&gt;&lt;a href=&quot;${links}&quot;&gt; ${links}&lt;/a&gt;&lt;/td&gt;
                                                      &lt;td&gt;${memo}&lt;/td&gt;

                                                    &lt;/tr&gt;`

              } else {
                  temp_html = `&lt;tr&gt;
                                                      &lt;th scope=&quot;row&quot; class=&quot;done&quot;&gt; completed &lt;/th&gt;
                                                      &lt;td class=&quot;done&quot;&gt;${category}&lt;/td&gt;
                                                      &lt;td class=&quot;done&quot;&gt;${bucket_Item}&lt;/td&gt;
                                                      &lt;td class=&quot;done&quot;&gt;&lt;a href=&quot;${links}&quot;&gt;${links}&lt;/a&gt;&lt;/td&gt;

                                                      &lt;td class=&quot;done&quot;&gt;${memo}&lt;/td&gt;

                                                    &lt;/tr&gt;`

              }

          $(&#39;#list-box&#39;).append(temp_html)
        }

      }
    });
  }

  function save_bucket() {
    let category = $(&#39;#category&#39;).val()
    let bucketItem = $(&#39;#bucketItem&#39;).val()
    let links = $(&#39;#links&#39;).val()
    let memo = $(&#39;#memo&#39;).val()

    $.ajax({
      type: &#39;POST&#39;,
      url: &#39;/nycBucket&#39;,
      data: {category_give:category, bucketItem_give:bucketItem, links_give:links, memo_give:memo},
      success: function (response) {
        alert(response[&#39;msg&#39;])
        window.location.reload()
      }
    });
  }

  function done_bucket(num){
    $.ajax({
        type: &quot;POST&quot;,
        url: &quot;/nycBucket/done&quot;,
        data: {num_give: num},
        success: function (response) {
            alert(response[&quot;msg&quot;])
            window.location.reload()
        }
    });
}

    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;!-- Navbar (sit on top) --&gt;
&lt;div class=&quot;w3-top&quot;&gt;
  &lt;div class=&quot;w3-bar w3-white w3-padding w3-card&quot; style=&quot;letter-spacing:4px;&quot;&gt;
    &lt;a href=&quot;#home&quot; class=&quot;w3-bar-item w3-button&quot;&gt;Bucket List Tracker and Travel Manager&lt;/a&gt;
    &lt;!-- Right-sided navbar links. Hide them on small screens --&gt;
    &lt;div class=&quot;w3-right w3-hide-small&quot;&gt;
      &lt;a href=&quot;#about&quot; class=&quot;w3-bar-item w3-button&quot;&gt;About&lt;/a&gt;
      &lt;a href=&quot;#bucket list&quot; class=&quot;w3-bar-item w3-button&quot;&gt;Bucket List&lt;/a&gt;
      &lt;a href=&quot;#manager&quot; class=&quot;w3-bar-item w3-button&quot;&gt;Travel Manager&lt;/a&gt;
      &lt;a href=&quot;#contact&quot; class=&quot;w3-bar-item w3-button&quot;&gt;Contact&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!-- Header --&gt;
&lt;header&gt;
  &lt;div class=&quot;header_image&quot; id=&quot;home&quot;&gt;
    &lt;h1&gt; Bucket List Tracker and Travel Manager&lt;/h1&gt;
  &lt;/div&gt;
&lt;/header&gt;
&lt;!-- page content --&gt;
&lt;div class=&quot;page-content&quot;&gt;
&lt;!-- About Section --&gt;
&lt;div class=&quot;about-section&quot; id=&quot;about&quot;&gt;
    &lt;div class=&quot;w3-col m6 w3-padding-large&quot; style=&quot;margin: 100px&quot; &gt;
        &lt;h1 class=&quot;w3-center&quot;&gt;About &lt;/h1&gt;&lt;br&gt;
        &lt;h5 class=&quot;w3-center&quot;&gt;Welcome to Subin&#39;s Web Development Project&lt;/h5&gt;&lt;br&gt;
        &lt;p class=&quot;w3-large&quot;&gt; The Bucket List Tracker and Travel Manager is a website created for a web development project using HTML, CSS, JS, and Python.&lt;/p&gt;
        &lt;p class=&quot;w3-large w3-text-grey w3-hide-medium&quot;&gt; This website is targeted for users who are traveling abroad and provides two main functions. &lt;/p&gt;
        &lt;p class=&quot;w3-large w3-text-grey w3-hide-medium&quot;&gt; 1) Bucket List: recording and keeping track of the travel bucket list.&lt;/p&gt;
        &lt;p class=&quot;w3-large w3-text-grey w3-hide-medium&quot;&gt; 2) Travel Manager: useful widgets for traveling abroad.&lt;/p&gt;

    &lt;/div&gt;
&lt;/div&gt;
  &lt;hr&gt;
&lt;!-- Bucket List Section --&gt;
&lt;div class=&quot;bucket-section&quot; id=&quot;bucket list&quot;&gt;
  &lt;div class=&quot;w3-col l6 w3-padding-large&quot; style=&quot;margin: 80px&quot;&gt;
      &lt;h1 class=&quot;w3-center&quot;&gt; Bucket List &lt;/h1&gt;&lt;br&gt;
      &lt;h4 class=&quot;w3-center&quot;&gt; Create your bucket list and track completed items, Bon Voyage!&lt;/h4&gt;
  &lt;/div&gt;
  &lt;div class=&quot;box-image&quot; id=&quot;open_box&quot; &gt;
  &lt;button onclick=&quot;open_box()&quot;&gt; click to start&lt;/button&gt;
  &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;mypost&quot; id=&quot;post-box&quot;&gt;
    &lt;div class=&quot;input-group mb-3&quot;&gt;
      &lt;label class=&quot;input-group-text&quot; for=&quot;inputGroupSelect01&quot;&gt; Bucket Category&lt;/label&gt;
      &lt;select class=&quot;form-select&quot; id=&quot;category&quot;&gt;
        &lt;option selected&gt;--choose--&lt;/option&gt;
        &lt;option value=&quot;Food &amp; Drinks&quot;&gt;Food &amp; Drinks&lt;/option&gt;
        &lt;option value=&quot;Arts &amp; Performances&quot;&gt;Arts &amp; Performances&lt;/option&gt;
        &lt;option value=&quot;Tours&quot;&gt;Tours&lt;/option&gt;
        &lt;option value=&quot;Date Nights &amp; Weekends&quot;&gt;Date Nights &amp; Weekends&lt;/option&gt;
        &lt;option value=&quot;Hangout with friends&quot;&gt;Hangout with friends&lt;/option&gt;
        &lt;option value=&quot;Shopping&quot;&gt;Shopping&lt;/option&gt;
      &lt;/select&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-floating mb-3&quot;&gt;
      &lt;input type=&quot;email&quot; class=&quot;form-control&quot; id=&quot;bucketItem&quot; placeholder=&quot;write here&quot;&gt;
      &lt;label for=&quot;floatingInput&quot;&gt;Bucket Litst Item&lt;/label&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-floating mb-3&quot;&gt;
      &lt;input type=&quot;email&quot; class=&quot;form-control&quot; id=&quot;links&quot; placeholder=&quot;URL&quot;&gt;
      &lt;label for=&quot;floatingInput&quot;&gt;Links&lt;/label&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-floating&quot;&gt;
            &lt;textarea class=&quot;form-control&quot; placeholder=&quot;Leave a comment here&quot; id=&quot;memo&quot;
                      style=&quot;height: 100px&quot;&gt;&lt;/textarea&gt;
      &lt;label for=&quot;floatingTextarea2&quot;&gt;Memo&lt;/label&gt;
    &lt;/div&gt;
    &lt;div class=&quot;mybutton&quot;&gt;
      &lt;div class=&quot;d-grid gap-2 d-md-block&quot;&gt;
        &lt;button type=&quot;button&quot; onclick=&quot;save_bucket()&quot; class=&quot;btn btn-dark&quot;&gt;Submit&lt;/button&gt;
        &lt;button type=&quot;button&quot; onclick=&quot;close_box()&quot; class=&quot;btn btn-outline-dark&quot;&gt;Close&lt;/button&gt;
      &lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;mybox&quot; id=&quot;bucket-box&quot;&gt;
  &lt;h2 class=&quot;w3-center&quot;&gt; Fall 2022 NYC Bucket List&lt;/h2&gt;
    &lt;table class=&quot;table&quot;&gt;
      &lt;thead&gt;
      &lt;tr&gt;
        &lt;th scope=&quot;col&quot;&gt; Complete &lt;/th&gt;
        &lt;th scope=&quot;col&quot;&gt;Category&lt;/th&gt;
        &lt;th scope=&quot;col&quot;&gt;Bucket List Item&lt;/th&gt;
        &lt;th scope=&quot;col&quot;&gt;Links&lt;/th&gt;
        &lt;th scope=&quot;col&quot;&gt;Memo&lt;/th&gt;
      &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody id=&quot;list-box&quot;&gt;

          &lt;tr&gt;
              &lt;td&gt; &lt;button onclick=&quot;done_bucket(1)&quot; type=&quot;button&quot; class=&quot;btn btn-outline-secondary&quot;&gt; ✔  &lt;/button&gt; &lt;/td&gt;
              &lt;td class=&quot;done&quot;&gt; &lt;/td&gt;
              &lt;td &gt;
              &lt;a href=&quot;&quot;&gt; &lt;/a&gt;&lt;/td&gt;
              &lt;td &gt; &lt;/td&gt;
              &lt;td &gt; &lt;/td&gt;

          &lt;/tr&gt;

      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/div&gt;
  &lt;hr&gt;

&lt;!-- Travel Manager Section --&gt;
  &lt;div class=&quot;travel-section&quot; id=&quot;manager&quot;&gt;
    &lt;h1 &gt;Travel Manager&lt;/h1&gt;&lt;br&gt;
      &lt;p&gt;Travel Manager section provides useful widgets that help the users to be up-to-date about the weather and currency of the country they are visiting. &lt;/p&gt;
      &lt;p&gt;This section also allow the users to access their Google Calender and a Map to manage their schedules and document places visited or need to be visited .&lt;/p&gt;
          &lt;div class=&quot;widget-section&quot; id=&quot;widget&quot; &gt;
            &lt;h3 class=&quot;w3-center&quot;&gt;Weather Widget&lt;/h3&gt;&lt;br&gt;

            &lt;div class=&quot;temperature&quot; style=&quot;margin: 80px&quot;&gt;
              &lt;div id=&quot;openweathermap-widget-15&quot;&gt;&lt;/div&gt;
              &lt;script&gt;window.myWidgetParam ? window.myWidgetParam : window.myWidgetParam = [];
              window.myWidgetParam.push({
                id: 15,
                cityid: &#39;5128581&#39;,
                appid: &#39;17ed6b98c8736346ea39457af086bcc1&#39;,
                units: &#39;metric&#39;,
                containerid: &#39;openweathermap-widget-15&#39;,
              });
              (function () {
                var script = document.createElement(&#39;script&#39;);
                script.async = true;
                script.charset = &quot;utf-8&quot;;
                script.src = &quot;//openweathermap.org/themes/openweathermap/assets/vendor/owm/js/weather-widget-generator.js&quot;;
                var s = document.getElementsByTagName(&#39;script&#39;)[0];
                s.parentNode.insertBefore(script, s);
              })();&lt;/script&gt;

            &lt;/div&gt;
            &lt;div class=&quot;currency&quot; style=&quot;margin: 80px&quot;&gt;
              &lt;h3 class=&quot;w3-center&quot;&gt;Currency Widget&lt;/h3&gt;&lt;br&gt;
              &lt;!-- EXCHANGERATES.ORG.UK EXCHANGE RATE CONVERTER START --&gt;
              &lt;script type=&quot;text/javascript&quot;&gt;
                var dcf = &#39;USD&#39;;
                var dct = &#39;KRW&#39;;
                var mc = &#39;2D6AB4&#39;;
                var mbg = &#39;FFFFFF&#39;;
                var f = &#39;arial&#39;;
                var fs = &#39;11&#39;;
                var fc = &#39;000000&#39;;
                var tf = &#39;arial&#39;;
                var ts = &#39;14&#39;;
                var tc = &#39;FFFFFF&#39;;
                var tz = &#39;-8&#39;;

              &lt;/script&gt;
              &lt;script type=&quot;text/javascript&quot; src=&quot;https://www.currency.me.uk/remote/ER-ERC-1.php&quot;&gt;&lt;/script&gt;
              &lt;small&gt;Source: &lt;a rel=&quot;nofollow&quot; href=&quot;//www.exchangerates.org.uk&quot; target=&quot;_new&quot;&gt;ExchangeRates.org.uk&lt;/a&gt;&lt;/small&gt;
              &lt;!-- EXCHANGERATES.ORG.UK  EXCHANGE RATE CONVERTER END --&gt;
            &lt;/div&gt;
          &lt;/div&gt;

          &lt;div class=&quot;calendar-section&quot; id=&quot;calendar&quot; style=&quot;margin: 80px&quot;&gt;
              &lt;h3 class=&quot;w3-center&quot;&gt;Manage your Calendar&lt;/h3&gt;&lt;br&gt;
              &lt;iframe src=&quot;https://calendar.google.com/calendar/embed?src=dc6d126b12a1d91eb23f694d761023728e9c88945bf65aaecc998d517967bfe4%40group.calendar.google.com&amp;ctz=America%2FNew_York&quot;
                      style=&quot;border: 0&quot; width=&quot;1000&quot; height=&quot;600&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;

          &lt;/div&gt;

          &lt;div class=&quot;map-section&quot; style=&quot;margin: 80px&quot;&gt;
            &lt;h3 class=&quot;w3-center&quot;&gt; Keep Track of your Saved and Visited Places&lt;/h3&gt;&lt;br&gt;
              &lt;iframe src=&quot;https://www.google.com/maps/d/u/0/embed?mid=1kw75SfFElWu2cVMZyvU8uKxyOLnU5hQ&amp;ehbc=2E312F&quot;
                      width=&quot;1000&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;
          &lt;/div&gt;

          &lt;/div&gt;

  &lt;/div&gt;

  &lt;hr&gt;
&lt;!-- Contact Section --&gt;
  &lt;div class=&quot;contact-section&quot; id=&quot;contact&quot;&gt;
    &lt;h1&gt;Contact&lt;/h1&gt;&lt;br&gt;
    &lt;p&gt;If you liked my project and would like to check out my other works or want to discuss for projects or offer please contact me&lt;/p&gt;
    &lt;p&gt;email: baeksbs3@gmail.com&lt;/p&gt;
  &lt;/div&gt;

&lt;!-- End page content --&gt;
&lt;/div&gt;

&lt;!-- Footer --&gt;
&lt;footer class=&quot;w3-center w3-light-grey w3-padding-32&quot;&gt;
  &lt;p&gt;Subin Baek 2022&lt;/p&gt;
&lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Weekly I Learned- 웹개발 종합반 5주차 ]]></title>
            <link>https://velog.io/@codename_suding/Weekly-I-Learned-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-5%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@codename_suding/Weekly-I-Learned-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-5%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 18 Oct 2022 15:58:34 GMT</pubDate>
            <description><![CDATA[<ul>
<li><h3 id="도메인-만들기-aws-연결하기">도메인 만들기, AWS 연결하기</h3>
<ul>
<li><p>가비아에서 내 웹사이트의 도메인 (주소)을  구매한다</p>
</li>
<li><p>AWS 에 가상의 컴퓨터를 구매해서 내 서버를 실행하고 종료한다</p>
<ul>
<li><p>사용하는 컴퓨터는 리눅스를 사용한다</p>
<ul>
<li>리눅스 명령어</li>
</ul>
</li>
<li><p>EC2 에서 우리가 빌려 쓸 가상의 컴퓨터에 접속 한다</p>
<ul>
<li><p>ubuntuserver 20.4 를 사용한다 (사용하게 될 서버)</p>
</li>
<li><p>port 22 가 열려있어야만 접속이 가능하다</p>
</li>
<li><p>다른 컴퓨터를 접속할때는 SSH (Secured Shell Protocol)를 사용하는데 보안이 뛰어나다</p>
<ul>
<li><p>terminal을 열어서 SSH에 접속 하고 리눅스를 사용해서 AWS  컴퓨터를 실행한다</p>
<p><a href="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/899f3b48-c0e0-4bd3-b375-e9f7f1f17519/ec2ubuntu_exported.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&amp;X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20221014%2Fus-west-2%2Fs3%2Faws4_request&amp;X-Amz-Date=20221014T205634Z&amp;X-Amz-Expires=86400&amp;X-Amz-Signature=ae70c3782113acb0e9e2e80a093dd20b15fb6f64865d05981a1bb8c429251bc4&amp;X-Amz-SignedHeaders=host&amp;x-id=GetObject">https://s3.us-west-2.amazonaws.com/secure.notion-static.com/899f3b48-c0e0-4bd3-b375-e9f7f1f17519/ec2ubuntu_exported.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&amp;X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20221014%2Fus-west-2%2Fs3%2Faws4_request&amp;X-Amz-Date=20221014T205634Z&amp;X-Amz-Expires=86400&amp;X-Amz-Signature=ae70c3782113acb0e9e2e80a093dd20b15fb6f64865d05981a1bb8c429251bc4&amp;X-Amz-SignedHeaders=host&amp;x-id=GetObject</a></p>
</li>
<li><p>terminal 에서 내 ubuntu 서버 접속이 되지 않는다</p>
<pre><code class="language-python">subinbaek@Subins-MacBook-Air ~ % /Users/subinbaek/Downloads/sparta_web.pem 
zsh: permission denied: /Users/subinbaek/Downloads/sparta_web.pem
subinbaek@Subins-MacBook-Air ~ % ssh i- /Users/subinbaek/Downloads/sparta_web.pem ubuntu@43.201.100.141
ssh: Could not resolve hostname i-: nodename nor servname provided, or not known
subinbaek@Subins-MacBook-Air ~ % sudo chmod /Users/subinbaek/Downloads/sparta_web.pem 
usage:    chmod [-fhv] [-R [-H | -L | -P]] [-a | +a | =a  [i][# [ n]]] mode|entry file ...
  chmod [-fhv] [-R [-H | -L | -P]] [-E | -C | -N | -i | -I] file ...
subinbaek@Subins-MacBook-Air ~ % ssh -i /Users/subinbaek/Downloads/sparta_web.pem  ubuntu@43.201.100.141
The authenticity of host &#39;43.201.100.141 (43.201.100.141)&#39; can&#39;t be established.
ED25519 key fingerprint is SHA256:AAteYphf9z5iPvzPMQVkqBJeoHLSy9CguOn+SzvxLcE.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added &#39;43.201.100.141&#39; (ED25519) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for &#39;/Users/subinbaek/Downloads/sparta_web.pem&#39; are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key &quot;/Users/subinbaek/Downloads/sparta_web.pem&quot;: bad permissions</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><a href="https://bobbyhadz.com/blog/aws-ec2-warning-unprotected-private-key-file">https://bobbyhadz.com/blog/aws-ec2-warning-unprotected-private-key-file</a></p>
</li>
<li><p>EC2 설치하기</p>
<pre><code class="language-python">  # python3 -&gt; python
  sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

  # pip3 -&gt; pip
  sudo apt-get update
  sudo apt-get install -y python3-pip
  sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

  # port forwarding
  sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000</code></pre>
</li>
</ul>
</li>
</ul>
<pre><code>### 숙제: 버켓리스트 만들기

- db 여러개 데이터 찾기 + 파이썬 len ()

    ```python
    @app.route(&quot;/bucket&quot;, methods=[&quot;POST&quot;])
    def bucket_post():
        bucket_receive = request.form[&#39;bucket_give&#39;]
        count = list(db.bucket.find({},{&#39;_id&#39;:False}))
        num = len(count)+1
        done = 0
        doc = {
            &#39;bucket&#39;: bucket_receive,
            &#39;num&#39;: num,
            &#39;done&#39; done
        }
        db.bucket.insert_one(doc)
        return jsonify({&#39;msg&#39;: &#39;저장 완료!&#39;})
    ```

    - 버켓 리스트가 여러개 생성되면 DB에서 데이터를 꺼내 올때 혼동이 올수 있으니 버켓 리스트를 생성할때 아이템마다 순서를 정해준다
    - count = list(db.bucket.find({},{&#39;_id&#39;:False}))
        - db에 저장된 아이템을 찾아서 순서를 매겨주기 위해 데이터를 먼저 찾는다
    - num = len(count) +1
        - leng(count) 는 아이템 개수를 돌려주는 공식이다. db.bucket 에 이는 모든 아이템은 개수에 + 1 개씩 더해서 아이템 순서를 정한다



- CSS (밑줄 치기 스타일 적용) , 조건문 활용하여 완료된 아이템 밑줄 그어주기

    ```python
    .mybox &gt; li &gt; h2 {
    max-width: 75%;
    font-size: 20px;
    font-weight: 500;
    margin-right: auto;
    margin-bottom: 0px;
    }
    .mybox &gt; li &gt; h2.done {
    text-decoration:line-through
    }
    ```

    - h2 에  class=”done” 적용하기

    ```jsx
    function show_bucket(){
        $(&#39;#bucket-list&#39;).empty()
        $.ajax({
            type: &quot;GET&quot;,
            url: &quot;/bucket&quot;,
            data: {},
            success: function (response) {
                let rows = response[&#39;buckets&#39;]
                for (let i = 0; i &lt; rows.length; i++) {
                    let bucket = rows[i][&#39;bucket&#39;]
                    let num = rows[i][&#39;num&#39;]
                    let done = rows[i][&#39;done&#39;]

                    let temp_html = ``
                    if (done == 0) {
                        temp_html = `&lt;li&gt;
                                        &lt;h2&gt;✅ ${bucket}&lt;/h2&gt;
                                        &lt;button onclick=&quot;done_bucket(${num})&quot; type=&quot;button&quot; class=&quot;btn btn-outline-primary&quot;&gt;완료!&lt;/button&gt;
                                    &lt;/li&gt;`
                    } else {
                        temp_html = `&lt;li&gt;
                                        &lt;h2 class=&quot;done&quot;&gt;✅ ${bucket}&lt;/h2&gt;
                                    &lt;/li&gt;`
                    }
                    $(&#39;#bucket-list&#39;).append(temp_html)
                }
            }
        });
    }
    ```

    - done 0일 때와  아닐때로 조건을 구분하여 조건에 해당되는 코드를 실행한다
        - if (done == 0) { }, 버켓아이템 보여주기, 완료 버튼 제공하기
        - else { } 는 h2 class= “done” 을 적용해서 버켓 아이템에  밑줄그어주기 , 완료 버튼은 보여주지 않기
- db 업데이트 해서 완료된 아이템  0 에서 1로 바꿔 주기 , int() 문자를 숫자로 바꿔주기

    ```python
    @app.route(&quot;/bucket/done&quot;, methods=[&quot;POST&quot;])
    def bucket_done():
        num_receive = request.form[&#39;num_give&#39;]
        db.bucket.update_one({&#39;num&#39;: int(num_receive)}, {&#39;$set&#39;: {&#39;done&#39;: 1}})
        return jsonify({&#39;msg&#39;: &#39;버킷 완료!&#39;})
    ```

    - db 에 있는 num 을 불러와서 bucket_done 이라는 함수가 실행되면 db에 done 을 0 에서 1로 바꿔준다
    - num 을 불러올때 db 안에서는 숫자가 아닌 문자로 저장되어있기 때문에 int() 라는 함수를 사용해서 숫자 1로 변환시켜 준다

### 미니 프로젝트

[Travel Manager](http://subin-100.shop/)</code></pre>]]></description>
        </item>
    </channel>
</rss>