<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>seung-sang.log</title>
        <link>https://velog.io/</link>
        <description>틈틈히 공부 홀릭</description>
        <lastBuildDate>Sat, 22 Jan 2022 05:03:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>seung-sang.log</title>
            <url>https://images.velog.io/images/seung-sang/profile/f6085411-adf8-4b00-aa49-8786a35d287e/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. seung-sang.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/seung-sang" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Flask 파일 다운로드]]></title>
            <link>https://velog.io/@seung-sang/flask-file-download</link>
            <guid>https://velog.io/@seung-sang/flask-file-download</guid>
            <pubDate>Sat, 22 Jan 2022 05:03:59 GMT</pubDate>
            <description><![CDATA[<p>html 의 form 태그로 전송한 파일을 Flask 서버에서 받아 저장해보자.</p>
<pre><code class="language-html">&lt;!-- form.html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
    &lt;script src=&quot;form.js&quot; defer&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;파일 업로드&lt;/h1&gt;
        &lt;form id=&quot;file-form&quot; 
              action=&quot;http://localhost:5000/upload&quot;
              method=&quot;POST&quot;
              enctype=&quot;multipart/form-data&quot;
              target=&#39;blankifr&#39;&gt; 
            &lt;input type=&quot;file&quot; name=&#39;file&#39; multiple /&gt;
            &lt;button id=&quot;file-submit&quot; type=&quot;button&quot;&gt;UPLOAD&lt;/button&gt;
        &lt;/form&gt;
    &lt;/body&gt;
    &lt;iframe name=&#39;blankifr&#39; style=&#39;display:none;&#39;&gt;&lt;/iframe&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">// form.js
const submit_form = document.querySelector(&quot;#file-form&quot;)
const submit_btn = document.querySelector(&#39;#file-submit&#39;)

submit_btn.addEventListener(&#39;click&#39;, function () {
    submit_form.submit()
})</code></pre>
<p>form 태그를 통해서 action 의 경로로 파일을 보낼 수 있다.</p>
<pre><code class="language-html">&lt;!-- form.html --&gt;
&lt;form id=&quot;file-form&quot; 
    action=&quot;http://localhost:5000/upload&quot;
    method=&quot;POST&quot;
    enctype=&quot;multipart/form-data&quot;
    target=&#39;blankifr&#39;&gt; </code></pre>
<p>action 은 파일이 전송될 경로,<br>method 는 파일을 Flask 서버로 보낼 것이기 때문에 POST<br>enctype 은 단순 텍스트가 아닌, 이미지 등을 전송할 것이기 때문에 &quot;multipart/form-data&quot;  target 은 <a href="https://velog.io/@seung-sang/form-submit-not-move-page">이미지 전환 방지 참고</a></p>
<p>이제 Flask 서버에서 form 이 보낸 파일들을 받아보자.
request.files.getlist(&#39;file&#39;) 를 사용하면 된다. 
매개 변수 &#39;file&#39; 은 파일을 업로드할 때 사용한 input의 name 값으로 사용해야 한다.</p>
<pre><code class="language-html">&lt;!-- form.html --&gt;
&lt;input type=&quot;file&quot; name=&#39;file&#39; multiple /&gt;</code></pre>
<p>Flaks 서버의 코드이다.</p>
<pre><code class="language-python"># app.py
from flask import Flask, request

app = Flask(__name__)

@app.route(&#39;/upload&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;])
def uploading():
    if request.method == &#39;POST&#39;:
        print(&#39;POST&#39;)
    files = request.files.getlist(&#39;file&#39;)
    for f in files:
        f.save(&#39;./files/&#39; + f.filename)
    return &#39;done!&#39;

if __name__ == &#39;__main__&#39;:
    app.run(host=&#39;127.0.0.1&#39;, port=5000, debug=True)</code></pre>
<p>파일을 업로드하면, </p>
<p><img src="https://images.velog.io/images/seung-sang/post/811843c3-7772-4e9c-93d8-f247a259f1e6/form_after.gif" alt=""></p>
<p>정상적으로 files 폴더 내부에 업로드한 파일이 생성된다.</p>
<p><img src="https://images.velog.io/images/seung-sang/post/1ebbfaef-5533-473f-a620-6f25ace5f2d6/flask-file-download.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Form Submit 페이지 이동 방지]]></title>
            <link>https://velog.io/@seung-sang/form-submit-not-move-page</link>
            <guid>https://velog.io/@seung-sang/form-submit-not-move-page</guid>
            <pubDate>Sat, 22 Jan 2022 02:36:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/seung-sang/post/aac46494-9939-402f-9624-b0b890b6f4aa/form_before.gif" alt=""></p>
<details>
<summary>submit 시, 페이지가 이동하는 코드 열기/닫기</summary>

<pre><code class="language-html">&lt;!-- form.html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
    &lt;script src=&quot;form.js&quot; defer&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;파일 업로드&lt;/h1&gt;
        &lt;form id=&quot;file-form&quot; 
              action=&quot;http://localhost:5000/upload&quot;
              method=&quot;POST&quot;
              enctype=&quot;multipart/form-data&quot;&gt;
            &lt;input type=&quot;file&quot; name=&#39;file&#39; multiple /&gt;
            &lt;button id=&quot;file-submit&quot; type=&quot;button&quot;&gt;UPLOAD&lt;/button&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">// form.js
const submit_form = document.querySelector(&quot;#file-form&quot;)
const submit_btn = document.querySelector(&#39;#file-submit&#39;)

submit_btn.addEventListener(&#39;click&#39;, function () {
    submit_form.submit()
})</code></pre>
</details>

<p>form 태그를 이용하여 파일을 전송하면 action 의 경로로 이동해 버린다.
페이지 이동없이, 단순히 파일만 action 의 경로로 전송하고 싶을 경우는 어떻게 해야할까?</p>
<p><img src="https://images.velog.io/images/seung-sang/post/2cd4b9d2-4a6e-4aa5-b59c-0f56e248e685/form_after.gif" alt=""> </p>
<p>form 의 target 속성을 이용하여 응답을 iframe 으로 보내버리면 된다.
form 의 target 과 iframe 의 name 을 일치시켜줘야 한다.
iframe 을 적용한 코드이다.</p>
<pre><code class="language-html">&lt;!-- form.html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
    &lt;script src=&quot;form.js&quot; defer&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;파일 업로드&lt;/h1&gt;
        &lt;form id=&quot;file-form&quot; 
              action=&quot;http://localhost:5000/upload&quot;
              method=&quot;POST&quot;
              enctype=&quot;multipart/form-data&quot;
              target=&#39;blankifr&#39;&gt; 
            &lt;input type=&quot;file&quot; name=&#39;file&#39; multiple /&gt;
            &lt;button id=&quot;file-submit&quot; type=&quot;button&quot;&gt;UPLOAD&lt;/button&gt;
        &lt;/form&gt;
    &lt;/body&gt;
    &lt;iframe name=&#39;blankifr&#39; style=&#39;display:none;&#39;&gt;&lt;/iframe&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-js">// form.js
const submit_form = document.querySelector(&quot;#file-form&quot;)
const submit_btn = document.querySelector(&#39;#file-submit&#39;)

submit_btn.addEventListener(&#39;click&#39;, function () {
    submit_form.submit()
})</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[코세라(coursera) jupyter 과제 로컬에 정리]]></title>
            <link>https://velog.io/@seung-sang/coursera-jupyter-local-save</link>
            <guid>https://velog.io/@seung-sang/coursera-jupyter-local-save</guid>
            <pubDate>Sat, 15 Jan 2022 08:34:16 GMT</pubDate>
            <description><![CDATA[<p>Coursera 의 &#39;Deep Learning Specialization&#39; 를 수강할 때, 실습을 위해 Jupyter 로 과제를 제공하고 있습니다.<br>Coursera 자체에서 각 과제간 스위칭이 힘들고, 수강이 완료된 이후에 접근이 불가하기 때문에 로컬에 저장할 필요가 있습니다.</p>
<p>저는 최종적으로 아래와 같이 저장하려고 합니다. (코드 이외에 이미지, 모듈 등)</p>
<p><img src="https://images.velog.io/images/seung-sang/post/d63e2f65-fd67-41ef-9385-b398f2427144/goal_folder_structure.png" alt=""></p>
<p>단순히 Jupyter 에서 File&gt;Download 시, 이미지 없이 코드만 저장되기 때문에 아래와 같이 보일 수 있습니다.<br><img src="https://images.velog.io/images/seung-sang/post/266d0872-9502-45db-ac27-5481f1bf8c01/ipynb_download.png" alt="">
코드만 다운받을 경우 이미지는 엑박으로 보여집니다.
<img src="https://images.velog.io/images/seung-sang/post/1ed62b73-c558-49c5-8996-a9c4d7b623ae/image_error.png" alt=""></p>
<h2 id="다운로드-순서">다운로드 순서</h2>
<p>이미지 포함 모든 파일을 다운로드해서 저장하겠습니다.</p>
<ol>
<li><p>File -&gt; Open 을 누릅니다.<br><img src="https://images.velog.io/images/seung-sang/post/220a792a-d692-4678-b920-711006016be8/open_terminal1.png" alt=""></p>
</li>
<li><p>ipynb 파일과 그 안에 사용되는 데이터 폴더들이 보이지만 다운받을 수 있는 버튼이 보이지 않습니다.<br><img src="https://images.velog.io/images/seung-sang/post/881a9adc-d9e4-4d3f-8fa1-011abc3f3c03/open_terminal2.png" alt=""></p>
</li>
<li><p>우측의 New -&gt; Terminal 을 누릅니다.<br><img src="https://images.velog.io/images/seung-sang/post/61e2f2af-f0e5-4957-807e-f59fb0b81e66/open_terminal3.png" alt=""></p>
</li>
<li><p>terminal 창에 &#39;tar -cvf release.tar release&#39; 를 입력합니다.<br><img src="https://images.velog.io/images/seung-sang/post/09d72f3e-f958-44b1-9b8b-355bcd44acaf/tar_ipynb.png" alt=""><br>(ls 입력하면 release 라는 폴더가 있는것을 알 수 있습니다. release 폴더 기준으로 하위 폴더에 각 과제와 관련된 폴더들이 모두 있습니다.)</p>
</li>
<li><p>뒤로가기 후, 최상위 폴더 버튼을 누르면, release.tar 이 존재합니다. release.tar 을 체크하면 Download 버튼이 뜹니다. 이를 다운받아 반디집같은 압축해제 프로그램으로 압축해제후 사용하시면 됩니다.
<img src="https://images.velog.io/images/seung-sang/post/da3c607a-4e48-4bf6-9937-277ee3d41d1d/download_ipynb_tar.png" alt=""></p>
</li>
</ol>
<br>
<br>
<br>

<p>이제 원하시는 구조로 로컬에 정리하시면 됩니다.<br><img src="https://images.velog.io/images/seung-sang/post/0717beab-4310-4f7e-877a-822d228d2674/goal_folder_structure.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정밀도(precision) 과 재현율(recall)]]></title>
            <link>https://velog.io/@seung-sang/precision-recall</link>
            <guid>https://velog.io/@seung-sang/precision-recall</guid>
            <pubDate>Sat, 15 Jan 2022 08:29:19 GMT</pubDate>
            <description><![CDATA[<p>정밀도(precision) : Positive 로 예측한 값 중 실제값도 Positive 인 비율
재현율(recall) : 실제값이 Positive 인 것 중에 예측값도 Positive 인 비율</p>
<p>precision = $\frac{TP}{TP +FP}$<br>recall = $\frac{TP}{TP +FN}$</p>
<img src=https://images.velog.io/images/seung-sang/post/db845b64-97c2-4fe9-8721-1f1fa547ef3f/precision-recall.png width=400px/>

<blockquote>
<p>정밀도와 재현율이 1에 가까워질수록 좋지만, 정밀도와 재현율은 trade-off 관계이다.</p>
</blockquote>
<p>즉, 두 값을 따로 보지 않고 같이 고려해야한다.</p>
<pre><code>재현율을 올리기 위해, 
Positive 로 판단하는 기준을 낮춰 Positive 로 판단할 확률을 높아진다. (FN 값이 낮아짐) 
하지만 Negative 도 Positive 로 판단하기도 쉬워짐(FP가 증가함)을 의미한다.
결국, 정밀도의 값이 줄어든다.  </code></pre><p>상황에 따라 어디에 더 초점을 맞춰서 고려할지 생각해야 한다.<br>예측을 더 잘하고 싶다면(잘못된 예측을 줄이고 싶다면) 정밀도에 좀 더 초점을 둬야한다.<br>실제 Positive 인 데이터를 Positive 로 예측하고 싶다면 재현율에 좀 더 초점을 둬야한다.  </p>
<blockquote>
<p>이러한 정밀도와 재현율의 trade-off 를 고려한 것이 F-Score 이다.</p>
</blockquote>
<p>현재 정밀도와 재현율은 TP를 분자로써 공유하기 때문에, 조화평균으로 고려해볼 수 있다.</p>
<p>조화평균에 대한 예시로 &#39;동일한 거리를 다른 속력으로 이동할 때, 평균속력은 무엇인가?&#39; 가 있다.<br>이 때, 동일한 거리에 대해서 시간의 영향성을 고려한다.<br>재현율과 정밀도도 유사하게 생각해보면 동일한 TP 에 대해서 (TP +FP) 와 (TP+ FN) 를 고려하는 것으로 볼 수 있다.<br>즉, 재현율과 정밀도를 조화평균을 사용하여 둘 사이의 관계를 나타내는 평균값을 구할 수 있다.<br>이제 이 값을 이용해서 재현율, 정밀도 바뀌어도 이전 값과 비교를 할 수 있게 되었다.  </p>
<p>도형으로 생각해보면 아래의 노란선이 조화평균입니다.<br>(재현율과 정밀도 값이, 지름(재현율+정밀도)를 공유하고 있습니다.)  </p>
<p><img src="https://images.velog.io/images/seung-sang/post/1e0874da-61d3-4298-9252-2fddae4f0052/precision-recall2.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기하 평균(Geometric Mean)]]></title>
            <link>https://velog.io/@seung-sang/geometric-mean</link>
            <guid>https://velog.io/@seung-sang/geometric-mean</guid>
            <pubDate>Sat, 15 Jan 2022 04:25:41 GMT</pubDate>
            <description><![CDATA[<p>(a&gt;0, b&gt;0, c&gt;0)</p>
<p>$$\sqrt[2]{ab} ,\quad \sqrt[3]{abc}$$</p>
<p>넓이가 ab 인 정사각형의 한변의 길이는 얼마인가?<br>부피가 abc 인 정육면체의 한변의 길이는 얼마인가?
$$\vdots$$</p>
</br>

<h2 id="기하평균의-실제-사용사례">기하평균의 실제 사용사례</h2>
<p>두 개의 주식이 있있는데, 
두 주식 가격을 각 만원에 샀다고 하자.<br>1번 주식은 1일차 때 20%가 오르고, 2일차 때 20%가 내렸다.<br>2번 주식은 1일차 때 20%가 내리고, 2일차 때 20%가 올랐다.    </p>
<blockquote>
<p>내 주식의 가치는 떨어졌을까? 올랐을까?</p>
</blockquote>
<ul>
<li>1번 주식.  </li>
</ul>
<table>
<thead>
<tr>
<th align="center">날짜</th>
<th align="center">등락률</th>
<th align="center">가격</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1일차</td>
<td align="center">20% ↑</td>
<td align="center">10,000 + 2,000 = 12,000</td>
</tr>
<tr>
<td align="center">2일차</td>
<td align="center">20% ↓</td>
<td align="center">12,000 - 2,400 = 9,600</td>
</tr>
</tbody></table>
<ul>
<li>2번 주식</li>
</ul>
<table>
<thead>
<tr>
<th align="center">날짜</th>
<th align="center">등락률</th>
<th align="center">가격</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1일차</td>
<td align="center">20% ↓</td>
<td align="center">10,000 - 2,000 = 8,000</td>
</tr>
<tr>
<td align="center">2일차</td>
<td align="center">20% ↑</td>
<td align="center">8,000 + 1,600 = 9,600</td>
</tr>
</tbody></table>
<p>두 주식의 가격은 그대로 만원이 아니라 만원보다 작아집니다.</p>
<p>기존에 있던것에 20% 가 플러스 마이너스되는 것이 아니라, 순차적으로 하나의 계산이 이루어지고 나온 값이 다음 계산에 적용됩니다.  </p>
</br>
</br>

<h2 id="도형으로-생각">도형으로 생각</h2>
<p>1번 주식에 대한 경우를 도형으로 생각해 봅시다.</p>
<!--
<svg width="300" height="80">
    <rect x="0" y="20" width="50" height="50" style="fill:blue;stroke:red;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="80" y="20" width="50" height="50" style="fill:blue;stroke:red;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="80" y="20" width="60" height="50" style="fill:blue;stroke:green;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="160" y="20" width="50" height="50" style="fill:blue;stroke:red;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="160" y="20" width="60" height="50" style="fill:blue;stroke:green;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="160" y="20" width="60" height="40" style="fill:blue;stroke:blue;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
</svg>
-->

<p><img src="https://images.velog.io/images/seung-sang/post/3d83281c-df7b-40d1-ab57-306eef3334e7/image.png" alt=""></p>
<p>빨간색은 처음 주식의 가격입니다.
1일차 때는 한변의 길이가 현재의 1.2(20%) 로 늘어났습니다.
2일차 때는 한변의 길이가 현재의 0.8(20%) 로 줄어들었습니다.</p>
<!--
<svg width="300" height="80">
    <rect x="0" y="20" width="50" height="50" style="fill:blue;stroke:red;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="80" y="20" width="60" height="40" style="fill:blue;stroke:blue;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
</svg>
-->

<p><img src="https://images.velog.io/images/seung-sang/post/5004719e-76f6-48c6-bda6-139369f26f0c/image.png" alt=""></p>
<p>최종적으로 마지막 사각형(파란색)과 처음 사각형(빨간색)을 비교하려고 하니, 어떤 사각형이 더 큰지 알수가 없습니다.  </p>
<p>이럴 때, 기하평균으로써 생각해 봅시다.
모두 하나의 기준인 정사각형으로 통일해봅니다.</p>
<!--
<svg width="300" height="80">
    <rect x="0" y="20" width="50" height="50" style="fill:blue;stroke:red;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
    <rect x="0" y="20" width="48.9" height="48.9" style="fill:blue;stroke:blue;stroke-width:3;fill-opacity:0.1;stroke-opacity:0.9" />
</svg>
-->

<p><img src="https://images.velog.io/images/seung-sang/post/a87ad0a9-6407-478d-81dc-443ffcab0a84/image.png" alt=""></p>
<p>직사각형을 정사각형으로 변환하면, 두 도형이 완전히 겹치지 않고 &#39;직사각형에서 정사각형으로 변환한 정사각형(파란색)&#39;이 조금 더 작은것을 알 수가 있습니다.  </p>
<p>이렇게 기하평균의 개념을 사용하면, 정사각형으로 변경하였을 때의 변의 길이를 비교하여 퍼센트 연산된 값을 비교해볼 수 있습니다.</p>
<p>이 예시에서는 2번의 퍼센트 연산이 일어났으므로 변이 두개인 정사각형을 생각했지만, 
3번의 퍼센트 연산이 일어나면 정육면체, ... 계속해서 차원을 확장해서 고려해볼수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클래스 변수(class variable)와 인스턴스 변수(instance variable)]]></title>
            <link>https://velog.io/@seung-sang/class-variable-vs-instance-variable</link>
            <guid>https://velog.io/@seung-sang/class-variable-vs-instance-variable</guid>
            <pubDate>Fri, 14 Jan 2022 11:26:15 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-python">class Factory:
    num = 0 # 클래스 변수
    def increaseClassNum(self):
        Factory.num += 1 # 클래스를 이용한 변수 접근
    def increaseInstanceNum(self):
        self.num += 1 # 인스턴스 변수</code></pre>
<p>클래스 변수는 Class 선언시 바로 아래 self.~ 형태가 아닌 변수,
인스턴스 변수는 self.~ 형태의 변수라고 생각하면 된다. </p>
<p>클래스 변수와 인스턴스 변수는 몇 가지 특징이 있다.</p>
<ol>
<li>클래스 변수는 모든 인스턴스가 공유할 수 있다.</li>
<li>인스턴스에서 인스턴스 변수를 클래스 변수와 동일한 이름으로 선언할 경우, 인스턴스에서 변수 호출시 클래스 변수가 아닌 인스턴스 변수를 호출하게 된다.</li>
</ol>
<h2 id="시나리오">시나리오</h2>
<p>좀 더 상세히 알기 위한 여러 케이스에 대한 시나리오이다.</p>
<blockquote>
<p>id 가 같으면 동일함을 의미합니다.</p>
</blockquote>
<ol>
<li>Factory 인스턴스 A 생성</li>
<li>A 의 increaseClassNum() 수행<ul>
<li>id(A.num) == id(Factory.num)</li>
<li>A.num : 1</li>
<li>Factory.num : 1</li>
</ul>
</li>
<li>Factory 클래스를 통해 직접적으로 num 을 3으로 수정<ul>
<li>id(A.num) == id(Factory.num)</li>
<li>A.num : 3</li>
<li>Factory.num : 3</li>
</ul>
</li>
<li>Factory 인스턴스 B 생성<ul>
<li>id(A.num) == id(B.num)</li>
<li>B.num : 3</li>
<li>Factory.num : 3</li>
</ul>
</li>
<li>B 의 increaseClassNum() 수행<ul>
<li>id(A.num) == id(B.num)</li>
<li>A.num : 4</li>
<li>B.num : 4</li>
<li>Factory.num : 4</li>
</ul>
</li>
<li>B 의 increaseInstanceNum() 수행<ul>
<li>id(A.num) != id(B.num)</li>
<li>id(A.num) == id(Factory.num)</li>
<li>id(B.num) != id(Factory.num)</li>
<li>A.num : 4</li>
<li>B.num : 5</li>
<li>Factory.num : 4</li>
</ul>
</li>
</ol>
<p>시나리오에 대한 코드와 각 출력값을 기록했습니다.</p>
<pre><code class="language-python"># 1. Factory 인스턴스 A 생성
A = Factory()

# 2. A 의 increaseClassNum() 수행
A.increaseClassNum()

print(id(A.num) == id(Factory.num))  # True

print(A.num)  # 1
print(Factory.num)  # 1

# 3. Factory 클래스를 통해 직접적으로 num 을 3으로 수정
Factory.num = 3

print(A.num)  # 3
print(Factory.num)  # 3

# 4. Factory 인스턴스 B 생성
B = Factory()

print(id(A.num) == id(B.num))  # True
print(B.num)  # 3
print(Factory.num)  # 3

# 5. B 의 increaseClassNum() 수행
B.increaseClassNum()

print(id(A.num) == id(B.num))  # True
print(A.num)  # 4
print(B.num)  # 4
print(Factory.num)  # 4

# 6. B 의 increaseInstanceNum() 수행
B.increaseInstanceNum()

print(id(A.num) == id(B.num))  # False
print(id(A.num) == id(Factory.num))  # True
print(id(B.num) == id(Factory.num))  # False
print(A.num)  # 4
print(B.num)  # 5
print(Factory.num)  # 4</code></pre>
]]></description>
        </item>
    </channel>
</rss>