<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>m</title>
        <link>https://velog.io/</link>
        <description>Backend Dev</description>
        <lastBuildDate>Wed, 24 Aug 2022 08:06:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>m</title>
            <url>https://velog.velcdn.com/images/mean-g/profile/ccd5361a-b202-4aae-a45b-788f4ddf098b/image.gif</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. m. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/mean-g" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Node.js] 초기세팅]]></title>
            <link>https://velog.io/@mean-g/Nodesetting</link>
            <guid>https://velog.io/@mean-g/Nodesetting</guid>
            <pubDate>Wed, 24 Aug 2022 08:06:48 GMT</pubDate>
            <description><![CDATA[<h3 id="1-프로젝트-시작-경로-작성하기">1. 프로젝트 시작 경로 작성하기</h3>
<p><code>mkdir node-test</code>로 디렉토리를 생성해 준다.
<code>cd node-test</code>로 디렉토리로 이동!</p>
<h3 id="2-packagejson--indexjs-생성하기">2. package.json &amp; index.js 생성하기</h3>
<p>안타깝게도 express generator로 생성하면 자꾸 오류가 나서 하나하나 생성해 준다..
오류가 왜 나는지 모르겠어서 어쩔 수 없다..
<code>npm init -y</code> 혹은 <code>npm init --yes</code>로 생성!
<img src="https://velog.velcdn.com/images/mean-g/post/fc779c49-d4c2-4bec-873f-c8b592d50ba5/image.png" alt=""></p>
<p>+) <code>-y</code>나 <code>--yes</code>가 package.json을 default 값으로 생성해 준다고 한다.
<img src="https://velog.velcdn.com/images/mean-g/post/a4039d45-d6b6-4688-9351-cff64bbb88d6/image.png" alt="">
그럼 이렇게! 파일이 생성되는데 중간에 main을 보면 메인 코드 파일로 index.js를 설정해둔 것을 볼 수 있다.
<code>code .</code>으로 vsc를 켜서 index.js파일을 생성해 주었다.</p>
<h3 id="3-필요한-모듈-설치하기">3. 필요한 모듈 설치하기</h3>
<p><code>npm install mysql2 express cors --save</code>와 <code>npm install -D nodemon</code>으로 mysql, express cors, nodemon을 설치한다.</p>
<h6 id="mysql2로-설치한-이유는-mysql을-설치하면-오류가-나기-때문이다">mysql2로 설치한 이유는.. mysql을 설치하면 오류가 나기 때문이다..............</h6>
<p>nodemon 앞에 <code>-D</code>를 쓰면 개발디펜던시가 추가된다.</p>
<h3 id="4-packagejson-수정하기">4. package.json 수정하기</h3>
<p>scripts에 test 라인을 추가해 줬다.
(npm start 명령어를 사용해 nodemon으로 index.js를 실행하기 위해!)</p>
<pre><code class="language-node"> &quot;scripts&quot;: {
    &quot;start&quot;: &quot;nodemon index.js&quot;,
    &quot;test&quot; : &quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;
  },</code></pre>
<h3 id="5-indexjs-수정하기">5. index.js 수정하기</h3>
<p>이제 index.js에 아무 내용도 없기 때문에 서버 구동을 위한 내용을 추가해 준다.</p>
<pre><code class="language-node">const express = require(&quot;express&quot;);
const cors    = require(&quot;cors&quot;);
const req     = require(&quot;express/lib/request&quot;);

const app     = express();

app.use(express.json());
app.use(express.urlencoded({extended:true}));
app.use(cors());

// localhost:4000/으로 get요청을 받으면 &#39;HELLO NODE&#39;를 출력
app.get(&#39;/&#39;, (req,res) =&gt; {
    res.send(&#39;HELLO NODE&#39;)
})

const port = 4000;
// 서버가 실행되면 &#39;서버켜짐&#39;을 출력
app.listen(port, () =&gt; {      
    console.log(&#39;서버켜짐&#39;);
})</code></pre>
<p>일단 여기까지 하고 <code>npm start</code>로 서버를 돌리면 서버가 돌아간다!<img src="https://velog.velcdn.com/images/mean-g/post/5d87099e-48c4-44a8-a18d-477c73956953/image.png" alt=""></p>
<h3 id="6-dotenv설치하고env-파일-생성하기">6. <code>dotenv</code>설치하고,<code>.env</code> 파일 생성하기</h3>
<p><code>npm install dotenv</code>로 dotenv를 설치해 준다.
dotenv는 환경변수를 파일에 저장할 수 있도록 해준다.</p>
<p>이제<code>.env</code> 파일을 생성하고 아래와 같은 내용을 적어준다.
<code>.env</code>파일은 환경변수를 관리하는 파일로 mysetting.py와 같은 역할의 파일인 것 같다.</p>
<pre><code>DB_DATABASE=(db이름)
DB_PASSWORD=(db비밀번호)
DB_USERNAME=root
DB_HOST=127.0.0.1
DB_PORT=3306</code></pre><p>등으로  <code>키=값</code>의 포멧으로 적어준다.</p>
<h3 id="7-config-폴더-생성">7. <code>config</code> 폴더 생성</h3>
<p><code>config</code>폴더 안에는 <code>.env</code>를 사용할 <code>mysql.js</code>파일을 생성해 주었다.</p>
<pre><code class="language-node">const dotenv = require(&quot;dotenv&quot;);
const mysql  = require(&quot;mysql2/promise&quot;);

dotenv.config();

const dbConfig = {
    host    : process.env.DB_HOST,
    user    : process.env.DB_USERNAME,
    database: process.env.DB_DATABASE,
    port    : process.env.DB_PORT,
    password: process.env.DB_PASSWORD
}

const connection = mysql.createPool(dbConfig);

module.exports = connection;</code></pre>
<p>+) <code>createPool</code>은 DB와의 연결을 미리 Pool에 저장해두고, 필요할 때 꺼내 쓰는 개념인 것 같다. <code>createConnection</code>과 <code>createPool</code> 두 가지 방법이 있는 거 같은데.. 차이점을 알아봐야 할 것 같다!</p>
<p>이제 DB와 연결이 끝났다.</p>
<h3 id="-users연결">+) <code>users</code>연결</h3>
<p>이제 <code>localhost:4000/users</code> 로 접근할 수 있게 만들어주자.</p>
<h4 id="1-indexjs-에서-url-열어주기">1. <code>index.js</code> 에서 url 열어주기</h4>
<pre><code class="language-node">const express = require(&quot;express&quot;);
const cors    = require(&quot;cors&quot;);
const req     = require(&quot;express/lib/request&quot;);

const app = express();

app.use(express.json());
app.use(express.urlencoded({extended:true}));
app.use(cors());

app.use(&#39;/users&#39;, require(&#39;./routes/userRouter&#39;))
//이전에는 localhost:4000/을 연결하면 &#39;HELLO NODE&#39;를 출력하도록 했는데 지워주고 localhost:4000/users로 접근하면 routers의 userRouter로 연결하도록 했다.

const port = 4000;

app.listen(port, () =&gt; {      
    console.log(&#39;서버켜짐&#39;);
})</code></pre>
<h4 id="2-routes폴더와-userrouter파일을-생성한다">2. <code>routes</code>폴더와 <code>userRouter</code>파일을 생성한다.</h4>
<p>1번에서 연결해 준 <code>routes</code>폴더의 <code>userRouter</code>파일이 없으니 생성해 주고 <code>userRouter</code>파일에 코드를 작성해 준다.</p>
<pre><code class="language-node">const router = require(&quot;express&quot;).Router();
const db     = require(&quot;../config/mysql&quot;);

router.get(&quot;/&quot;, async(req, res, next) =&gt; {
    try {
        const sql = 
        &#39;select * from users&#39;
        const [rows, fields] = await db.query(sql)
        return res.status(200).json({message:&quot;success&quot;, result:rows});
    } catch(e) {
        console.log(e.message);
    }
});

module.exports = router;</code></pre>
<h4 id="3-postman-돌려보기">3. postman 돌려보기</h4>
<p><code>npm start</code>로 다시 서버를 켜주고 postman으로 테스트를 해보면 db에 넣어둔 user정보들이 뜬다!<img src="https://velog.velcdn.com/images/mean-g/post/ae829d5b-682e-44e5-8ffc-74daf8a8f3d5/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GIT] Conflict]]></title>
            <link>https://velog.io/@mean-g/Conflict</link>
            <guid>https://velog.io/@mean-g/Conflict</guid>
            <pubDate>Fri, 12 Aug 2022 01:12:41 GMT</pubDate>
            <description><![CDATA[<h4 id="1-conflict-발생">1. conflict 발생</h4>
<p><img src="https://velog.velcdn.com/images/mean-g/post/38188507-9d96-4caa-a01d-4267d0e1f60a/image.png" alt="">
conflict는 직역하면 &#39;충돌&#39;이다. 말 그대로 내가 지금 올린 PR의 코드와 이미 merge된 코드가 같은 부분이 달라져 충돌이 일어나는 것이다.
git으로 협업을 하다 보면 자주 일어나는 상황이지만, conflict를 처음 봤을 땐 조금 많이 당황했다. 하지만 다행히도 멘토님과 함께였기에😇 멘토님이 알려주신 팁 덕분에 이후 conflict가 나면 차근차근 해결할 수 있게 되었다!</p>
<h4 id="2-해결하기">2. 해결하기</h4>
<h5 id="1-main-브랜치로-이동하기">1) main 브랜치로 이동하기</h5>
<p><code>git checkout main</code> 을 이용해서 main으로 이동한다.
-&gt; <code>git pull main</code>으로 git에 merge(rebase)된 코드를 다시 받아온다.</p>
<h5 id="2-작업-브랜치로-돌아가기">2) 작업 브랜치로 돌아가기</h5>
<p><code>git checkout 브랜치 이름</code>으로 작업하던 브랜치로 다시 이동해 준다.
-&gt; <code>git merge main</code> 혹은 <code>git rebase -i main</code>으로 main을 받아온다.</p>
<h5 id="3-conflict-해결하기">3) conflict 해결하기</h5>
<p>에러 메세지가 뜨면 <code>code .</code>혹은 직접 vsc를 실행시켜 목록에 빨간 글씨로 바뀐 파일명과 빨간색 !를 찾아준다.
-&gt; 해당 파일에 연한 글씨로 Accept ~~라는 문구가 쭉 적힌 줄을 볼 수 있다.<img src="https://velog.velcdn.com/images/mean-g/post/8006b528-4cd0-444e-bc95-0103c2ba1ed6/image.png" alt=""><img src="https://velog.velcdn.com/images/mean-g/post/d91b5648-22b1-482a-abe3-0b3b508c7ab3/image.png" alt=""></p>
<p>-&gt; 성향에 따라 다르지만 멘토님은 전후 변경사항을 모두 불러오고, 비교 후 정리하는 방향으로 진행하신다고 하셨고, conflict를 몇 번 겪어보니... 그렇게 진행하는 게 좋을 것 같아서 쭉 사용하고 있다.</p>
<p>-&gt; conflict 난 코드들 정리 후 저장해 주기
-&gt; 차분하게 <code>git add .</code> 후 commit 을 다시 남겨주고, push를 하면 끝난다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] Q() ]]></title>
            <link>https://velog.io/@mean-g/Django-Q</link>
            <guid>https://velog.io/@mean-g/Django-Q</guid>
            <pubDate>Sun, 07 Aug 2022 08:53:25 GMT</pubDate>
            <description><![CDATA[<h3 id="1-q-객체란">1. Q 객체란?</h3>
<p>1) django ORM에서 spl의 query 문처럼 &#39;or&#39;조건을 쓰고 싶을 때 사용한다.</p>
<p>ex)</p>
<pre><code class="language-python">#sql - query문
select * from products where category=티제품 or sub_category=밀크티

#django ORM
Product.objects.filter(Q(category=티제품 | Q(sub_category=밀크티))</code></pre>
<p>2) 사용을 위해 
<code>from django.db.models        import Q</code>를 해주어야 한다.</p>
<p>3) |와 &amp;
q objects에서 
<code>|</code> = <code>where (조건) or (조건)</code> 으로 하나라도 조건에 맞으면 모든 결괏값을  보여주는 합집합이다.
<code>&amp;</code> = <code>where(조건) and (조건)</code> 으로 모든 조건을 만족해야지 해당 결괏값(모든 조건을 만족하는)을 보여주는 교집합이다.</p>
<p>조건을 계속 추가할 수도 있다.</p>
<p>4) <code>Q()</code> 는 <code>~~.objects.all()</code>과 동일하다.
전체를 변수에 담아두는 느낌..!
<br><br>
+) 추가적으로 같이 사용할 django 메서드도 남겨놓는다.
gt (greater than) : <code>&gt;</code>
lt (less than) : <code>&lt;</code>
gte(greater than or equal) : <code>&gt;=</code>
lte(less than or equal) : <code>&lt;=</code></p>
<p><br><br></p>
<h6 id="-프로젝트에-사용하는-필터링을-위해-보고-있는데-역시-이론은-이해가-가지만-막상-사용하는-게-힘든-거-같다">+) 프로젝트에 사용하는 필터링을 위해 보고 있는데 역시 이론은 이해가 가지만 막상 사용하는 게 힘든 거 같다.</h6>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Software testing]]></title>
            <link>https://velog.io/@mean-g/Software-testing</link>
            <guid>https://velog.io/@mean-g/Software-testing</guid>
            <pubDate>Sun, 07 Aug 2022 08:45:22 GMT</pubDate>
            <description><![CDATA[<h2 id="1-sotrware-testing-이란">1. Sotrware Testing 이란?</h2>
<h4 id="1-오류를-확인하는-작업이다">1) 오류를 확인하는 작업이다.</h4>
<ul>
<li>실제로 서비스를 사용화하기 전 오류가 없는지 검증을 하고 서비스를 상용화하기 위해서 필요한 과정이다.
서비스가 상용화되고 난 후 오류를 발견해서 수정하려면 금전적인 이슈와 함께 사용자가 불편을 겪기 때문이다.</li>
</ul>
<h4 id="2-서비스의-결함을-확인할-수-있다">2) 서비스의 결함을 확인할 수 있다.</h4>
<ul>
<li>실제 서비스를 제공하기 직전까지 수정해서 소비자에게 결함이 노출되는 일을 사전에 방지한다. 또한 출시 후 지속적인 피드백에 답변하는 것보다 시간을 절약할 수 있다.</li>
</ul>
<h4 id="4-서비스의-품질을-향상시킬-수-있다">4) 서비스의 품질을 향상시킬 수 있다.</h4>
<ul>
<li>리팩토링을 통해 서비스 구조나 품질 또한 개선할 수 있다.</li>
</ul>
<h4 id="4-확장성이-좋아진다">4) 확장성이 좋아진다.</h4>
<ul>
<li>새로운 코드를 붙일 때 더 간편하고 빠르게 붙일 수 있다.<br></li>
<li>) 나의 코드에서 원하는 결과들을 나오게 하기 위한 테스트 코드를 작성하여 테스트를 진행한다.
그리고 테스트 코드에서 원치 않던 결과가 나오면 처음으로 돌아가 코드를 수정 후 다시 테스트를 진행한다.</li>
</ul>
<h2 id="2-manual-testing--automation-testing">2. Manual Testing &amp; Automation Testing</h2>
<h4 id="1-manual-testing">1) Manual testing</h4>
<ul>
<li>꼭 해봐야 하지만, 사람이 직접 하는 만큼 불안정성이 높고, 인력이 소모되며 비용이 높으며 속도는 느리다는 단점이 있다.</li>
</ul>
<h4 id="2-automation-testing">2) Automation testing</h4>
<ul>
<li>안정성이 높고 속도가 빠르며 확장성도 높다. 또한 인력 소모는 줄어들고 비용은 낮아지는 장점이 있다.</li>
</ul>
<h2 id="3-system-test-전략">3. System test 전략</h2>
<h4 id="1-e2e-end-toend-tests">1) E2E (End-toEnd) Tests</h4>
<ul>
<li>프론트엔드와 백엔드의 완성된 코드를 직접 맞춰보는 작업이다. (전체적인 서비스의 flow를 맞춰보는 작업)</li>
<li>구글에 따르면 전체 test에서 10% 정도의 중요도와 시간 소모를 가진다고 한다. 하지만 복잡도는 가장 높은 작업이다.</li>
</ul>
<h4 id="2-integration-tests통합-테스트">2) Integration Tests(통합 테스트)</h4>
<ul>
<li>웹페이지, Postman 등을 사용해서 API 호출 시 올바르게 동작하는지 확인하는 작업이다. 모듈 간의 호환성을 검증하는 단계이다.</li>
<li>중요도와 시간 소모는 20% 정도이다.</li>
</ul>
<h4 id="3-unit-tests단위-테스트">3) Unit Tests(단위 테스트)</h4>
<ul>
<li>독립적으로 진행되는 가장 마이크로한 테스트로 class나 함수 하나하나를 테스트하는 것이다. (하나의 기능이나 메서드에 대한 테스트)</li>
<li>전체적인 중요도와 시간 소모는 70%로 가장 크지만 복잡도는 낮다. 하지만 단위 테스트를 함으로서 빠른 문제 파악이 가능하며, 리팩토링 시 안정성을 확보하고 단위 테스트를 코드에 대한 문서로 활용할 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/mean-g/post/3a1ef892-a4a7-4bc3-963e-61350cfe484c/image.png" alt=""></p>
<p>+) 이론적으로는 굉장히 간단하다. 테스트 코드 작성도 익숙해지면 반복작업정도로 생각한다는데, 아직 작성해 보지 않아서 그런지 막연한 걱정만 가득하다...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] AWS란?]]></title>
            <link>https://velog.io/@mean-g/AWS</link>
            <guid>https://velog.io/@mean-g/AWS</guid>
            <pubDate>Sun, 31 Jul 2022 13:13:45 GMT</pubDate>
            <description><![CDATA[<h3 id="1-aws란">1. AWS란?</h3>
<ul>
<li><strong>Amazon Web Services</strong>의 약자로, Amazon에서 제공하는 <strong>클라우드 서비스</strong>이다. 네트워킹을 기반으로 가상 컴퓨터와 스토리지, 네트워크 인프라 등.. 다양한 서비스를 제공하고 있다.</li>
</ul>
<h3 id="2-traditional-it">2. Traditional IT</h3>
<ul>
<li><p>서버는 일종의 데이터로 <strong>트래픽이 많아지면 서버 과부하가 걸리거나 다운</strong>되어 버린다.
그를 방지하기 위해 대표적으로는 2가지 방식으로 <strong>서버를 보완</strong>하는데, 하나는 <strong>Scale-up(스케일 업)</strong>이라는 컴퓨터 사양을 올려버리는 방식과 <strong>Scale-Out(스케일 아웃)</strong>이라는 서버를 추가하는 방식이 있다.</p>
</li>
<li><p>하지만 이러한 서버 보완 방법은 집에서 관리하기에도 한계가 있고, 회사의 서버실도 결국 물리적인 한계가 있어서 Data center에서 빌리는 방법이 생겼다.
하지만 결국 Datacenter도 비용적 측면에서 문제가 생긴다. 보통 monthly나 yearly 계약으로 중간에 계약 변경이 힘들었던 탓에 새로운 시스템을 원하는 소비층이 생겨났다.</p>
</li>
</ul>
<h3 id="3-cloud-computing-클라우드-컴퓨팅-이란">3. Cloud computing (클라우드 컴퓨팅) 이란?</h3>
<ul>
<li>인터넷을 통해 IT 리소스와 애플리케이션을 <strong>On-demand(온디맨드)</strong>로 제공하는 서비스로 기존의 물리적 컴퓨팅 리소스를 네트워크 기반 서비스 형태로 제공하는 것이다. 사용한 만큼만 지불하는 pay as you go 요금(종량과금제)이 적용된다. 이를 통해 정확하게 필요한 타입과 크기의 리소스를 지정해서 사용할 수 있고, 기존보다 간편하게 서버나 스토리지, DB에 접근할 수 있는 솔루션이 생긴다.</li>
<li>cloud computing에는 <strong>Iaas, Paas, SaaS</strong>라는 3가지 종류가 있다.</li>
</ul>
<h4 id="1-iaasinfrastructure-as-a-service">1) IaaS(Infrastructure as a Service)</h4>
<ul>
<li><p>서버, 네트워크, OS, 스토리지와 같은 IT 리소스를 가상화해서 제공하는 서비스이다.</p>
</li>
<li><p>가상 서버와 스토리지 그리고 가상 네트워크 등의 리소스를 서비스 형태로 제공하며, 자유도가 높은 만큼 개발자가 할 일이 많아서 경험도가 낮은 개발자가 사용하기엔 다소 어려움이 있다.</p>
</li>
</ul>
<h4 id="2-paasplatform-as-a-service">2) PaaS(Platform as a Service)</h4>
<ul>
<li><p>애플리케이션 서버 같은 미들웨어를 제공하며, 주로 개발 환경과 관련한 서비스(OS, DB, WAS, JDK)를 제공한다.</p>
</li>
<li><p>하드웨어, OS, 미들웨어에 대한 관리를 할 필요 없이 애플리케이션을 실행할 수 있게 해준다. 인프라가 제공되어 자유도는 낮지만 관리적인 측면에서는 효율적이다.</p>
</li>
</ul>
<h4 id="3-saassoftware-as-a-service">3. SaaS(Software as a Service)</h4>
<ul>
<li><p>완성된 형태의 소프트웨어 또는 애플리케이션의 기능만 제공한다.</p>
</li>
<li><p>모든 것을 다 제공하기에 사용만 하면 되고, 자유도가 낮다. 또한 제공하는 모든 서비스를 사용한다는 가정하에 구독료를 책정해서 불필요한 지출이 생긴다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] CSV파일이란?]]></title>
            <link>https://velog.io/@mean-g/CSV</link>
            <guid>https://velog.io/@mean-g/CSV</guid>
            <pubDate>Sun, 31 Jul 2022 12:50:38 GMT</pubDate>
            <description><![CDATA[<h3 id="1-csv파일이란">1. CSV파일이란?</h3>
<ul>
<li>파일 형식으로, 확장자명은 <code>.csv</code>이다.</li>
<li>Comma Seperated Value의 줄임말로, 콤마로 구분된 텍스트 데이터이다. 규칙적으로 콤마와 함께 구분되어 있어서 엑셀과 같은 프로그램으로도 읽을 수 있고 생성할 수 있다.</li>
<li>주로 테이블 형태로 구성된 자료나 텍스트 자료를 저장할 때 사용한다.</li>
<li>데이터 크기가 작고, 많은 애플리케이션에서 사용할 수 있는 범용 형식이라 자료를 주고받는 다양한 상황에서 CSV 형식을 사용한다.</li>
<li>같은 데이터를 저장하면 JSON 데이터에 비해 절반 이하의 용량으로 저장할 수 있다.</li>
<li>쉼표를 대신하여 다른 문자 ($,%,…)를 사용해 구분하도록 지정할 수 있다. (데이터 자체에 쉼표가 포함될 때)
<img src="https://velog.velcdn.com/images/mean-g/post/8dd56486-a80c-4ea9-a5ec-8e70f0bec6a4/image.png" alt=""></li>
</ul>
<h3 id="2-python은-어떻게-csv-파일을-읽을까">2. Python은 어떻게 CSV 파일을 읽을까?</h3>
<ul>
<li>파이썬에는 CSV 파일을 다루는 모듈이 있다 → <code>csv.reader()</code> 혹은 <code>csv.DictRedader()</code>라는 메소드를 사용하면 매우 쉽게 .csv 파일을 다룰 수 있다.</li>
<li>python에서 with open (file_name) as (file_name): 구문을 이용하면 외부 파일을 연 상태로 작업한다. csv.reader 메소드를 이용하면 파일 내부의 모든 행을 rows라는 변수에 담을 수 있다. 모든 행을 한 줄 한 줄 읽으면서 작업을 수행하기 위해서 for 문을 활용한다.</li>
</ul>
<h3 id="3-csv-파일-쓰기">3. CSV 파일 쓰기</h3>
<p><code>.csv</code> 파일을 쓰기 모드로 오픈하고 파일 객체를 csv.writer(파일객체)에 넣으면 된다.</p>
<p>CSV writer는 writerow()라는 메서드를 통해 list 데이터를 한 라인 추가하게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 인증 & 인가]]></title>
            <link>https://velog.io/@mean-g/%EC%9D%B8%EC%A6%9D-%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@mean-g/%EC%9D%B8%EC%A6%9D-%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 23 Jul 2022 04:46:52 GMT</pubDate>
            <description><![CDATA[<h3 id="1-암호화">1. 암호화?</h3>
<h4 id="1-개인-정보는-개인정보보호법으로-인해-암호화해서-저장해야-한다">1) 개인 정보는 개인정보보호법으로 인해 암호화해서 저장해야 한다.</h4>
<h4 id="2-단방향-해시">2) 단방향 해시</h4>
<ul>
<li>원래 해시(hash)함수는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해 사용된다. 하지만, 복원이 불가능한 단방향 해시함수는 암호화적 용도로 사용된다.
ex) MD5, SHA-1, SHA-256 등이 있다.</li>
<li>결과만 봐서는 당장 식별이 불가능하지만, 같은 비밀번호를 해싱하면 항상 같은 결과가 도출된다. 이런 허점을 이용한 Rainbow table이라 불리는 가능한 경우의 수를 해시값으로 만들어서 판매하는 서비스도 있다.</li>
</ul>
<h4 id="3-salting--keystretching">3) Salting &amp; KeyStretching</h4>
<ul>
<li>단방향 해시의 단점을 보완하기 위해 생겨난 아이디어.</li>
<li>비밀번호와 함께 임의로 생성한 문자열(salt)를 합쳐서 해싱한 값을 저장한다. 비교를 위해 해시값과 salt 값을 같이 저장한다.</li>
<li>추가적으로 무작위 대입을 통해 해시값을 계산하는데 걸리는 시간을 늘리기 위해 Key Stretching을 사용한다.</li>
<li>Key Stretching은 salting 및 해싱을 반복해서 키값을 계속 늘리는 작업이다.</li>
</ul>
<h4 id="4-bcrypt">4) bcrypt</h4>
<ul>
<li>Salt와 Key Stretching 개념들을 실제로 적용하기 편하게 해주는 대표적인 라이브러리이다.</li>
<li>다양한 언어를 지원하며, 사용이 간편해서 쉽게 적용이 가능하다.</li>
<li>bcrypt는 hash결괏값에 소금값과 해시값, 반복 횟수를 같이 보관하기 때문에 비밀번호 해싱을 적용하는데 DB 설계가 덜 복잡하다.</li>
<li>bcrypt 사용 시 해싱된 결괏값(Digest)의 구조는 아래와 같다.
<img src="https://velog.velcdn.com/images/mean-g/post/27ebadf3-b8d4-4a87-8ce1-1014c84f350a/image.png" alt=""></li>
</ul>
<h4 id="5-jwt">5) JWT</h4>
<ul>
<li>사용자가 서버에 로그인했을 경우, http의 특성상 로그인했다는 것을 기록할 수 없다. 이때 headers에 메타데이터를 보내서 확인다는데 이 메타데이터가 JSON Web Token으로 JWT라고 부른다.</li>
<li>암호화는 무거운 작업이라 지속적으로 로그인 요청을 보내면 부담스러우므로 Token 사용으로 가볍게 돌린다.
<img src="https://velog.velcdn.com/images/mean-g/post/5bc8b69e-c224-4364-af34-b93032959a9d/image.png" alt=""></li>
<li>JWT구조</li>
</ul>
<p>-Header(헤더) : 토큰 타입과 해시 알고리즘 정보가 들어간다.
헤더의 내용은 BASE64방식으로 인코딩후 기록된다.
ex) <code>{&quot;alg&quot;:&quot;HS256&quot;,&quot;yyp&quot;:&quot;JWT&quot;}</code></p>
<p>-Payload(내용) : 만료시간을 나타내는 exp와 같이 미리 정의된 집합인 Registered Claim, 공개용 정보 전달을 목적으로 하는 Public Claim, 그리고 클라이언트와 서버 간 협의하에 사용하는 Private Claim가 있다. 이 세 가지 요소를 조합하여 작성한 뒤 BASE64 인코딩 후 기록된다.
ex) <code>{&quot;user-id&quot;:1,&quot;exp:1539517391}</code>
-&gt; pk 값(user_id...)을 사용하는데, 개인 정보가 아니기 때문이다.
-&gt; 우리 쪽 정보임을 알 수 있는 건, 시그니처가 붙기 때문이다.
-&gt; 토큰에는 만료시간을 주고 시간 리필 혹은 재충전을 해주어야 한다.</p>
<p>-Signature(서명) : JWT가 원본 그대로임을 확인할 때 사용하는 부분이다.
시그니처는 BASE64URL 인코드된 header와 payload 그리고 JWT secret(별도 생성)을 헤더에 지정된 암호 알고리즘으로 암호화하여 전송한다. (복호화가 가능하다)
프론트에서 JWT를 백엔드 API 서버로 전송하면, 서버에서는 전송받은 JWT의 서명 부분을 복호화 하여 서버에서 생성한 JWT가 맞는지 확인한다.</p>
<ul>
<li>Header와 Payload는 BASE64 인코딩 한 것으로 누구나 원본을 볼 수 있다. (암호화가 x) 그러므로 개인 정보는 담으면 안 된다. ( 그래서 settings.py에 있는 SECRET KEY를 사용하는 것 )</li>
</ul>
<p><img src="https://velog.velcdn.com/images/mean-g/post/49bfe6e3-e96f-4c84-b884-09a95f64fd40/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Decorator]]></title>
            <link>https://velog.io/@mean-g/Decorator</link>
            <guid>https://velog.io/@mean-g/Decorator</guid>
            <pubDate>Thu, 21 Jul 2022 12:18:21 GMT</pubDate>
            <description><![CDATA[<p>오설록 클론 코딩을 하면서 데코레이터를 사용해 보게 되었다.
개념부터 찬찬히 훑어보고 코드를 짜려고 정리를 해보았다.</p>
<h3 id="1-데코레이터decorator란">1. 데코레이터(decorator)란?</h3>
<ul>
<li>기존의 코드에 여러 가지 기능을 추가하는 파이썬 구문이다.</li>
<li>추가할 기능의 함수를 wrapping 해서, 다양한 곳에 간단하게 재사용 할 수 있게 해준다.</li>
<li>특정 함수가 실행되기 전에 먼저 실행되어, 사전에 하고 싶은 작업을 처리하는 함수</li>
</ul>
<h3 id="2-데코레이터는-언제-사용할까">2. 데코레이터는 언제 사용할까?</h3>
<ul>
<li>로그인한 사용자에게 토큰을 발행하고, 이 토큰을 새로운 요청마다 HTTP 리퀘스트 헤더에 넣어서 보내주면 로그인 상태를 유지시켜 준다. 이 토큰이 유효한 토큰인지 확인하기 위해 로그인 인증 데코레이터를 사용한다.</li>
<li>데코레이터 함수를 재사용해서, main 함수에 대한 가독성과 직관성을 좋게 한다. (같은 패턴을 여러 번 사용하더라도 @만 붙이면 돼서 간편하다)</li>
<li>사용자가 특정 기능을 수행하기 전, 사용자가 그 기능을 수핼할 권한이 있는지 확인한다.</li>
</ul>
<h3 id="3-데코레이터를-사용해보자">3. 데코레이터를 사용해보자</h3>
<p>TimeStamp모델을 위해 만들었던<code>core</code>라는 앱에 <code>utils.py</code>에 파일을 따로 생성해주었다.</p>
<pre><code class="language-python">#먼저 모듈들을 import해준다.
from django.http        import JsonResponse
from users.models       import User
from django.conf        import settings

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:

            access_token = request.headers.get(&#39;Authorization&#39;)
            #HTTPRequest의 헤더인 Authorization의 값을 가져온다.
            payload      = jwt.decode(access_token, settings.SECRET_KEY, settings.ALGORITHM)
            #토큰을 디코딩하면 나오는 사용자 정보이다. 디코딩에 사용되는 SECRET_KEY, ALGORITHM이 토큰 발행 시 넣은 정보와 동일해야 한다.
            user_id      = payload[&#39;id&#39;]
            #user_id에 payload에서 디코딩해서 나온 사용자 정보를 저장한다.
            request.user = User.objects.get(id = user_id)
            #request에 user변수를 저장한다. user변수에는 user_id와 일치하는 DB의 User 테이블의 사용자 정보를 넣어준다.

            return func(self, request, *args, **kwargs)

        except jwt.exceptions.DecodeError:
            return JsonResponse({ &#39;message&#39; : &#39;INVALID_TOKEN&#39; }, status = 400)
            #우리에게 없는 토큰 값이 들어오면 INVALID_TOKEN 에러를 반환한다.

        except KeyError:
            return JsonResponse({ &#39;message&#39; : &#39;KEY_ERROR&#39; }, status = 400)

    return wrapper</code></pre>
<p><br><br></p>
<hr>
<br>
+)데코레이터에 대해 정리하면서 개념은 조금 잡힌 거 같은데 아직... 코드는 처음이라 그런지 두루뭉실하게 아는지 코드를 설명하기 조금 어렵다. 프로젝트가 끝나면 다시 한번 더 되돌아봐야 할 것 같다😇]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Code kata 3-2]]></title>
            <link>https://velog.io/@mean-g/Code-kata-3-2</link>
            <guid>https://velog.io/@mean-g/Code-kata-3-2</guid>
            <pubDate>Wed, 20 Jul 2022 01:00:21 GMT</pubDate>
            <description><![CDATA[<h3 id="1-문제">1. 문제</h3>
<p>문자로 구성된 배열을 input으로 전달하면, 문자를 뒤집어서 return 해주세요.</p>
<ul>
<li>새로운 배열을 선언하면 안 됩니다.</li>
<li>인자로 받은 배열을 수정해서 만들어주세요.
ex)<pre><code>Input: [&quot;h&quot;,&quot;e&quot;,&quot;l&quot;,&quot;l&quot;,&quot;o&quot;]
Output: [&quot;o&quot;,&quot;l&quot;,&quot;l&quot;,&quot;e&quot;,&quot;h&quot;]
</code></pre></li>
</ul>
<p>Input: [&quot;H&quot;,&quot;a&quot;,&quot;n&quot;,&quot;n&quot;,&quot;a&quot;,&quot;h&quot;]
Output: [&quot;h&quot;,&quot;a&quot;,&quot;n&quot;,&quot;n&quot;,&quot;a&quot;,&quot;H&quot;]</p>
<pre><code>
#### 1) reverse 사용하기</code></pre><p>def reverse_string(s):
  s.reverse()
  return s</p>
<pre><code>로 돌리면 간단히 답이 나오는데, 너무 간단히 풀려서 다른 방식으로도 풀어 보았다.

---

#### 2) swap으로 풀기</code></pre><p>def reverse_string(s):
  i = 0
  j = len(s) - 1</p>
<p>  while (i&lt;j):
    s[i], s[j] = s[j], s[i]
    i += 1
    j -= 1
  return s</p>
<pre><code>마침 요즘 기초를 다시 보고 있어서 스왑이 생각나서 시작해 봤다.
i로 앞에서부터 시작하고, j는 뒤에서부터 시작해서 서로 바꿔준다.
그리고 i는 더하고 j는 빼가면서 for 문으로 돌려준다.
그리고 i와 j가 만나면 종료

###### 코드가 조금 길어지긴 했지만 그래도..! 새로운 방법을 찾았다!</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] 기초파이썬 #3]]></title>
            <link>https://velog.io/@mean-g/Basic-python3</link>
            <guid>https://velog.io/@mean-g/Basic-python3</guid>
            <pubDate>Sun, 17 Jul 2022 09:20:49 GMT</pubDate>
            <description><![CDATA[<p>요즈음 파이썬 기초가 부족했음을 느끼고 있다..
공 부 많 이 할 걸......</p>
<h4 id="1표현식expression">1.표현식(expression)</h4>
<ul>
<li>어떠한 값을 만들어 내는 코드이다.
ex) <code>23</code>, <code>10+20+30</code>, <code>&quot;Basic python&quot;</code> ...등</li>
</ul>
<h4 id="2-문장statement">2. 문장(statement)</h4>
<ul>
<li>표현식이 하나 이상 모이면 문장이 된다.(파이썬에서는 한 줄이 하나의 문장이다.)</li>
</ul>
<h4 id="3-프로그램program">3. 프로그램(program)</h4>
<ul>
<li>문장이 모이면 프로그램이 된다.</li>
</ul>
<h4 id="4-키워드keyword">4. 키워드(keyword)</h4>
<ul>
<li>특별한 의마가 부여된 단어로 파이썬이 만들어질 때 만들어진 것이다.
ex) <code>False</code>, <code>True</code>, <code>None</code>, <code>and</code>, <code>as</code>, <code>assert</code>, <code>break</code>...등<pre><code>#키워드 확인하는 코드
</code></pre></li>
</ul>
<p>import keyword
print(keyword.kwlist)</p>
<pre><code>![](https://velog.velcdn.com/images/mean-g/post/94a6a9f1-2b2a-446f-9f53-93329101bc85/image.png)

#### 5. 식별자(identifier)
- 이름을 붙일 때 사용하는 단어이다.
키워드와 공백은 사용할 수 없고 특수문자는 언더 바(`_`)만 사용 가능하고, 숫자로 시작할 수 없다.
ex) `mean_g`, `meang`, `mean_g2`, `_mean_g`

+) 스네이크 케이스(snake_case : 공백에 언더 바(_)를 넣는다.)와 카멜 케이스(CarmelCase : 단어의 시작을 대문자로 한다.)가 있다.

#### 6. 주석(comment)
- 주석처리 하고자 하는 부분 앞에 #을 붙혀서 사용한다. 주석처리가 되면 프로그램에 어떠한 영향도 끼치지 않는다.
ex) `#주석예시입니다.`

#### 7. 연산자
- 값과 값 사이에 기능을 적용하는 역할을 한다.
- 숫자연산자
`+` : 더하기 연산자, `+=` : 더한 후 대입
ex) `2+2`, ` a += 1` ..
`-` : 빼기 연산자, `-=` : 빼고난 후 대입
ex) `4-2`, `a -= 1`
`*` : 곱하기 연산자, `*=` : 곱하고 난 후 대입
ex) `2*2`, `a *= 2`
`/` : 나누기 연산자, `/=` : 나눈 후 대입
ex) `4/2`, `4 /= 2`
`%` : 나머지 연산자, `%=` : 나머지 연산 후 대입
ex) `4%3`, `4 %= 3`
`**` : 제곱 연산자, `**=` : 제곱 후 대입
ex) `4**2`, `4**=2`
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Server open test]]></title>
            <link>https://velog.io/@mean-g/sign-up-log-in</link>
            <guid>https://velog.io/@mean-g/sign-up-log-in</guid>
            <pubDate>Wed, 13 Jul 2022 12:07:47 GMT</pubDate>
            <description><![CDATA[<p>오늘을 만들어둔 서버에 front분들이 연결해서 로그인과 회원가입을 해보았다.
 +백엔드 서버끼리도 ip 주소를 바꿔서 회원가입과 로그인을 해봤다. 쏘신기..🥺</p>
<hr>
<h3 id="1-서버를-열어보자">1. 서버를 열어보자</h3>
<h4 id="1-보통-혼자-코드를-짤-때는-python-managepy-runserver라고-찾았는데-이제는-내-ip도-같이-써야-한다">1) 보통 혼자 코드를 짤 때는 <code>python manage.py runserver</code>라고 찾았는데 이제는 내 ip도 같이 써야 한다.</h4>
<p><code>python manage.py runserver 0:8000</code> 0자리에 ip를 넣으면 된다.</p>
<p>-&gt; ip 찾는 법
Mac : <code>ipconfig getifaddr en0</code>를 터미널에 치면 나온다.
<img src="https://velog.velcdn.com/images/mean-g/post/85f6d622-fa73-4fba-bca4-ec3819304b82/image.png" alt=""></p>
<h4 id="2-runserver-가-돌아갔다면-front에게-ip와-엔드-포인트를-전달해-주면-된다">2) runserver 가 돌아갔다면 front에게 ip와 엔드 포인트를 전달해 주면 된다.</h4>
<p>이건 프론트분들이 돌려보는 나의 서버.....
<img src="https://velog.velcdn.com/images/mean-g/post/a4d4b94f-a570-46fe-9dd6-29ecb7ded13e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 정규표현식, 정규식 (Regular Expressions)]]></title>
            <link>https://velog.io/@mean-g/Regular-Expressions</link>
            <guid>https://velog.io/@mean-g/Regular-Expressions</guid>
            <pubDate>Sat, 09 Jul 2022 06:06:28 GMT</pubDate>
            <description><![CDATA[<h3 id="1-정규표현식regex-이란">1. 정규표현식(/regex/) 이란?</h3>
<ul>
<li><p>Regular expression 의 약자이다.</p>
</li>
<li><p>정규표현식은 <strong>여러 문자가 섞여 있는 문자열을 처리</strong>할 때 사용하는 방법으로, 정규표현식을 사용하면 훨씬 간편하고 직관적인 코드로 작성할 수 있어 많이 사용된다.</p>
</li>
<li><p>문자열에 특정한 규칙이 있는 경우, 해당 규칙을 식으로 정의하여 규칙에 맞는 문자열들을 추출할 때 사용하는 기능이다.</p>
</li>
</ul>
<pre><code class="language-python"># python에서는 re모듈을 통해 정규표현식을 사용할 수 있다.
import re

...

# 패턴 작성은 re모듈을 사용하고, 시작점에 &#39;^를 끝에 $&#39;표시를 사용해 주면 된다.
REGEX_ID       = &#39;^[a-zA-Z0-9]{4,12}$&#39;
REGEX_EMAIL    = &#39;^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$&#39;
REGEX_PASSWORD = &#39;^(?=.*[a-z])(?=.*\d)(?=.*[$@$!%*#?&amp;])[a-z\d$@$!%*#?&amp;]{8,16}$&#39;
REGEX_BIRTHDAY = &#39;^(19\d{2}|20\d{2})-(0[0-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$&#39;</code></pre>
<pre><code class="language-javascript">//Javascript에서는 &#39;대신 /으로 정규식을 감싸주면 된다.
REGEX_ID       = /^[a-zA-Z0-9]{4,12}$/
REGEX_EMAIL    = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
REGEX_PASSWORD = /^(?=.*[a-z])(?=.*\d)(?=.*[$@$!%*#?&amp;])[a-z\d$@$!%*#?&amp;]{8,16}$/
REGEX_BIRTHDAY = /^(19\d{2}|20\d{2})-(0[0-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/</code></pre>
<hr>
<p><a href="https://regexr.com">사이트에 접속</a>하면 간단하게 사용해 볼 수 있다. 재밌게 이해할 수 있어서 좋다🥺</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] ManyToManyField(다대다)와 Foreign Key(외래키)]]></title>
            <link>https://velog.io/@mean-g/ManyToManyFieldForeign-Key</link>
            <guid>https://velog.io/@mean-g/ManyToManyFieldForeign-Key</guid>
            <pubDate>Wed, 06 Jul 2022 08:24:54 GMT</pubDate>
            <description><![CDATA[<h3 id="1-foreign-key외래키란">1. Foreign Key(외래키)란?</h3>
<ul>
<li><p>외래키(Foreign Key)란 테이블의 필드(attribute) 중 다른 테이블의 행(row)를 식별할 수 있는 키다.
일반적으로 외래키 값을 가지고 있는 테이블을 부모 테이블, 외래키가 포함된 테이블을 자식 테이블이라고 한다.</p>
</li>
<li><p>데이터베이스에 테이블을 만들 때 효율적으로 테이블을 만들 수 있게 해준다. 쉽게 생각하면 테이블과 테이블을 연결해 준다고 생각하면 될 거 같다.</p>
</li>
</ul>
<h3 id="2-many-to-many다대다란">2. Many to Many(다대다)란?</h3>
<ul>
<li>별도로 중간 테이블을 설정해 주지 않아도 자동으로 중간 테이블을 설정해 준다.</li>
</ul>
<pre><code class="language-python">class Movie(models.Model):
    title = models.CharField(max_length=50)
    release_date = models.DateField()
    running_time = models.CharField(max_length=50)

    class Meta:
        db_table = &#39;movies&#39;

class Actor(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=50)
    date_of_birth = models.DateField()
    movie = models.ManyToManyField(Movie, through=&#39;ActorMovie&#39;)

    class Meta:
        db_table = &#39;actors&#39;</code></pre>
<ul>
<li><p>위 코드처럼 두 개의 테이블을 생성하고 ManyToMany Field를 사용해서 Actor 테이블이 Movie 테이블을 참조하도록 만들었다.
여기서 중간 테이블을 따로 만들지 않았지만, 자동적으로 중간 테이블이 생기며 DB를 확인해 보면 ManyToMany Field로 엮인 두 테이블 이름에 _을 넣어준 새로운 테이블이 생겨난다.</p>
</li>
<li><p><code>through</code> 옵션을 사용하지 않는다면 중간 테이블에 직접 접근해서 객체로 사용할 수는 없다.
어떤 객체를 생성하고 해당 객체를 통해 중간 테이블에 접근하여 객체를 사용해야 해서 loss 발생하게 된다.
ManyToMany Field 사용 중에도 중간 테이블을 직접 설정해 주고 <code>through</code> 옵션으로 중간 테이블임을 인식시켜줘야 한다.</p>
</li>
<li><p>여기서는 <code>Movie</code>에서 <code>Actor</code>를 참조할 수 있기 때문에, 거꾸로 <code>Actor</code>에서 <code>Movie</code>를 가져오기 위해 <code>actor.movies.all()</code> 을 사용하면 <code>Actor</code>는 <code>Movie</code>와 연결되지 않았으므로 <code>AttributeError</code> 가 뜨고 직접적으로 데이터를 가져올 수는 없다.</p>
</li>
</ul>
<p>→ <code>_set</code> 붙혀주기 : </p>
<pre><code class="language-python">actor1.movie_set.all()
&lt;QuerySet [&lt;movie: actor&gt;]&gt;</code></pre>
<p>→ related_name : <code>_set</code> 대신 사용이 가능하다.</p>
<pre><code class="language-python">class Movie(models.Model):
        ...
        actors = models.ManyToManyField(&#39;Actor&#39;, related_name=&#39;movies&#39;)</code></pre>
<p>related_name은 참조되는 테이블이 참조하는 테이블의 데이터를 가져오기 위해 사용하는 이름을 정의한다.</p>
<pre><code class="language-python">actor1.movies.all()
&lt;QuerySet [&lt;movie: actor&gt;]&gt;</code></pre>
<p>이경우 정상적으로 출력되는 걸 확인할 수 있다.</p>
<h3 id="3-manytomanyfield의-이점은-무엇일까">3. ManyToManyField의 이점은 무엇일까?</h3>
<p>1) 중간 테이블을 직접 만들어주지 않아도 된다.
2) 중간 테이블을 거치지 않고 언제든지 데이터를 쉽게 추가하고 가져올 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] 상대경로와 절대경로]]></title>
            <link>https://velog.io/@mean-g/path</link>
            <guid>https://velog.io/@mean-g/path</guid>
            <pubDate>Tue, 05 Jul 2022 14:46:53 GMT</pubDate>
            <description><![CDATA[<h3 id="1-sysmodules-와-syspath의-차이점은-무엇일까">1. <code>sys.modules</code> 와 <code>sys.path</code>의 차이점은 무엇일까?</h3>
<h4 id="1-sysmodules">1) <code>sys.modules</code></h4>
<ul>
<li>파이썬에서 모듈이나 package를 찾기 위해 가장 먼저 확인하는 곳이다.</li>
<li>단순한 dictionary로, 이미 import된 모듈과 package들을 저장하고 있다.(= 한 번 import된 모듈과 package들은 파이썬이 다시 찾지 않아도 되도록 한다.)</li>
<li>새로 import 한 모듈은 <code>sys.modules</code>에서 찾을 수 없다.</li>
</ul>
<h4 id="2-syspath">2) <code>sys.path</code></h4>
<ul>
<li>파이썬에서 모듈이나 package를 찾기 위해 마지막에 확인하는 곳.</li>
<li>list 형태로 string 요소들을 가지고 있다.</li>
<li>각 string 요소들은 경로를 나타낸다.<pre><code class="language-python">[&#39;&#39;,
&#39;/Users/song-eun-u/anaconda3/bin&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python36.zip&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python3.6&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python3.6/site-packages&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa&#39;,
&#39;/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions&#39;,
&#39;/Users/song-eun-u/.ipython&#39;]</code></pre>
<ul>
<li>파이썬은 list의 각 경로를 하나하나 확인하면서 해당 경로에 import 하고자 하는 package가 위치해 있는지 확인한다.<br>

</li>
</ul>
</li>
</ul>
<h3 id="2-sys-도-import-해야-하는-모듈이다-파이썬은-sys-모듈의-위치를-어떻게-찾을-수-있을까">2. sys 도 import 해야 하는 모듈이다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까?</h3>
<p>1) <code>sys</code>는 파이썬에 포함된 모듈이다. 그러므로 <code>sys</code> 모듈을 import 해서 <code>sys.module</code>과 <code>sys.path</code>를 출력, 수정할 수 있다.</p>
<pre><code class="language-python">import sys
print(sys.path)
print(sys.modules)</code></pre>
<p>2) 파이썬은 import 하고자 하는 모듈과 package를 찾을 때에 먼저 sys.modules를 보고, 없으면 파이썬 built-in 모듈들을 확인하고 마지막으로 sys.path에 지정되어 있는 경로들을 확인해서 찾는다.</p>
<p>3) sys.path에서도 못 찾으면 ModuleNotFoundError 에러를 리턴한다.
<br></p>
<h2 id="3-absolute-path와-relative-path의-차이점은-무엇일까">3. Absolute path와 relative path의 차이점은 무엇일까?</h2>
<h4 id="1-absolute-path-">1) Absolute path :</h4>
<ul>
<li>절대경로 ( import 하는 파일이나 경로에 상관없이 항상 경로가 동일하다.)</li>
<li>경로가 길어질 수 있는 단점이 있다 (-&gt;이러한 단점 보완을 위해 relative path를 사용한다.)</li>
</ul>
<h4 id="2-relative-path-">2) Relative path :</h4>
<ul>
<li>import 하는 위치를 기준으로 경로를 정의한다.</li>
<li>주로 local package 안에서 다른 local package로 import 할 때 사용된다.</li>
<li>헷갈리기 쉽고, 파일 위치가 변경되면 경로 위치도 변경되어야 한다. (-&gt;absolute path를 사용하길 권장한다.)<br>


</li>
</ul>
<h3 id="4-calculator-패키지를-만들고-mainpy에서-상대경로로-add_and_mutiply를-임포트-했을-때-발생하는-에러를-확인하고-파이썬-공식-문서를-참고해서-main-module에서는-패키지의-모듈을-어떻게-임포트-해야-할까">4. calculator 패키지를 만들고 main.py에서 상대경로로 add_and_mutiply를 임포트 했을 때 발생하는 에러를 확인하고, 파이썬 공식 문서를 참고해서 main module에서는 패키지의 모듈을 어떻게 임포트 해야 할까?</h3>
<p><img src="https://velog.velcdn.com/images/mean-g/post/f6c86fcc-c3d0-4895-b974-f368e7a712f2/image.png" alt=""></p>
<p>우선 calculator 패키지를 만들고 main.py에서 add_andmutiply를 임포트 하면 해당 에러가 발생한다.
<img src="https://velog.velcdn.com/images/mean-g/post/1f9ac2f5-9b3d-4c11-a8b6-390c4ec5cce1/image.png" alt="">
상위 패키지를 알 수 없는 상대를 가져오려는 시도를 했다고 한다.</p>
<p>공식 문서를 보면 아래와 같은 문구가 있다.</p>
<p><strong>&lt; Since the name of the main module is always &quot;<strong>main</strong>&quot;, modules intended for use as the main module of a Python application must always use absolute imports. &gt;</strong></p>
<p>main 모듈은 항상<code>__main__</code>이고, 메인 모듈에서는 항상 절대경로를 사용해야 한다고 한다.</p>
<p>절대경로로 바꿔서 돌려보면 정상적으로 출력되는 걸 확인할 수 있다.
<img src="https://velog.velcdn.com/images/mean-g/post/f1899613-6f99-41f3-8386-e3ee78d30557/image.png" alt=""></p>
<h3 id="5-add_and_multiplypy에서-multiply-함수를-절대경로와-상대경로도-각각-임포트-해보고-main-모듈과-차이점을-생각해-보고-결과를-출력하자">5. add_and_multiply.py에서 multiply 함수를 절대경로와 상대경로도 각각 임포트 해보고 main 모듈과 차이점을 생각해 보고 결과를 출력하자.</h3>
<p>add_and_multiply.py는 패키지 안에 있는 모듈이라서 절대경로와 상대경로가 모두 정상적으로 출력된다.
하지만 main.py는 패키지 안에 속하지 않았으므로 상대경로는 실행이 안 되며 절대경로만 실행할 수 있다.
<br></p>
<h3 id="6-__init__py-파일의-역할은">6. <code>__init__.py</code> 파일의 역할은?</h3>
<p><code>__init__.py</code>    는 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
python3.3 이전 버전은 패키지에 포함된 디렉터리에 <code>__init__.py</code> 파일이 없다면 패키지로 인식을 하지 않는다고 한다.
(python3.3이후로는 없어도 패키지로 인식한다_PEP420)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] HTTP란?]]></title>
            <link>https://velog.io/@mean-g/HTTP</link>
            <guid>https://velog.io/@mean-g/HTTP</guid>
            <pubDate>Sat, 02 Jul 2022 08:30:04 GMT</pubDate>
            <description><![CDATA[<h3 id="1-http란">1. HTTP란?</h3>
<ul>
<li>HTTP의 HT는, Hyper Text의 약자로 HTML(HyperText Markup Language), 문서와 문서가 링크로 연결되어 있음을 뜻한다.
T는 Transfer, Html로 만든 웹페이지 문서(파일)을 보낸다.
P는 Protocol, 컴퓨터끼리 어떻게 HTML 파일을 주고받을지에 대한 소통 방식 또는 약속이다.</li>
</ul>
<h3 id="2-http란">2. HTTP란?</h3>
<h4 id="1-request--response">1) Request / Response</h4>
<ul>
<li>요청(request) 하나당, 하나의 응답(response)으로 이루어진다.<h4 id="2-stateless">2) Stateless</h4>
</li>
<li>HTTP 개별 통신은 모두 독립이어서, 과거의 HTTP 통신의 결과(상태)를 보존하지 않는다.
<img src="https://velog.velcdn.com/images/mean-g/post/217ffeba-0d84-4fdc-a14a-8643c66a0ca8/image.png" alt=""><img src="https://velog.velcdn.com/images/mean-g/post/448bda98-f2c5-46ba-a8c5-fce4d1e3ebfa/image.png" alt=""><h6 id="그래서-이런-결과가-나온다">그래서 이런 결과가 나온다.</h6>
</li>
</ul>
<p>+) 번거로운 측면이 있어서 토큰(Token) 방식을 이용하기도 한다.</p>
<h3 id="3-http-메시지-구조">3. HTTP 메시지 구조</h3>
<h4 id="1-request-메시지-구조">1) Request 메시지 구조</h4>
<ul>
<li><p>Start Line</p>
<ul>
<li>요청의 첫 번째 줄으로 HTTP method(요청이 의도한 액션을 정의), Request target(요청이 전송되는 목표 url), HTTP version이 있다.
ex) <code>POST /users/login HTTP/1.1</code></li>
</ul>
</li>
<li><p>Headers</p>
<ul>
<li>요청의 메타데이터를 담고 있는 부분이다. {key:value}형태로 이루어져 있다.
ex)<pre><code>Headers:{
Host : www.wecode.co.kr
User-Agent : chrome
Content-Type : application/json
Content-Length : 50
}</code></pre></li>
</ul>
</li>
<li><p>Body</p>
<ul>
<li>요청의 실제 내용 부분으로, 요청 메서드에 따라 존재하지 않을 수 있다.
ex) <pre><code>Body:{
&quot;username&quot; : &quot;wecode&quot;,
&quot;password&quot; : &quot;wecode123&quot;`
}</code></pre></li>
</ul>
</li>
</ul>
<h4 id="2-response-메시지-구조">2) Response 메시지 구조</h4>
<ul>
<li><p>Status Line</p>
<ul>
<li>응답의 첫 번째 줄로 상태를 나타낸다. HTTP version, Status Code(응답 상태 코드), Status Text(응답의 상태를 간략히 설명하는 텍스트)가 있다.
ex) <code>HTTP/1.1 404 Not Found</code>, <code>HTTP/1.1 200 SUCCESS</code></li>
</ul>
</li>
<li><p>Headers</p>
<ul>
<li>응답의 메타데이터를 담고 있는 부분이다. {key:value}형태로 이루어져 있다.
ex)<pre><code>Headers:{
Host : www.wecode.co.kr
User-Agent : chrome
Content-Type : application/json
Content-Length : 50
}</code></pre></li>
</ul>
</li>
<li><p>Body</p>
<ul>
<li>응답해 줄 데이터로, 요청 메서드에 따라 존재하지 않을 수 있다.
ex)<pre><code>Body:{
&quot;message&quot; : &quot;success&quot;,
&quot;token&quot; : &quot;qfsaldjiowj&quot;
}</code></pre></li>
</ul>
</li>
</ul>
<p><br><br></p>
<h3 id="4-http-request-methods">4. HTTP Request Methods</h3>
<h4 id="1-get">1) GET</h4>
<ul>
<li>데이터를 받아오기만 할 때 사용하며, 웹페이지에 접속해서 필요한 데이터를 불러올 때 사용한다.<h4 id="2-post">2) POST</h4>
</li>
<li>데이터를 생성 / 수정할 때 사용하며, body에 담는 내용이 핵심이다.<h4 id="3-delete">3) DELETE</h4>
</li>
<li>서버에 저장된 특정 데이터를 삭제할 때 사용한다.
<br><br></li>
</ul>
<p>+)다양한 Status code코드들이 있다... 크게 이렇게 볼 수 있지 않을까..?
<img src="https://velog.velcdn.com/images/mean-g/post/240b0330-1bd6-4123-a09d-e1e1cfa441ed/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GIT] Git & Github이란?]]></title>
            <link>https://velog.io/@mean-g/GitGithub</link>
            <guid>https://velog.io/@mean-g/GitGithub</guid>
            <pubDate>Wed, 29 Jun 2022 07:01:01 GMT</pubDate>
            <description><![CDATA[<h3 id="1-git-과-github의-차이는-뭘까">1. Git 과 Github의 차이는 뭘까?</h3>
<h4 id="1-git">1) Git</h4>
<ul>
<li>공식 명칭은 분산 버전 관리 시스템(VCS, Version Control System)이다.</li>
<li><strong>프로젝트 파일의 변경 사항을 추적하는 시스템</strong>이다.</li>
<li>Commit 을 남겨두면, 필요할 때 언제든지 이전 버전의 코드로 돌아갈 수 있다.</li>
<li><code>gitblame</code> 을 이용해서 코드를 쓴 사람을 찾을 수 있다.</li>
<li>하나의 프로젝트로 여러명의 개발자가 협업할 수 있다. ( 프로젝트 관리에 가장 널리 사용되는 툴이다.)</li>
</ul>
<h4 id="2-github">2) Github</h4>
<p><img src="https://velog.velcdn.com/images/mean-g/post/4e27ac30-ad65-4539-bad9-b15f7758886d/image.png" alt=""></p>
<ul>
<li>개발자 커뮤니티라고 생각하면 될 거 같다.</li>
<li>Git repository를 위한 호스팅 플랫폼이다.<br>

</li>
</ul>
<h3 id="2-terminal에서-git-명령어를-사용해보자">2. Terminal에서 Git 명령어를 사용해보자.</h3>
<h4 id="1-기본-linux-명령어-">1) 기본 linux 명령어 :</h4>
<ul>
<li><p>현재위치 확인 : <code>pwd</code></p>
</li>
<li><p>경로 이동 : <code>cd 이동할 경로</code></p>
<ul>
<li>ex) <code>cd my_folder</code></li>
</ul>
</li>
<li><p>폴더 생성 : <code>mkdir 폴더이름</code></p>
<ul>
<li>ex) <code>mkdir new_folder</code></li>
</ul>
</li>
<li><p>파일 목록 확인 : <code>ls</code> 또는 <code>ls -al</code></p>
</li>
<li><p>파일 생성 : <code>touch 파일이름.확장자</code></p>
<ul>
<li>ex)<code>touch mean-g.md</code></li>
</ul>
</li>
<li><p>vim 에디터 열기 : <code>vi 파일이름.확장자</code></p>
<ul>
<li>ex)<code>vi mean-g.md</code></li>
</ul>
</li>
</ul>
<h4 id="2-git-명령어-">2) Git 명령어 :</h4>
<ul>
<li><p>git 시작 : <code>git init</code></p>
</li>
<li><p>git 상태 확인 : <code>git status</code></p>
</li>
<li><p>파일 수정 이력 기록 : <code>git commit</code></p>
</li>
<li><p>commut 이력 보기 : <code>git log</code></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Storage & Cookie란?]]></title>
            <link>https://velog.io/@mean-g/Storage-Cookie</link>
            <guid>https://velog.io/@mean-g/Storage-Cookie</guid>
            <pubDate>Wed, 29 Jun 2022 01:20:18 GMT</pubDate>
            <description><![CDATA[<h3 id="1-application-패널의-기능은">1. Application 패널의 기능은?</h3>
<ul>
<li><p>개발자 도구</p>
<ul>
<li>브라우저에서 제공하는 도구 (ex. IE 개발자 도구, Safari 개발자 도구, Chrome 개발자 도구,..), 웹 사이트를 즉각적으로 수정하고 문제 발생 시 원인을 파악하여 빠르게 대응할 수 있게 도와준다.</li>
</ul>
</li>
<li><p>브라우저 저장소의 기능을 담당한다. (로딩 된 웹 페이지에서 사용된 모든 리소스를 검사할 수 있는 패널이다.)
Ex) 이미지, 쿠키, 로컬 및 세션 스토리지..</p>
</li>
<li><p>프로그레시브 웹 앱 디버그</p>
</li>
<li><p>스토리지, DB 및 캐시 검사 및 관리</p>
</li>
<li><p>쿠키 검사 및 삭제</p>
</li>
<li><p>리소스 검사</p>
<br>

</li>
</ul>
<h3 id="2-local-storage-session-storage-cookie-차이점은">2. Local Storage, Session Storage, Cookie 차이점은?</h3>
<h4 id="공통사항">공통사항</h4>
<ul>
<li>Storage는 브라우저 저장소, 값의 성격에 따라 다르게 사용된다. 원래는 쿠키를 사용했고, html5에서 Local Storage와 Session Storage가 새로 도입되었다.<h4 id="1-local-storage">1) Local Storage</h4>
</li>
<li>사용자가 지우지 않으면 계속 브라우저에 남아있다. (Key-Value 페어의 객체 형태로 저장, 데이터의 영구성 보장)<h4 id="2-session-storage">2) Session Storage</h4>
</li>
<li>윈도우나 브라우저 탭을 닫으면 제거된다. (Key-Value 페어의 객체 형태로 저장)<h4 id="3-cookie">3) Cookie</h4>
</li>
<li>시간제한 설정이 가능하며, 프론트엔드와 백엔드 통신과 관련이 있다. 용량이 작다(4kb까지만 저장이 가능). (Key-Value페어의 문자열 형태로 데이터 저장 - 세미콜론으로 구분) 텍스트 타입이라 문자열만 저장한다.(사용자의 ID 차이?)<br>



</li>
</ul>
<h3 id="3-local-storage-session-storage-cookie-사용-예시---어떤-데이터를-어디에-저장하면-좋을까">3. Local Storage, Session Storage, Cookie 사용 예시 - 어떤 데이터를 어디에 저장하면 좋을까?</h3>
<h4 id="1-local-storage-1">1) Local Storage</h4>
<ul>
<li>지속적으로 필요한 데이터를 저장하면 좋다.<ul>
<li>data persistant( ex.Id 저장, 비회원 카트..)</li>
<li>UI 정보 (ex. 에어비엔비, 스카이스캐너 인천공항 -&gt; 베네치아 검색하면 그대로 유지)<h4 id="2-session-storage-1">2) Session Storage</h4>
</li>
</ul>
</li>
<li>잠깐 사용하는 정보를 저장하기 좋다.<ul>
<li>보안이 중요한 은행 사이트 정보, specific 한 유저 정보, 언어 선택...<h4 id="3-cookie-1">3) Cookie</h4>
</li>
</ul>
</li>
<li>직접적이지 않은 서비스 데이터를 저장하기에 좋다.     - ex. 이벤트 팝업, 약관 동의..</li>
</ul>
<br>

<h4 id="-비밀번호와-같은-중요-정보는-스토리지에-저장하면-위험하다-로컬스토리지나-세션스토리지는-클라이언트-사이드이기-때문에-쉽게-해킹당할-수-있기-때문이다-사이트--서비스의-특성-회사의-방침에-따라-user-data를-어떻게-처리하는지-전부-다르기-때문에-서비스-특성이나-기획에-맞게-적절하게-처리해야-한다">+) 비밀번호와 같은 중요 정보는 스토리지에 저장하면 위험하다. 로컬스토리지나 세션스토리지는 클라이언트 사이드이기 때문에 쉽게 해킹당할 수 있기 때문이다. 사이트 / 서비스의 특성, 회사의 방침에 따라 user data를 어떻게 처리하는지 전부 다르기 때문에 서비스 특성이나 기획에 맞게 적절하게 처리해야 한다.</h4>
<br>



<h3 id="4-local-storage-에-특정-데이터를-저장하고-가져오는-방법">4. Local Storage 에 특정 데이터를 저장하고 가져오는 방법</h3>
<p><img src="https://velog.velcdn.com/images/mean-g/post/74af8a41-3e80-41fa-b9dc-bc12b2cfd47d/image.png" alt="">
<strong>setItem()</strong> - key, value 추가
<strong>getItem()</strong> - value 읽어 오기
<strong>removeItem()</strong> - item 삭제. &gt; localStorage.removeItem(key);
<strong>clear()</strong> - 도메인 내의 localStorage 값 삭제 &gt; localStorage.clear();
<strong>length *<em>- 전체 item 갯수 &gt; localStorage.length;
*</em>key()</strong> - index로 key 이름 찾기 &gt; localStorage.key(index);</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Set, Dictionary, List, Tuple의 간단한 차이]]></title>
            <link>https://velog.io/@mean-g/Set-Dictionary-List-Tuple</link>
            <guid>https://velog.io/@mean-g/Set-Dictionary-List-Tuple</guid>
            <pubDate>Sun, 26 Jun 2022 09:02:12 GMT</pubDate>
            <description><![CDATA[<h2 id="1-list--tuple">1. List &amp; Tuple</h2>
<h4 id="공통-사항-">공통 사항 :</h4>
<ul>
<li>데이터들을 저장하게 해 주는 Data Structure (자료구조)이다.</li>
</ul>
<h4 id="list">List</h4>
<ul>
<li><p>수정이 가능하다.</p>
</li>
<li><p><code>[]</code> 를 사용한다.
<img src="https://velog.velcdn.com/images/mean-g/post/9047073e-19c0-4178-9d9b-f55694fd070c/image.png" alt=""></p>
</li>
<li><p>수정이 용의하기에 차지하는 메모리의 용량이 크다.</p>
</li>
</ul>
<h4 id="tuple">Tuple</h4>
<ul>
<li><p>수정이 불가능하다.</p>
</li>
<li><p><code>()</code>를 사용한다.
<img src="https://velog.velcdn.com/images/mean-g/post/f4a2dd5a-bdb1-4fb5-afb0-83c182e847e9/image.png" alt=""></p>
</li>
<li><p>기능이 적은만큼 차지하는 메모리의 용량이 작다. -&gt; 수정이 필요없는 간단한 형태의 데이터를 표현하기에는 tuple이 효과적이다.</p>
<br>
<br>


</li>
</ul>
<h2 id="2set--dictionary">2.Set &amp; Dictionary</h2>
<h4 id="공통-사항--1">공통 사항 :</h4>
<ul>
<li>데이터들을 저장하게 해 주는 Data Structure (자료구조)이다.</li>
</ul>
<h4 id="set-">Set :</h4>
<ul>
<li><p><code>{}</code>를 사용한다.
<img src="https://velog.velcdn.com/images/mean-g/post/d4076f7f-299f-41ce-9f55-1a2bfbcba822/image.png" alt=""></p>
</li>
<li><p>list와 같이 여러 다양한 타입의 요소(element)들을 저장할 수 있다.</p>
</li>
<li><p>하지만 list와 다르게 순서대로 저장되지 않는다. (ordering이 없으며, <code>for</code>문으로 읽어내면 요소들이 무작위로 나온다.) </p>
</li>
<li><p>동일한 값의 요소(중복되는 요소)는 1개만 존재할 수 있다. (새로 저장하는 요소가 기존 요소와 동일한 값이라면, 새로운 요소가 기존의 요소를 치환(replace)한다.)</p>
</li>
</ul>
<h4 id="dictionary-">Dictionary :</h4>
<ul>
<li><code>{}</code>를 사용한다.</li>
<li><code>key</code>값과 <code>value</code>값으로 이루어져있다.
<img src="https://velog.velcdn.com/images/mean-g/post/b436d42a-5222-4715-9c29-28e3e2473b27/image.png" alt=""></li>
<li>element를 읽는 방법은 list와 유사하지만, <code>index</code>가 아닌 <code>key</code>값을 사용한다.</li>
<li><code>key</code>값은 <code>string</code>뿐만아닌 숫자도 가능하나, 중복될 수 없다. (같은 값의 <code>key</code>값이 추가된다면 Set처럼 새로운 값이 기존 key의 요소를 치환한다.)
<img src="https://velog.velcdn.com/images/mean-g/post/bc247bb0-0043-4ba4-82e8-178b41682bfd/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 매개변수(Parameter)와 인수(Argument)]]></title>
            <link>https://velog.io/@mean-g/ParameterArgument</link>
            <guid>https://velog.io/@mean-g/ParameterArgument</guid>
            <pubDate>Sun, 26 Jun 2022 04:22:47 GMT</pubDate>
            <description><![CDATA[<h3 id="1-함수를-정의-할-때-default-value-parameter를-non-default-value-parameter-앞에-정의하면-안-되는-이유는-뭘까">1. 함수를 정의 할 때 default value parameter를 non-default value parameter 앞에 정의하면 안 되는 이유는 뭘까?</h3>
<ul>
<li>Default value parameter는 자신의 자리를 알고 있지만, non-Default value parameter는 모르기 때문에 자리에 맞춰서 정의해야 하는 게 아닐까?</li>
<li><blockquote>
<p>앞에서 default value parameter를 쓰더라도 positional arguments를 따라 순차적으로 인수가 할당되므로, 앞에 default value parameter에도 인수가 할당되고, 마지막 non-default value parameter에는 할당할 수 있는 인수가 없으므로 SyntaxError가 뜬다. 이런 일을 방지하고자 함수에서는 non-default value를 우선적으로 배치한다.</p>
<br>
</blockquote>
</li>
</ul>
<h3 id="2-위치-인수positional-arguments와-가변-인수variable-length-arguments의-위치를-참고-자료를-통해-조사해서-어떤-에러가-발생하는지-확인하고-에러를-고쳐보자">2. 위치 인수(positional arguments)와 가변 인수(variable length arguments)의 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생하는지 확인하고, 에러를 고쳐보자.</h3>
<p><img src="https://velog.velcdn.com/images/mean-g/post/b8736e1f-9b3b-4e6b-b8b7-2ed6705191af/image.png" alt="">
여기에서는 <code>*args</code>가 중간에 위치하고 있어서 오류가 발생함으로
아래처럼 수정해 준다.
<img src="https://velog.velcdn.com/images/mean-g/post/6f87566d-efda-489d-8620-c9c41ac48d23/image.png" alt="">
<code>*args</code> 위치만 바꿔주면 정상적으로 출력이 된다.
<br></p>
<h3 id="3-가변-키워드-인수-variable-length-keyword-arguments의-위치를-참고-자료를-통해-조사해서-어떤-에러가-발생하는지-확인하고-에러를-고쳐보자">3. 가변 키워드 인수 (variable length keyword arguments)의 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생하는지 확인하고, 에러를 고쳐보자.</h3>
<p><img src="https://velog.velcdn.com/images/mean-g/post/3748ec51-a6bb-46ae-bf03-b2b91b8a332f/image.png" alt="">
여기서는 <code>**kwargs</code>의 위치를 뒤쪽으로 수정해 준다.
<img src="https://velog.velcdn.com/images/mean-g/post/a36bc909-ab44-4858-af74-20baba7b7142/image.png" alt="">
이렇게 <code>**kwargs</code>의 위치만 수정해 주면 된다.</p>
<br>

<h3 id="4-위치-인수와-키워드-가변-키워드-인수-variable-length-keyword-arguments의-위치를-위치를-참고-자료를-통해-조사해서-어떤-에러가-발생하는지-확인하고-에러를-고쳐보자">4. 위치 인수와 키워드 가변 키워드 인수 (variable length keyword arguments)의 위치를 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생하는지 확인하고, 에러를 고쳐보자.</h3>
<p><img src="https://velog.velcdn.com/images/mean-g/post/c55af962-1c29-4c0e-8357-b84e1369502d/image.png" alt="">
해당 문제에서는 age와 address의 위치만 수정해 주면 된다.
<img src="https://velog.velcdn.com/images/mean-g/post/5b9f7ce4-93a2-4328-acbe-45286c6d64fc/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] 기초파이썬 #2]]></title>
            <link>https://velog.io/@mean-g/Basic-python2</link>
            <guid>https://velog.io/@mean-g/Basic-python2</guid>
            <pubDate>Thu, 23 Jun 2022 10:52:00 GMT</pubDate>
            <description><![CDATA[<h3 id="4-math-expressions">4. Math Expressions</h3>
<ul>
<li><p>더하기 <code>+</code>
ex) <code>num1 = 1</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num2 = 4</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num3 = num1 + num2</code>
num3는  1<code>+</code>4로, 5가 됩니다.</p>
</li>
<li><p>빼기<code>-</code>
ex) <code>num3 = num1 - num2</code>
num3는  1<code>-</code>4로, 3이 됩니다.</p>
</li>
<li><p>곱하기<code>*</code>
ex) <code>num3 = num1 * num2</code>
num3는  1<code>*</code>4로, 4가 됩니다.</p>
</li>
<li><p>나누기<code>/</code>
ex) <code>num3 = num1 / num2</code>
num3는  1<code>/</code>4로, 0.25가 됩니다.</p>
</li>
<li><p>정수 나누기<code>//</code>
ex) <code>num1 = 8</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num2 = 3</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num3 = num1 * num2</code>
num3는  8<code>//</code>3으로 2가 됩니다.</p>
</li>
</ul>
<h5 id="정수-나누기는-꼭-정수가-필요한-상황에서-유용하며-특히-slicing에서-많이-사용된다">+)정수 나누기는 꼭 정수가 필요한 상황에서 유용하며, 특히 slicing에서 많이 사용된다.</h5>
<ul>
<li>나머지<code>%</code> (나누기 한 나머지의 값을 계산한다.)
ex) <code>num1 = 8</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num2 = 3</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num3 = num1 % num2</code>
num3는  8 <code>%</code> 3로, 2가 됩니다.</li>
</ul>
<hr>
<ul>
<li>변수 값 더하기 <code>+=</code>
ex) <code>num1 = 10</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num += 1</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>print(num1)</code>
결과값 11이 출력된다.</li>
</ul>
<ul>
<li>변수 값 빼기 <code>-=</code>
ex) <code>num1 = 10</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num -= 1</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>print(num1)</code>
결과값 9이 출력된다.</li>
</ul>
<ul>
<li><p>변수 값 더하기 <code>*=</code>
ex) <code>num1 = 10</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num *= 2</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>print(num1)</code>
결과값 20이 출력된다.</p>
</li>
<li><p>나누기한 값을 변수에 저장한다. <code>/=</code>
ex) <code>num1 = 10</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>num /= 2</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>print(num1)</code>
결과값 5가 출력된다.</p>
</li>
<li><p>멱법(Exponentiation) <code>**</code>
ex) 10의 2승</p>
</li>
<li><blockquote>
<p><code>num1 = 10 ** 2</code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>print(num1)</code>
결과값 100이 출력된다.</p>
</blockquote>
</li>
</ul>
<h4 id="연산자의-우선순위를-생각하고-진행해야-한다">*연산자의 우선순위를 생각하고 진행해야 한다.</h4>
]]></description>
        </item>
    </channel>
</rss>