<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyun.log</title>
        <link>https://velog.io/</link>
        <description>10분만 쉬어요</description>
        <lastBuildDate>Thu, 11 Jul 2024 08:25:15 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hyun.log</title>
            <url>https://velog.velcdn.com/images/hyun-wle/profile/366714f9-11d2-4bdb-ada5-c2774c3b934e/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hyun.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyun-wle" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Mac 초기 설정]]></title>
            <link>https://velog.io/@hyun-wle/Mac-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@hyun-wle/Mac-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Thu, 11 Jul 2024 08:25:15 GMT</pubDate>
            <description><![CDATA[<h1 id="homebrew-설치">HomeBrew 설치</h1>
<pre><code class="language-bash">/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;

echo &gt;&gt; /Users/woo/.zprofile
echo &#39;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&#39; &gt;&gt; /Users/woo/.zprofile
eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;

brew install iterm2

</code></pre>
<h1 id="zsh-설정">ZSH 설정</h1>
<h2 id="1-각종-플러그인-설치">1. 각종 플러그인 설치</h2>
<h3 id="linux의-경우">linux의 경우</h3>
<p><a href="https://gist.github.com/n1snt/454b879b8f0b7995740ae04c5fb5b7df">https://gist.github.com/n1snt/454b879b8f0b7995740ae04c5fb5b7df</a></p>
<h3 id="mac의-경우">mac의 경우</h3>
<pre><code class="language-bash"># oh my zsh 설치
sh -c &quot;$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)&quot;
</code></pre>
<ul>
<li>auto suggestions</li>
<li>auto completion</li>
<li>syntax highlighting</li>
<li>auto jump<pre><code class="language-bash">

</code></pre>
</li>
</ul>
<p>brew install zsh-autosuggestions
brew install autojump
brew install zsh-syntax-highlighting
brew install zsh-fast-syntax-highlighting</p>
<pre><code>

```bash
#.zshrc 파일에 추가
plugins=(git zsh-autosuggestions zsh-syntax-highlighting fast-syntax-highlighting autojump)
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
bindkey &#39;\t&#39; autosuggest-accept</code></pre><p>completion 전략 적용을 위해선 다음 명령어를 수행한다.
<code>autoload compinit &amp;&amp; compinit</code>
<a href="https://github.com/zsh-users/zsh-autosuggestions/issues/515">https://github.com/zsh-users/zsh-autosuggestions/issues/515</a></p>
<h2 id="2-테마-설정">2. 테마 설정</h2>
<p><a href="https://github.com/romkatv/powerlevel10k">https://github.com/romkatv/powerlevel10k</a>
powerlevel10k가 최고다</p>
<pre><code class="language-bash">git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
echo &#39;source ~/powerlevel10k/powerlevel10k.zsh-theme&#39; &gt;&gt;~/.zshrc</code></pre>
<h2 id="3-vim-설정">3. vim 설정</h2>
<p>자동 들여쓰기, 하이라이팅, 탭 사이즈, 마지막으로 수정한 곳 부터 시작</p>
<pre><code class="language-shell"># ~/.vimrc

set autoindent
set cindent

syntax on

set ts=4
set shiftwidth=4

au BufReadPost *
\ if line(&quot;&#39;\&quot;&quot;) &gt; 0 &amp;&amp; line(&quot;&#39;\&quot;&quot;) &lt;= line(&quot;$&quot;) |
\ exe &quot;norm g`\&quot;&quot; |
\ endif </code></pre>
<p>만약 vim 테마를 vscode 스타일로 변경하고싶다면</p>
<pre><code class="language-bash">mkdir -p ~/.vim/pack/themes/start
cd ~/.vim/pack/themes/start
git clone https://github.com/tomasiser/vim-code-dark</code></pre>
<p>이후 .vimrc에 다음을 추가해준다: <code>colorscheme codedark</code></p>
<h1 id="키보드-설정">키보드 설정</h1>
<h3 id="₩-대신에-backtick-입력되도록-만들기"><code>₩</code> 대신에 backtick 입력되도록 만들기</h3>
<pre><code class="language-bash">mkdir -p ~/Library/KeyBindings
vi ~/Library/KeyBindings/DefaultKeyBinding.dict

{
    &quot;₩&quot; = (&quot;insertText:&quot;, &quot;`&quot;);
}</code></pre>
<h3 id="기계식-키보드-2번-눌림-해결-unshaky">기계식 키보드 2번 눌림 해결: Unshaky</h3>
<p><a href="https://github.com/aahung/Unshaky/releases">https://github.com/aahung/Unshaky/releases</a></p>
<h1 id="제어센터-설정">제어센터 설정</h1>
<p>설정-제어센터-블루투스 제어센터에서 보이기</p>
<h1 id="잠금화면에서-화면-켜두기">잠금화면에서 화면 켜두기</h1>
<p><code>brew install --cask keepingyouawake</code></p>
<h1 id="dock-애니메이션-속도-조정">Dock 애니메이션 속도 조정</h1>
<pre><code class="language-bash"># 애니메이션 속도
defaults write com.apple.dock autohide-time-modifier -float 0.5;killall Dock
# 반응 속도
defaults write com.apple.Dock autohide-delay -float 0 &amp;&amp; killall Dock
# 초기화
defaults delete com.apple.dock autohide-time-modifier; killall Dock</code></pre>
<h1 id="기타-설정">기타 설정</h1>
<ul>
<li>DisplayLink 설치 (모니터 3개 이상)</li>
<li>mos: 마우스 부드럽게</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git Commit History 마음대로 변경하기]]></title>
            <link>https://velog.io/@hyun-wle/Git-commit-%ED%9E%88%EC%8A%A4%ED%86%A0%EB%A6%AC-%EB%B3%80%EA%B2%BD%EB%B2%95</link>
            <guid>https://velog.io/@hyun-wle/Git-commit-%ED%9E%88%EC%8A%A4%ED%86%A0%EB%A6%AC-%EB%B3%80%EA%B2%BD%EB%B2%95</guid>
            <pubDate>Tue, 02 Jan 2024 08:53:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>앗! 실수로 회사 계정으로 커밋했다!</p>
</blockquote>
<p>Bulb-Talk 프로젝트를 처음 시작할 때, 첫 커밋의 Author가 회사 계정으로 설정되어있는 채로 커밋한 바람에 회사계정이 영원히 contributer로남게되었다</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/f8307109-a66b-4d00-a208-600ff4ccd92b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/8a16470c-7e61-4c9a-8f8f-54df96ae3800/image.png" alt="">
문제의 최초 commit.</p>
<p>사실 개인 레포지토리에 컨트리뷰터에 누가 있든 별로 상관은 없다. 누가 보는 것도 아니고, 굳이 커밋 히스토리 최 하단을 보지도 않는다.
하지만 불편하다!</p>
<blockquote>
<p>불편하면 자세를 고쳐앉아!
하지만 개발자는 자세가 아니라 문제를 고쳐야지!</p>
</blockquote>
<p>불편한 일이 생겼을 때, 자세를 고쳐앉는 건 하수다.
엔지니어는 문제를 고친다.</p>
<h1 id="저-멀리있는-commit을-어떻게-고칠까">저 멀리있는 Commit을 어떻게 고칠까?</h1>
<p>최신 commit이라면 <code>git commit --amend</code> 명령어로 바로 수정이 가능하지만, 저 멀리 있는 커밋은 그럴 수 없다.
이 때 사용하는 것이 rebase이다.</p>
<h3 id="rebase">Rebase</h3>
<p>Rebase는 깃에서 사용하는 branch 관리 전략중 하나로, 비슷한 전략중 하나로 Merge가 있다.</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/92d3f5ed-08ae-43d6-8464-7187d1c5fa29/image.png" alt=""></p>
<p>Merge와 Rebase의 차이는 위 그림 하나로 요약된다.
merge가 두개의 branch를 합치는 전략이라면, rebase는 기존 branch에 새로운 commit을 끼워 넣는다.</p>
<p>merge는 branch의 생성과 삭제가 명확하게 보이지만 갈수록 branch가 늘어나 복잡해보인다는 단점이 있고, rebase는 branch가 하나만 남기 때문에 간결해 보인다는 장점이 있다.
자세한 내용은 <a href="https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0">공식 문서</a>에 잘 나와있다. </p>
<p>우리는 브랜치를 여러개 만들 것이 아니기에, 이러한 내용을 몰라도 되지만, rebase의 commit을 &#39;끼워 넣는다&#39; 라는 기능에 주목하면, 우리의 잘못된 최초의 commit을 수정할 수 있다는 점을 알게된다.</p>
<h3 id="처음으로-rebase-해보자">처음으로 Rebase 해보자!</h3>
<pre><code class="language-bash">git rebase -i  --committer-date-is-author-date --root</code></pre>
<p><code>-i</code> : interactive. 대화형
<code>--committer-date-is-author-date</code>: Author date와 committer date를 일치시킨다. rebase를 하게되면, committer date가 현재로 변경된다. 그럼 지금까지 했던 모든 commit 시간이 현재 시간으로 변경되기 때문에, commit history가 예쁘게 나오지 않는다. 이를 방지하기 위해 위 옵션을 넣어줘야한다.</p>
<p><code>--root</code>: 최초 commit으로 이동한다. --root대신 커밋id를 넣어서 해당 커밋으로 이동할 수도 있다.
위 명령어를 통해, 첫 커밋으로 바로 rebase가 가능하다. 
<img src="https://velog.velcdn.com/images/hyun-wle/post/267a9dad-7a24-46cf-96eb-b6049421cddc/image.png" alt="">
그럼 위와 같은 창이 뜨는데, 여기서 첫번째 commit의 pick을 edit으로 수정한다. </p>
<p>이 외에도 다음 작업도 가능하다.</p>
<ul>
<li>커밋 순서 변경</li>
<li>커밋 합치키</li>
<li>커밋 분할</li>
<li>커밋 메세지 편집</li>
<li>커밋 삭제 및 건너뛰기</li>
</ul>
<pre><code class="language-bash">$ git log
commit fbf8a34fe14438794facdc6e046fa344b8517afd (HEAD)
Author: company &lt;company@company.com&gt;
Date:   Sun Jul 30 21:38:40 2023 +0900

    [ADD] First Commit
</code></pre>
<p>git log 확인 결과 첫 커밋으로 돌아온 것을 알 수 있다!</p>
<p>이제 amend를 통해 commit을 수정할 시간이다.</p>
<pre><code>git commit --amend --author=&quot;harrier999 &lt;harrier999@github.com&gt;&quot;</code></pre><p><img src="https://velog.velcdn.com/images/hyun-wle/post/3bc7d26e-17b7-466e-8fbe-ff21b18c512e/image.png" alt="새로운 캡션!"></p>
<p>만약 <code>--committer-date-is-author-date</code> 옵션을 주지 않고 Rebase하면, 위 이미지처럼 commit 시간이 현재 시간과 동일하게 통일된다. 꼭 옵션을 넣어주자</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/94a11bee-9b6d-4e4c-8799-9c37c3e602c3/image.png" alt="캡션2">
git log 명령어에서는 정상적으로 Date가 출력된다.
그런데 왜 github에서는 시간이 다르게 보일까?</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/05d27591-093e-445d-ac61-b69132d6ee26/image.png" alt="">
git log에서 보여지는 시간은 CommitDate가 아닌 AuthorDate이다.
반면에 github에서 보여지는 시간은 CommitDate이다.
<code>git log --pretty=fuller</code> 명령어를 이용하면 AuthorDate와 CommitDate를 모두 볼 수 있다.</p>
<h3 id="어떻게-commit-author-date를-변경할-수-있을까">어떻게 Commit, Author Date를 변경할 수 있을까?</h3>
<p>author를 변경했더니 commit date가 초기화되고, 그대로 냅두자니 author가 계속 남아있는게 불편하다. 좋은 방법이 없을까?</p>
<pre><code>git filter-branch --env-filter &#39;export GIT_COMMITTER_DATE=&quot;$GIT_AUTHOR_DATE&quot;&#39; -- --all</code></pre><p>filter-branch라는 명령어를 이용해 AuthorDate를 CommitDate과 동일하게 만들 수 있다.</p>
<p>하지만 filter-branch는, 모든 commit 내역을 한 번에 수정하는 강력하지만 위험한 툴이기 때문에 사용을 권장하지 않는다.</p>
<p>대신에, 처음 rebase를 할 때부터 commit date를 변경하지 않도록 설정할 수 있다.</p>
<pre><code>git rebase -i --committer-date-is-author-date --root</code></pre><p>이 옵션을 추가한 후 rebase를 하면 committer date가 변경되지 않는다.</p>
<h2 id="정리">정리</h2>
<pre><code>git rebase -i --committer-date-is-author-date --root
git amend --author=&quot;harrier999 &lt;harrier999@github.com&gt;&quot;
git rebase --continue
git push -f</code></pre><p>g</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[hasura metadata 조회]]></title>
            <link>https://velog.io/@hyun-wle/hasura-metadata-%EC%A1%B0%ED%9A%8C</link>
            <guid>https://velog.io/@hyun-wle/hasura-metadata-%EC%A1%B0%ED%9A%8C</guid>
            <pubDate>Tue, 08 Aug 2023 05:28:41 GMT</pubDate>
            <description><![CDATA[<p>hasura를 이용해 분산시스템을 구성하다보면, metadata DB를 하나로 통합해야할 때가 있다.</p>
<p>그러나 막상 metadata DB로 지정한 데이터베이스에 들어가보면, 어떠한 데이터도 들어있지 않음을 알 수 있다. </p>
<p>본인의 경우 다음과 같이 metadata DB를 설정해두었다.</p>
<pre><code class="language-yaml">HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://hasura_connector@company.cluster-gabqpvs5581.ap-northeast-1.rds.amazonaws.com:5432/hasura_metadata</code></pre>
<p>해당 DB에 접근해보았다.</p>
<pre><code>template1=&gt; \dt
Did not find any relations.</code></pre><p>그러나 어떠한 테이블도 존재하지 않았다.</p>
<pre><code>template1=&gt; SELECT datname FROM pg_database;
  datname  
-----------
 template0
 rdsadmin
 postgres
 hasura_metadata
 template1</code></pre><p>혹시나 다른 데이터베이스를 생성한 것 아닐까 확인해보았지만, 데이터베이스가 추가로 생성된 것은 없었다.</p>
<p>Hasura는 일반적으로 사용하는 Public 스키마가 아닌 <code>hdb_catalog</code>라는 새로운 스키마에 메타데이터를 저장한다. </p>
<pre><code>hasura_metadata=&gt;  \dn
   List of schemas
    Name     | Owner  
-------------+--------
 hdb_catalog | hasura
 public      | hasura
(2 rows)</code></pre><p>해당 스키마에서 테이블을 이용하기 위해서는 다음과 같이 현재 스키마를 Public에서 <code>hdb_catalog</code>로 변경해주어야한다.</p>
<pre><code class="language-sql">SET search_path TO hdb_catalog;</code></pre>
<p>그런 다음 테이블을 조회해보면 Hasura의 metadata가 저장되는 테이블들을 볼 수 있게 되었다.</p>
<pre><code>template1=&gt; \dt
                         List of relations
   Schema    |                Name                 | Type  | Owner  
-------------+-------------------------------------+-------+--------
 hdb_catalog | hdb_action_log                      | table | hasura
 hdb_catalog | hdb_cron_event_invocation_logs      | table | hasura
 hdb_catalog | hdb_cron_events                     | table | hasura
 hdb_catalog | hdb_metadata                        | table | hasura
 hdb_catalog | hdb_scheduled_event_invocation_logs | table | hasura
 hdb_catalog | hdb_scheduled_events                | table | hasura
 hdb_catalog | hdb_schema_notifications            | table | hasura
 hdb_catalog | hdb_version                         | table | hasura
(8 rows)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Dart/Flutter VSCode 설정]]></title>
            <link>https://velog.io/@hyun-wle/DartFlutter-VSCode-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@hyun-wle/DartFlutter-VSCode-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Sun, 28 May 2023 23:18:41 GMT</pubDate>
            <description><![CDATA[<p><code>Ctrl + Shift + P</code>로 vscode 검색창을 연 다음,
user settings(JSON)을 검색하고 열어준다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/30843f6d-24fa-4f56-bf9c-847e1dd93447/image.png" alt=""></p>
<p>그런 다음 JSON 파일에 
아래 항목을 추가해준다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/1b36a3fa-d9a4-407b-96a3-f1dace654d3d/image.png" alt=""></p>
<pre><code class="language-python">&quot;dart.previewFlutterUiGuides&quot;: true,
&quot;editor.codeActionsOnSave&quot;: {
  &quot;source.fixAll&quot;: true
},</code></pre>
<p><code>&quot;dart.previewFlutterUiGuides&quot;: true,</code>: 혼잡한 플러터의 들여쓰기에 희망을 준다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/9b5ff3e5-c008-413e-ac8a-4ecbdf53c018/image.png" alt=""></p>
<p><code>&quot;editor.codeActionsOnSave&quot;: {&quot;source.fixAll&quot;: true}</code>: 저장시에 prefer_const_constructor 같은 잡다한 것을 알아서 수정해준다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unreal Engine  ERROR: cmd.exe failed with args /c "C:\Users\woo\Unreal Projects\delete_it\Intermediate\Android\arm64\gradle\rungradle.bat" :app:assembleDebug]]></title>
            <link>https://velog.io/@hyun-wle/Unreal-Engine-ERROR-cmd.exe-failed-with-args-c-CUserswooUnreal-ProjectsdeleteitIntermediateAndroidarm64gradlerungradle.bat-appassembleDebug</link>
            <guid>https://velog.io/@hyun-wle/Unreal-Engine-ERROR-cmd.exe-failed-with-args-c-CUserswooUnreal-ProjectsdeleteitIntermediateAndroidarm64gradlerungradle.bat-appassembleDebug</guid>
            <pubDate>Tue, 16 May 2023 12:04:41 GMT</pubDate>
            <description><![CDATA[<pre><code>ERROR: cmd.exe failed with args /c &quot;C:\Users\woo\Unreal Projects\delete_it\Intermediate\Android\arm64\gradle\rungradle.bat&quot; :app:assembleDebug</code></pre><p>안드로이드로 언리얼엔진 프로젝트를 패키징 할 때 발생하는 오류.
gradle 버전 문제로 발생한다.</p>
<pre><code>C:\Program Files\Epic Games\UE_5.2\Engine\Build\Android\Java\gradle\gradle\wrapper</code></pre><p>대충 위와 같이 생긴 경로에 가서</p>
<p><code>gradle-wrapper.properties</code>파일을 수정해주면 된다.</p>
<pre><code>#Tue Feb 04 16:06:19 EST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip</code></pre><p>gradle-wrapper.properties 파일은 위와 같은 내용을 담고있는데, </p>
<p>마지막줄의 <code>distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip</code>을</p>
<p><code>distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip</code>로 바꿔준다</p>
<p>그래들 버전이 6.2 이상이기만 하면 작동하는 듯 하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[회사 서버에 github 로그인 없이 배포하기]]></title>
            <link>https://velog.io/@hyun-wle/%ED%9A%8C%EC%82%AC-%EC%84%9C%EB%B2%84%EC%97%90-github-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%86%EC%9D%B4-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyun-wle/%ED%9A%8C%EC%82%AC-%EC%84%9C%EB%B2%84%EC%97%90-github-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%86%EC%9D%B4-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 27 Feb 2023 07:27:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>*회사 공용서버에 내 github 아이디를 사용하지 않고 git을 사용할 수는 없을까?    *</p>
</blockquote>
<p><a href="https://blog.leocat.kr/notes/2017/11/27/github-deploy-key">https://blog.leocat.kr/notes/2017/11/27/github-deploy-key</a></p>
<p>서버에서 github를 사용할 땐 참 난감하다. </p>
<p>내 아이디로 로그인하자니, 내 개인 레포지토리까지 접속할 수 있어 꺼리직하다.</p>
<p>그래서 레포지토리 별로 접근 권한을 설정할 수 있는 Fine grained token 또는 Deploy key 방식을 이용하는 것이 바람직하다.</p>
<p>이번에는 Deploy key를 이용한 github 사용법을 알아보자</p>
<h3 id="ssh-key-generator">SSH Key Generator</h3>
<p>아래 명령어를 통해 새로운 rsa 키를 만들 수 있다.</p>
<pre><code class="language-shell">ssh-keygen -t rsa -f my_key</code></pre>
<p>-t는 타입을 지정하는 옵션이며, -f는 key를 저장할 파일 이름이다.</p>
<p>위 명령어를 실행하면 ~/.ssh 폴더에 <code>my_key</code>와 <code>my_key.pub</code> 파일이 생성된다.</p>
<p><code>my_key</code>는 private key로써, 어떠한 경우에도 컴퓨터 밖으로 노출되면 안된다.
.ssh 폴더 내부에서 사용되기 때문에 굳이 복사하거나 <code>cat</code> 명령어로 열어볼 필요도 없다.</p>
<p><code>my_key.pub</code>는 public key로써, 인터넷에 올려도 된다. 이것을 깃허브에 등록하면 내 컴퓨터에 저장된 private key를 이용해 레포지토리에 접근할 수 있다.</p>
<p>public key의 예시는 다음과 같고, private key에 비해 상대적으로 짧다.</p>
<pre><code>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu+j7Gcd3zAVy+jY7yDqAu+MihMd9xoZdDpTtZJMDT9tc39aCt5WCeFZUbt6QGe2hHOcOXAxLiA+RQjUHrT4AnIxEA2OpyJImPbEXysgRdWavUMYyn2UtU96S2xLxWBHstj+vb6J8XXRQ7tYzTecbAf5H44wELsaOypeH+z8Lu4a4+bU1KcFnoL/jDXuwZTdB6jPDpj61TrySJ6WZNHfpMu5g8z2jJw6qZ8+vw/ib0wJfXnf/6bRHL19gWW43auOwSXOYTArB2Oz2n56lScyVrchT/+Yrs6EjioS/qIKxFxLkg5cZ4+6RQ1MksZ48eSdagrt9UZ4TBDmJDS3/Anuf4CvJV7/loYBabTUg6fBYjwk+ajo1AUgcqsEKmwfMTc5Z7nXeTPOIJwFlArexiq3v+slWG/6dr0kN0ZilpHV5sgorFayPRg627qolHCdBeOje/LGJJNSfkrFRyEpU4bn3xwbFgn3Qyk6NGaGS4X4/CaLhhTBv1NcpcuWXE= hyun-wle@velog.MacBookPro.local</code></pre><h3 id="github-deploy-keys">Github Deploy Keys</h3>
<p>원하는 레포지토리로 이동 -&gt; settings -&gt; Deploy Keys 로 들어가면 key를 등록할 수 있다.
settings가 안보이는 경우는, 레포지토리 권한이 없어서 보이지 않는 것이다. 
settings는 보이지만, Deploy Keys가 보이지 않는 경우, 레포지토리 권한이 낮아서 발생한다.
Deploy key를 등록하기 위해선 해당 레포지토리의 Owner여야한다.</p>
<p>add deploy key를 눌러 새 key를 추가하자.
title은 마음대로 정해도 좋고, key에는 .pub파일의 내용을 복붙하면 된다.</p>
<h3 id="ssh-config">ssh config</h3>
<p>깃허브에 deploy key를 등록했다면, ssh에도 private key가 어디 있는지 명시해줘야한다.</p>
<p><code>~/.ssh/config</code> 파일에 다음 내용을 추가한다. <code>config</code>파일이 없다면 새로 만들면 된다.</p>
<pre><code class="language-shell">Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/my_key
    IdentitiesOnly yes
    Port 22</code></pre>
<h3 id="git-clone">git clone</h3>
<p>마지막으로 deploy key를 등록했던 레포지토리를 클론하면된다.</p>
<p>이 때 HTTP 주소를 이용한 clone이 아닌, SSH 주소를 이용한 clone을 해야한다.
깃허브 주소를 복사할 때, HTTP 대신 SSH를 선택하면 된다.</p>
<p>HTTP 형식
<code>https://github.com/my_company/company_repo</code>
SSH 형식
<code>git@github.com:my_company/company_repo</code></p>
<p>이를 통해 로그인 없이 git에 접근하는 방법을 알아보았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[golang test code]]></title>
            <link>https://velog.io/@hyun-wle/golang-test-code</link>
            <guid>https://velog.io/@hyun-wle/golang-test-code</guid>
            <pubDate>Thu, 16 Feb 2023 02:35:03 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@chappi/GO-Test-code-1%EC%9D%BC%EC%B0%A8-golang%EC%97%90%EC%84%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-coverage-%ED%99%95%EC%9D%B8-%EB%B0%A9%EB%B2%95">https://velog.io/@chappi/GO-Test-code-1%EC%9D%BC%EC%B0%A8-golang%EC%97%90%EC%84%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-coverage-%ED%99%95%EC%9D%B8-%EB%B0%A9%EB%B2%95</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML 전역속성]]></title>
            <link>https://velog.io/@hyun-wle/HTML-%EC%A0%84%EC%97%AD%EC%86%8D%EC%84%B1</link>
            <guid>https://velog.io/@hyun-wle/HTML-%EC%A0%84%EC%97%AD%EC%86%8D%EC%84%B1</guid>
            <pubDate>Mon, 01 Aug 2022 13:03:41 GMT</pubDate>
            <description><![CDATA[<h1 id="전역속성">전역속성</h1>
<blockquote>
<p>모든 HTML 태그에 적용될 수 있는 속성</p>
</blockquote>
<ul>
<li>title: 마우스를 대면 title 값이 출력된다.</li>
<li>style: css 속성을 태그 안에 넣을 수 있다.</li>
<li>class 중복 가능 .으로 지정<pre><code class="language-CSS">.class {
  color: red;
}</code></pre>
</li>
<li>id 고유함 #으로 지정<pre><code class="language-CSS">#id {
  color: red;
}</code></pre>
</li>
<li>data
<code>&lt;div data-DATANAME=&quot;DATA&quot;&gt;어쩌구저쩌구&lt;/div&gt;</code>
이런식으로 데이터 저장 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[anaconda 사용법]]></title>
            <link>https://velog.io/@hyun-wle/anaconda-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@hyun-wle/anaconda-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Thu, 12 May 2022 04:01:18 GMT</pubDate>
            <description><![CDATA[<p>가상환경 리스트 확인 conda info --envs</p>
<p>conda create --name &quot;ENV_NAME&quot; &quot;PACKAGE_LIST&quot;
(conda create --n)</p>
<p>conda update --all</p>
<p>conda activate &quot;ENV_NAME&quot;</p>
<p>conda deactivate &quot;ENV_NAME&quot;</p>
<p>conda env remove -n ENV_NAME
conda remove --name myenv --all</p>
<p>conda clean --all 불필요한 파일 제거 </p>
<p>Windows에서 anaconda prompt 실행
<img src="https://velog.velcdn.com/images/hyun-wle/post/796bfcac-34b6-4a1e-93b3-d9b796c5fd47/image.png" alt=""></p>
<p>설치후 검색으로 열 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/1654ee6a-b78a-4ec2-aa87-0591c677253a/image.png" alt="">
실행시 나오는 화면.</p>
<p>conda info --envs로 가상환경 리스트 확인
<img src="https://velog.velcdn.com/images/hyun-wle/post/efcb6872-3505-4de9-bae0-a1adb61130c3/image.png" alt="">
아직 base만 존재한다</p>
<p>conda create --name &quot;ENV_NAME&quot;으로 새 가상환경 생성.</p>
<p>conda activate &quot;ENV_NAME&quot;으로 가상환경 실행</p>
<p>conda install --yes --file requirements.txt 필요한 패키지 설치</p>
<p>conda -V로 버전 확인
conda update -n vase conda 로 업데이트</p>
<p>conda install &quot;PACKAGE_NAME&quot;으로 설치되지 않는 패키지들이 많다.
<a href="https://anaconda.org/">https://anaconda.org/</a> 
여기서 검색하여 정확한 설치 경로가 나와있다.</p>
<p>conda install -c conda-forge fastapi 로 fastapi 설치
conda install -c conda-forge uvicorn 로 uvicorn 설치</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SRGAN 따라하기]]></title>
            <link>https://velog.io/@hyun-wle/SRGAN-%EB%94%B0%EB%9D%BC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyun-wle/SRGAN-%EB%94%B0%EB%9D%BC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 11 May 2022 12:20:15 GMT</pubDate>
            <description><![CDATA[<p><a href="https://github.com/leftthomas/SRGAN">https://github.com/leftthomas/SRGAN</a></p>
<p>Super Resolution으로 유명한 SRGAN 모델</p>
<h1 id="srgan을-사용해보자">SRGAN을 사용해보자</h1>
<h2 id="0-환경설정">0. 환경설정</h2>
<ul>
<li>ubuntu 18.04 LTS</li>
<li>git, conda, pip3, pytorch가 설치된 환경.
인터넷에 설치법이 쉽게 나와있으니 참고하도록 하자</li>
</ul>
<h2 id="1-코드-다운로드">1. 코드 다운로드</h2>
<ul>
<li>github에서 코드를 다운받는다.
<code>git clone https://github.com/leftthomas/SRGAN.git SRGAN</code></li>
</ul>
<pre><code class="language-bash">root@7310e7ec2d72:~# git clone https://github.com/leftthomas/SRGAN.git SRGAN
Cloning into &#39;SRGAN&#39;...
remote: Enumerating objects: 1064, done.
remote: Total 1064 (delta 0), reused 0 (delta 0), pack-reused 1064
Receiving objects: 100% (1064/1064), 32.17 MiB | 8.22 MiB/s, done.
Resolving deltas: 100% (675/675), done.
root@7310e7ec2d72:~#</code></pre>
<ul>
<li>SRGAN 폴더로 이동
<code>cd SRGAN</code></li>
<li>폴더 내용물 확인
<code>ls</code><pre><code class="language-bash">root@7310e7ec2d72:~/SRGAN# ls
LICENSE    benchmark_results  data_utils.py  images   model.py      statistics         test_image.py  train.py
README.md  data               epochs         loss.py  pytorch_ssim  test_benchmark.py  test_video.py  training_results</code></pre>
README.md 파일에 사용법이 있을 것이다.</li>
<li>텍스트파일 내용물 확인
<code>cat README.md</code><pre><code class="language-bash"># SRGAN
A PyTorch implementation of SRGAN based on CVPR 2017 paper
[Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network](https://arxiv.org/abs/1609.04802).
</code></pre>
</li>
</ul>
<h2 id="requirements">Requirements</h2>
<ul>
<li><a href="https://www.anaconda.com/download/">Anaconda</a></li>
<li>PyTorch
...<pre><code>내용물이 길고 마크다운 언어로 작성된 듯하다. 
github 페이지에서 직접 확인하자.
</code></pre></li>
</ul>
<p><a href="https://github.com/leftthomas/SRGAN">https://github.com/leftthomas/SRGAN</a>
웹브라우저에서 접속
페이지 하단에 아래와 같은 내용을 확인 할 수 있다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/cb14b237-f1e0-439a-bad6-522744806aed/image.png" alt=""></p>
<h2 id="2-train">2. Train</h2>
<p>모든 머신러닝 모델은 학습이 필요하다.
README.md의 Usage 부분에서 확인한 대로 SRGAN 폴더에서
<code>python train.py</code></p>
<pre><code class="language-bash">root@7310e7ec2d72:~/SRGAN# python train.py
Traceback (most recent call last):
  File &quot;train.py&quot;, line 32, in &lt;module&gt;
    train_set = TrainDatasetFromFolder(&#39;data/DIV2K_train_HR&#39;, crop_size=CROP_SIZE, upscale_factor=UPSCALE_FACTOR)
  File &quot;/opt/ml/SRGAN/data_utils.py&quot;, line 44, in __init__
    self.image_filenames = [join(dataset_dir, x) for x in listdir(dataset_dir) if is_image_file(x)]
FileNotFoundError: [Errno 2] No such file or directory: &#39;data/DIV2K_train_HR&#39;</code></pre>
<p>에러가 뜨면서 실행되지 않는다.</p>
<p>마지막 줄에 에러 원인이 나와있다.</p>
<pre><code>FileNotFoundError: [Errno 2] No such file or directory: &#39;data/DIV2K_train_HR&#39;</code></pre><p><code>&#39;data/DIV2K_train_HR&#39;</code> 경로를 찾을 수 없다고 한다. 
README.md 파일을 보니 dataset은 따로 다운로드 해야한다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/5e5880c9-78e0-464e-b378-e50ea57b6128/image.png" alt=""></p>
<p>here라고 적힌 링크를 따라가니 baidu 클라우드로 연결된다.
다운로드하기 복잡하므로 다른 dataset을 이용하자.</p>
<p>README.md 파일엔 VOC2012 dataset을 사용한다고 적혀있는데, 코드상에선 DIV2K dataset을 활용했다.</p>
<p>자주 쓰이는 image dataset은 나중에 따로 정리하도록 하고, 이번에는 DIV2K Dataset을 이용해보자.</p>
<p><a href="https://data.vision.ee.ethz.ch/cvl/DIV2K/">https://data.vision.ee.ethz.ch/cvl/DIV2K/</a></p>
<p>위 링크에서 다운로드 가능하다. 
<img src="https://velog.velcdn.com/images/hyun-wle/post/4f8010bc-4c87-474e-b49b-86ab99cb3806/image.png" alt="">
페이지 최 하단부에 다운로드 링크가 있다.</p>
<p>학습과 검증을 위해선 Train Dataset과 Validation Dataset이 필요하다
또한 SR 학습을 위해 Low Resolution High Resolution 파일이 모두 필요하다.</p>
<p>그러나 우리의 코드에는 해상도를 변환해주는 코드가 있으므로 최하단의 두개의 High Resolution images 파일만 다운로드 받아준다.</p>
<p>각각 3.4GB, 0.4GB 정도이다.</p>
<p>터미널 환경에서도 다운로드 할 수 있다.
먼저 SRGAN/data 폴더로 이동하자.
<code>cd data</code>
그리고 다음 명령어로 다운받는다.
<code>wget http://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_train_HR.zip</code>
<code>wget http://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_valid_HR.zip</code></p>
<pre><code>root@7310e7ec2d72:~/SRGAN/data# wget http://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_train_HR.zip
--2022-05-11 12:50:22--  http://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_train_HR.zip
Resolving data.vision.ee.ethz.ch (data.vision.ee.ethz.ch)... 129.132.52.178, 3001:67a:10ec:37b2::108
Connecting to data.vision.ee.ethz.ch (data.vision.ee.ethz.ch)|110.172.52.228|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_train_HR.zip [following]
--2022-05-11 12:50:32--  https://data.vision.ee.ethz.ch/cvl/DIV2K/DIV2K_train_HR.zip
Connecting to data.vision.ee.ethz.ch (data.vision.ee.ethz.ch)|110.172.52.228|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3530603713 (3.3G) [application/zip]
Saving to: ‘DIV2K_train_HR.zip’

DIV2K_train_HR.zip             37%[=================&gt;                                ]   1.24G  11.2MB/s    eta 3m 18s</code></pre><p>wget이 설치되지 않은 경우
<code>sudo apt install wget</code> 을 먼저 실행한다.</p>
<pre><code>root@7310e7ec2d72:~/SRGAN/data# apt install wget
Reading package lists... Done
Building dependency tree
Reading state information... Done
wget is already the newest version (1.19.4-1ubuntu2.2).
0 upgraded, 0 newly installed, 0 to remove and 36 not upgraded.</code></pre><p>두 파일을 모두 다운로드 했으면, 압축을 해제시켜줘야 한다.
<code>ls</code> 명령어로 다운받은 파일을 확인한다.</p>
<pre><code>root@7310e7ec2d72:~/SRGAN/data# ls
DIV2K_train_HR.zip  DIV2K_valid_HR.zip</code></pre><p>unzip 명령어로 압축해제.
설치되어있지 않은 경우 <code>sudo apt install unzip</code></p>
<p><code>unzip DIV2K_train_HR.zip</code>
<code>unzip DIV2K_valid_HR.zip</code></p>
<pre><code>  inflating: DIV2K_train_HR/0544.png
  inflating: DIV2K_train_HR/0416.png
  inflating: DIV2K_train_HR/0295.png
  inflating: DIV2K_train_HR/0538.png
...</code></pre><p>압축 해제되는 이미지 파일 하나하나가 표시된다.
<code>ls</code> 명령어로 확인해보자</p>
<pre><code>root@7310e7ec2d72:~/SRGAN/data# ls
DIV2K_train_HR  DIV2K_train_HR.zip  DIV2K_valid_HR  DIV2K_valid_HR.zip</code></pre><p>압축 해제된 것을 확인할 수 있다.</p>
<p>다시 SRGAN 폴더로 돌아가자.
<code>cd ..</code>
dataset을 넣어줬으니 train이 정상작동할 것이다.
<code>python train.py</code></p>
<pre><code>root@7310e7ec2d72:~/SRGAN# python train.py
# generator parameters: 734219
# discriminator parameters: 5215425
Downloading: &quot;https://download.pytorch.org/models/vgg16-397923af.pth&quot; to /opt/ml/.cache/torch/hub/checkpoints/vgg16-397923af.pth
100%|████████████████████████████████████████████████████████████████████████████████| 528M/528M [00:08&lt;00:00, 63.1MB/s]
[1/100] Loss_D: 0.8443 Loss_G: 0.0450 D(x): 0.5024 D(G(z)): 0.3312: 100%|███████████████| 13/13 [00:26&lt;00:00,  2.06s/it]
[converting LR images to SR images] PSNR: 15.3047 dB SSIM: 0.3970: 100%|██████████████| 100/100 [00:33&lt;00:00,  3.03it/s]
[saving training results]: 100%|████████████████████████████████████████████████████████| 20/20 [00:20&lt;00:00,  1.01s/it]
[2/100] Loss_D: 0.8718 Loss_G: 0.0213 D(x): 0.4618 D(G(z)): 0.2530: 100%|███████████████| 13/13 [00:26&lt;00:00,  2.04s/it]
[converting LR images to SR images] PSNR: 14.3030 dB SSIM: 0.3909: 100%|██████████████| 100/100 [00:32&lt;00:00,  3.03it/s]
[saving training results]: 100%|████████████████████████████████████████████████████████| 20/20 [00:20&lt;00:00,  1.05s/it]
[3/100] Loss_D: 0.8175 Loss_G: 0.0186 D(x): 0.4169 D(G(z)): 0.2086: 100%|███████████████| 13/13 [00:26&lt;00:00,  2.04s/it]
[converting LR images to SR images] PSNR: 18.2039 dB SSIM: 0.5148: 100%|██████████████| 100/100 [00:34&lt;00:00,  2.91it/s]
[saving training results]: 100%|████████████████████████████████████████████████████████| 20/20 [00:20&lt;00:00,  1.03s/it]
[4/100] Loss_D: 0.4785 Loss_G: 0.0176 D(x): 0.6804 D(G(z)): 0.1720:  31%|████▉           | 4/13 [00:08&lt;00:25,  2.88s/it][4/100] Loss_D: 0.5887 Loss_G: 0.0185 D(x): 0.6745 D(G(z)): 0.2311: 100%|███████████████| 13/13 [00:26&lt;00:00,  2.04s/it]
[converting LR images to SR images] PSNR: 18.2836 dB SSIM: 0.5135:  39%|█████▊         | 39/100 [00:13&lt;00:22,  2.70it/s][converting LR images to SR images] PSNR: 18.4853 dB SSIM: 0.5229:  75%|███████████▎   | 75/100 [00:25&lt;00:07,  3.26it/s]</code></pre><p>정상적으로 실행된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[깃허브2]]></title>
            <link>https://velog.io/@hyun-wle/%EA%B9%83%ED%97%88%EB%B8%8C2</link>
            <guid>https://velog.io/@hyun-wle/%EA%B9%83%ED%97%88%EB%B8%8C2</guid>
            <pubDate>Fri, 06 May 2022 10:03:58 GMT</pubDate>
            <description><![CDATA[<h1 id="깃허브-2">깃허브 2</h1>
<p>git status를 보면 
untracked와 tracked 상태가 있다.
tracked는 한 번이라도 add 된 파일
untracked는 한 번도 add 되지 않은 파일이다.
<img src="https://velog.velcdn.com/images/hyun-wle/post/97166ce8-63e6-491d-86a6-5cba59ddec88/image.png" alt=""></p>
<p>git은 add한 파일만 commit한다.
git commit -a를 붙히면 자동으로 add와 commit을 해준다.</p>
<p>이 때 tracked file만 add 되고 untracked file은 add 되지 않는다.</p>
<p>.gitignore 파일을 통해 무시할 파일을 설정할 수 있다.
.gitignore에 등록하면 status에서 아예 보이지 않는다.
.gitignore은 어떤 파일을 무시할 지 결정하는 일종의 프로젝트 정책이다.
.git file 안에 exclude 폴더에 무시할 파일을 설정하면 프로젝트가 아닌 나만의 정책을 설정할 수 있다. 
.gitignore: 깃허브에 업로드해서 다른 사람도 동일하게 설정
.git/exclude: 업로드하지 않고 나만 설정</p>
<p>일반적으로 config 파일은 .gitignore에 등록하지 않는다.
만약 config파일의 형식이 필요하다면? 
config.json.template 처럼 뒤에 template를 붙혀 어떤 형식으로 써야할지 업로드한다.</p>
<p>git log --oneline : 한줄로 요약</p>
<p>git commit --amend -m &quot;template 추가&quot;
: 마지막 커밋 메세지를 변경한다.
이 때 commit id도 바뀐다.</p>
<p>git commit id는 commit의 변경사항, 시간, commit msg 등을 모두 포함한 hash값이다. </p>
<p>amend는 커밋을 수정하는 것이 아닌, 커밋과 연결고리를 끊고 새로운 커밋을 생성하는 것이다.</p>
<h2 id="git-reset-vs-revert-vs-checkout">git reset vs revert vs checkout</h2>
<h3 id="git-checkout-commit_id">git checkout COMMIT_ID</h3>
<p>해당 commit id 시점으로 이동한다. (master는 그대로, HEAD는 해당 commit id로 이동)
git checkout master라고 하면 다시 되돌아온다.
master의 commit id를 입력해도 되지만 </p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/bdec7234-11d7-4f0c-bdad-e537203bc916/image.png" alt="">
<img src="https://velog.velcdn.com/images/hyun-wle/post/4e87608f-c84d-4993-8015-fe4fcebf6d86/image.png" alt=""></p>
<p>새로운 commit을 했을 때, HEAD가 master를 따라가지 않는다.
HEAD와 master가 분리된 상태를 detached라고 한다.</p>
<p>어떻게 master가 C를 가르키게 할 수 있을까?
이 때 reset을 사용한다.</p>
<p>checkout은 HEAD를 움직인다.
reset은 head가 가르키는 branch를 움직인다.</p>
<h3 id="git-reset---hard-commit_id">git reset --hard commit_ID</h3>
<p>git checkout master
git reset --hard COMMIT_ID
head가 master를 가르키는 상태에서 reset을 하면 해당 commit으로 head와 master가 이동한다.</p>
<p>이때, commit id가 완전히 삭제되므로 reset은 신중해야한다.</p>
<p>reflog를 이용해 복원할 수 있긴 하다</p>
<p>git reflog
<img src="https://velog.velcdn.com/images/hyun-wle/post/99c30499-b082-4783-89b9-7e1697ed9cc7/image.png" alt="">
지금까지 이동했던 모든 기록이 남는다.</p>
<p>이것을 이용해 완전히 없어진 commit으로 이동할 수 있다.
commit id를 이용해도 되지만 HEAD@(4)와 같이 헤드 번호로 이동할 수도 있다.</p>
<p>immutability:불변성
이전에 작업했던 모든 기록이 남아있다. 수정할 떄는 기존 데이터를 복제한 후 수정한다.</p>
<p>HEAD: working directory가 어떤 버전과 같은가.
master: 해당 branch에서 가장 마지막으로 작업한 commit
checkout: HEAD를 움직인다.
reset: attached state(HEAD-&gt;master) 인 경우 branch가 움직인다 (master 이동)
dettached인 경우 checkout과 동일(head만 이동)</p>
<p>master는 branch의 이름이다.
git branch를 이용해 branch를 생성할 수 있다.</p>
<h3 id="git-tag">git tag</h3>
<p>특정 commit에 tag를 추가할 수 있다. 이 태그로 checkout하면 커밋 id를 몰라도 해당 커밋으로 이동할 수 있다.
또는 reset을 할수도 있다.</p>
<p>git reset --hard TAG
git checkout TAG</p>
<p>git push --set-upstream origin master
로컬 저장소를 원격저장소의 어느 곳에 push할 지 정할 수 있다.
짧게 git push -u라고 할 수도 있다.</p>
<p>git branch -D BRANCH_NAME
해당 branch를 삭제할 수 있다.</p>
<p>origin master와
local의 master는 완전히 다른 저장소.</p>
<p>git pull을 하면 자동으로 git fetch와 git merge를 해준다.
git fetch
git merge origin/master: 현재 HEAD와 origin/master를 병합한다.</p>
<h3 id="revert">revert</h3>
<h2 id="conflict">conflict</h2>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/7a6389d4-a0fe-43dc-a294-90d40483814b/image.png" alt="">
<img src="https://velog.velcdn.com/images/hyun-wle/post/d813a5f7-bf6f-4d5e-be1a-ac442882e6f5/image.png" alt="">
<img src="https://velog.velcdn.com/images/hyun-wle/post/8fa26b17-2a03-4309-aff2-2ec50e4d06ad/image.png" alt=""></p>
<p>나의 작업은 HEAD, 원격 저장소는 origin/master로 표시되고있다.</p>
<p><a href="https://github.com/egoingsb/offline/wiki/git">https://github.com/egoingsb/offline/wiki/git</a> 설치.</p>
<p>충돌이 났을 때 어떤 change를 accept할 지 정할 수 있다.
accept 후 commit 하면 병합이 완료된다.</p>
<p>충돌이 적을경우 vscode에서 바로 수정이 가능하지만</p>
<p>많을 경우 git mergetool을 이용해 작업한다.</p>
<p>이 때 .orig 파일이 생성되는데, 이는 백업파일이므로 삭제해도 된다.</p>
<h2 id="rebase">rebase</h2>
<p>rebase와 merge는 복잡도가 같다.</p>
<p>rebase를 자주해주면 쉽다.</p>
<p>git commit을 안하고 amend하면 commit msg만 바꿀 수 있다.
commit 후 amend하면 커밋 내용도 바꿀 수 있다.</p>
<p>rebase 할 때는 merge를 하면 안된다.
따라서 pull도 하면 안된다.</p>
<p>rebase란?
merge없이 모든 작업이 순서대로 작업된 것처럼 보이게 하는 것.
부모 commit을 변경하는 방식으로 작동.</p>
<p>회사마다 rebase로 할지, merge로 할지 규칙이 있다.</p>
<p>merge든 rebase든 병합된 결과는 항상 같다.</p>
<p>git rebase origin/master: local master가 origin master 다음 작업으로 인식된다.</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/1b81654c-4cff-4f96-84c7-a53657d82e04/image.png" alt="">
일반적인 분기</p>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/990fa7e5-8608-482a-a4a1-aa9365bfaa59/image.png" alt="">
rebase를 이용해 하나로 통합</p>
<p>git rebase abort로 rebase를 취소하거나 
git rebase continue로 재개할 수도 있다.</p>
<p>git push --force: 강제로 push</p>
<h2 id="revert-1">revert</h2>
<p>revert를 하면 해당 커밋에 변경되었던 내용만 취소할 수 있다.</p>
<p>v1
v2
v3
v4 의 커밋이 있고
revert v1을 하면
v2 v3 v4의 변경사항은 유지하고
v1의 변경사항만 취소된다.</p>
<p>단, v1에서 수정했던 사항을 v2,v3,v4에서 또 수정했다면 conflict 발생</p>
<h2 id="pull-request">pull request</h2>
<p><img src="https://velog.velcdn.com/images/hyun-wle/post/ad371eca-a290-4d5b-834f-c0391a037cc3/image.png" alt=""></p>
<p>feature/login에서 작업한 내용을 master에 병합하겠다라는 뜻</p>
<p>merge pull request: 원격 저장소에서 merge가 일어난다.</p>
<p>충돌 가능성이 있는 경우  pull request 페이지에서 충돌 여부를 알려준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[pandas[2]]]></title>
            <link>https://velog.io/@hyun-wle/pandas2</link>
            <guid>https://velog.io/@hyun-wle/pandas2</guid>
            <pubDate>Mon, 28 Mar 2022 03:53:05 GMT</pubDate>
            <description><![CDATA[<h1 id="selection-and-drop">Selection and drop</h1>
<h2 id="selection">selection</h2>
<p>데이터를 가져오는 것</p>
<pre><code class="language-python">df[&#39;ten&#39;]</code></pre>
<pre><code>0       2.31
1       7.07
2       7.07
3       2.18
4       2.18
       ...  </code></pre><p>column을 list 형태로 주면 1개 이상의 특정 column을 선택할 수도 있다.</p>
<pre><code class="language-python">df[[&quot;six&quot;, &quot;nine&quot;, &#39;seven&#39;]]</code></pre>
<pre><code>    six    nine    seven
0    18.0    0.00632    24.0
1    0.0    0.02731    21.6
2    0.0    0.02729    34.7
3    0.0    0.03237    33.4
4    0.0    0.06905    36.2
...    ...    ...    ..</code></pre><pre><code>df[[&quot;six&quot;]]</code></pre><pre><code>    six
0    18.0
1    0.0
2    0.0
3    0.0
4    0.0
...    ...</code></pre><p>2차원 배열을 넣어주면 data frame으로, 1차원 배열을 넣으면 series로 출력된다.</p>
<pre><code>df[0:4]</code></pre><pre><code>    nine    six    ten    twelve    eleven    eight    five    ZN    four    CRIM    INDUS    three    thirteen    seven
0    0.00632    18.0    2.31    0    0.538    6.575    65.2    4.0900    1    296.0    15.3    396.90    4.98    24.0
1    0.02731    0.0    7.07    0    0.469    6.421    78.9    4.9671    2    242.0    17.8    396.90    9.14    21.6
2    0.02729    0.0    7.07    0    0.469    7.185    61.1    4.9671    2    242.0    17.8    392.83    4.03    34.7
3    0.03237    0.0    2.18    0    0.458    6.998    45.8    6.0622    3    222.0    18.7    394.63    2.94    33.4</code></pre><p>숫자를 넣어주면 row index에 해당하는 값만 불러온다.</p>
<pre><code>df[0:4][[&quot;nine&quot;, &#39;six&#39;]]</code></pre><pre><code>    nine    six
0    0.00632    18.0
1    0.02731    0.0
2    0.02729    0.0
3    0.03237    0.0</code></pre><p>row index와 column이름을 같이 사용하면 이렇게 불러올 수도 있다.</p>
<h2 id="boolean-selection">boolean selection</h2>
<pre><code class="language-python">df[df[&#39;six&#39;] &gt;0]</code></pre>
<pre><code>    nine    six    ten    twelve    eleven    eight    five    ZN    four    CRIM    INDUS    three    thirteen    seven
0    0.00632    18.0    2.31    0    0.538    6.575    65.2    4.0900    1    296.0    15.3    396.90    4.98    24.0
6    0.08829    12.5    7.87    0    0.524    6.012    66.6    5.5605    5    311.0    15.2    395.60    12.43    22.9
7    0.14455    12.5    7.87    0    0.524    6.172    96.1    5.9505    5    311.0    15.2    396.90    19.15    27.1
8    0.21124    12.5    7.87    0    0.524    5.631    100.0    6.0821    5    311.0    15.2    386.63    29.93    16.5
9    0.17004    12.5    7.87    0    0.524    6.004    85.9    6.5921    5    311.0    15.2    386.71    17.10    18.9</code></pre><p>True인 index만 selection할 수도 있다.</p>
<pre><code>s_data[list(range(0, 10, 3))]

0    0.00632
3    0.03237
6    0.08829
9    0.17004
Name: nine, dtype: float64</code></pre><p>list 형태도 가능</p>
<h2 id="iloc-loc">iloc, loc</h2>
<p><img src="https://images.velog.io/images/hyun-wle/post/6e7610b6-0376-4568-87f6-fd9cfc0faed0/image.png" alt=""></p>
<h2 id="indexing">indexing</h2>
<pre><code>df3.index = list(range(5, 8, 1))

nine    six    ten    twelve    eleven    eight    five    ZN    four    CRIM    INDUS    three    thirteen    seven
5    0.00632    18.0    2.31    0    0.538    6.575    65.2    4.0900    1    296.0    15.3    396.90    4.98    24.0
6    0.02731    0.0    7.07    0    0.469    6.421    78.9    4.9671    2    242.0    17.8    396.90    9.14    21.6
7    0.02729    0.0    7.07    0    0.469    7.185    61.1    4.9671    2    242.0    17.8    392.83    4.03    34.7</code></pre><p>이렇게 인덱싱을 바꿀 수도 있다.</p>
<pre><code>df_r = df3.reset_index()
df_r

    index    nine    six    ten    twelve    eleven    eight    five    ZN    four    CRIM    INDUS    three    thirteen    seven
0    5    0.00632    18.0    2.31    0    0.538    6.575    65.2    4.0900    1    296.0    15.3    396.90    4.98    24.0
1    6    0.02731    0.0    7.07    0    0.469    6.421    78.9    4.9671    2    242.0    17.8    396.90    9.14    21.6
2    7    0.02729    0.0    7.07    0    0.469    7.185    61.1    4.9671    2    242.0    17.8    392.83    4.03    34.7</code></pre><p>reset index를 하면 index가 추가로 생성된다.</p>
<ul>
<li><code>drop=True</code>로 하면 기존 index는 사라진다</li>
<li><code>inplace=True</code>를 하면 실제로 df의 값이 바뀐다(할당 필요 없음)</li>
</ul>
<h2 id="drop">Drop</h2>
<pre><code>df.drop(1)</code></pre><p>1번 index가 삭제된다.
axis를 넣어 column이나 row를 선택하여 삭제할 수 있다.</p>
<pre><code>small_df.drop(&#39;nine&#39;, axis=1)

    six    ten
0    18.0    2.31
1    0.0    7.07
2    0.0    7.07
3    0.0    2.18</code></pre><p>마찬가지로 implace=True를 하면 자기 자신에서 삭제할 수 있다.</p>
<h1 id="dataframe-operations">dataframe operations</h1>
<pre><code>s1 = Series(data=range(1,5), index=list(&quot;abcd&quot;))
s2 = Series(data=range(5,11), index=list(&quot;bcdefg&quot;))

s1 + s2

a     NaN
b     7.0
c     9.0
d    11.0
e     NaN
f     NaN
g     NaN
dtype: float64</code></pre><p>index가 겹치는경우 연산수행, 없으면 NaN</p>
<p>dataframe도 마찬가지이다.</p>
<pre><code>df1 = pd.DataFrame(data = np.arange(9).reshape(3, 3), columns=list(&#39;abc&#39;))

    a    b    c
0    0    1    2
1    3    4    5
2    6    7    8

df2 = pd.DataFrame(data=np.arange(16).reshape(4,4), columns=list(&#39;abcd&#39;))

a    b    c    d
0    0    1    2    3
1    4    5    6    7
2    8    9    10    11
3    12    13    14    15

df1 + df2

    a    b    c    d
0    0.0    2.0    4.0    NaN
1    7.0    9.0    11.0    NaN
2    14.0    16.0    18.0    NaN
3    NaN    NaN    NaN    NaN
</code></pre><p><code>df1.add(df2, fill_value=0)</code>를 쓰면 자동으로 NaN대신 0을 채워준다.</p>
<h2 id="series--dataframe">series + dataframe</h2>
<pre><code>df1.add(s1, axis=0)
    a    b    c
0    0    1    2
1    4    5    6
2    8    9    10</code></pre><p>axis를 정해주면 broadcasting되어 실행된다.</p>
<h1 id="lambda--map">lambda &amp; map</h1>
<h2 id="lambda">lambda</h2>
<pre><code>f = lambda x : x**2
f(df1)

a    b    c
0    0    1    4
1    9    16    25
2    36    49    64</code></pre><h2 id="map">map</h2>
<p>변환하는 함수</p>
<pre><code>list(map(lambda x: x+5, df))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]</code></pre><pre><code>z = {1:&#39;a&#39;, 2:&#39;b&#39;, 3:&#39;c&#39;}
s1.map(z)

0    NaN
1      a
2      b
dtype: object</code></pre><pre><code>def f (x):
    if x &gt;0:
        return 1
    else:
        return 0

df.iloc[:][1].map(f)  
0      1
1      0
2      0
3      0
4      0
      ..</code></pre><p><code>df[1].unique()</code> 실행시 중복되는 값을 제거하고 한 번씩만 보여준다.</p>
<h2 id="apply">apply</h2>
<ul>
<li>map과 달리 Series 전체(column)에 대한 함수를 적용</li>
<li>입력 값이 시리즈 데이터로 입력받아 handling가능</li>
</ul>
<pre><code>f = lambda x : x.max() - x.min()
df.apply(f)

0      88.96988
1     100.00000
2      27.28000
3       1.00000
4       0.48600
5       5.21900
6      97.10000
7      10.99690
8      23.00000
9     524.00000
10      9.40000
11    396.58000
12     36.24000
13     45.00000
dtype: float64

df.apply(np.mean)

0       3.613524
1      11.363636
2      11.136779
3       0.069170
4       0.554695
5       6.284634
6      68.574901
7       3.795043
8       9.549407
9     408.237154
10     18.455534
11    356.674032
12     12.653063
13     22.532806
dtype: float64</code></pre><h1 id="pandas-built-in-functions">pandas built-in functions</h1>
<ul>
<li>describe: numeric type 데이터의 요약 정보를 보여줌</li>
<li>unique: 시리즈 데이터의 유일한 값을 리스트로 반환함</li>
<li>sum: axis를 설정할 수 있음</li>
<li>isnull</li>
<li>sort_values</li>
<li>corr, cov, corrwith : 상관관계</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[File Handling]]></title>
            <link>https://velog.io/@hyun-wle/File-Handling</link>
            <guid>https://velog.io/@hyun-wle/File-Handling</guid>
            <pubDate>Mon, 14 Mar 2022 05:22:33 GMT</pubDate>
            <description><![CDATA[<h1 id="file-handling">File Handling</h1>
<blockquote>
<p>File System: OS에서 파일을 저장하는 트리구조 저장체계</p>
</blockquote>
<h2 id="텍스트-파일-읽기">텍스트 파일 읽기</h2>
<h3 id="파일-통으로-읽기">파일 통으로 읽기</h3>
<pre><code class="language-python">f = opne(&quot;file_name.txt&quot;, &quot;r&quot;)
contents = f.read()
print(contents)
f.close()</code></pre>
<h3 id="라인별로-읽기-1">라인별로 읽기 1</h3>
<pre><code class="language-python">with open(&quot;untitled.txt&quot;,&#39;r&#39;, encoding=&#39;UTF8&#39;) as f:
    contents = f.read()
print(contents)
print(&quot;----&quot;)
print(contents.split(&quot;\n&quot;)[1])
</code></pre>
<h3 id="라인별로-읽기-2">라인별로 읽기 2</h3>
<pre><code class="language-python">with open(&quot;untitled.txt&quot;,&#39;r&#39;, encoding=&#39;UTF8&#39;) as f:
    content_list = f.readlines()
    print(content_list[1])
</code></pre>
<blockquote>
<p>with를 이용하면 인덴트 영역 안에서만 사용가능하다. f.close 없어도 된다.</p>
</blockquote>
<h3 id="1번에-1줄만-읽기">1번에 1줄만 읽기</h3>
<pre><code class="language-python">with open(&quot;untitled.txt&quot;,&#39;r&#39;, encoding=&#39;UTF8&#39;) as f:
    while True:
        line = f.readline()
        if not line:
            break
        print(line)</code></pre>
<h2 id="파일-쓰기">파일 쓰기</h2>
<h3 id="write-모드로-쓰기">write 모드로 쓰기</h3>
<pre><code class="language-python">f = open(&quot;write.txt&quot;, &#39;w&#39;, encoding=&#39;utf8&#39;)
for i in range(1, 11):
    data = &quot;{0} 번째 줄입니다.\n&quot;.format(i)
    f.write(data)
f.close()</code></pre>
<h3 id="append-모드로-쓰기">append 모드로 쓰기</h3>
<pre><code class="language-python">f = open(&quot;write.txt&quot;, &#39;a&#39;, encoding=&#39;utf8&#39;)
for i in range(11, 21):
    data = &quot;{0} 번째 줄입니다.\n&quot;.format(i)
    f.write(data)
f.close()</code></pre>
<p><img src="https://images.velog.io/images/hyun-wle/post/b74f3c25-270e-4a60-8093-fdef34e75b4f/image.png" alt=""></p>
<h2 id="directory-다루기">directory 다루기</h2>
<h3 id="디렉토리-생성">디렉토리 생성</h3>
<pre><code class="language-python">import os
os.mkdir(&quot;log&quot;)</code></pre>
<p>&quot;log&quot; 폴더가 생성된다.</p>
<h3 id="이미-존재하는-디렉토리-예외처리">이미 존재하는 디렉토리 예외처리</h3>
<pre><code class="language-python">try:
    os.mkdir(&quot;log&quot;)
except FileExistsError as e:
    print(&quot;file already exists&quot;)</code></pre>
<h3 id="파일-디렉토리-존재-여부">파일, 디렉토리 존재 여부</h3>
<pre><code class="language-python">os.path.exists(&quot;log&quot;)
os.path.isfile(&quot;untitled.txt&quot;)</code></pre>
<h3 id="shutil쉘-유틸">shutil(쉘 유틸)</h3>
<p>파일을 이동시키거나 복사할 수 있다.</p>
<pre><code class="language-python">import shutil

source = &quot;untitled.txt&quot;
dest = os.path.join(&quot;log&quot;)

shutil.copy(source, dest)</code></pre>
<p><code>os.path.join</code>을 이용하면 현재 경로에 경로 추가가 쉽다. 맥과 윈도우는 sep이 다르기때문.</p>
<p>요즘엔 pathlib을 이용해 path를 객체로 다룸</p>
<pre><code class="language-python">import pathlib
cwd = pathlib.Path.cwd()
list(cwd.parents)</code></pre>
<pre><code>[WindowsPath(&#39;C:/Users/user/python&#39;),
 WindowsPath(&#39;C:/Users/user&#39;),
 WindowsPath(&#39;C:/Users&#39;),
 WindowsPath(&#39;C:/&#39;)]</code></pre><h3 id="pickle">pickle</h3>
<p>파이썬의 객체는 메모리에 있어야한다.</p>
<ul>
<li>파이썬의 객체를 영속화하는 built-in 객체</li>
<li>데이터, object등 실행중 정보를 저장 -&gt; 불러와서 사용</li>
<li>저장해야하는 정보, 계산결과(모델)등 활용이 많음</li>
</ul>
<pre><code class="language-python">import pickle

f = open(&quot;list.pickle&quot;, &quot;wb&quot;)
test = [1, 2, 3, 4, 5]
pickle.dump(test, f)
f.close()
del test # test 객체를 list.pickle에 저장한 후 삭제한다.

f = open(&quot;list.pickle&quot;, &quot;rb&quot;) #list.pickle로부터 로드
test_pickle = pickle.load(f)
print(test_pickle)</code></pre>
<p>다른 객체들도 pickle을 이용해 영속화 가능</p>
<pre><code class="language-python">class Hello:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def bye(self):
        print(&#39;goodbye&#39;)

f = open(&quot;list.pickle&quot;, &#39;wb&#39;)
hello = Hello(10, 20)
pickle.dump(hello, f)
del hello
f.close()</code></pre>
<p>피클에 저장 후 로드</p>
<pre><code class="language-python">f = open(&quot;list.pickle&quot;, &#39;rb&#39;)
hello2 = pickle.load(f)
hello2.bye()
hello2.a</code></pre>
<p>결과</p>
<pre><code>goodbye
10</code></pre><h2 id="logging">Logging</h2>
<blockquote>
<p>로그 남기기
프로그램이 실행되는 동안 일어나는 정보를 기록 남기기
유저의 접근, Exception, 특정 함수의 사용 등
DB, 콘솔 출력
로그 분석을 통해 의미있는 결과 도출 가능</p>
</blockquote>
<pre><code class="language-python">import logging

logging.debug(&quot;틀림&quot;)
logging.info(&quot;info&quot;)
logging.warning(&quot;warn&quot;)
logging.error(&quot;error&quot;)
logging.critical(&quot;critical&quot;)</code></pre>
<p><img src="https://images.velog.io/images/hyun-wle/post/2fc6f523-d2de-498f-a357-a8bda97df8b1/image.png" alt=""></p>
<ul>
<li>프로그램 진행 상황에 따라 다른 Level의 Log 출력</li>
<li>개발시점, 운영시점마다 다른 Log가 남을수 있도록 지원함</li>
<li>Debug &gt; INFO &gt;WARNIGN &gt;ERROR&gt; CRITICAL
<img src="https://images.velog.io/images/hyun-wle/post/ebdccbce-85ae-4824-9228-c1ebfec46de7/image.png" alt=""></li>
</ul>
<h3 id="logging-level-정의">logging level 정의</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[Python Exception]]></title>
            <link>https://velog.io/@hyun-wle/Python-Exception</link>
            <guid>https://velog.io/@hyun-wle/Python-Exception</guid>
            <pubDate>Mon, 14 Mar 2022 02:39:23 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-python">try:
    예외 발생 가능 코드
except &lt;Exception Type&gt;:
    예외 발생시 대응하는 코드</code></pre>
<p>if else 문으로 처리해도 되지만
예외처리를 권장하는 경우 있음
ex)</p>
<pre><code class="language-python">for i in range(10):
    try:
        print(10/i)
    except ZeroDivisionError:
        print(&quot;Not divided by 0&quot;)</code></pre>
<p>ZeroDivisionError 는 built in error이다.</p>
<p>Exception을 잡으면 자동으로 종료되지 않고 위로 올라가 다시 수행한다. 수행한다.
IndexError, NameError, ZeroDivisionError, ValueError등이 있다.</p>
<p>Exception은 모든 에러를 잡는다.
as ...를 이용하면 ...에 에러 내용을 담을 수 있다.</p>
<pre><code class="language-python">a = range(5)
for i in range(10):
    try:
        print(a[i])
        print(v)
    except IndexError as e:
        print(e)
    except Exception as e:
        print(e)</code></pre>
<pre><code>0
name &#39;v&#39; is not defined
1
name &#39;v&#39; is not defined
2
name &#39;v&#39; is not defined
3
name &#39;v&#39; is not defined
4
name &#39;v&#39; is not defined
range object index out of range
range object index out of range
range object index out of range
range object index out of range
range object index out of range</code></pre><pre><code class="language-python">try:

except:

else:

finally:
</code></pre>
<p>이런식으로 짤 수도 있다.
문제가 있으면 except, 없으면 else, 그리고 무조건 finally를 실행</p>
<p>하지면 if문은 logic적인 문제를 다룰 때 사용하는걸 권장
except는 처리가 잘못된 경우에 사용.</p>
<h3 id="raise">raise</h3>
<pre><code class="language-python">raise &lt;Exception Type&gt; # 예외정보</code></pre>
<p>의도적으로 Exception을 일으키기 위해 사용</p>
<pre><code class="language-python">while True:
    value = &quot;012345&quot;
    for digit in value:
        if digit not in &quot;0123&quot;:
            raise ValueError(&quot;0123에 속하지 않음&quot;)
        print(&quot;정수값&quot;, int(digit))</code></pre>
<h3 id="특정-조건이-아닐-때-에러-발생시키기">특정 조건이 아닐 때 에러 발생시키기</h3>
<pre><code class="language-python">assert isinstance(a, int)</code></pre>
<p>a가 int값이 아니면 에러 발생</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[구글 크롬 방문기록 저장 경로]]></title>
            <link>https://velog.io/@hyun-wle/%EA%B5%AC%EA%B8%80-%ED%81%AC%EB%A1%AC-%EB%B0%A9%EB%AC%B8%EA%B8%B0%EB%A1%9D-%EC%A0%80%EC%9E%A5-%EA%B2%BD%EB%A1%9C</link>
            <guid>https://velog.io/@hyun-wle/%EA%B5%AC%EA%B8%80-%ED%81%AC%EB%A1%AC-%EB%B0%A9%EB%AC%B8%EA%B8%B0%EB%A1%9D-%EC%A0%80%EC%9E%A5-%EA%B2%BD%EB%A1%9C</guid>
            <pubDate>Thu, 17 Feb 2022 14:52:08 GMT</pubDate>
            <description><![CDATA[<p>C:\Users\USERNAME\AppData\Local\Google\Chrome\User Data\Default\History</p>
<p>SQLite 형식으로 저장되어있다. 
SQLite DB 뷰어를 이용하면 볼 수 있다.</p>
<p>방문기록, 횟수, 타이핑 여부, 접근 페이지, 머문 시간까지 알 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Attention Is All You Need]]></title>
            <link>https://velog.io/@hyun-wle/Attention-Is-All-You-Need</link>
            <guid>https://velog.io/@hyun-wle/Attention-Is-All-You-Need</guid>
            <pubDate>Fri, 04 Feb 2022 06:11:57 GMT</pubDate>
            <description><![CDATA[<h1 id="자연어-발전">자연어 발전</h1>
<p>RNN -&gt; LSTM -&gt; Seq2Seq -&gt; Attention -&gt; Transformer -&gt; ...</p>
<h2 id="rnn-recurrent-neural-network">RNN (Recurrent Neural Network)</h2>
<p>순환신경망. 
<img src="https://images.velog.io/images/hyun-wle/post/3f1536b4-652f-4741-9958-bd39403c2843/image.png" alt="">
결과값을 출력층 뿐만 아니라 다음 은닉층으로도 보낸다.
<img src="https://images.velog.io/images/hyun-wle/post/3dd5380e-de13-44ca-9bb1-d68abde67dd7/image.png" alt=""></p>
<h2 id="lstm-long-short-term-memory-models">LSTM (Long Short-Term Memory models)</h2>
<p>순환 신경망(RNN) 기법의 하나로 셀, 입력 게이트, 출력 게이트, 망각 게이트를 이용해 기존 순환 신경망(RNN)의 문제인 기울기 소멸 문제(vanishing gradient problem)를 방지하도록 개발되었다.
<img src="https://images.velog.io/images/hyun-wle/post/0c2be443-0140-408b-84d1-165c2b92778a/image.png" alt=""> 
RNN에서는, t값이 커질수록 x1의 정보량은 손실된다.
<img src="https://images.velog.io/images/hyun-wle/post/07859efd-b700-4e9a-94ec-1033477d3147/image.png" alt="">
LSTM에서는 은닉층에 입력, 망각, 출력 게이트를 추가함. </p>
<h2 id="seq2seq">Seq2Seq</h2>
<p>입력 문장을 하나의 context vector로 압축하는 Encoder, 
번역된 단어를 출력하는 Decoder로 구성된다.</p>
<h3 id="seq2seq--attention">Seq2Seq + Attention</h3>
<h2 id="transformer">Transformer</h2>
<p>CNN, RNN 필요없음
    Positional Encoding을 이용해 단어의 순서 정보 전달
       인코더와 디코더만으로 구성됨
    Attention 레이어를 중첩하여 만듦</p>
<blockquote>
<p>Embedding: 자연어를 기계가 이해할 수 있는 vector로 표현하는 것</p>
</blockquote>
<p>RNN을 사용하지 않기 때문에 임베딩에 위치정보 포함</p>
<h3 id="attention">Attention</h3>
<p><a href="https://wikidocs.net/22893">https://wikidocs.net/22893</a>
한 단어가 다른 단어에 주는 영향력을 attention score로 표현
문맥에 대한 정보를 학습.
어탠션을 위한 3가지 요소 쿼리, 키, 값
물어보는 주체: query
객체: key,
I am a Teacher 에서 I가 다른 am, a, teacher에 대한 영향력이 궁금하다면 I가 쿼리, am a teacher가 키가 된다.
<img src="https://images.velog.io/images/hyun-wle/post/38cb648e-0866-46a8-84a9-692595ee99ab/image.png" alt=""></p>
<p>각 Attention들은 h들로 구분된다.
<img src="https://images.velog.io/images/hyun-wle/post/963095de-ba1e-43ea-8803-067f965cddf1/image.png" alt=""></p>
<h4 id="3-attention-layers">3 Attention Layers</h4>
<p><img src="https://images.velog.io/images/hyun-wle/post/8d6c3a5c-01b2-4990-8181-a98a686714ca/image.png" alt=""></p>
<h4 id="self-attention">self attention</h4>
<p>query와 key를 모두 자기 자신으로 설정.
한 문장 안에서 단어들간의 관계를 파악할 수 있다.</p>
<blockquote>
<p><strong>Today</strong> is happy because <strong>it</strong> is sunny.</p>
</blockquote>
<h4 id="positional-encoding">Positional Encoding</h4>
<h4 id="residual-connection-잔여학습">Residual connection (잔여학습)</h4>
<p>이전 학습 결과와 원본 데이터를 모두 입력받는 것</p>
<p><img src="https://images.velog.io/images/hyun-wle/post/acb46bcb-60f5-4d94-bd50-67ef497ee9cf/image.png" alt="">
인코더의 출력값이 모든 디코더의 입력값이 된다.</p>
<h3 id="한국어-리뷰">한국어 리뷰</h3>
<p><a href="https://idontknowmathematics.tistory.com/11">https://idontknowmathematics.tistory.com/11</a></p>
<h3 id="참고문헌-해설들">참고문헌 해설들</h3>
<h4 id="1jimmy-lei-ba-jamie-ryan-kiros-and-geoffrey-e-hinton-layer-normalization-arxiv-preprint-arxiv160706450-2016">[1]Jimmy Lei Ba, Jamie Ryan Kiros, and Geoffrey E Hinton. Layer normalization. arXiv preprint arXiv:1607.06450, 2016.</h4>
<p><a href="https://an-seunghwan.github.io/deep-learning/layernorm/">https://an-seunghwan.github.io/deep-learning/layernorm/</a>
Layer normalization</p>
<h4 id="2dzmitry-bahdanau-kyunghyun-cho-and-yoshua-bengio-neural-machine-translation-by-jointly-learning-to-align-and-translate-corr-abs14090473-2014">[2]Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. Neural machine translation by jointly learning to align and translate. CoRR, abs/1409.0473, 2014.</h4>
<p><a href="https://misconstructed.tistory.com/49">https://misconstructed.tistory.com/49</a></p>
<h4 id="12-sepp-hochreiter-and-jürgen-schmidhuber-long-short-term-memory-neural-computation">[12] Sepp Hochreiter and Jürgen Schmidhuber. Long short-term memory. Neural computation</h4>
<p><a href="https://cryptosalamander.tistory.com/175">https://cryptosalamander.tistory.com/175</a>
LSTM</p>
<h4 id="7junyoung-chung-çaglar-gülçehre-kyunghyun-cho-and-yoshua-bengio-empirical-evaluation-of-gated-recurrent-neural-networks-on-sequence-modeling-corr-abs14123555-2014">[7]Junyoung Chung, Çaglar Gülçehre, Kyunghyun Cho, and Yoshua Bengio. Empirical evaluation of gated recurrent neural networks on sequence modeling. CoRR, abs/1412.3555, 2014.</h4>
<p><a href="https://coshin.tistory.com/45">https://coshin.tistory.com/45</a>
Gating Mechanism</p>
<h4 id="18-oleksii-kuchaiev-and-boris-ginsburg-factorization-tricks-for-lstm-networks-arxiv-preprint-arxiv170310722-2017">[18] Oleksii Kuchaiev and Boris Ginsburg. Factorization tricks for LSTM networks. arXiv preprint arXiv:1703.10722, 2017.</h4>
<p>factorization trick. </p>
<h4 id="26-noam-shazeer-azalia-mirhoseini-krzysztof-maziarz-andy-davis-quoc-le-geoffrey-hinton-and-jeff-dean-outrageously-large-neural-networks-the-sparsely-gated-mixture-of-experts-layer-arxiv-preprint-arxiv170106538-2017">[26] Noam Shazeer, Azalia Mirhoseini, Krzysztof Maziarz, Andy Davis, Quoc Le, Geoffrey Hinton, and Jeff Dean. Outrageously large neural networks: The sparsely-gated mixture-of-experts layer. arXiv preprint arXiv:1701.06538, 2017.</h4>
<p>정보 거의 없음</p>
<h4 id="20-samy-bengio-łukasz-kaiser-can-active-memory-replace-attention-in-advances-in-neural-information-processing-systems-nips-2016">[20] Samy Bengio Łukasz Kaiser. Can active memory replace attention? In Advances in Neural Information Processing Systems, (NIPS), 2016.</h4>
<p><a href="https://blog.lunit.io/2017/03/28/neural-gpus-and-extended-neural-gpus/">https://blog.lunit.io/2017/03/28/neural-gpus-and-extended-neural-gpus/</a>
Extended Neural GPU</p>
<h4 id="15-nal-kalchbrenner-lasse-espeholt-karen-simonyan-aaron-van-den-oord-alex-graves-and-koray-kavukcuoglu-neural-machine-translation-in-linear-time-arxiv-preprint-arxiv161010099v2-2017">[15] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, Aaron van den Oord, Alex Graves, and Koray Kavukcuoglu. Neural machine translation in linear time. arXiv preprint arXiv:1610.10099v2, 2017.</h4>
<p>ByteNet</p>
<h4 id="8-jonas-gehring-michael-auli-david-grangier-denis-yarats-and-yann-n-dauphin-convolutional-sequence-to-sequence-learning-arxiv-preprint-arxiv170503122v2-2017">[8] Jonas Gehring, Michael Auli, David Grangier, Denis Yarats, and Yann N. Dauphin. Convolutional sequence to sequence learning. arXiv preprint arXiv:1705.03122v2, 2017.</h4>
<p>Conv2S</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 코드 실시간]]></title>
            <link>https://velog.io/@hyun-wle/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%BD%94%EB%93%9C-%EC%8B%A4%EC%8B%9C%EA%B0%84</link>
            <guid>https://velog.io/@hyun-wle/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%BD%94%EB%93%9C-%EC%8B%A4%EC%8B%9C%EA%B0%84</guid>
            <pubDate>Sun, 30 Jan 2022 12:01:43 GMT</pubDate>
            <description><![CDATA[<p><a href="https://codepen.io/">https://codepen.io/</a></p>
<p>이걸 emmet이라 한다.</p>
<p>bc:orange 
div&gt;ul&gt;li*4{$}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[VScode]]></title>
            <link>https://velog.io/@hyun-wle/VScode</link>
            <guid>https://velog.io/@hyun-wle/VScode</guid>
            <pubDate>Sun, 30 Jan 2022 06:25:05 GMT</pubDate>
            <description><![CDATA[<p>ctrl + H : 바꾸기</p>
<p>alt shift + 방향키: 복붙</p>
<p>alt + 방향키: 줄 옮기기</p>
<p>코드 선택 후 ctrl + k, ctrl + f: 코드 자동 정렬</p>
<p>ctrl shift p : 모든 설정</p>
<p>ctrl + H : 바꾸기</p>
<p>ctrl w = 탭 닫기</p>
<p>ctrl + \ = 탭 분할</p>
<p>ctrl + / : 주석</p>
<p>ctrl + P = 파일이나 기호 탐색</p>
<p>ctrl + B = 사이드바 열고 닫기</p>
<h1 id="vscode-확장기능">vscode 확장기능</h1>
<ul>
<li>auto rename
  자동으로 html 태그의 앞 뒤를 동시에 바꿔준다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Pythonic Code]]></title>
            <link>https://velog.io/@hyun-wle/Python-Pythonic-Code</link>
            <guid>https://velog.io/@hyun-wle/Python-Pythonic-Code</guid>
            <pubDate>Wed, 19 Jan 2022 07:06:27 GMT</pubDate>
            <description><![CDATA[<h2 id="일반-코드와의-차이">일반 코드와의 차이</h2>
<pre><code class="language-python">numbers = [&#39;one&#39;, &#39;two&#39; &#39;three&#39;]
str1 = &#39;&#39;

for number in numbers:
    str1 += number</code></pre>
<p>다음은 파이썬스러운 코드이다.</p>
<pre><code class="language-python">str2 = &#39;&#39;.join(numbers)</code></pre>
<h3 id="split">split()</h3>
<p>string  값을 기준값으로 나눠서 List 형태로 변환</p>
<pre><code class="language-python">items = &quot;zero one two three&quot;
item = items.splice() #[&quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;]</code></pre>
<h3 id="list-comprehension">list comprehension</h3>
<h3 id="general-code">general code</h3>
<pre><code class="language-python">result1 = []
for i in range(10):
    result1.append(i)</code></pre>
<h3 id="pythonic-code">pythonic code</h3>
<pre><code class="language-python">result2 = [i for i in range(10)]</code></pre>
<h4 id="nested-loop">nested loop</h4>
<pre><code class="language-python">word1 = &quot;Hello&quot;
word2 = &quot;World&quot;
result = [i+j for i in word1 for j in word2]
#[&#39;HW&#39;, &#39;Ho&#39;, &#39;Hr&#39;, ..., &#39;ol&#39;, &#39;od&#39;]</code></pre>
<h4 id="filter">filter</h4>
<pre><code class="language-python">result2 = [i+j for i in word1 for j in word2 if not(i==j)]

result3 = [i+j for i in word1 for j in word2 if not(i==j) else &quot;goood&quot;]</code></pre>
<p>조건문을 넣을 수도 있다.</p>
<h4 id="2-dimentional-list">2 dimentional list</h4>
<pre><code class="language-python">words = &#39;Hello world to me&#39;.split()
stuff = [[w.upper(), w.lower(), len(w)] for w in words]
# [[&#39;HELLO&#39;, &#39;hello&#39;, 5], ..., [&#39;ME&#39;, &#39;me&#39;, 2]]</code></pre>
<h4 id="2d-vs-1d">2d vs 1d</h4>
<pre><code class="language-python">case_1 = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]
case_2 = [&#39;c&#39;, &#39;e&#39;, &#39;a&#39;]
result = [i+j for i in case_1 for j in case_2]
# [ac ae aa bc... ce ca]
result = [[i+j for i in case_1] for j in case_2]
# [[ac bc cc] [ae be ce] ...]</code></pre>
<h2 id="enumerate--zip">enumerate &amp; zip</h2>
<h3 id="enumerate">enumerate</h3>
<ul>
<li>list의 element를 추출할 때 번호를 붙혀서 추출</li>
<li>index와 element를 동시에 알 수 있다.<pre><code class="language-python">for i, v in enumerate([&#39;tic&#39;, &#39;tac&#39; &#39;toe&#39;]):
  print(i, v)
# 0 tic
# 1 tac
# 2 toe</code></pre>
<h3 id="zip">zip</h3>
여러개의 list를 하나의 list로 묶어준다
` list(zip(list1, list2)) # [(&#39;a&#39;, &#39;가&#39;), (&#39;b&#39;, &#39;나&#39;)] </li>
</ul>
<h2 id="lambda">lambda</h2>
<ul>
<li>함수 이름 없이 함수처럼 쓸 수 있는 익명 함수</li>
<li>수학의 람다 대수에서 유래
<code>(lambda x, y : x + y)(10, 50) # 60</code>
<code>up_low = lambda x : x.lower() + x.upper()</code></li>
<li>python3 부터는 권장하지 않음 (PEP8)<ul>
<li>테스트의 어려움, 어려운 문법, 문서화 docstring 미비, ...</li>
<li>그래도 많이 쓰긴 함<h3 id="map-function">map function</h3>
</li>
</ul>
</li>
<li>함수의 결과 값을 한번에 list화<pre><code class="language-python">ex = [1, 2, 3, 4, 5]
f = lambda x, y: x + y
print(list(map(f, ex, ex))
# [2, 4, 6, 8, 10]</code></pre>
이럴 경우 알아보기 힘들다. 따라서<pre><code class="language-python">result = [f(value) for value in ex]</code></pre>
이런 식으로 적는 것이 편하다.</li>
</ul>
<p>-lambda 대신 일반 함수도 사용 가능하다.</p>
<h3 id="reduce-function">reduce function</h3>
<ul>
<li>자주 쓰진 않지만 대용량의 데이터를 활용할 때 사용한다</li>
</ul>
<pre><code class="language-python">from functools import reduce
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]</code></pre>
<p><strong>lambda, map, reduce는 직관성이 떨어지기에 사용을 권장하지는 않는다.</strong></p>
<h1 id="iterable-object">iterable object</h1>
<ul>
<li>sequence형 데이터(리스트, 튜플 등등)은 모두 iterable obj로서 <strong>next</strong>, <strong>iter</strong> 기능이 있다.<h2 id="generator">generator</h2>
</li>
<li>element가 사용되는 시점에 값을 메모리에 반환</li>
<li>iterable obj를 특수한 형태로 사용해주는 함수</li>
<li>큰 데이터를 처리할 때 사용</li>
<li>주로 파일 데이터 처리시 사용</li>
<li>loop이 중단될 가능성이 있을 때</li>
<li>대기하다가 필요할 때만 값을 반환하기 때문에 메모리 절약 가능 <pre><code class="language-python">range(1000) # [1, 2, 3, 4, ..., 999] 깂이 한번에 반환됨</code></pre>
<pre><code class="language-python">def generator_list(value):
for i in range(value):
    yield i
result = generator_list(1000) 
#아직 result는 1000개의 값이 들어있지 않음
[value for value in generator_list(1000)]
#또는
list(result) 
#이렇게 해야만 1000개의 값이 메모리에 저장됨
</code></pre>
</li>
</ul>
<pre><code>다음과 같이 괄호로 감싸 선언도 가능하다
```python
gen_ex = (n*n for n in range(500))</code></pre><h2 id="function-passing-argument">function passing argument</h2>
<blockquote>
<p>파이썬에는 parameter를 넘겨주는 여러 방법이 있다.</p>
</blockquote>
<h3 id="keyword-argument">keyword argument</h3>
<ul>
<li>함수에 입력되는 parameter의 변수명을 사용, arguments를 넘김</li>
<li>값을 순서대로 넣지 않아도 됨<pre><code class="language-python">def func1(arg1, arg2):
  print(arg1 + arg2)
</code></pre>
</li>
</ul>
<p>func1(arg2 = &quot;hello&quot;, arg1 = &quot;bye&quot;)</p>
<pre><code>
### default argument
- parameter의 기본값을 사용, 입력하지 않을 경우 기본 값 출력
```python
def func2(arg1, arg2 = &quot;hello&quot;):
    print(arg1 + arg2)

func2(bye)
func2(&quot;good&quot;, &quot;bye&quot;)</code></pre><h3 id="가변인자-variable-length">가변인자 (variable length)</h3>
<ul>
<li>prameter의 수가 정해지지 않은 경우</li>
<li>tuple 타입으로 전달됨<pre><code class="language-python">def func3(*args):
  print(list(args))
</code></pre>
</li>
</ul>
<p>func3(1, 2, 3, 4)</p>
<pre><code>
### 키워드 가변인자 (keyword variable-length)
- parameter의 이름을 따로 정하지 않고 입력하는 방법
- asterisk 두개(**)를 사용하여 함수의 parameter를 표시함
- 입력된 값은 dict type로 사용 가능
- 가변인자는 오직 한개만 기존 가변인자 다음에 사용
```python
def func4(**kwargs):
    print(kwargs)

func4(first=1, second=4, third=3)</code></pre><blockquote>
<p>normal parameter, variable, keyword length, variable length 순으로 써야한다.</p>
</blockquote>
<pre><code class="language-python">def func5(one, two=3, *args, **kwargs):
    ...
     ...

func5(1, 2, 3, 4, 5, first=1, second=3, hello=5)</code></pre>
<p><strong>한번 keyword variable을 쓰면 뒤는 모두 keyword variable이어야 한다.</strong></p>
<h3 id="asterisk">asterisk</h3>
<ul>
<li>곱하기, 제곱, 가변인자 등에 사용</li>
<li>또는 tuple, dict 등 자료형에 들어가 있는 값을 unpacking<pre><code class="language-python">def asterisk_test1(a, *args):#여기서 *은 가변인자를 위한 *
  print(args)
def asterisk_test2(a, args):
  print(args)
  print(*args)
</code></pre>
</li>
</ul>
<p>asterisk_test1(1, *(2, 3, 4, 5, 6))    # (1, 2, 3, 4, 5, 6)
asterisk_test2(1, (2, 3, 4, 5, 6))     # 1, (1, 2, 3, 4, 5, 6)
                    # (1, 2, 3, 4, 5, 6)</p>
<pre><code>### keyword unpacking
- dict형식 데이터를 keyword parameter로 변환해줌
```python
def asterisk_test3(a, b, c, d):
    print(a, b, c, d)
data = {&#39;b&#39;:1, &#39;c&#39;:2, &#39;d&#39;:3}
asterisk_test(10, **data) # (10, 1, 2, 3)

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Data Structure]]></title>
            <link>https://velog.io/@hyun-wle/Python-Data-Structure</link>
            <guid>https://velog.io/@hyun-wle/Python-Data-Structure</guid>
            <pubDate>Wed, 19 Jan 2022 03:11:02 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Data structure는 데이터를 효율적으로 저장하기 위한 구조이다.</p>
</blockquote>
<h2 id="stack--queue">Stack &amp; Queue</h2>
<h3 id="stack">Stack</h3>
<ul>
<li>나중에 넣은 데이터를 먼저 반환하도록 선계된 메모리 구조</li>
<li>Last in First Out (LIFO)</li>
<li>Data의 입력을 Push, 출력을 Pop이라고 함<pre><code class="language-python">&gt;&gt;&gt; a = [1, 2, 3]
&gt;&gt;&gt; a.append(4)
&gt;&gt;&gt; a.append(5)
&gt;&gt;&gt; a.pop()
5
&gt;&gt;&gt; a
[1, 2, 3, 4]</code></pre>
<h3 id="queue">Queue</h3>
</li>
<li>먼저 넣은 데이터를 먼저 반환하도록 설계된 메모리 구조</li>
<li>First in First Out(FIFO)<pre><code class="language-py">&gt;&gt;&gt; a = [1, 2, 3]
&gt;&gt;&gt; a.append(4)
&gt;&gt;&gt; a.append(5)
&gt;&gt;&gt; a.pop(0)
1
&gt;&gt;&gt; a.pop(0)
2</code></pre>
stack은 pop()을 이용해 데이터를 반환하지만
queue는 pop(0)를 이용해 데이터를 반환받아야함.</li>
</ul>
<h2 id="tuple--set">Tuple &amp; Set</h2>
<h3 id="tuple">Tuple</h3>
<ul>
<li>값의 변경이 불가능한 리스트</li>
<li>선언시 &quot;[]&quot;가 아닌 &quot;()&quot;를 사용</li>
<li>리스트의 연산, 인덱신, 슬라이싱 등을 동일하게 사용가능</li>
<li>변경을 하면 안되는 데이터 저장에 사용<pre><code class="language-python">t = (1) #정수로 인식
tu = (1, ) # 이렇게 작성해야한다.</code></pre>
</li>
</ul>
<h3 id="set">Set</h3>
<ul>
<li>값을 순서 없이 저장.</li>
<li>중복 불허</li>
<li>set 객체 선언을 이용하여 객체 생성<pre><code class="language-python">s1 = set([1, 2, 3, 4)
s2 = {1, 2, 3, 4} # 두가지 방법 모두 가능
s1.add(1) # 1추가
s1.remove(2) # 2 삭제
s2.updata([5, 2, 1]) # 여러개 추가
s2.discard(5) #5 삭제
s2.clear() #모든 원소 삭제</code></pre>
이외에도 set은 다양한 집합 연산을 지원한다.<pre><code class="language-python">s1.union(s2)
s1 | s2
s1.intersection(s2)
s1 &amp; s2
s1.difference(s2)
s1 - s2</code></pre>
<h2 id="dictionary">Dictionary</h2>
</li>
<li>데이터(value)를 저장할 때 구분 지을 수  있는 값(key)를 함께 저장</li>
<li>key 값을 활용하여 value값을 관리</li>
<li>dict = {key:value} 형식<pre><code class="language-python">dict = {&quot;go&quot;: &quot;가다&quot;, &quot;home&quot;: &quot;집&quot;}
dict[&quot;hello&quot;] = &quot;안녕&quot;
dict[&quot;bye&quot;] = &quot;잘가&quot;
&quot;hello&quot; in dict.keys()
&quot;집&quot; in dict.values()</code></pre>
</li>
</ul>
<h2 id="collection-module">Collection module</h2>
<ul>
<li>List, Tuple, Dict에 대한 Python Built-in 확장 자료구조(모듈)</li>
<li>편의성, 실행 효율 등을 사용자에게 제공함<h3 id="deque">Deque</h3>
</li>
<li>stack과 queue를 지원하는 모듈</li>
<li><strong>List에 비해 빠른 자료 저장</strong> 방식을 지원</li>
<li>rotate, reverse등 연결리스트의 특성을 지원함</li>
<li>기존 list형태의 함수를 모두 지원함<pre><code class="language-python">from collections import deque
</code></pre>
</li>
</ul>
<p>deque_list = deque()
deque_list.appendleft(10)
deque_list.rotate(1)
deque_list.extend([6, 3])
deque_list.extendleft([11, 33])</p>
<pre><code>jupyter notebook에서 %timeit 함수명()을 이용하면 쉽게 시간을 측정할 수 있다.

### Defaultdict
- dict type의 값에 기본 값을 지정.
```python
from collections import defaultdict

d = defaultdict(lambda : 0)
print(d[&quot;hello&quot;]) # 0

text = &quot;fdas gfjo jfods jflds fjowe fjowe fjeow feowu sfds.&quot;
word = text.split()
for word in text:
    d[[word] += 1</code></pre><p>이런 식으로 단어의 출현 빈도를 세는데 사용할 수도 있다.</p>
<h3 id="counter">Counter</h3>
<ul>
<li>Sequence type의 data element 들의 갯수를 dict 형태로 반환</li>
<li>자주 사용하진 않음<pre><code class="language-python">from collections import Counter
</code></pre>
</li>
</ul>
<p>C = Counter([&quot;B&quot;, &quot;S&quot;, &quot;S&quot;, &quot;B&quot;, &quot;S&quot;])</p>
<h1 id="b2-s3">{&quot;B&quot;:2, &quot;S&quot;:3}</h1>
<pre><code>
### namedtuple
- Tuple 형태로 data 구조체를 저장하는 방법
- 저장되는 data의 variable을 사전에 지정해서 저장함
```python
from collections import namedtuple

Point = namedtuple(&#39;Point&#39;, [&#39;x&#39;, &#39;y&#39;])
p = Point(x=11, y=22)
print(p[0] + p[1])</code></pre>]]></description>
        </item>
    </channel>
</rss>