<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yoo_oon.Dev</title>
        <link>https://velog.io/</link>
        <description>Concilio et Labore ( 지혜와 노력으로 )</description>
        <lastBuildDate>Tue, 31 Jan 2023 07:44:42 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yoo_oon.Dev</title>
            <url>https://velog.velcdn.com/images/yoo_oon/profile/ce184cef-7361-4a34-a088-b7bafeec3103/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yoo_oon.Dev. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yoo_oon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Tableau] 그룹,집합 예시]]></title>
            <link>https://velog.io/@yoo_oon/Tableau-%EA%B7%B8%EB%A3%B9%EC%A7%91%ED%95%A9-%EC%98%88%EC%8B%9C</link>
            <guid>https://velog.io/@yoo_oon/Tableau-%EA%B7%B8%EB%A3%B9%EC%A7%91%ED%95%A9-%EC%98%88%EC%8B%9C</guid>
            <pubDate>Tue, 31 Jan 2023 07:44:42 GMT</pubDate>
            <description><![CDATA[<h3 id="그룹">그룹</h3>
<p>항목 내 데이터들을 묶어주는 것</p>
<hr>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/70a49826-beae-46d6-894b-d5db54a452a7/image.png" alt=""></p>
<p>일반적으로 초기 시/도 데이터는 위와 같이 강원~충남처럼 나누어져있는 것을 확인 할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/7c28441e-136b-49b2-ae2a-051cad8683cd/image.png" alt=""></p>
<p>태블로에서는 그룹 생성을 통해 항목 내의 데이터를 위와 같이 묶어 줄 수 있다.
<em>(경기,서울) = 수도권 / (이외의 지역) = 이외</em></p>
</br>

<h4 id="group을-사용하지-않았을-경우의-영역-차트">Group을 사용하지 않았을 경우의 영역 차트 <img src="https://velog.velcdn.com/images/yoo_oon/post/e57d8074-7525-4252-b1f1-87616b4c4edc/image.png" alt=""></h4>
<h4 id="group을-사용했을-경우의-영역-차트">Group을 사용했을 경우의 영역 차트<img src="https://velog.velcdn.com/images/yoo_oon/post/0fab24b0-d429-4936-893b-44ece56e690b/image.png" alt=""></h4>
<p>항목 내의 데이터를 새로운 별칭(수도권,이외)로 지정하여 항목 내 데이터를 새롭게 Group을 생성 할 수 있는 것을 확인 할 수 있다.</p>
</br>

<hr>
<h3 id="집합">집합</h3>
<p>집합에 포함되는지 아닌지로 나누는 것
집합에 포함(IN) or 미포함(OUT)의 기준으로 나뉜다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/f91720cb-2395-4440-83de-78ed88d66513/image.png" alt=""></p>
<p>고객들 중 매출 상위 10명의 집합을 생성 할 경우</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/6d6aa8ee-dd88-48c0-b7ec-76ac20ed3eba/image.png" alt=""></p>
<p>위의 과정에서 매출 상위 10명,20명의 집합을 생성한 후
생성한 두 집합을 선택한 뒤 집합을 생성하면 다음과 같이 두 개의 집합을 엮을 수 있다.</p>
<p>Setting 사항에 매출 상위20명에 대하여 <strong>공유 데이터를 제외하고</strong> 라고 되어 있는 것을 확인 할 수 있다.
이는 간단하게 생각해서 전체 1위<del>20위중 1위</del>10위 데이터를 제외하라는 말과 같으므로
<strong>매출 상위 11위~20위에 대한 집합이 생성된다.</strong></p>
</br>

<p><img src="https://velog.velcdn.com/images/yoo_oon/post/90ed6cd1-79f5-48b3-b5eb-e5f35c0e28d7/image.png" alt="">
이후 색상별로 구분하고 싶어서 집합에 하나라도 포함되는 경우를 a, 이외의 경우를 b라고 하는 계산식을 생성했다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/93096d6f-cb53-42f9-b9bd-fcc255ec5983/image.png" alt="">
그리고 매출 상위고객의 순번을 확인하기 위해 INDEX()함수를 사용한뒤 앞서 만든 계산식으로 색상을 부여했지만
계산식에 의거하여 IN인경우와 아닌 경우가 나뉘어져 색상이 부여되었지만 INDEX에 의해 IN이 아닌 경우.
즉 out인 경우들중 첫번째값들이 1번 섹션에 포함되어 분배된 것을 확인 할 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/f0b4c9b5-5f77-41ed-9e65-82137a3216b7/image.png" alt="">
이를 해결하기 위한 방법으로 테이블 계산 편집 - 특정 차원 - IN or OUT까지 모두 선택해주면 아래와 같이 올바르게 정렬이 된다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/41c7b33a-de33-445f-975e-550dbab2773e/image.png" alt="">
처음 의도한 바와 같이 IN이 포함되있는 경우, 그렇지 않은 경우(out) 위와 같이 표현 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Fixed를 활용한 금액에 따른 색상 설정]]></title>
            <link>https://velog.io/@yoo_oon/Tableau-Fixed%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EA%B8%88%EC%95%A1%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%83%89%EC%83%81-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@yoo_oon/Tableau-Fixed%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EA%B8%88%EC%95%A1%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%83%89%EC%83%81-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Tue, 31 Jan 2023 01:28:38 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/yoo_oon/post/cb24f0f8-7eb5-40a2-86ba-c262d8420798/image.png" alt=""></p>
<p>년월에 해당하는 세그먼트의 수익을 사용자가 설정한 금액에 따라 색상의 범위를 만드는 예시</p>
<p>Fixed 함수를 사용하여 세그먼트의 항목별로 금액에 따른 범위를 설정해주면 위의 이미지와 같이 설정 가능하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Data Join & Blending]]></title>
            <link>https://velog.io/@yoo_oon/Tableau-Data-Join-Blending</link>
            <guid>https://velog.io/@yoo_oon/Tableau-Data-Join-Blending</guid>
            <pubDate>Tue, 31 Jan 2023 01:21:05 GMT</pubDate>
            <description><![CDATA[<h1 id="데이터-시트-연결">데이터 시트 연결</h1>
<h2 id="join">Join</h2>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/ac43f0c1-2e4b-4ccc-85e9-7dbc219846e4/image.PNG" alt=""></p>
<p>모든 Join은 각 행을 기준으로 한다.</p>
<ul>
<li><p><strong>Inner Join</strong>
  A,B 행 데이터가 같은 경우, 열을 합친다.</p>
</li>
<li><p><strong>Outer Join</strong>
  A,B 모든 행렬 데이터를 합친다.</p>
</li>
<li><p><strong>Left Join</strong>
  기준 A 테이블에서 공통인 데이터들만 합친다. (오른쪽 테이블에 일치하는 값이 없는 경우)</p>
<ul>
<li>B 테이블 칼럼이 A 테이블 칼럼으로 붙는다.</li>
</ul>
</li>
<li><p><strong>Right Join</strong>
  기준 B 테이블에서 공통된 데이터들만 합친다. ( 왼쪽 테이블에 일치하는 값이 없는 경우 )</p>
<ul>
<li>A 테이블 칼럼이 B 테이블 칼럼으로 붙는다.</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>왼쪽 조인으로 연결</li>
<li>countd(IF [반품?] = &quot;Yes&quot; ) Then [주문 번호] END</li>
<li>반품률 계산 한 것을 숫자형식-백분율 로 설정하면 %를 백분율로 설정 가능하다.</li>
</ul>
<h2 id="blending">Blending</h2>
<h3 id="blending과-left-join의-차이점">Blending과 left join의 차이점</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/4415a4ea-683e-4b1a-bd13-2e043852f85c/image.png" alt="">
<img src="https://velog.velcdn.com/images/yoo_oon/post/0a27b068-7202-469d-901e-2963bb06cc07/image.png" alt="">
join의 경우 A Table에 대해 B Table이 붙도록 되어있는 반면,
blending의 경우 위의 예시처럼 A Table에는 product 값이 Rice,Bread로 나뉘어져있어서 1대1 매칭이 되지 않아 &#39; * &#39; 표시로 나오게 된다.</p>
<p>이를 해결하는 방법은 B Table에도 Product 칼럼을 생성해준다면 1대1로 매칭이 될 것이다.</p>
<hr>
<h2 id="relationship">Relationship</h2>
<ul>
<li>데이터를 끌어올 때 키 값을 잘 맞춰주어여함<ul>
<li>ex) 날짜-숫자 -&gt; 숫자-숫자</li>
</ul>
</li>
<li>이중 축 - 축 동기화</li>
<li>매출 성장률을 합계 매출에 덮어 씌운다.
참고: 레이블이 다른 마크와 겹치도록 허용( 모든 값 출력)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] 매개변수 동작으로 시트변경]]></title>
            <link>https://velog.io/@yoo_oon/Tableau-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EB%8F%99%EC%9E%91%EC%9C%BC%EB%A1%9C-%EC%8B%9C%ED%8A%B8%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@yoo_oon/Tableau-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EB%8F%99%EC%9E%91%EC%9C%BC%EB%A1%9C-%EC%8B%9C%ED%8A%B8%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Fri, 11 Nov 2022 06:37:29 GMT</pubDate>
            <description><![CDATA[<h2 id="매개변수-동작을-활용하여-버튼을-눌렀을-때-다른-시트로-변경하는-방법">매개변수 동작을 활용하여 버튼을 눌렀을 때 다른 시트로 변경하는 방법</h2>
<br>
---

<h3 id="선행과정">선행과정</h3>
<ul>
<li>버튼 클릭을 통해서 변경되어질 ex) year,month 시트에 사용자가 생성한 매개변수를 통한 filter 적용이 되어 있어야함 
( Because, 당연하게도 매개변수 동작이므로 해당 매개변수를 클릭했을 때 필터 조건에 의해 시트를 변경하기 위함임 )</li>
</ul>
<pre><code>Ex) 필터조건_매개변수 change가 year or month일 때

IF [change] = &#39;Year&#39; then &#39;Year&#39;
ELSEIF [change]=&#39;month&#39; then &#39;month&#39;
END</code></pre><hr>
<br>

<h3 id="매개변수-동작-설정">매개변수 동작 설정</h3>
<h4 id="year-button">year button</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/735b8b20-5c10-42be-b16f-9e44f1ebe4f4/image.PNG" alt=""></p>
<h4 id="month-button">month button</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/1798b74a-e208-4aaf-90a3-8fa29c0cd8ee/image.PNG" alt=""></p>
<hr>
<br>

<h3 id="실행화면">실행화면</h3>
<h4 id="year-button-동작">year button 동작</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/6fb8a42f-6dfa-4090-ad7a-dbe503cb538d/image.PNG" alt=""></p>
<h4 id="month-button-동작">month button 동작</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/7c3ab57f-9a26-4f33-8ca3-01641226b965/image.PNG" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[향후 계획에 대해 세워보기]]></title>
            <link>https://velog.io/@yoo_oon/%ED%96%A5%ED%9B%84-%EA%B3%84%ED%9A%8D%EC%97%90-%EB%8C%80%ED%95%B4-%EC%84%B8%EC%9B%8C%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@yoo_oon/%ED%96%A5%ED%9B%84-%EA%B3%84%ED%9A%8D%EC%97%90-%EB%8C%80%ED%95%B4-%EC%84%B8%EC%9B%8C%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Mon, 10 Oct 2022 13:07:21 GMT</pubDate>
            <description><![CDATA[<p>올해 졸업을 하고나서 3월말부터 이어드림스쿨의 커리큘럼을 따라서 정말 정신없이 데이터분석,머신러닝,딥러닝을 공부하고 여러 프로젝트를 달려왔다.</p>
<p>처음에는 강의가 빠르게 나가다보니 끝까지 잘 따라 갈 수 있을까? 하는 생각도 많이 들었다. 실제로 200명 가까이 되었던 수강생들이 지금 기준으로 100여명정도만 남았을 정도로 많은 분들이 프로그래밍에 대해 벽을 느끼고 또는 적성에 맞지않아서 포기했었다. 나는 그래도 중간에 포기하고 싶지 않았고, 어떻게든 끝까지 따라가보자라는 생각을 그냥 했던 거 같다.</p>
<p>그렇게 python에 대한 기본 지식이 잡히면서 그래도 코드를 보고 이렇게 돌아가는구나 어디가 틀렸구나 정도를 아는 수준에 도달했을 때부터 흥미가 생기고 더 열심히 해보려고 했다. 그리고 여러 프로젝트를 하면서 팀장 직책을 맡아서 팀원분들과 소통하고 조율하면서 나 스스로를 놓지 않으려고 그래도 나름 노력했던게 많이 도움이 되었던 거 같다.</p>
<p>마지막 기업 연계 프로젝트의 기획 발표를 나름 성공적으로 끝내던 찰나에.
데이터 분석 및 시각화를 하는 기업의 채용형 인턴십 공고를 보게 되었다.
너무나 관심이 있던 분야였고, 해보고 싶다는 생각이 많이 들었다. 그래서 아직 많이 부족하지만 합격하면 열심히 해보자라는 생각으로 나름 포트폴리오를 정리하고 자소서를 작성하여 넣어보았다. </p>
<p>*<em>운이 좋게도 합격을 하여 인턴십의 기회를 얻을 수 있었고 내일이면 첫 출근을 하게 된다.
*</em>
부트캠프를 통해서 내가 취업을 할 수 있을까라는 생각과 고민을 되게 많이 했는데, 이렇게 인턴십 기회를 얻을 수 있어서 되게 기대가 되고 설레기도 한다..!</p>
<p>그래서 기업에서 정규직으로 전환된다면 너무 좋겠지만 아니더라도 많이 배우고 공부 할 수 있을 것 같다는 생각에 개인적으로 틈틈히 공부를 해야겠다는 생각이 들었다.</p>
<p>나의 일단 계획은 이렇다..!</p>
<pre><code>1. SQLD 자격증 취득
2. SQL 다시 꾸준히 공부
3. Tableau 공부
4. 컴활 1급 실기 준비하기</code></pre><p>인턴십을 진행하면서 병행 할 수 있을지 모르겠지만 자격증 공부하면서 빠르게 적응해보고싶다!!
운동도 다시 하면서! 
내년에는 어엿한 사회의 직장인이 되어 있기를 기대 해본다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[OpenCV] 체적측량 프로젝트_Image detection 관련 함수 정리]]></title>
            <link>https://velog.io/@yoo_oon/OpenCV-%EC%B2%B4%EC%A0%81%EC%B8%A1%EB%9F%89-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8Image-detectaion-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@yoo_oon/OpenCV-%EC%B2%B4%EC%A0%81%EC%B8%A1%EB%9F%89-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8Image-detectaion-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 27 Sep 2022 02:28:36 GMT</pubDate>
            <description><![CDATA[<h2 id="체적측량-프로젝트를-진행하면서-몰랐던-메소드에-대해서-정리">체적측량 프로젝트를 진행하면서 몰랐던 메소드에 대해서 정리</h2>
<h3 id="cv2adaptivethreshold-src-maxvalue-adaptivemethod-thresholdtype-blocksize-c">cv2.adaptiveThreshold (src, maxValue, adaptiveMethod, thresholdType, blockSize, C)</h3>
<pre><code>Parameters:    
src – grayscale image
maxValue – 임계값
adaptiveMethod – thresholding value를 결정하는 계산 방법
thresholdType – threshold type
blockSize – thresholding을 적용할 영역 사이즈
C – 평균이나 가중평균에서 차감할 값</code></pre><h3 id="cv2findcontourssrc-mode-method-contours-hierarchy-offset">cv2.findContour(ssrc, mode, method, contours, hierarchy, offset)</h3>
<pre><code>src: 입력 영상, 검정과 흰색으로 구성된 바이너리 이미지
mode: 컨투어 제공 방식 (cv2.RETR_EXTERNAL: 가장 바깥쪽 라인만 생성, cv2.RETR_LIST: 모든 라인을 계층 없이 생성, cv2.RET_CCOMP: 모든 라인을 2 계층으로 생성, cv2.RETR_TREE: 모든 라인의 모든 계층 정보를 트리 구조로 생성)
method: 근사 값 방식 (cv2.CHAIN_APPROX_NONE: 근사 없이 모든 좌표 제공, cv2.CHAIN_APPROX_SIMPLE: 컨투어 꼭짓점 좌표만 제공, cv2.CHAIN_APPROX_TC89_L1: Teh-Chin 알고리즘으로 좌표 개수 축소, cv2.CHAIN_APPROX_TC89_KCOS: Teh-Chin 알고리즘으로 좌표 개수 축소)
contours(optional): 검출한 컨투어 좌표 (list type)
hierarchy(optional): 컨투어 계층 정보 (Next, Prev, FirstChild, Parent, -1 [해당 없음])
offset(optional): ROI 등으로 인해 이동한 컨투어 좌표의 오프셋</code></pre><h3 id="cv2contourareacontour-orientednone">cv2.contourArea(contour, oriented=None)</h3>
<pre><code>외곽선이 감싸는 영역의 면적을 반환합니다
• contour: 외곽선 좌표. numpy.ndarray. shape=(K, 1, 2)
• oriented: True이면 외곽선 진행 방향에 따라 부호 있는 면적을 반환. 기본값은 False.</code></pre><h3 id="cv2arucodetectmarkers">cv2.aruco.detectMarkers</h3>
<pre><code>detectMarkers() 메서드를 사용하여 이미지에서 마커를 감지하는 것</code></pre><h3 id="cv2polylinesimg-pts-isclosed-color-thickness-linetype">cv2.polylines(img, pts, isClosed, color, thickness, lineType)</h3>
<pre><code>img: 그림을 그릴 이미지 파일 
pts: 연결할 꼭짓점 좌표, Numpy array
isClosed: 닫힌 도형 여부, True/False
color: BGR형태의 선 색상 (ex; (255, 0, 0) -&gt; Blue) 
thickness (int): 선의 두께. pixel (default=1)
lineType: 선 그리기 형식 (cv2.LINE_4, cv2.LINE_8, cv2.LINE_AA)</code></pre><h3 id="cv2arclengthcurve-closed">cv2.arcLength(curve, closed)</h3>
<pre><code>외곽선 길이를 반환합니다.
• curve: 외곽선 좌표. numpy.ndarray. shape=(K, 1, 2)
• closed: True이면 폐곡선으로 간주</code></pre><h3 id="cv2minarearectcnt">cv2.minAreaRect(cnt)</h3>
<pre><code>주어진 점을 감싸는 최소 크기 회전된 사각형을 반환합니다.
인자로 입력한 contour에 외접하면서 면적이 가장 작은 직사각형을 구하는 데 활용.</code></pre><h3 id="cv2boxpointsrect">cv2.boxPoints(rect)</h3>
<pre><code>minAreRect()함수로 얻은 rect의 꼭지점 4개의 좌표를 얻기 위해 사용</code></pre><h3 id="cv2puttextimg-text-org-font-fontscale-color-thickness-linetype">cv2.putText(img, text, org, font, fontScale, color, thickness, lineType)</h3>
<pre><code>text: 표시할 문자열 
org: 문자열을 표시할 위치(좌측 하단 기준) (x, y)
font: 글꼴(cv2.FONT_XXXX 형식) 
fontScale: 글꼴 크기</code></pre><h3 id="parameters--cv2arucodetectorparameters_create">parameters = cv2.aruco.DetectorParameters_create()</h3>
<pre><code>Create a new set of DetectorParameters with default values.</code></pre><h3 id="aruco_dict--cv2arucodictionary_getcv2arucodict_5x5_50">aruco_dict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_5X5_50)</h3>
<pre><code>5x5 bits, minimum hamming distance between any two codes = 8, 50 codes
- 해밍거리 : 두 문자열의 같은 위치에 있는 두 문자를 비교해 다른 문자의 수를 세는 것 
-&gt; 에러 감지</code></pre><p> <a href="https://docs.opencv.org/4.x/d9/d6a/group__aruco.html">https://docs.opencv.org/4.x/d9/d6a/group__aruco.html</a>
 (OpenCV-ArucoMarker.docs)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Tableau ]]></title>
            <link>https://velog.io/@yoo_oon/TIL-Tableau</link>
            <guid>https://velog.io/@yoo_oon/TIL-Tableau</guid>
            <pubDate>Fri, 23 Sep 2022 01:51:04 GMT</pubDate>
            <description><![CDATA[<h1 id="tableau">Tableau</h1>
<pre><code>See and Understand Data</code></pre><h3 id="장점">장점</h3>
<ol>
<li>No code -&gt; Speed good!</li>
<li>상호작용 Good</li>
<li>Communitys
3-1. Tableau Public,MakeoverMonday,TableauTipTuesday...etc
다양한 커뮤니티들이 운영 중이기에 여러 정보를 습득 할 수 있다.</li>
</ol>
<h3 id="서버데이터-연결하는경우">서버데이터 연결하는경우</h3>
<ul>
<li>실시간 대시보드를 사용할 떄</li>
<li>업데이트와 스키마 변경이 빈번할때</li>
<li>보안이 중요한 데이터 일 경우(권한이 필요할때)</li>
</ul>
<h4 id="서버의-종류">서버의 종류</h4>
<ul>
<li>Mysql</li>
<li>Google Bigquery,spreadsheet</li>
<li>Salefore</li>
<li>Amazon Redshif</li>
</ul>
<p>이외에도 무수히 많은 서버를 지원  </p>
</br>


<hr>
<h3 id="url-주소-불러오는-방법">URL 주소 불러오는 방법</h3>
<p>=importhtml(&quot;<a href="https://www.worldometers.info/coronavirus/&quot;,&quot;talbe&quot;,1">https://www.worldometers.info/coronavirus/&quot;,&quot;talbe&quot;,1</a>)</p>
<ul>
<li>해당 주소에서 테이블 형식으로 첫번재 테이블을 가져온다</li>
<li>구글시트에 함수로 입력하면 지속적으로 갱신가능(지금은 막힌것으로 보임)</li>
</ul>
</br>


<hr>
<h1 id="데이터-관계는-데이터-분석을-위해-여러-테이블에서-데이터를-결합하는-방법">데이터 관계는 데이터 분석을 위해 여러 테이블에서 데이터를 결합하는 방법</h1>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/9039908d-8c6c-4fb1-b9fc-042fb29d9889/image.PNG" alt="">   </p>
<ul>
<li>조인과 달리 단일 테이블로 병합되지 않고 각 테이블을 유지하기 때문에 집계값이 중복되지 않는다.</li>
</ul>
<h2 id="연결">연결</h2>
<ol>
<li>데이터베이스에 쿼리 보내고 결과에 따라 뷰 업데이트</li>
<li>성능을 향상시키기 위해 데이터를 로컬에 저장</li>
</ol>
<h2 id="데이터-원본창">데이터 원본창</h2>
<p>그룹만들기: 서로 다른 차원 멤버들을 그룹지어준다
분할: 태블로가 알아서 적절하게 분할해 여러개 열로 나누어준다
피벗: 가로늘어진것을 세로로 바꾸어준다.</p>
</br>

<hr>
<h1 id="pratice_visualize">Pratice_Visualize</h1>
<h3 id="scatter-plot">Scatter plot</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/72502528-a398-4fa6-b63a-c83211e6b797/image.PNG" alt=""></p>
<h3 id="lineplot">Lineplot</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/8ea78a9e-bdf5-4985-a4da-6c0e0cc754e1/image.PNG" alt=""></p>
<ul>
<li>년 정보는 열에 넣어주는것이 좋다.</li>
<li>ctrl cmd를 누르고 필드를 복사 가능하고</li>
<li>레이블을 선택할 경우 차트에 반영 가능하다.<h3 id="bar-chart">Bar chart</h3>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/7f441ec4-0d27-4ea6-b65e-8e1e8b127b5b/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/yoo_oon/post/2cd1c4b9-18b2-42b7-ba5a-94f975dc4340/image.PNG" alt=""></p>
<h3 id="map-chart">Map Chart</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/b7ee3861-f3be-4c77-98c2-bb680d647114/image.PNG" alt=""></p>
<h3 id="dashboard">Dashboard</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/62539eec-944f-4286-b862-aa23fb2f5cef/image.png" alt=""></p>
<p>앞서 연습해본 차트들을 하나의 DashBoard에서 표현이 가능하다...!</p>
<hr>
<h1 id="차원--측정값">차원 &amp; 측정값</h1>
<p>차원과 측정값이 함꼐할떄 인사이트 발생</p>
<ul>
<li>측정값은 그 자체 만으로 인사이트 x</li>
<li>차원으로 쪼개지면 의미를 갖게 된다</li>
</ul>
<p>차원 : 나눠서 볼 기준( 지역,연도,성별)</p>
<ul>
<li>숫자를 자르는 기준 (범주형데이터)</li>
<li>측정:  값 그자체(매출 수익 배송비 등)</li>
<li>숫자(수치형 데이터)</li>
</ul>
<p>ex) 측정값만 넣어두면 마크가 1개만 찍힌다
ex) 여기에 차원값을 추가하면 마크가 쪼개지면서 마크의 수가 증가하게된다.</p>
<h2 id="연속-데이터">연속 데이터</h2>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/b0eef87a-7a21-4748-ac92-0aa18fd51904/image.PNG" alt=""></p>
<ul>
<li>연속은 초록 / 오름.내림 정렬x / 트렌드 확인 가능 / Header</li>
</ul>
<h2 id="불연속-데이터">불연속 데이터</h2>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/6ff73428-b34d-4447-a53b-ada3690c7724/image.PNG" alt=""></p>
<ul>
<li>불연속은 파란색 / 오름.내림 정렬o / 카테고리별 /Axis</li>
</ul>
<hr>
<h3 id="집계방식">집계방식</h3>
<p>row level vs agg level
we have to ues agg level</p>
<hr>
<h1 id="워크시트">워크시트</h1>
<h2 id="마크카드">마크카드</h2>
<h3 id="색상">색상</h3>
<p>Cognitive load (인지부하)
여러 색상을 사용하면 보는 사람이 인지하기 힘들다.</p>
<h3 id="vlod-세부정보">VLOD (세부정보)</h3>
<h3 id="서식">서식</h3>
<p>격자선, 영 기준선, 축 눈금자 -&gt; 없음으로 설정하면 깔끔하게 확인</p>
<hr>
<h1 id="차트">차트</h1>
<h3 id="100-누적차트">100% 누적차트</h3>
<p>feature가 너무 많을때 직관적으로 볼 수 있음</p>
<h3 id="슬로프차트">슬로프차트</h3>
<p>전년도 대비</p>
<h3 id="이중차트">이중차트</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/6a311e60-3bf7-4fcf-ba24-9a056571b0a3/image.PNG" alt=""></p>
<h3 id="스파크-라인">스파크 라인</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/4bedc1dc-05f2-4898-9759-5e2f334a5211/image.PNG" alt=""></p>
<ul>
<li>트렌드 추세선 확인 가능</li>
<li>머리글 표시 해제</li>
<li>축편집 - 0 포함 해제</li>
</ul>
<h3 id="캘린더-차트">캘린더 차트</h3>
<h3 id="간트-차트">간트 차트</h3>
<p>날짜를 나타내는 차트</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] 농산물가격변동률 ( TIL )]]></title>
            <link>https://velog.io/@yoo_oon/AI-%EB%86%8D%EC%82%B0%EB%AC%BC%EA%B0%80%EA%B2%A9%EB%B3%80%EB%8F%99%EB%A5%A0-TIL</link>
            <guid>https://velog.io/@yoo_oon/AI-%EB%86%8D%EC%82%B0%EB%AC%BC%EA%B0%80%EA%B2%A9%EB%B3%80%EB%8F%99%EB%A5%A0-TIL</guid>
            <pubDate>Tue, 20 Sep 2022 08:50:50 GMT</pubDate>
            <description><![CDATA[<p>시계열
ML(catboost)+DL(lstm)</p>
<p>ml (data,feature) - 2차원 (catboost)</p>
<ul>
<li>df=df.astype(np.float32)를 통해 타입 통일
catboost&#39;grid_Search_result </li>
</ul>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/2d939973-30e1-47b2-ae59-1f3f69eb6d4a/image.png" alt=""></p>
<ul>
<li>해야할일</li>
</ul>
<ol>
<li>grid search parameter 수정하여 rmse값 낮춰보기</li>
<li>catboost 결과 값을 DL 모델에 적용하는 방법 구상</li>
</ol>
<p>dl (data,time_step,feature) - 3차원 (lstm)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] 예시를 통한 Class 이해하기]]></title>
            <link>https://velog.io/@yoo_oon/Python-%EC%98%88%EC%8B%9C%EB%A5%BC-%ED%86%B5%ED%95%9C-Class-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@yoo_oon/Python-%EC%98%88%EC%8B%9C%EB%A5%BC-%ED%86%B5%ED%95%9C-Class-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 07 Sep 2022 08:19:59 GMT</pubDate>
            <description><![CDATA[<p>*<em>Python class 함수에 관하여 공부를 하긴 했지만 뭔가 머리 속으로 명확하게 자리잡고 있는 것 같지 않아서 
내가 가장 좋아하는 축구 도메인으로 예시 코드를 작성하면서 정리해보았다...! *</em></p>
<hr>
<h1 id="class-예시">Class 예시</h1>
<h3 id="class-생성">Class 생성</h3>
<pre><code class="language-python">class EPL():
    def __init__(self,team,key_def,key_mid):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid
# EPL 클래스 생성

epl = EPL(&quot;MU&quot;,&quot;Varane&quot;,&quot;Antony&quot;)
print(epl.key_mid)

Antony
</code></pre>
<pre><code class="language-python">기본적으로 클래스 내의 함수를 선언할 때는 
def __init(self...)와 같이 생성자를 생성해주는 것이 기본!</code></pre>
<hr>
<h3 id="class-내부-함수-구현">Class 내부 함수 구현</h3>
<pre><code class="language-python">class EPL():
    def __init__(self,team,key_def,key_mid):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid

    def is_EPL_player(self):
        list = [&quot;Kane&quot;,&quot;Son&quot;,&quot;Antony&quot;,&quot;Varane&quot;]
        if self.key_mid in list:
            return &quot;of coruse&quot;
        else:
            return &quot;Abs No&quot;

epl = EPL(&quot;TOT&quot;,&quot;Dier&quot;,&quot;Kane&quot;)
epl2 = EPL(&quot;TOT&quot;,&quot;Sanches&quot;,&quot;Son&quot;)
epl3 = EPL(&quot;PSG&quot;,&quot;Ramos&quot;,&quot;Messi&quot;)


print(epl.is_EPL_player())
print(epl2.is_EPL_player())
print(epl3.is_EPL_player())

of coruse
of coruse
Abs No


# 클래스 내부에 함수 구현
# EPL 선수인지 아닌지 구분

</code></pre>
<pre><code class="language-python">
class EPL():
    def __init__(self,team,key_def,key_mid):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid

    def is_EPL_player(self):
        list = [&quot;Kane&quot;,&quot;Son&quot;,&quot;Antony&quot;,&quot;Varane&quot;,&quot;eriksen&quot;]
        if self.key_mid in list:
            return &quot;of course&quot;
        else:
            return &quot;Abs No&quot;

    def print_team(self):
        return f&quot;This team is {self.team}.&quot;

epl = EPL(&quot;TOT&quot;,&quot;Dier&quot;,&quot;Kane&quot;)
epl2 = EPL(&quot;TOT&quot;,&quot;Sanches&quot;,&quot;Son&quot;)
epl3 = EPL(&quot;PSG&quot;,&quot;Ramos&quot;,&quot;Messi&quot;)


print(epl.print_team())
print(epl2.print_team())
print(epl3.print_team())

This team is TOT.
This team is TOT.
This team is PSG.
</code></pre>
<hr>
<h2 id="class-상속">Class 상속</h2>
<pre><code class="language-python">
class Champions(EPL):
      def __init__(self,team,key_def,key_mid,key_att):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid
        self.key_att = key_att

chams = Champions(&quot;Bar&quot;,&quot;umtiti&quot;,&quot;Dejong&quot;,&quot;Depay&quot;)
chams2 = Champions(&quot;TOT&quot;,&quot;Dier&quot;,&quot;Kane&quot;,&quot;Son&quot;)

print(chams.is_EPL_player())
print(chams2.is_EPL_player())

Abs No
of course</code></pre>
<pre><code class="language-python">class Europa(EPL):
    def __init__(self,team,key_def,key_mid,key_att):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid
        self.key_att = key_att
</code></pre>
<p>새로운 Class를 생성하고 이를 상속 받기 위해서는 위와 같이 New_Class(Super_Class) 형식으로 사용해야한다.</p>
<hr>
<h2 id="super-class">Super Class</h2>
<pre><code class="language-python">class Champions(EPL):
    def __init__(self,team,key_def,key_mid,key_att):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid
        self.key_att = key_att

    def is_EPL_player(self):
        list = [&quot;Kane&quot;,&quot;Son&quot;,&quot;Antony&quot;,&quot;yoon&quot;]
        if self.key_mid in list:
            return &quot;of course&quot;
        else:
            return &quot;Abs No&quot;        

class Europa(EPL):
    def __init__(self,team,key_def,key_mid,key_att):
        self.team = team
        self.key_def = key_def
        self.key_mid = key_mid
        self.key_att = key_att

chams = Champions(&quot;TOT&quot;,&quot;Dier&quot;,&quot;eriksen&quot;,&quot;Son&quot;)
print(chams.is_EPL_player())

europa  = Europa(&quot;MU&quot;,&quot;Varane&quot;,&quot;eriksen&quot;,&quot;CR&quot;)
print(europa.is_EPL_player())


Abs No
of course
</code></pre>
</br>


<p><strong>같은 is_EPL_player()함수를 불러왔는데 왜 결과 값이 다를까?</strong></p>
<p><strong>chams.is_EPL_player()</strong>의 경우 Champions Class안에 포함되어 있는 def is_EPL_player 내의 리스트에서 비교했기 때문에 eriksen이 존재하지 않으므로 Abs NO가 출력되고</p>
<p><strong>europa.is_EPL_player()</strong>의 경우에는 Europa Class안에 def is_EPL_player 함수가 포함되어 있지 않기 때문에 처음에 선언하나 Super class(EPL)에 있는 is_EPL_player 함수 내의 리스트에서 비교했기 때문에 이때에는 eriksen이 존재한다 그렇기 때문에 of course가 출력된다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 코테 Review]]></title>
            <link>https://velog.io/@yoo_oon/TIL-%EC%BD%94%ED%85%8C-Review</link>
            <guid>https://velog.io/@yoo_oon/TIL-%EC%BD%94%ED%85%8C-Review</guid>
            <pubDate>Mon, 05 Sep 2022 06:28:02 GMT</pubDate>
            <description><![CDATA[<h1 id="좌석구매">좌석구매</h1>
<ul>
<li>문제설명</li>
</ul>
<blockquote>
</blockquote>
<p>공연을 관람하기 위한 100,000 x 100,000 크기의 격자 모양의 좌석이 있습니다
이 공연장의 표를 구매하기 위해 K명의 관람객이 매표소에 한 줄로 서 있습니다. 
이때, 관람객은 자신이 원하는 좌석에만 공연을 관람하려고 합니다. 
각 관람객은 매표소에서 자신이 원하는 좌석의 좌표를 말하고, 
아직 아무도 구매하지 않은 좌석이면 해당 좌석의 표를 삽니다.<br>그러나 만약 이미 구매된 좌석이면 공연 관람을 포기하고 집으로 돌아갑니다.
줄을 서 있는 사람들이 구매하려는 좌석의 좌표가 순서대로 담겨있는 
배열 seat가 매개변수로 주어질 때, 표를 구매하는데 성공한 사람의 수를 return 하도록 
solution 함수를 완성해 주세요. </p>
<ul>
<li>제한사항</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li><p>줄을 서 있는 관람객의 수는 1 이상 100,000 이하입니다.</p>
</li>
<li><p>seat에는 관람객이 구매하려는 좌석의 좌표가 가장 앞에 있는 사람부터 순서대로 들어있습니다.</p>
</li>
<li><p>seat의 각 원소는 관람객이 구매하려는 좌석의 좌표이며, [가로 좌표, 세로 좌표] 순입니다.</p>
</li>
<li><p>가로 좌표, 세로 좌표의 범위는 1 이상 100,000 이하의 정수입니다.</p>
</li>
<li><p>입출력 예</p>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center">seat</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[[1,1],[2,2],[3,3]]</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">[[1,1],[2,1],[1,2],[3,4],[2,1],[2,1]]</td>
<td align="center">4</td>
</tr>
</tbody></table>
<blockquote>
<ul>
<li>입출력 예 설명<ul>
<li>입출력 예 #1<ul>
<li>가장 앞사람부터 순서대로 (1,1), (2,2), (3,3) 위치의 좌석을 구매하여 총 3명의 관람객이 구매에 성공했습니다.</li>
</ul>
</li>
<li>입출력 예 #2<ul>
<li>가장 앞사람부터 순서대로 (1,1), (2,1), (1,2), (3,4) 위치의 좌석을 구매하였습니다.</li>
<li>5,6번째 관람객이 구매하려는 좌석은 2번째 관람객이 이미 구매하였으므로 5,6번째 관람객은 집으로 돌아갑니다.</li>
<li>따라서 총 4명의 관람객이 구매에 성공했습니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<hr>
<h1 id="책상의-재고">책상의 재고</h1>
<ul>
<li>문제설명</li>
</ul>
<blockquote>
</blockquote>
<p>OO 가구점에서는 책상이 하루에 1개씩 판매됩니다. 
현재 N개의 책상을 가지고 있고, M일에 한 번씩 도매점으로부터 책상이 1개씩 입고됩니다. 
책상의 재고가 0이 될 때까지 며칠이 걸리는지 return하는 solution 함수를 완성해 주세요. 
단, 재고가 0이 될 때, 도매점으로부터 입고되는 날이면 재고가 다시 1개 늘어납니다.</p>
<ul>
<li>제한사항</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li><p>N : 100 이하의 자연수</p>
</li>
<li><p>M : 2보다 크거나 같고 100보다 작거나 같은 자연수</p>
</li>
<li><p>입출력 예</p>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center">N</th>
<th align="center">M</th>
<th align="center">answer</th>
</tr>
</thead>
<tbody><tr>
<td align="center">2</td>
<td align="center">2</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">9</td>
<td align="center">3</td>
<td align="center">13</td>
</tr>
</tbody></table>
<ul>
<li>입출력 예 설명</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>입출력 예 #1<ul>
<li>현재 2개의 책상을 가지고 있으므로 2일째 되는 날 재고가 0이 됩니다. 재고가 0이 되는 날이 도매점으로부터 입고되는 날이므로 재고가 1개 늘어, 최종적으로 다음 날 3일째 재고가 0이 됩니다.<br>2 -&gt; 1(1일째) -&gt; 0+1(2일째, 입고되는 날) -&gt; 0(3일째) </li>
</ul>
</li>
</ul>
<blockquote>
<ul>
<li>입출력 예 #2<ul>
<li>다음과 같은 과정을 거쳐 13일째 재고가 0이 됩니다.<br>9 -&gt; 8(1일째) -&gt; 7(2일째) -&gt; 6+1(3일째, 입고되는 날) -&gt; 6(4일째) -&gt; 5(5일째) -&gt; 4+1(6일째, 입고되는 날) -&gt; 4(7일째) -&gt; 3(8일째) -&gt; 2+1(9일째, 입고되는 날) -&gt; 2(10일째) -&gt; 1(11일째) -&gt; 0+1(12일째, 입고되는 날) -&gt; 0(13일째)</li>
</ul>
</li>
</ul>
</blockquote>
<hr>
<h1 id="진법-표현하기">진법 표현하기</h1>
<ul>
<li>문제 설명</li>
</ul>
<blockquote>
</blockquote>
<p>철수는 N(2&lt;=N&lt;=26)진법 수를 표현하는데 필요한 N개의 수를 서로 다른 임의의 소문자 알파벳들로 바꿔 표현하려고 합니다. 그러기 위해 각 수를 어떤 알파벳으로 표현할 것인지에 대한 규칙을 표로 만들어 보았습니다. 예를 들어, 5진법 수를 아래와 같은 규칙으로 나타낸다고 하겠습니다.<br>위의 규칙을 적용하면 5진수 120은 otz가 되고, 5진수 33은 hh가 됩니다.<br>철수는 음이 아닌 두 개의 N진수 A,B(A&gt;=B)를 자신만의 규칙으로 적었고, A - B를 계산하고 싶습니다. 규칙 rule과 두 수 A,B를 바꿔 표현한 값이 주어질 때, 
철수의 규칙대로 나타낼 때의 A-B를 return하도록 solution 함수를 완성해주세요.<br>(rule[i]는 한 자릿수 i를 철수의 규칙으로 나타낸 값이며, 숫자는 0으로 시작하지 않습니다.)</p>
<ul>
<li>제한 사항</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li><p>제한사항</p>
<ul>
<li><code>rule</code>의 길이는 <code>2</code>이상 <code>26</code>이하입니다.</li>
<li><code>A</code>와 <code>B</code>의 길이는 <code>1</code>이상 <code>10</code>이하입니다.</li>
<li><code>rule</code>, <code>A</code>, <code>B</code>는 알파벳 소문자만 포함합니다.</li>
<li><code>A</code>와 <code>B</code>에 포함되는 각 알파벳은 <code>rule</code>에 딱 <code>한 번</code> 등장합니다.</li>
<li>알파벳으로 나타내기 전의 <code>A</code>는 <code>B</code>보다 크거나 같습니다</li>
</ul>
</li>
<li><p>입출력 예</p>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center">rule</th>
<th align="center">A</th>
<th align="center">B</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">zothf</td>
<td align="center">otz</td>
<td align="center">hh</td>
<td align="center">ht</td>
</tr>
<tr>
<td align="center">ab</td>
<td align="center">ba</td>
<td align="center">a</td>
<td align="center">ba</td>
</tr>
</tbody></table>
<hr>
<h1 id="택시-나눠타기">택시 나눠타기</h1>
<ul>
<li>문제 설명</li>
</ul>
<blockquote>
<p>철수의 생일을 맞아 XX 식당에서 생일 파티를 하기로 했습니다. 생일 파티를 하는 XX 식당까지는 택시를 타고 이동하기로 했습니다. 철수의 친구들은 친한 친구들끼리 그룹을 구성하고 있으며, 한 사람당 하나의 그룹에만 속해 있습니다. 택시를 탈 때는 반드시 같은 그룹에 속한 친구들은 같은 택시를 타기로 했으며, 한 택시에는 여러 그룹이 함께 탈 수 있습니다. 단, 택시에는 최대 4명까지 함께 탑승 가능합니다. 각 그룹의 구성원 수가 들어있는 배열 s가 매개변수로 주어질 때, 필요한 택시의 수의 최솟값을 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<ul>
<li>제한사항 </li>
</ul>
<blockquote>
<ul>
<li>s는 각 그룹별 구성원 수가 들어있는 배열이며, 배열의 길이(그룹의 수)는 100,000 이하의 자연수입니다.</li>
</ul>
</blockquote>
<ul>
<li>각 그룹의 구성원 수는 4 이하의 자연수입니다.</li>
</ul>
<ul>
<li>입출력 예</li>
</ul>
<table>
<thead>
<tr>
<th align="center">s</th>
<th align="center">output</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[1,2,4,3,3]</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center">[2,3,4,4,2,1,3,1]</td>
<td align="center">5</td>
</tr>
</tbody></table>
<ul>
<li>입출력 예 설명</li>
</ul>
<blockquote>
<ul>
<li>입출력 예 #1<ul>
<li>한 그룹당 하나씩의 택시를 이용한다면 총 5대의 택시가 필요합니다.그러나 다음과 같이 탑승한다면 4대의 택시만으로도 충분합니다.<ul>
<li>첫 번째 그룹(1명)과 네 번째 그룹(3명)이 같은 택시를 탑니다.</li>
<li>그 외 나머지 그룹은 모두 다른 택시를 탑니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>입출력 예 #2<ul>
<li>한 그룹당 하나씩의 택시를 이용한다면 총 8대의 택시가 필요하지만, 다음과 같이 탑승한다면 5대의 택시만으로도 충분합니다.<ul>
<li>첫 번째 그룹(2명)과 다섯 번째 그룹(2명)이 같은 택시를 탑니다.</li>
<li>두 번째 그룹(3명)과 여섯 번째 그룹(1명)이 같은 택시를 탑니다.</li>
<li>일곱 번째 그룹(3명)과 여덟 번째 그룹(1명)이 같은 택시를 탑니다.</li>
<li>그 외 나머지 그룹은 모두 다른 택시를 탑니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Docker] Docker 실습]]></title>
            <link>https://velog.io/@yoo_oon/Docker-Docker-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@yoo_oon/Docker-Docker-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Wed, 31 Aug 2022 08:59:03 GMT</pubDate>
            <description><![CDATA[<h1 id="docker-생성-및-배포-실습-featerror">Docker 생성 및 배포 실습 (feat.error)</h1>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/0e12b8ca-0f43-45d6-ade4-603c60b9d675/image.png" alt=""></p>
<pre><code class="language-python">From ubuntu 
# 이미지 생성

Run apt-get update &amp;&amp; apt-get install -y python3 python3-pip


WORKDIR /app

COPY . /app
# 해당 디렉터리에 위치한 모든 파일(main.py,requirements.txt)을 app에 복사

Run pip3 install -r requirements.txt
# API 설치

#Run python3 main.py
#-&gt; build x
# image는 서버를 실행할 준비를 하는 것이지 실행하는 것은 아니다.

CMD [&quot;python3&quot;, &quot;main.py&quot;]
# CMD에서 python으로 main.py를 실행

</code></pre>
<pre><code class="language-python">from fastapi import FastAPI

app = FastAPI()


@app.get(&quot;/&quot;)
def hello_world():
    return {&quot;message&quot;: &quot;Hello World&quot;}


if __name__ == &quot;__main__&quot;:
    import uvicorn
    uvicorn.run(app, host=&quot;0.0.0.0&quot;, port=8000)
    # 서버 접속 port를 지정
    # docker에서 접속하려면 포트포워딩을 통해서 포트 번호를 맞춰주어야한다.
</code></pre>
<pre><code class="language-python"># requirements.txt에는 api들이 들어가게 된다.
fastapi
uvicorn
</code></pre>
<pre><code>docker build -f Dockerfile .
# 해당 코드를 입력하게 되면 image id와 tag가 none인 상태로 할당된다.</code></pre><p><img src="https://velog.velcdn.com/images/yoo_oon/post/b61afa8e-ccf4-4624-b8b4-1f4c409cc59d/image.png" alt=""></p>
<hr>
<h3 id="image-id--tag-할당">IMAGE ID / TAG 할당</h3>
<pre><code class="language-python">image id 할당하기

docker build -t yoon/docker_tuto .
# tag를 할당하지 않을 경우에는 자동으로 latest로 할당된다.
docker build -t yoon/docker_tuto:tag1 -t yoon/docker_tuto:tag2 . 
# 2개의 IMAGE와 TAGING 가능      </code></pre>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/d07be3a1-7593-457e-952e-260d2251de74/image.png" alt=""></p>
<hr>
<h3 id="size-경량화">SIZE 경량화</h3>
<pre><code class="language-python">From python:3-alpine
#ubuntu는 무거운 tool이기에 위와 같은 방법으로 경량화 작업을 할 수 있다
#python3 설치할 필요가 없다.

WORKDIR /app

COPY . /app
# 해당 디렉터리에 위치한 모든 파일(main.py,requirements.txt)을 app에 복사

Run pip install -r requirements.txt
# API 설치

CMD [&quot;python&quot;, &quot;main.py&quot;]
# CMD에서 python으로 main.py를 실행
</code></pre>
<p>python:3-alpine 으로 size 경량화가 가능하다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/0d239cfc-a24e-4c3b-899f-abd8b64faae5/image.png" alt=""></p>
<p>같은 코드로 이루어진 IMAGE이지만 alpine 코드로 SIZE를 경량화 할 수 있는 것을 확인 할 수 있다.</p>
<hr>
<h3 id="docker-push">Docker push</h3>
<p>Github에서 local에서 file을 <strong>add-&gt;commit-&gt;push</strong> 하는 것 처럼
Docker도 이와 유사하게 local에서 image를 <strong>build-&gt;push</strong> 해야 docker hub&#39;s repo에 등록이 된다</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/0117900f-f9a5-4563-9fd0-eaa69edfc022/image.png" alt=""></p>
<pre><code>docker push yooon/lesson1-docker-tuto-alpine
#생성한 image를 push</code></pre><p><img src="https://velog.velcdn.com/images/yoo_oon/post/6c0e84b0-ab2c-4ce6-919f-9ef81110e5cf/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/f0b7f77e-c50f-4280-98fc-132783b5f24e/image.png" alt=""></p>
<p>위와 같이 dockerhub -&gt; repo에 등록 된 것을 확인 할 수 있다.</p>
<hr>
<h3 id="change-env">Change ENV</h3>
<p>flask를 이용한 프로젝트를 진행 했을 때, 수정된 코드가 잘 적용이 되었는지 확인하기 위해서 
포트를 종료하고 다시 실행시켰던 경험이 있었다.</p>
<p>docker에는 이러한 불편함을 해소 시켜줄 수 있는 ENV 기능이 크게 2가지로 존재한다.</p>
<ul>
<li>main.py에서 <strong>ENV PORT number</strong>를 지정해주는 방법</li>
<li>terminal에서 <strong>--env PORT = number -p number:number</strong> 간편하게 포트포워딩 해주는 방법</li>
</ul>
<pre><code>
import os

from fastapi import FastAPI

app = FastAPI()


@app.get(&quot;/&quot;)
def hello_world():
    return {&quot;message&quot;: &quot;Hello World&quot;}


if __name__ == &quot;__main__&quot;:
    import uvicorn
    #uvicorn.run(app, host=&quot;0.0.0.0&quot;, port=8000)
    uvicorn.run(app, host=&quot;0.0.0.0&quot;, port=int(os.environ[&quot;PORT&quot;]))
    # Env 설정을 통해 port 번호를 입력하지 않고 os에서 불러와서 동작하도록 한다.
</code></pre><pre><code>
From python:3-alpine
# ubuntu는 무거운 tool이기에 위와 같은 방법으로 경량화 작업을 할 수 있다
#python3 설치할 필요가 없다.

ENV PORT 8080

WORKDIR /app

COPY . /app
# 해당 디렉터리에 위치한 모든 파일(main.py,requirements.txt)을 app에 복사

Run pip install -r requirements.txt
# API 설치



CMD [&quot;python&quot;, &quot;main.py&quot;]
# CMD에서 python으로 main.py를 실행

</code></pre><pre><code> docker run -it --env PORT=7777 -p 7777:7777 yooon/lesson2-fastapi       
 #위와 같은 방식으로 코드를 수정하지않고 환경변수를 코드를 추가하여 바로바로 수정된 포트번호로 접속할 수 있다.</code></pre><hr>
<h3 id="docker-file-cicd">Docker file CI/CD</h3>
<p>*<em>lint &amp; unittest 중 error가 발생 할 때는 오류 코드를 확인하고 해결하자
*</em></p>
<h3 id="ci">CI</h3>
<h4 id="lint">LINT</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/23cdbf55-d7f4-4011-940c-088e04b19705/image.PNG" alt=""></p>
<ul>
<li>black, flake8 error가 발생 할 경우 </li>
<li><blockquote>
<p>black linter! : black main.py를 실행</p>
</blockquote>
</li>
<li><blockquote>
<p>flake8 linter!: 쓸 때 없는 주석 처리를 제거</p>
</br>
</blockquote>
</li>
</ul>
<h4 id="unittest">UNITTEST</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/d8fc30dc-00f0-4e70-9a1f-97acb4a8186c/image.png" alt=""></p>
<ul>
<li>test file을 check할 때 위의 환경변수 version으로 인한 error가 많이 발생했었다.
workflows 내의 error code를 잘 확인해서 해결하도록 한다.</li>
</ul>
<h3 id="cd">CD</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/f13ef633-06a8-473b-9485-2cfb5f7d9038/image.png" alt=""></p>
<pre><code>CD = Continuous Delivery or Deployment 
즉, 지속적인 제공 및 배포를 의미한다.
그래서 당연하게도 앞선 과정에서 작성한 files을 docker hub에 push를 해야하는데 
그게 바로 CD이다.</code></pre><p>docker hub에 우리의 files를 push하기 위해서는 당연하게도 docker site에 자동으로 로그인을 하는 과정이 필요하고 그 과정에서 DOCKER_USERNAME,DOCKER_PASSWORD가 필요하다.</p>
<p>하지만, 해당 정보는 코드로 공개할 수 없는 개인정보이기 때문에 Token을 암호화하여 사용하는 것과 같이 ID,Password도 암호화하여 사용해야한다.</p>
<p>이를 위해서는 Github -&gt; 해당 Repo -&gt; setting -&gt; secrets -&gt; Actions 에서 추가해주면 된다.
여기에서 주의할 점은 DOCKER_USERNAME은 email이 아닌 username으로 사용해야한다는 것이다.
당연하게도 접속할 때 사용하는 email이라고 생각했는데 오류가 발생했었다...ㅎ</p>
<p>추가적으로 앞선 CI/CD과정 중 cd.yml에는 우리가 docker push라는 명령어를 통해서 yooon/lesson1-docker-tuto-alpine을 추가한 것과 같이 docker image를 push하는 명령어가 포함 되어있다. cd.yml에 push 명령어가 추가되어 있기 때문에 terminal에서 push를 따로 하지 않아도 되는 편리함도 있다. </p>
</br>




<hr>
<h2 id="docker-hub">Docker hub</h2>
<pre><code>결국 우리가 하고자 하는 것은 우리가 코드를 작성할 때, 
해당 코드가 올바르게 작성된 코드인지 아닌지 테스트를 하고 docker hub repo에 지속적으로 통합하는 것</code></pre><p><img src="https://velog.velcdn.com/images/yoo_oon/post/f93e4e96-0747-468e-92bc-1d720d335181/image.png" alt=""></p>
<p>위의 이미지 중 yooon/lesson2-fastapi는 코드를 새롭게 수정하고 반영할 때 마다 자동으로 테스트 과정을 거친 뒤 docker hub repo에 저장된 것을 확인 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] github/workflows/*.yml push error]]></title>
            <link>https://velog.io/@yoo_oon/Git-githubworkflows.yml-push-error</link>
            <guid>https://velog.io/@yoo_oon/Git-githubworkflows.yml-push-error</guid>
            <pubDate>Mon, 29 Aug 2022 07:38:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/yoo_oon/post/8b34db96-7f54-4130-b1a6-154ced1f6f04/image.png" alt=""></p>
<p>CI 실습을 위해 .github/workflows/lint.yml 파일을 생성하고 add,commit후 push하는 과정에서 위와 같은 오류가 발생하였다.</p>
<p>구글링을 통해 알아보니 GitActions내의 workflows를 사용하기 위해서는 personal_token에서 workflow 권한을 주어야 하는데, 이전에 기간이 만료되고 새로운 token을 생성할때 workflow 권한 설정을 해주지 않았기 때문에 발생하는 오류였다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/1ac8dd89-d2de-46e2-af93-db72e93b909b/image.png" alt="">
그래서 위와 같이 새로운 token을 생성하고 workflow 권한도 추가 해주었다.
그 다음, mac 기준으로 키체인 접근 -&gt; github로 들어가서 부여받은 새로운 token 값을 다시 입력 해주어야 제대로 git push가 이루어진다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/0ebaf1bd-fadd-4a3f-94d7-16726b109814/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CI] Continuous Integration]]></title>
            <link>https://velog.io/@yoo_oon/CI-Continuous-Integration</link>
            <guid>https://velog.io/@yoo_oon/CI-Continuous-Integration</guid>
            <pubDate>Mon, 29 Aug 2022 07:25:45 GMT</pubDate>
            <description><![CDATA[<p>최근 듣고 있는 연사님의 강의를 통해 CI에 대해서 알아 볼 수 있는 시간을 가졌다.</p>
<p>신입 개발자에게 코딩,엔지니어링 요소도 물론 중요하지만, 해당 요소를 많이 기대하지는 않고 기본기를 많이 중요시 한다고 하시면서 CI의 중요성에 대해서 말씀해주시며 CI를 사용하는 습관을 가지면 좋겠다고 조언해주셨다.</p>
</br>

<hr>
<h1 id="ci">CI</h1>
<p>CI란
<strong>Continuous Integration</strong>로 지속적인 통합으로 소스/버전에 대한 코드 변경사항을 주기적으로 commit &amp; push하여 자동으로 테스트 과정을 거치고 동작이 이루어지는지 error사항은 없는지 확인 하는 것을 의미한다.
(현업에서는 시니어 개발자가 CI를 통해 error 사항이 발생했을 때 merge 되는 것을 방지하기 위해 사용한다.)</p>
<p>간단하게 빌드,테스트,배포의 자동화 과정이라고 할 수 있다.</p>
</br>

<hr>
<h2 id="git-actions">Git actions</h2>
<p>Github Actions를 사용하여 repo에서 바로 소프트웨어 개발 워크플로를 자동화, 사용자 지정 및 실행하며, CI/CD를 포함하여 원하는 작업을 수행하기 위한 작업을 검색, 생성 및 공유하고 완전히 사용자 정의된 워크플로에서 작업을 결합할 수 있다.</p>
<p><a href="https://docs.github.com/en/actions">https://docs.github.com/en/actions</a></p>
<h3 id="lint">Lint</h3>
<pre><code>Lint: 코드의 문법 및 코드 스타일의 오류를 미리 점검하기 위해서 사용하는 툴
(ex. python: black,flake8... etc..)</code></pre></br>

<h4 id="lint-예시-코드">Lint 예시 코드</h4>
<pre><code class="language-python">
name: Lint Code Base

on: push

jobs:
  # Set the job key. The key is displayed as the job name
  # when a job name is not provided
  super-lint:
    # Name the Job
    name: Lint Code Base
    # Set the type of machine to run on
    runs-on: ubuntu-latest

    env:
      #OS: ${{ matrix.os }}
      PYTHON: &#39;3.7&#39;

    steps:
      # Checks out a copy of your repository on the ubuntu-latest machine
      - name: Checkout code
        uses: actions/checkout@v2

      # Runs the Super-Linter action
      - name: Lint Code Base
        uses: github/super-linter@v4
        env:
          DEFAULT_BRANCH: master
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VALIDATE_PYTHON_BLACK: true
          VALIDATE_PYTHON_FLAKE8: true</code></pre>
<pre><code>경로: .github/workflows/lintcode.yml</code></pre><p>위의 예시 코드는 yml형식으로 되어 있고 같은 폴더에 위치한 *.py file를 자동으로 확인해준다.</p>
<ul>
<li>jobs: job은 여러 steps으로 나뉜다.<ul>
<li>runs-on: ubuntu 환경에서 실행.</li>
</ul>
</li>
<li>env: 어떤 python version에서 실행하는지 여부.</li>
<li>steps: Task의 집합으로 action을 실행한다.
  linter(python_black,python_flake8)과 같은 작업을 실행.</li>
</ul>
</br>

<h4 id="git-actions에서-lintcode-정상-작동-예시">Git actions에서 Lintcode 정상 작동 예시</h4>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/b94044a4-4f9c-4bf0-b743-9e46615ef54a/image.png" alt=""></p>
</br>

<hr>
<h3 id="code-coverage">Code Coverage</h3>
<h4 id="coverage">Coverage</h4>
<pre><code>coverage: 작성한 코드가 테스트에 얼마만큼 충족되었는지 알려주는 툴</code></pre><pre><code>name: Coverage Report

# Run this workflow every time a new commit pushed to your repository
on: push

jobs:
  coverage-report:
    name: Coverage Report
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Python 3.7
        uses: actions/setup-python@v2
        with:
          # Semantic version range syntax or exact version of a Python version
          python-version: &#39;3.7&#39; 
          # Optional - x64 or x86 architecture, defaults to x64
          architecture: &#39;x64&#39;

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

      - name: Run unit test
        run: |
          coverage run --source=./ -m unittest discover -p &quot;*_test.py&quot;

      - name: Publish code coverage
        uses: paambaati/codeclimate-action@v3.0.0
        with:
          coverageCommand: coverage xml
          coverageLocations: ${{github.workspace}}/coverage.xml:coverage.py
        env:
          CC_TEST_REPORTER_ID: 24437f0fe93e1caa579319885785a0172b2343e17af1dfce3a8aaecc2606a51c
          # codeclimate -&gt; repo setting -testcoverage id
</code></pre><pre><code>경로: .github/workflows/coverage.yml
    +) requirements.txt</code></pre></br>


<h3 id="coveragexml에서-유심히-볼-내용">coverage.xml에서 유심히 볼 내용</h3>
<pre><code>- name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

  - name: Run unit test
    run: |
      coverage run --source=./ -m unittest discover -p &quot;*_test.py&quot;

    env:
      CC_TEST_REPORTER_ID: token_ID</code></pre><h4 id="requirementstxt">requirements.txt</h4>
<pre><code>black==19.10b0
coverage==4.3
codeclimate-test-reporter==0.2.3</code></pre><p>해당 txt에는 lint,coverage,codeclimate등의 패키지 목록이 담겨있다.</p>
<h4 id="unittest를-사용하는경우">unittest를 사용하는경우</h4>
<pre><code>coverage run --source=./ -m unittest discover -p &quot;*_test.py&quot;
    -&gt; terminal에 위의 명령어를 통해 실행 할 수 있다.    

coverage xml
    -&gt; terminal에 위의 명령어를 통해 internet과 연결하는 xml file을 생성 할 수 있다.</code></pre><h4 id="env">env</h4>
<pre><code>env:
    CC_TEST_REPORTER_ID: token_ID</code></pre></br>    

<pre><code>token_ID 경로 : codeclimate -&gt; repo setting -testcoverage ID copy</code></pre><p>CC_TEST_REPORTER_ID의 경우, codeclimate에서 제공하는 id 값을 사용하여야 coverage의 진행률을 확인 할 수 있다.
<a href="https://docs.codeclimate.com/docs/configuring-test-coverage">https://docs.codeclimate.com/docs/configuring-test-coverage</a> (참고 url)</p>
</br>

<hr>
<h2 id="codeclimate">CodeClimate</h2>
<p>앞선 내용에서 Git actions &amp; lint,coverage code를 사용하여 CI를 자동화하는 과정을 살펴보았다.</p>
<p>앞선 과정에 대한 코드의 품질에 대한 평가 및 이를 한 눈에 보기 쉽게 시각화 해주는 사이트를 CodeClimate라고 할 수 있다.</p>
<p>또한, CodeClimate는 Git 계정과 연동이 가능하기 때문에 자신의 repo에 대한 품질 평가를 진행 할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/fa4e1e90-25d2-4b31-82a5-e5cb3ddd2365/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/a49ee3d4-a83b-4ff5-9d60-0e44bcee39e6/image.png" alt="">codeclimate 사이트에서 py file별, 종합적으로 품질 평가 결과를 확인 할 수 있다.
</br></p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/31cc7ae1-1b60-422a-812f-6ab2313c7bb3/image.png" alt="">
Github repo에서도 markdown 설정을 통해 다음과 같이 확인 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DVC] Data Version Control]]></title>
            <link>https://velog.io/@yoo_oon/DVC-Data-Version-Control</link>
            <guid>https://velog.io/@yoo_oon/DVC-Data-Version-Control</guid>
            <pubDate>Thu, 25 Aug 2022 08:51:35 GMT</pubDate>
            <description><![CDATA[<h1 id="dvc">DVC</h1>
<p>DVC는 Data Version Control로 문자 그대로 데이터의 버전 관리를 도와주는 툴이라고 할 수 있다.</p>
<p>DVC는 MLproject들의 소스 코드 or 버전 관리를 위해 사용되며 사용방식이 Git과 매우 유사했다.
다만, Git은 대용량 데이터를 업로드하여 보관할 수 없지만 DVC는 가능했다.</p>
</br>

<h2 id="설치-및-실습">설치 및 실습</h2>
<h3 id="설치-후-tracking-data-생성">설치 후 tracking data 생성</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/00f375c7-d04e-492d-8906-5e8b4a1051dc/image.png" alt=""></p>
<pre><code class="language-python">pip install dvc
wget https://github.com/iterative/dvc/releases/download/2.10.2/dvc_2.10.2_amd64.deb
# pip를 이용한 설치를 진행했을 떄 오류가 발생했을 경우
# wget을 사용하여 링크주소를 복사하여 직접 다운받아서 설치하면 정상 작동한다.

- 설치 완료 후 git init / dvc init 으로 저장소를 초기화해준다.
- 그 다음으로 dvc로 버전을 tracking할 txtf file을 생성해준다.
# demo.txt에는 Good afternoon yoon!</code></pre>
</br>

<h3 id="data-addcommitpush">Data add,commit,push</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/256e3631-2932-40bf-b83d-02483dfd3e07/image.png" alt=""></p>
<pre><code class="language-python">demo.txt /demo.txt.dvc 파일을 확인하고
git commit &amp; push를 진행한다.
# push를 하기 전에 자신의 구글드라이브 계정과 연동해야한다.
# 구글 드라이브에 폴더를 생성하여 들어가서 해당 폴더의 주소를 입력해주면 된다.</code></pre>
</br>

<h3 id="check-uploaded-data--pull">Check uploaded data &amp; pull</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/935e3003-4066-437c-897b-68219584559f/image.png" alt=""></p>
<pre><code class="language-python">dvc push했던 캐시 &amp; 데이터를 삭제한 뒤,
dvc pull로 구글 드라이브에 업로드 한 데이터를 불러온 뒤
이전의 데이터와 불어온 데이터가 맞는지 확인해본다.
Good afternoon yoon!로 동일한 데이터가 불러와졌다.</code></pre>
</br>

<h3 id="dvc-version-update--load">Dvc version update &amp; load</h3>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/cafe8fbc-0bcf-4e84-aa20-e51144f210ee/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/30e8ff70-01e3-464e-85f4-432f180d75c7/image.png" alt=""></p>
<pre><code class="language-python">기존의 Good afternoon yoon!의 내용인 demo.txt를
Good afternoon yoon!
-&gt; Hello bro!

위의 내용으로 변경 후 add,commit push를 하므로써 Update를 진행한다.

git log --online
#log를 확인하고
git checkout 5504f5f data/demo.txt.dvc
#이전 버전으로 되돌린다.
dvc checkout
#demo.txt.dvc 파일을 확인하고 demo.txt 파일을 이전 버전으로 되돌린다.
cat demo.txt

---

Good afternoon yoon!
 -&gt; Hello bro! 

Good afternoon yoon!
#위의 업데이트 버전에서 아래의 이전 버전으로 되돌아 간 것을 확인했다면 DVC의 간단한 update &amp; load를 과정을 살펴볼 수 있다.

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Flask] Flask/Rest/Fast API]]></title>
            <link>https://velog.io/@yoo_oon/Flask-FlaskRestFast-API</link>
            <guid>https://velog.io/@yoo_oon/Flask-FlaskRestFast-API</guid>
            <pubDate>Thu, 25 Aug 2022 08:00:27 GMT</pubDate>
            <description><![CDATA[<h1 id="flask--rest--fastapi">Flask / Rest / FastAPI</h1>
<h1 id="rest-api">REST API?</h1>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/8e58c196-aba5-48ba-be27-2d3e859ef080/image.png" alt=""></p>
<p><a href="https://velog.io/@0andwild/RESTful-API%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">https://velog.io/@0andwild/RESTful-API란-무엇인가</a></p>
<ul>
<li>자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것<ul>
<li>URL을 통해 Resource를 명시</li>
<li>HTTP Method(POST,GET,PUT,DELETE)를 통해 opreation 수행</li>
</ul>
</li>
</ul>
<ol>
<li>슬<strong>래시 구분자(/)는 계층관계를 나타내는데 사용한다.</strong></li>
<li><strong>URL 마지막 문자로 슬래시(/)를 포함하지 않는다</strong></li>
<li><strong>하이픈 ( - )은 URL 가독성을 높이는데 사용한다.</strong><ol>
<li><strong>밑줄 ( _ )은 URL에 사용하지 않는다.</strong></li>
</ol>
</li>
<li><strong>URL 경로에는 소문자가 적합하다.</strong></li>
</ol>
<ul>
<li><strong>URL</strong> 경로에 대문자 사용은 피하도록 한다.</li>
</ul>
<ol>
<li><strong>파일확장자는 URL에 포함하지 않는다.</strong><ol>
<li>REST API 에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 <strong>URL</strong>안에 포함시키지 않는다.</li>
<li>대신 Accept Header 를 사용한다.</li>
<li>ex) GET: <a href="http://restapi.exam.com/orders/2/Accept">http://restapi.exam.com/orders/2/Accept</a>: image/<strong>jpg</strong></li>
</ol>
</li>
</ol>
<hr>
<h1 id="flask">Flask</h1>
<h2 id="operation-flow-of-flask">Operation Flow of Flask</h2>
<h3 id="flask-setting">Flask setting</h3>
<pre><code class="language-python">from flask import Flask
from flask import render_template
from flask import request

app = Flask(__name__) # 모듈 이름 생성</code></pre>
<pre><code class="language-python">@app.route(&#39;/SpecialSale&#39;)
# 127.0.0.1:5000의 다음 단인
# **127.0.0.1:5000/SpecialSale** 주소에 할당된 경로로 이동하여 해당 경로의 내용을 출력

# if @app.route(&#39;/&#39;)라면 http://localhost:5000/를 가리킨다.

def PredictionSpecialSale():
    busy_day = request.args.get(&#39;busy_day&#39;)
    high_temperature = request.args.get(&#39;high_temperature&#39;)
# html의 KEY &amp; VALUE에 해당하는 값을 get을 통해 받아온다.

    if busy_day == None or high_temperature == None:
        return render_templates(&#39;SpecialSale.html&#39;, Output = &#39;&#39;)

    Input = pd.DataFrame({
        &#39;busy_day&#39;:[int(busy_day)],
        &#39;high_temperature&#39;:[float(high_temperature)]
    })
    ModelOutput = model.predict(Input)[0][0]

    return render_templates(&#39;SpecialSale.html&#39;, Output = ModelOutput)
# if문이 아니라면 templates에 있는 html을 불러와서 output을 출력해준다.</code></pre>
<pre><code class="language-python">app.run(host=&#39;0.0.0.0&#39;, port=5000)</code></pre>
<h3 id="html-setting">Html setting</h3>
<pre><code class="language-python">&lt;form action=&quot;SpecialSale&quot;&gt;

    &lt;div class=&quot;form-group&quot;&gt;
      &lt;label for=&quot;busy_day&quot;&gt;busy_day&lt;/label&gt;
      &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;busy_day&quot; name=&quot;busy_day&quot;&gt;
# name에 해당하는 busy_day가 KEY값이 되고 입력받는 값이 VALUE가 됀다

&lt;/div&gt;

    &lt;div class=&quot;form-group&quot;&gt;
      &lt;label for=&quot;high_temperature&quot;&gt;Temperature:&lt;/label&gt;
      &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;pwd&quot; name=&quot;high_temperature&quot;&gt;
# name에 해당하는 busy_day가 KEY값이 되고 입력받는 값이 VALUE가 됀다
    &lt;/div&gt;
&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Submit&lt;/button&gt;
  &lt;/form&gt;

  &lt;button type=&quot;button&quot; class=&quot;btn btn-success&quot;&gt;{{ Output }}&lt;/button&gt;
# button form에 output을 올려서 render_templates값을 받아온다.
&lt;/div&gt;</code></pre>
<h1 id="fastapi">FastAPI</h1>
<ul>
<li>표준 파이썬 타입을 바탕으로 한 현대적이고 빠른(고성능) API 서버 웹 프레임워크</li>
</ul>
<pre><code class="language-python">pip install fastapi
pip install &quot;uvicorn[standard]&quot; # 실시간 미리보기
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Python Advanced_basic ]]></title>
            <link>https://velog.io/@yoo_oon/Python-Python-Advancedbasic-TIL</link>
            <guid>https://velog.io/@yoo_oon/Python-Python-Advancedbasic-TIL</guid>
            <pubDate>Wed, 24 Aug 2022 13:34:59 GMT</pubDate>
            <description><![CDATA[<h3 id="네이밍-컨벤션">네이밍 컨벤션</h3>
<p>여러종류의 네이밍 컨벤션이 있지만 python에서는 스네이크, java에서는 카멜 케이스를 사용한다.</p>
<p>#스네이크 케이스 : 각 단어를 _ 로 구분하는 것을 의미</p>
<pre><code class="language-python">snake_case = naming</code></pre>
<p>#카멜 케이스 : 첫 단어의 시작은 소문자로 하고 중간 문자를 대문자로 하는 것을 의미</p>
<pre><code class="language-java">camelCase = naming</code></pre>
<hr>
<p>range는 대표적인 
list(range(5))
-&gt; 0, 1, 2, 3, 4</p>
<h3 id="enumerate">enumerate</h3>
<p>순서가 있는 자료형을 인덱스를 포함한 enumerate 객체로
리턴할 때 사용
</br></p>
<p>0 a1 , 1 b2 , 2 c3와 같이 <strong>인덱스와 값을 동시에 출력</strong>하는 방법</p>
<pre><code class="language-python"> a = [&#39;a1&#39;, &#39;b2&#39;, &#39;c3’]

 # CASE 1: index 루프
 for i in range(len(a)):
 print(i, a[i])

 # CASE 2: index와 값을 따로 늘리면서 조회
 i = 0
 for v in a:
 print(i, v)
 i += 1</code></pre>
<p>위의 2가지 case도 가능한 방법이지만 enumerate()를 활용하면 간단하게 출력이 가능하다.</p>
<pre><code class="language-python"> #CASE 3: enumerate()를 활용한다
 for i, v in enumerate(a):
 print(i, v)
</code></pre>
<hr>
<h3 id="print">Print</h3>
<h4 id="sep">sep</h4>
<pre><code class="language-python">sep을 사용하여 print문에서 ,와 함께 출력 가능
print(1,2,sep=&#39;,&#39;)
# 1,2</code></pre>
<h4 id="end">end</h4>
<pre><code class="language-python">end 파라미터에 공백을 추가하여 줄바꿈을 하지 않도록 설정
print(11,end=&#39;&#39;)
print(22)
# 11 22</code></pre>
<h4 id="join">join</h4>
<pre><code class="language-python">join을 사용하여 리스트 안의 값을 한번에 출력 가능
 a = [&#39;A&#39;, &#39;B&#39;]
 print(&#39; &#39;.join(a))
 # AB</code></pre>
<h4 id="f-string">f-string</h4>
<pre><code class="language-python">num = 13
booked = room

print(f&#39;{num+1} : {booked}&#39;)
#14:room</code></pre>
<h4 id="pass">pass</h4>
<pre><code> class MyClass(object):
 def method_a(self):
 # 여기에 pass를 넣으면 오류가 발생했을때 통과한다.
 pass
 def method_b(self):
 print(&quot;Method B&quot;)
 c = MyClass()
</code></pre><hr>
<h3 id="자료형">자료형</h3>
<h4 id="pythons-datatype">Python&#39;s DataType</h4>
<pre><code class="language-shell"> Text Type : str
 Numeric Types : int, float, complex
 Sequence Types : list, tuple, range
 Mapping Type : dict
 # hash개념이므로 자료를 불러오기에 용이(속도 빠름)
 Set Types : set, frozenset
 Boolean Type : bool
 Binary Types : bytes, bytearray, memoryview</code></pre>
<hr>
<h2 id="module">Module</h2>
<pre><code>Module은 함수나 변수 또는 클래스를 모아 놓은 파일로 
다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만든 것을 의미
</code></pre><p>Module&#39;s example</p>
<pre><code class="language-python"># module_ex.py
 def add(a, b):
 return a + b
 def sub(a, b): 
 return a - b

from module_ex import add,sub</code></pre>
<h2 id="packing-unpacking">Packing, Unpacking</h2>
<ul>
<li>패킹: 변수를 컬렉션으로 묶어서 대입</li>
<li>언패킹: 컬렉션에 있는 인자들을 여러 개의 변수에 나누어 대입</li>
</ul>
<pre><code class="language-python">numbers = (1, 2, 3, 4, 5,6)  # 패킹
a, b, c, d, e ,f= numbers  # 언패킹</code></pre>
<pre><code class="language-python">a, _, _, d, e,f = numbers 
print(a, b,_,_, _, d, e )
-&gt; 1 2 3 3 3 4 5
# _ 의 변수를로 언패킹 할 때는 앞에서 사용한 변수들을 제외하고 다음에 올 변수들을 사용한다.</code></pre>
<pre><code class="language-python">a, b, *c = nums  
print(a, b, c)
-&gt; 1 2 [3, 4, 5, 6]
# 언패킹시 좌측에 * 을 붙일 시에 a,b에 할당되지 않은 남은 변수들을 대입 받을 수 있다.</code></pre>
<h2 id="lint--set-later">lint ( set later...)</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MLOps] MLOps]]></title>
            <link>https://velog.io/@yoo_oon/MLOps-MLOps-TIL</link>
            <guid>https://velog.io/@yoo_oon/MLOps-MLOps-TIL</guid>
            <pubDate>Tue, 23 Aug 2022 08:48:42 GMT</pubDate>
            <description><![CDATA[<h1 id="mlops">MLOps</h1>
<p><strong>ML 시스템 개발(Dev)과 운영(Ops)을 통합하는 것을 목표로 하는 ML 엔지니어링 문화 및 방식</strong></p>
<p>서비스화 -&gt; 성능 저하 여부 / 시스템 문제 발생 여부/데이터 분포 변화 모니터링 / 데이터 백업 etc
-&gt; 단방향 흐름의 문제</p>
<p>이를 해결하기 위해 MLOps 탄생
ML + DevOPs = MLOps</p>
<ul>
<li>버전관리<ul>
<li>데이터 버전</li>
<li>모델 버전</li>
</ul>
</li>
<li>테스트 자동화<ul>
<li>모델 학습 자동화</li>
<li>모델 성능 평가 자동화</li>
</ul>
</li>
<li>모니터링<ul>
<li>서빙 모델 모니터링</li>
<li>데이터 변화 모니터링</li>
<li>시스템 안정성 모니터링</li>
</ul>
</li>
<li><em>AI service = ML + data (model &lt; data가 중요)*</em></li>
</ul>
<p>데이터 수집 파이프 라인 - sqoop,flume,kafka,flink,spark streaming,ariflow ...</p>
<p>데이터 저장 - Mysql, Hadoop ...</p>
<p>데이터 관리 - TFDV,DVC ...</p>
<p>모델 개발- jupyter hub,docker,kubeflow,optuna ...</p>
<p>모델 버전 관리- Git , MLflow,jenkins ...</p>
<p>모델 학습 &amp; 스케줄링 관리 - Grafana,Kubernetes ...</p>
<p>모델 패키징 - docker,flask,fastAPI,kubeflow ...</p>
<p>서빙 모니티링 - prometheus,grafama ...</p>
<p>파이프라인 매니징 - kubeflow,argo,workflows,airflow</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Docker] Docker ]]></title>
            <link>https://velog.io/@yoo_oon/Docker-Docker-TIL</link>
            <guid>https://velog.io/@yoo_oon/Docker-Docker-TIL</guid>
            <pubDate>Tue, 23 Aug 2022 08:47:25 GMT</pubDate>
            <description><![CDATA[<h1 id="docker">Docker</h1>
<pre><code>Build once , Run Anywhere
  -&gt; 애플리케이션을 개발, 제공 및 실행하기 위한 개방형 플랫폼.
    -&gt; 어떤 환경에서도 ML model을 실행 할 수 있도록 하는 것을 의미한다.
    -&gt; java가 모든 환경에 적용 가능하게 된 것 처럼.</code></pre></br>

<hr>
<h2 id="container">Container</h2>
<pre><code>애플리케이션을 패키징 및 실행 할 수 있는 기능을 제공하며, 격리 및 보안을 통해 하나의 호스트에서 여러 컨테이너를 동시에 실행 가능하다.
- 애플리케이션을 배포하고 테스트하는 단위</code></pre><hr>
<h1 id="docker-overview">Docker Overview</h1>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/c0f6c6d9-fd28-4e60-96f7-30308188b55c/image.png" alt=""></p>
<ul>
<li><p>Client : Dokcer에 명령어를 전송하는 사용자.</p>
</li>
<li><p>Image: containers에 실행에 필요한 정보가 담겨있는 파일.</p>
<ul>
<li>containers의 정보를 snapshot으로 저장 </li>
</ul>
</li>
<li><p>Container : Image를 불러와서 메모리를 할당하여 os가 활성화된 상태</p>
<ul>
<li>서버 실행 = container가 image를 불러와서 실행된 상태</li>
</ul>
</li>
<li><p>Registry : docker_hub와 같이 docker image를 등록해두는 곳 (ex. AWS,GCR)</p>
</li>
</ul>
<hr>
<h2 id="docker-명령어--1-">Docker 명령어 ( 1 )</h2>
<pre><code class="language-shell">docker pull : docker image repository 부터 Docker image 를 pull

docker images : 로컬에 존재하는 docker image 리스트를 출력

docker ps : 현재 실행중인 도커 컨테이너 리스트를 출력

docker run : 도커 컨테이너를 실행
ex) docker run -it --name demo1 ubuntu:18.04 /bin/bash
    - it: container 를 실행시키고 terminal로 접속
    -  --name: 컨테이너 id (9802839)를 구분하기 쉽도록 yoon1 과 같이 이름을 지정
    - /bin/bash : 컨테이너를 실행시킴과 동시에 실행할 커맨드 bash 터미널을 사용하는 것을 의미

docker exec : Docker 컨테이너 내부에서 명령을 내리거나, 내부로 접속

docker logs : 도커 컨테이너의 log 를 확인

docker stop : 실행 중인 도커 컨테이너를 중단

docker rm : 도커 컨테이너를 삭제

docker rmi : 도커 이미지를 삭제</code></pre>
<hr>
<h2 id="docker-명령어--2-">Docker 명령어 ( 2 )</h2>
<pre><code class="language-shell">
FROM : base image로 어떠한 image를 사용할 것인지 명시
-FROM ubuntu:18.04

COPY : &lt;src&gt;의 file or directory를 &lt;dest&gt;경로에 복사
- COPY dir1/dir2

RUN : 명시한 커맨드를 docker container에 실행
 -RUN [&quot;executable-command&quot;, &quot;parameter1&quot;, &quot;parameter2&quot;]
 -RUN pip install -r requirements.txt 

CMD : docker container가 시작될 때 실행 ( = ENTRYPOINT
- CMD python helloworld.py

WORKDIR : container 내의 어떤 디렉토리에서 수행할 것인지 명시
- WORKDIR /path/to/workdir

ENV : container 내부에서 지속적으로 사용될 env variable 값을 설정
- ENV LANGUAGE ko_KR.UTF-8

EXPOSE : container에서 port/protocol을 지정
- EXPOSE &lt;port&gt;/&lt;protocol&gt;
</code></pre>
<h2 id="docker-build">Docker build</h2>
<pre><code class="language-shell">docker build -t example:v1.0.0 .
#1.0.0 . : dot을 꼭 써주어야함
#example (name) , v.1.0.0 (tag)

docker run my-image:v1.0.0 
#실행</code></pre>
<h2 id="docker-registry">Docker Registry</h2>
<pre><code class="language-shell">docker run -d -p 5000:5000 --name registry registry
docker tag yoon:v1.0.0 localhost:5000/yoon:v1.0.0</code></pre>
<p><img src="https://velog.velcdn.com/images/yoo_oon/post/8a9d7199-d7c0-4241-afda-906fe019dbeb/image.png" alt=""></p>
<ul>
<li>yoon을 새로 생성한 registry를 바라보도록 tag
docker push localhost:5000/yoon:v1.0.0</li>
<li>yoon을 registry에 push
curl -X GET <a href="http://localhost:5000/v2/_catalog">http://localhost:5000/v2/_catalog</a></li>
<li>localhost:5000&#39;s registry에 어떤 이미지가 저장되어 있는지 리스트 출력
curl -X GET <a href="http://localhost:5000/v2/my-image/tags/list">http://localhost:5000/v2/my-image/tags/list</a></li>
<li>yoon에 어떤 tage가 저장되어 있는지 list 출력</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kubernetes] Kubernetes ]]></title>
            <link>https://velog.io/@yoo_oon/Kubernetes-Kubernetes-TIL</link>
            <guid>https://velog.io/@yoo_oon/Kubernetes-Kubernetes-TIL</guid>
            <pubDate>Tue, 23 Aug 2022 08:42:36 GMT</pubDate>
            <description><![CDATA[<h1 id="kubernetes">Kubernetes</h1>
<pre><code>컨테이너화된 workroad와 service를 관리하기 위한 이식성이 있고, 확장 가능한 오픈소스 플랫폼

-개발환경에서는 app을 실행하는 container를 관리하고 가동 중지 시간이 없는지 확인이 필요하다.
-이때 kubernetes는 app의 확장과 장애 조치를 처리하고 배포 패턴등을 제공하며 이를 쉽게 관리 할 수 있다.</code></pre><p><a href="https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/">https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/</a>
</br></p>
<hr>
<h2 id="yaml">YAML</h2>
<ul>
<li>데이터 직렬화에 쓰이는 포맷/양식 중 하나<ul>
<li>데이터 직렬화란?<ul>
<li>서비스간에 Data 를 전송할 때 쓰이는 포맷으로 변환하는 작업<ul>
<li>ex) 쿠버네티스 마스터에게 요청을 보낼 때 사용</li>
</ul>
</li>
</ul>
</li>
<li>다른 데이터 직렬화 포맷<ul>
<li>XML, JSON</li>
</ul>
</li>
</ul>
</li>
<li>파일 포맷<ul>
<li><code>.yaml</code>, <code>.yml</code></br>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="grammer">Grammer</h2>
<h3 id="key-value">Key-Value</h3>
<p>기본적으로 Key-Value 구조</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: yoon
      image: yoon:1.25</code></pre>
</br>

<h3 id="자료형">자료형</h3>
<pre><code class="language-yaml">STRING

# 일반적인 문자열은 그냥 작성해도 되고, 따옴표로 감싸도 가능
example: this is string
example: &quot;this is string&quot;
---------

# 반드시 따옴표로 감싸주어야 하는 경우 :
# 숫자를 문자열 타입으로 지정하고 싶은 경우
example: 123
example: &quot;123&quot;
---------

# y, yes, true 등의 YAML 예약어와 겹치는 경우
example: &quot;y&quot;
---------

# :, {, }, ,, #, *, =, \n 등의 특수 문자를 포함한 경우
example: &quot;a : b&quot;
example: &quot;a#bc*&quot;
---------

INTEGER
# integer type
example: 123

# hexadecimal type: 0x 로 시작
example: 0x1fff



</code></pre>
<h3 id="list">List</h3>
<pre><code class="language-yaml"># - 를 사용하여 list 를 명시할 수 있다
examples:
  - ex_one: 1
  - ex_two: 2
---------

# [ ] 로 입력 가능
examples: [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]
---------

# list 의 원소는 어떤 자료형이든 가능합니다.
spec:
  containers:
    - name: yoon
      image: yoon:1.25
    - name: ubuntu
      image: ubuntu
      commands:
        - sleep
        - 3600
    - name: python
      image: python:3.8</code></pre>
<h3 id="multi-line-strings">Multi Line strings</h3>
<pre><code class="language-yaml">|

example: |
  Hello
  yoon
# &quot;Hello\nyoon\n \n&quot; 으로 줄바꿈이 가능

---------

&gt;

example: &gt;
  Hello
  yoon
# &quot;Hello yoon \n&quot; 으로도 줄바꿈이 가능
</code></pre>
<h3 id="multi-document-yaml">Multi document yaml</h3>
<p>---를 통해 하나의 yaml에 여러개의 doc를 작성 할 수 있다.</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
  name: one
---
apiVersion: v1
kind: Service
metadata:
  name: two
---
apiVersion: v1
kind: Deployment
metadata:
  name: three
</code></pre>
</br>

<hr>
<h2 id="pod">POD</h2>
<pre><code>쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위
    -쿠버네티스는 Pod 단위로 스케줄링, 로드밸런싱, 스케일링 등의 관리 작업을 수행
        -하나의 Pod 은 한 개의 Container 혹은 여러 개의 Container로 구성 가능</code></pre></br>

<h4 id="pod-예시">POD 예시</h4>
<pre><code class="language-yaml">
apiVersion: v1 # kubernetes resource 의 API Version을 의미
kind: Pod # kubernetes resource name
metadata: # 메타데이터 : name, namespace, labels, annotations 등을 포함
  name: counter

spec: # 메인 파트!!!! : resource 의 desired state 를 명시
  containers:
  - name: yoons&#39;container # container 의 이름
    image: yoon # container 의 image
    args: [/bin/sh, -c, &#39;i=0; while true; do echo &quot;$i: $(date)&quot;; i=$((i+1)); sleep 1; done&#39;] # 해당 image 의 entrypoint 의 args 로 입력하고 싶은 부분
</code></pre>
<h3 id="pod-생성-및-조회">POD 생성 및 조회</h3>
<pre><code class="language-shell">vi pod_ex.yaml

kubectl apply -f pod_ex.yaml 
#kubernetes resource 를 생성

kubectl get pod_ex
# ContainerCreating &amp; 조회

kubectl get pod -n kube-system
# kube-system namespace 의 pod 을 조회합니다.
</code></pre>
<ul>
<li><strong>namespace</strong> 란 ?<ul>
<li>namespace 는 kubernetes 에서 리소스를 격리하는 가상의(논리적인) 단위</li>
</ul>
</li>
</ul>
<hr>
</br>

<h2 id="deployment">Deployment</h2>
<p>-&gt; Pod와 Replicaset에 대한 관리를 제공하는 단위
여기서 관리란 Self-healing, Scaling, Rollout(무중단 업데이트)를 의미</p>
<h3 id="deployment-예시">Deployment 예시</h3>
<pre><code class="language-yaml">apiVersion: apps/v1 # kubernetes resource 의 API Version
kind: Deployment # kubernetes resource name
metadata: # 메타데이터 : name, namespace, labels, annotations 등을 포함
  name: nginx-deployment
  labels:
    app: nginx


spec: # 메인 파트!!! : resource 의 desired state 를 명시
  replicas: 3 # 동일한 template 의 pod 을 3 개 복제본으로 생성
  selector:
    matchLabels:
      app: nginx
  template: # Pod 의 template 을 의미
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx # container 의 이름
        image: nginx:1.14.2 # container 의 image
        ports:
        - containerPort: 80 # container 의 내부 Port
</code></pre>
<h3 id="deployment-생성-및-조회">Deployment 생성 및 조회</h3>
<pre><code class="language-shell">
vi deployment.yaml
kubectl apply -f deployment.yaml

kubectl get deployment
# 다음과 같은 메시지가 출력
# NAME               READY   UP-TO-DATE   AVAILABLE   AGE
# nginx-deployment   0/3     3            0           10s

kubectl get deployment ,?pod
</code></pre>
<h3 id="deploymentpodreplica-생성--삭제">Deployment,pod,replica 생성 &amp; 삭제</h3>
<pre><code class="language-shell">
kubectl delete pod &lt;pod-name&gt;
# 해당 pod을 삭제하면 자동으로 새로운 pod가 생성된다.
# deployment.yaml내에는 relicas가 여전히 3으로 지정되어 있기 때문

kubectl scale deployment/nginx-deployment --replicas=5
kubectl get deployment
# replicas의 숫자를 변경하여 추가 및 삭제가 가능하다.

kubectl delete deployment &lt;deployment-name&gt;
kubectl get deployment
# deployment의 name을 지정하여 삭제 또한 가능

</code></pre>
<h2 id="service">Service</h2>
<p>-&gt; 쿠버네티스에 배포한 애플리케이션(Pod)을 외부에서 접근하기 쉽게 추상화한 리소스</p>
<h2 id="pvc">PVC</h2>
<p>-&gt; Persistent Volume Claim (PVC) 는 stateless 한 Pod 이 영구적으로(persistent) 데이터를 보존하고 싶은 경우 사용하는 리소스</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spark] SparkSQL Java version error]]></title>
            <link>https://velog.io/@yoo_oon/Spark-SparkSQL-Java-version-error</link>
            <guid>https://velog.io/@yoo_oon/Spark-SparkSQL-Java-version-error</guid>
            <pubDate>Tue, 23 Aug 2022 04:50:45 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/yoo_oon/post/372fb067-be5b-4bce-bf3b-e933d4c5193e/image.png" alt=""></p>
<p>sparksession을 import하고 builder를 실행 할 경우 위와 같은 error가 발생 할 수 있다. 
해당 error code가 발생 할 경우 java version을 변경 해주면 해결이 된다.</p>
<ul>
<li><p>Mac의 경우
brew install --cask adoptopenjdk8</p>
</li>
<li><p>windows의 경우
기존의 Java를 삭제하거나 새로 jdk8 version으로 다운 받고 시스템 환경변수를 새롭게 수정해준다.</p>
</br>

</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>