<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>rocky-won.log</title>
        <link>https://velog.io/</link>
        <description>Python을 좋아합니다.</description>
        <lastBuildDate>Thu, 04 Dec 2025 01:56:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>rocky-won.log</title>
            <url>https://velog.velcdn.com/images/rocky-won/profile/b0a6aaa1-5b00-40e5-b920-1740c68beacd/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. rocky-won.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/rocky-won" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[LOG-001] FastAPI 메모리 부족 문제 해결]]></title>
            <link>https://velog.io/@rocky-won/LOG-001-FastAPI-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%B6%80%EC%A1%B1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@rocky-won/LOG-001-FastAPI-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%B6%80%EC%A1%B1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Thu, 04 Dec 2025 01:56:27 GMT</pubDate>
            <description><![CDATA[<p><strong>날짜:</strong> 2025-12-04
<strong>프로젝트:</strong> ML Platform API
<strong>키워드:</strong> Kubernetes, Memory Management, OOM Kill, FastAPI, Resource Limits</p>
<hr>
<h2 id="문제-상황">문제 상황</h2>
<p>FastAPI 서버가 메모리 부족으로 반복적으로 종료되는 현상 발생</p>
<pre><code>현상: Pod가 주기적으로 재시작
원인 추정: OOM (Out of Memory) Kill</code></pre><h2 id="원인-분석">원인 분석</h2>
<p>Kubernetes deployment 설정을 확인한 결과, 메모리 리소스 할당이 부족함을 발견. 초기에는 경량 데이터와 서비스를 제공하던 역할만 하고 있어서 메모리 할당량을 적게 부여한 상태였음.</p>
<p><strong>기존 설정:</strong></p>
<pre><code class="language-yaml">resources:
  requests:
    cpu: &quot;100m&quot;
    memory: &quot;128Mi&quot;    # 너무 낮음
  limits:
    cpu: &quot;500m&quot;
    memory: &quot;512Mi&quot;    # ML 작업에 부족</code></pre>
<p><strong>문제점:</strong></p>
<ul>
<li>FastAPI 애플리케이션이 ML 관련 작업 수행 (pandas, numpy, quantstats 등)</li>
<li>차트 생성, 보고서 생성 등 메모리 intensive한 작업이 늘어남</li>
<li>512Mi limit를 초과하면 OOM Kill 발생 → Pod 종료 → 재시작 반복</li>
</ul>
<h2 id="해결-방법">해결 방법</h2>
<p>메모리 리소스 할당량 증가:</p>
<pre><code class="language-yaml">resources:
  requests:
    cpu: &quot;100m&quot;
    memory: &quot;512Mi&quot;    # 128Mi → 512Mi (4배)
  limits:
    cpu: &quot;500m&quot;
    memory: &quot;2Gi&quot;      # 512Mi → 2Gi (4배)</code></pre>
<p><strong>적용:</strong></p>
<pre><code class="language-bash">kubectl apply -f kubernetes/deployment.yaml</code></pre>
<p>변경 사항 적용 후 rolling update를 통해 새로운 메모리 설정으로 pod 재시작.</p>
<h2 id="학습-포인트">학습 포인트</h2>
<h3 id="1-kubernetes-memory-requests-vs-limits">1. Kubernetes Memory Requests vs Limits</h3>
<p><strong>Memory Requests (요청량):</strong></p>
<ul>
<li>Pod 스케줄링 시 사용 (어느 노드에 배치할지 결정)</li>
<li>실제 메모리 사용량을 제한하지 않음</li>
<li>requests가 낮아도 pod가 바로 종료되지는 않음</li>
</ul>
<p><strong>Memory Limits (제한량):</strong></p>
<ul>
<li>실제 메모리 사용량의 상한선</li>
<li>이 값을 초과하면 <strong>OOM Kill 발생</strong> → Pod 강제 종료</li>
<li><strong>이게 메모리 부족으로 pod가 죽는 진짜 원인</strong></li>
</ul>
<h3 id="2-requests가-낮을-때의-영향">2. Requests가 낮을 때의 영향</h3>
<ol>
<li><strong>스케줄링</strong>: requests가 낮으면 어떤 노드에도 쉽게 배치 가능</li>
<li><strong>Eviction 우선순위</strong>: 노드 전체 메모리 부족 시 requests가 낮은 pod부터 축출될 수 있음</li>
<li><strong>리소스 경쟁</strong>: 실제로 많은 메모리를 사용하는데 requests가 낮으면 다른 pod들과 메모리 경쟁</li>
</ol>
<h3 id="3-리소스-할당-전략">3. 리소스 할당 전략</h3>
<p><strong>권장 설정:</strong></p>
<ul>
<li><strong>requests</strong> = 실제 평균 사용량</li>
<li><strong>limits</strong> = 피크 사용량 + 여유분</li>
</ul>
<p><strong>모니터링:</strong></p>
<pre><code class="language-bash"># Pod 메모리 사용량 확인
kubectl top pods -n fastapi-app

# Pod 상세 정보
kubectl describe pod &lt;pod-name&gt; -n fastapi-app</code></pre>
<h2 id="추가-고려사항">추가 고려사항</h2>
<h3 id="고가용성-high-availability">고가용성 (High Availability)</h3>
<p>현재 deployment 설정:</p>
<pre><code class="language-yaml">replicas: 2
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0</code></pre>
<p><strong>질문:</strong> 노드 1개 vs 노드 2개?</p>
<p><strong>답변:</strong> 프로덕션 환경에서는 <strong>노드 2개 권장</strong></p>
<p><strong>이유:</strong></p>
<ol>
<li><strong>고가용성</strong>: 노드 1개 장애 시에도 서비스 계속 운영</li>
<li><strong>무중단 배포</strong>: <code>maxUnavailable: 0</code> 설정과 조합하여 진정한 무중단 배포</li>
<li><strong>장애 격리</strong>: 한 노드의 하드웨어/커널 문제가 전체 서비스에 영향 없음</li>
<li><strong>Pod 분산</strong>: 2개 replica가 서로 다른 노드에 배치되어 리스크 분산</li>
</ol>
<p><strong>추가 최적화 - Pod Anti-affinity:</strong></p>
<pre><code class="language-yaml">spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - fastapi
          topologyKey: kubernetes.io/hostname</code></pre>
<p>이 설정은 2개 pod를 서로 다른 노드에 배치하도록 유도함.</p>
<h3 id="replica-제대로-작동하는지-확인">Replica 제대로 작동하는지 확인</h3>
<pre><code class="language-bash"># Pod 개수 확인
kubectl get pods -n fastapi-app -l app=fastapi

# Pod가 어느 노드에 있는지 확인 (분산되어 있는지)
kubectl get pods -n fastapi-app -l app=fastapi -o wide

# Deployment 상태 확인
kubectl get deployment -n fastapi-app fastapi-deployment</code></pre>
<p><strong>주의:</strong> 노드가 1개밖에 없으면 pod 2개가 같은 노드에 배치됨 → 고가용성 없음</p>
<h2 id="다음-액션">다음 액션</h2>
<ul>
<li><input disabled="" type="checkbox"> 메모리 사용량 모니터링 (kubectl top pods)</li>
<li><input disabled="" type="checkbox"> 여전히 OOM 발생 시 limits를 4Gi까지 증가 고려</li>
<li><input disabled="" type="checkbox"> 노드 개수 및 분산 상태 확인</li>
<li><input disabled="" type="checkbox"> 필요시 Pod Anti-affinity 설정 추가</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발자라는 이름의 감옥]]></title>
            <link>https://velog.io/@rocky-won/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%9D%BC%EB%8A%94-%EC%9D%B4%EB%A6%84%EC%9D%98-%EA%B0%90%EC%98%A5</link>
            <guid>https://velog.io/@rocky-won/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%9D%BC%EB%8A%94-%EC%9D%B4%EB%A6%84%EC%9D%98-%EA%B0%90%EC%98%A5</guid>
            <pubDate>Thu, 27 Nov 2025 06:06:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ol>
<li>소는 가축이 아니다.</li>
</ol>
</blockquote>
<p>나는 소가 가축이 아니라고 생각한다. 이 판단은 내가 소고기를 먹는 것을 좋아하는 것과는 무관하게 성립하는 명제다. 내게 &#39;소&#39;는 어떠한 집단적 범주이기 이전에 하나의 개별자로서 생명을 의미한다. 소가 가축이 된 이야기는 인류의 문명적 서사와 함께할 뿐, 소를 인식하는 나의 인식 체계의 근본 명제가 되지는 못하는 셈이다. 가축 이외의 가능성을 타진하는 것이 소에 대한 최소한의 배려라고 생각한다.</p>
<blockquote>
<ol start="2">
<li>개발자는 개발하는 사람이 아니다.</li>
</ol>
</blockquote>
<p>이 명제는 소에 대한 나의 사유와 동일한 궤적을 그린다. 개발자라는 단어는 이미 기술 문명 사회의 거대한 서사 속에서 굳어진 기표가 되었다. 이 기표는 문제를 효율적으로 해결하는 사람, 코드를 짜는 기계, 특정 기술 스택의 전문가, 높은 연봉을 받는 직업인 같은 일련의 기의를 불러일으킨다. 사회는 이 기표가 함축하는 기의를 확대 재생산하며 소비한다. 이 집단적 기의의 압박 속에서 개별자는 가축화의 위험에 놓인다.</p>
<blockquote>
<ol start="3">
<li>커리어는 여정이 아니다.</li>
</ol>
</blockquote>
<p>커리어가 하나의 여정이라는 관념은 새로운 신화다. 이 관념에는 개인의 파편화된 밥벌이 경험을 유기적이고 통합적인 계획의 대상으로 만드는 힘이 있다. 현대 사회의 불안한 노동 환경 위에 휩쓸려가지 않도록 부표를 세우는 정박성이 있는 셈이다. 하지만 여기에는 한 가지 부작용이 있다. 바로 오늘의 체험을 약화시킨다는 점이다. 체험을 약화시키는 질문은 바로 이런 것이다. &#39;다음 직급으로 승진하기 위해 오늘 하루 나는 충분히 발전했던가?&#39; 이같은 질문이 독극물처럼 느껴지는 이유는 발견의 즐거움, 배움에 감탄하는 존재로서의 자신을 질식시키기 때문이다. 잘못된 질문은 매일의 하루를 이력서의 재료로 축소시키고 만다.</p>
<blockquote>
<ol start="4">
<li>개발자는 개발을 체험하는 존재다.</li>
</ol>
</blockquote>
<p>개발자는 매번 새로운 코드를 작성할 때마다 단순한 기능 구현 이상의 무언가를 투영한다. 그가 투영하는 것은 자신의 존재와 생명이다. 밤샘 작업 끝에 찾아온 깨달음, 디버깅 속에서 얻은 고독한 기쁨, 또는 자신의 서비스가 누군가의 삶을 개선할 때 느끼는 미묘한 성취감 등이야말로 &#39;개발자&#39;라는 기표가 포착하지 못하는 살아있는 기의이다. 소를 가축이라는 범주로 가두지 않고 생명으로 인식하듯, 개발자 역시 직업이라는 프레임 너머의 주체로 호명되어야 까닭은 이러한 창조성을 부흥시키기 위함이다.</p>
<blockquote>
<ol start="5">
<li>개발자는 가축이 아니다.</li>
</ol>
</blockquote>
<p>소가 가축이 아니듯, 개발자도 개발하는 사람이 아니다. 이 선언은 개발자의 직무를 부정하는 것이 아니라 직무가 존재의 전부가 아님을 강조한다. &#39;개발자&#39;라는 기표를 잠시 내려놓을 때, 우리는 그 자리에 서 있는 한 명의 복잡하고 입체적인 인간을 발견하게 된다. 이 인간은 가축이 아니다. 그는 개발자라는 기표의 울타리를 넘어설 수 있는 생명력을 지닌 존재다. 나는 이같은 새로운 언어적 코드의 발명과 매핑이야말로 개발자가 추구할 수 있는 궁극의 개발 활동이라 생각한다. 개발자는 결국, 자신을 설명하는 언어를 발명하는 존재다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[우선순위 큐와 힙]]></title>
            <link>https://velog.io/@rocky-won/%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84-%ED%81%90%EC%99%80-%ED%9E%99</link>
            <guid>https://velog.io/@rocky-won/%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84-%ED%81%90%EC%99%80-%ED%9E%99</guid>
            <pubDate>Thu, 20 Nov 2025 12:36:17 GMT</pubDate>
            <description><![CDATA[<h2 id="part-1-기본-이론">Part 1. 기본 이론</h2>
<hr>
<h3 id="우선순위-큐priority-queue">우선순위 큐(Priority Queue)</h3>
<p>데이터를 다루다 보면 여러 작업 중 ‘가장 중요한 것’을 빠르게 처리해야 하는 상황이 자주 발생한다.우선순위 큐는 이러한 데이터를 효율적으로 관리하기 위한 자료구조이며 핵심 연산은 다음과 같다.</p>
<ul>
<li>원소 삽입</li>
<li>최대(또는 최소) 원소 반환</li>
<li>최대(또는 최소) 원소 삭제</li>
</ul>
<h3 id="힙heap">힙(Heap)</h3>
<p>힙은 우선순위 큐를 효율적으로 구현하기 위해 사용되는 전형적인 자료구조다. 힙은 우선순위 큐를 구현하기 위해 완전 이진트리(complete binary tree)라는 구조를 사용한다.</p>
<ul>
<li>이진트리: 모든 노드가 2개 이하의 자식을 가진 트리</li>
<li>포화 이진트리: 모든 내부 노드가 정확히 2개의 자식을 가진 트리</li>
<li>완전 이진트리: 마지막 레벨을 제외한 모든 레벨이 꽉 차 있고, 마지막 레벨의 노드는 왼쪽부터 채워진 트리</li>
</ul>
<h2 id="part-2-heap-구현">Part 2. Heap 구현</h2>
<hr>
<h3 id="힙에-값-추가하기percolate-up">힙에 값 추가하기(percolate up)</h3>
<p>힙에 값을 추가할 때는 추가하는 값을 리스트의 가장 마지막에 추가한 다음 부모와의 값 비교를 통해 값을 올리는 percolate up 작업을 수행한다.</p>
<pre><code>def percolate_up(A, i):
    parent = (i-1)//2
    if i &gt; 0 and A[parent] &lt; A[i]:
        A[parent], A[i] = A[i], A[parent]
        percolate_up(A, parent)</code></pre><h3 id="힙에-값-삭제하기percolate-down">힙에 값 삭제하기(percolate down)</h3>
<p>힙에서 값을 삭제할 때는 0번째 인덱스에 위치한 값을 반환하고, 리스트의 마지막에 위치한 값을 0번째 인덱스로 옮겨와서 percolate down 작업을 수행한다.</p>
<pre><code>def percolate_down(A, i):
    left = 2*i+1
    right = 2*i+2
    n = len(A)

    largest = i

    if left &lt; n and A[largest] &lt; A[left]:
        largest = left

    if right &lt; n and A[largest] &lt; A[right]:
        largest = right

    if largest != i:
        A[i], A[largest] = A[largest], A[i]
        percolate_down(A, largest)</code></pre><h3 id="힙-생성">힙 생성</h3>
<p>임의의 리스트를 힙으로 만들기 위해서는 트리의 모든 서브트리가 힙 특성을 만족해야 한다. 이를 위해 리프 노드의 부모인 (n-1)//2 인덱스부터 시작해, 각 노드에 대해 percolate_down을 수행한다.</p>
<pre><code>for i in range((n-1)//2, -1, -1):
    percolate_down(A, i)</code></pre><p>이 방식은 bottom-up 접근으로서, 전체 리스트를 한 번에 힙으로 만든다.</p>
<h2 id="part-3-심화">Part 3. 심화</h2>
<hr>
<h3 id="q-heapify는-왜-bottom-uppercolate-down-방식을-사용하는가">Q) heapify()는 왜 bottom-up(percolate-down) 방식을 사용하는가?</h3>
<p>힙을 만드는 방법은 두 가지가 있다.</p>
<h3 id="방법-a-top-down-방식percolate-up">방법 A. top-down 방식(percolate-up)</h3>
<p>초기 상태: 빈 힙
리스트의 모든 원소를 하나씩 push</p>
<pre><code>for x in array:
    heappush(heap, x)</code></pre><h3 id="방법-b-bottom-up-방식percolate-down">방법 B. bottom-up 방식(percolate-down)</h3>
<p>초기 상태: 리스트 전체가 배열로 전체
아래처럼 한 번에 heapify</p>
<pre><code>i = (n-1)//2 down to 0:
    percolate_down(array, i)</code></pre><p>heapify는 결국 percolate-down 기반이 훨씬 효율적이기 때문에 bottom-up을 사용한다.</p>
<p>Q) 왜 percolate-up은 비효율적(O(N log N))인가?</p>
<ul>
<li>percolate-up은 노드가 들어올 때 부모 방향으로 이동한다.</li>
<li>문제는 leaf 노드는 움직일 때마다 log N만큼 올라와야 가능하다.</li>
<li>전체 노드의 약 절반이 leaf이기 때문에 이동 비용이 커질 확률이 매우 높다.</li>
</ul>
<p>Q) 왜 bottom-up + percolate-down은 효율적(O(N))인가?</p>
<ul>
<li>트리의 아래쪽에는 노드가 엄청 많다. </li>
<li>하지만 leaf는 percolate-down 비용이 거의 0이다.</li>
<li>많은 노드는 거의 이동이 없고, 적은 노드는 이동이 많아 선형 시간으로 수렴한다.</li>
</ul>
<h3 id="amortized-analysis-percolate-down">Amortized Analysis (percolate-down)</h3>
<p>힙은 완전 이진트리이므로, 루트에서부터의 레벨을 다음과 같이 정의한다.</p>
<ul>
<li>레벨 0: 루트 노드</li>
<li>레벨 1: 루트의 자식들</li>
<li>레벨 2: 그 아래 레벨</li>
<li>레벨 H: 가장 아래 리프 (H = 트리 높이 ≈ ⌊log₂n⌋)</li>
</ul>
<p><strong>1. 레벨 k에 있는 노드 수: $\frac{n}{2^{k+1}}$</strong>
k가 커질수록 노드 수가 기하급수적으로 증가한다.</p>
<p><strong>2. 레벨 k가 내려갈 수 있는 최대 percolate-down 깊이</strong>
레벨 k의 노드가 내려갈 수 있는 최대 깊이는 H-k이다. 
위 레벨일수록 percolate 비용은 크지만 노드 수가 거의 없다.</p>
<p><strong>3. 전체 heapify 비용 공식</strong>
레벨 k의 총 비용
$$
T(n) = (n / 2^{k+1})(H-k)
$$</p>
<p>전체 heapify 비용:
$$
T(n) = \sum (n / 2^{k+1})(H-k)
$$</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Separation of Concerns as a Design Principle for Quantitative Trading Systems]]></title>
            <link>https://velog.io/@rocky-won/Separation-of-Concerns-as-a-Design-Principle-for-Quantitative-Trading-Systems</link>
            <guid>https://velog.io/@rocky-won/Separation-of-Concerns-as-a-Design-Principle-for-Quantitative-Trading-Systems</guid>
            <pubDate>Thu, 02 Oct 2025 07:48:23 GMT</pubDate>
            <description><![CDATA[<p>인간의 시각 시스템은 놀랍도록 정교하지만, 동시에 근본적으로 오류 가능성을 내포하고 있다. 착시(optical illusion)는 인간의 감각이 완벽한 진실을 인식하지 못한다는 분명한 증거이다. 그럼에도 불구하고, 우리는 착시에 의해 절벽에서 떨어져 죽지 않는다. 그 이유는 인간의 생존을 보장하는 인지 구조가 “절대적 정확성”이 아니라 “오류를 흡수할 수 있는 구조적 복원력(Robustness)”을 기반으로 설계되어 있기 때문이다.</p>
<p>시각 신호는 단일 경로로 의사결정을 결정하지 않는다. 감각 정보는 전정기관(Vestibular System), 고유수용감각(Proprioception), 과거 환경 경험 등의 다양한 신호원으로 보완되며, 하나의 모듈이 오류를 내더라도 즉시 균형 보정이 이루어진다. 즉, 인간은 한 번의 잘못된 판단이 치명적 실패로 전파되지 않도록 계층적으로 분리된 다중 의사결정 경로와 상호 보정 루프를 통해 생존성을 유지한다.</p>
<p>이와 같은 관점에서 보면, 고신뢰도를 요구하는 시스템일수록 정확성(Accuracy)보다 견고성(Robustness)을 우선하는 것이 논리적으로 정합적이다. 특히 금융 시장과 같이 고잡음·비정상(non-stationary) 환경에서 작동하는 정량적 트레이딩 시스템은, “항상 맞는 모델”을 설계하기보다, “틀려도 무너지지 않는 구조”를 설계해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[꼭 알아둬야 할 Python 설치 지식 (macOS)]]></title>
            <link>https://velog.io/@rocky-won/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@rocky-won/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 02 Sep 2024 10:53:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>파이썬 프로젝트 관리의 핵심은 파이썬 버전과 의존성을 관리하는 것이다. 이를 위해 가장 기본적으로 알아야 하는 명령어는 <strong>파이썬 설치 경로 확인</strong> 방법과 <strong>파이썬 설치 방법</strong>이다. 또한 패키지들의 의존성을 잘 관리하기 위해서는 poetry와 같은 프로젝트 관리 도구를 잘 숙지하고 있는 것도 중요하다.</p>
</blockquote>
<h2 id="1-파이썬-설치-경로-확인">1. 파이썬 설치 경로 확인</h2>
<hr>
<h3 id="설치-경로-확인-명령어">설치 경로 확인 명령어</h3>
<p>파이썬 설치 위치를 확인하면 현재 사용 중인 파이썬 인터프리터가 어디에 있고, 어떤 도구에 의해 설치되었는지도 알 수 있다. 또한 poetry와 같은 패키지 관리 도구를 사용할 때 파이썬 버전을 지정할 수 있다.</p>
<pre><code># python 명령어가 가리키는 실행 파일의 위치
$ which python  

# python3 명령어가 가리키는 실행 파일의 위치
$ which python3  

# python3.11 명령어가 가리키는 실행 파일의 위치
$ which python3.11  

# Poetry를 사용하여 프로젝트에서 python3.11 버전 사용
$ poetry env use /path/to/python3.11  </code></pre><p><br></br></p>
<h3 id="2-파이썬-설치-도구별-설치-경로-intel">2) 파이썬 설치 도구별 설치 경로 (Intel)</h3>
<p>1️⃣ Homebrew: <code>/usr/local/bin/python3.x</code>
2️⃣ pyenv: <code>~/.pyenv/versions/3.x.x/bin/python</code>
3️⃣ Anaconda:
 기본 환경: <code>/Users/username/anaconda3/bin/python</code>
 가상 환경: <code>/Users/username/anaconda3/envs/env_name/bin/python</code></p>
<p><br></br></p>
<h3 id="3-파이썬-설치-도구별-설치-경로-apple-silicon">3) 파이썬 설치 도구별 설치 경로 (Apple Silicon)</h3>
<p>1️⃣ Homebrew: <code>/opt/homebrew/bin/python3.x</code>
2️⃣ pyenv: <code>~/.pyenv/versions/3.x.x/bin/python</code>
3️⃣ Anaconda:
기본 환경: <code>/Users/username/anaconda3/bin/python</code>
가상 환경: <code>/Users/username/anaconda3/envs/env_name/bin/python</code></p>
<h2 id="brbr"><br></br></h2>
<h2 id="2-파이썬-설치-방법들">2. 파이썬 설치 방법들</h2>
<hr>
<h3 id="1-homebrew를-사용하여-설치-macos">1) Homebrew를 사용하여 설치 (macOS)</h3>
<p>Homebrew는 macOS에서 패키지를 쉽게 설치하고 관리할 수 있는 패키지 관리 시스템이다. 터미널에서 아래의 명령어를 실행하여 파이썬을 설치 할 수 있다.</p>
<pre><code>brew install python@3.11
python3.11 --version

# python3 명령어가 Python 3.11을 가리키도록 강제로 설정
brew link --overwrite python@3.11</code></pre><p><br></br></p>
<h3 id="2-pyenv를-사용하여-설치">2) pyenv를 사용하여 설치</h3>
<p>pyenv는 여러 버전의 Python을 동시에 설치하고, 각 프로젝트마다 다른 버전을 사용할 수 있게 해주는 도구이다.macOS에서 Homebrew를 사용해 pyenv를 설치한다. 설치 후 셸 초기화 파일 설정이 필요하다는 것이 특징이다.</p>
<pre><code>brew install pyenv

# 셸 초기화 파일(~/.zshrc, ~/.bashrc, 등)에 다음을 추가합니다:
echo &#39;export PYENV_ROOT=&quot;$HOME/.pyenv&quot;&#39; &gt;&gt; ~/.zshrc
echo &#39;export PATH=&quot;$PYENV_ROOT/bin:$PATH&quot;&#39; &gt;&gt; ~/.zshrc
echo &#39;eval &quot;$(pyenv init --path)&quot;&#39; &gt;&gt; ~/.zshrc
source ~/.zshrc

# Python 3.11 설치
pyenv install 3.11.0

# 특정 프로젝트에서 Python 3.11 사용 설정
pyenv local 3.11.0</code></pre><p><br></br></p>
<h3 id="3-anaconda를-사용하여-설치">3) Anaconda를 사용하여 설치</h3>
<p>Anaconda는 데이터 과학과 머신러닝에 자주 사용되는 Python 배포판으로, 가상 환경 관리와 함께 다양한 패키지를 쉽게 설치할 수 있다.</p>
<pre><code># Python 3.11을 사용하는 가상 환경(py311) 생성
conda create -n py311 python=3.11

# 설치된 Conda 가상환경 목록 출력
conda env list

# 생성한 가상 환경 활성화
conda activate py311</code></pre><p>Anaconda로 설치된 파이썬 및 가상 환경은 Anaconda가 설치된 디렉토리 안에 위치한다. macOS 기준  /Users/username/anaconda3/ 에 설치된다.</p>
<p><br></br></p>
<h2 id="3-마무리">3. 마무리</h2>
<hr>
<p>어떤 설치 방법을 이용하든 결국 파이썬 인터프리터 자체는 동일하다. 다만 설치 방법별로 <strong>가상 환경 관리</strong> 및 <strong>패키지 간의 의존성 충돌 해소</strong>를 수동으로 해야하는지, 자동으로 관리되는지가 달라진다.</p>
<ul>
<li><p>시스템 기본 파이썬 또는 Homebrew를 사용해 설치한 파이썬을 사용할 경우 venv나 virtualenv를 사용해 가상 환경을 수동으로 생성하고 관리해야 한다. 또한 패키지 간의 의존성 문제를 수동으로 해결해야 한다.</p>
</li>
<li><p>pyenv를 사용해 파이썬을 설치한 경우 pyenv-virtualenv 플러그인을 통해 가상 환경을 생성하고 관리할 수 있다. 마찬가지로 패키지 간의 의존성 문제를 수동으로 해결해야 한다.</p>
</li>
<li><p>Anaconda의 경우 conda 명령어를 통해 가상 환경을 생성하고 의존성도 자동으로 관리해 의존성 충돌 문제를 최소화해준다. 단 conda와 pip 혼용시 의존성 문제 발생 가능성이 높아 주의해야 한다.</p>
</li>
</ul>
<p>각 방법의 장단점을 이해하고, 프로젝트에 맞는 적절한 방법을 선택하여 파이썬 개발 환경을 효율적으로 관리해보자. 파이썬 버전 및 패키지 관리만 잘해도 불필요한 오류로 낭비되는 시간을 크게 줄일 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[1-1]  파이썬의 시퀀스와 반복문]]></title>
            <link>https://velog.io/@rocky-won/1-1-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%98-%EC%8B%9C%ED%80%80%EC%8A%A4%EC%99%80-%EB%B0%98%EB%B3%B5%EB%AC%B8</link>
            <guid>https://velog.io/@rocky-won/1-1-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%98-%EC%8B%9C%ED%80%80%EC%8A%A4%EC%99%80-%EB%B0%98%EB%B3%B5%EB%AC%B8</guid>
            <pubDate>Sun, 01 Sep 2024 16:59:44 GMT</pubDate>
            <description><![CDATA[<h2 id="파이썬-시퀀스-주요-기능">파이썬 시퀀스 주요 기능</h2>
<h3 id="슬라이싱"><strong>슬라이싱</strong></h3>
<ul>
<li><p>슬라이싱은 파이썬의 1.0 버전부터 존재한 기능으로, 기존의 다른 언어보다 직관적이고 일관적인 방식으로 구현되었다. </p>
<pre><code>numbers = [1, 2, 3, 4, 5]
print(numbers[1:4])   # 2번째부터 4번째까지 출력: [2, 3, 4]
print(numbers[::-1])  # 역순으로 출력: [5, 4, 3, 2, 1]</code></pre></li>
<li><p>슬라이싱을 하면 새로운 리스트 객체가 생성되지만 <strong>얕은 복사</strong>를 한다는 것을 유의해야 한다. 리스트의 내부 객체가 만약 변경 가능한 객체(Mutable Object)라면 해당 객체를 수정했을 때 원본 리스트에도 영향을 준다.</p>
<pre><code>&gt;&gt;&gt; original_list = [[1, 2], [3, 4]]
&gt;&gt;&gt; sliced_list = original_list[1]
&gt;&gt;&gt; sliced_list[0] = &#39;NEW VALUE&#39;
&gt;&gt;&gt; print(&quot;Original list:&quot;, original_list)
Original list: [[1, 2], [&#39;NEW VALUE&#39;, 4]]</code></pre></li>
</ul>
<h3 id="리스트-컴프리헨션">리스트 컴프리헨션</h3>
<ul>
<li>리스트 컴프리헨션은 파이썬 2.0 버전부터 도입된 기능으로 <a href="https://peps.python.org/pep-0202/">PEP 202</a> 문서를 통해 관련 내용을 확인할 수 있다.<pre><code>numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [num for num in numbers if num % 2 == 0]
print(even_numbers)  # 출력: [2, 4, 6]</code></pre></li>
</ul>
<h3 id="제너레이터">제너레이터</h3>
<ul>
<li>제너레이터는 파이썬 2.2 버전에서 도입된 기능으로, <a href="https://peps.python.org/pep-0255/">PEP 255</a>에 정의되어 있다. 제너레이터는 메모리 효율성을 극대화하면서 반복 작업을 수행할 수 있도록 도와준다.<pre><code>def infinite_sequence():
  num = 0
  while True:
      yield num
      num += 1
</code></pre></li>
</ul>
<h1 id="제너레이터는-필요할-때만-값을-생성하므로-메모리-효율적이다">제너레이터는 필요할 때만 값을 생성하므로 메모리 효율적이다</h1>
<p>gen = infinite_sequence()
print(next(gen))  # 출력: 0</p>
<pre><code>
### zip() 함수
- zip() 함수는 파이썬의 내장 함수로, 여러 시퀀스를 병렬로 묶어주는 기능을 제공한다. 동일한 길이의 시퀀스를 함께 묶어, 각 시퀀스에서 같은 인덱스에 위치한 요소들을 튜플로 반환한다.</code></pre><p>names = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;]
scores = [85, 92, 78]
grades = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;]
for name, score, grade in zip(names, scores, grades):
    print(f&quot;{name}: {score}, Grade: {grade}&quot;)</p>
<p>&quot;&quot;&quot;
출력:
Alice: 85, Grade: A
Bob: 92, Grade: B
Charlie: 78, Grade: C
&quot;&quot;&quot;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[1-2] PEP 8 스타일 가이드]]></title>
            <link>https://velog.io/@rocky-won/1-2-PEP-8-%EC%8A%A4%ED%83%80%EC%9D%BC-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%A5%BC-%EB%94%B0%EB%A5%B4%EC%9E%90</link>
            <guid>https://velog.io/@rocky-won/1-2-PEP-8-%EC%8A%A4%ED%83%80%EC%9D%BC-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%A5%BC-%EB%94%B0%EB%A5%B4%EC%9E%90</guid>
            <pubDate>Sun, 01 Sep 2024 07:01:23 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="pep-8-스타일-가이드를-따르자">PEP 8 스타일 가이드를 따르자</h2>
<p>파이썬을 파이썬스럽게 사용하려면 PEP 8을 알아야 한다. 파이썬 개선 제안서 (Python Enhancement Proposal) #8, 다른 말로 <a href="https://peps.python.org/pep-0008/">PEP 8</a>은 파이썬 코드를 어떻게 구성할지 알려주는 스타일 가이드다. <strong>화이트스페이스, 네이밍, 표현식과 문장</strong>에 관한 규칙의 주요 내용은 다음과 같다.</p>
<h3 id="화이트스페이스whitespace">화이트스페이스(whitespace)</h3>
<p>1️⃣ 탭이 아닌 스페이스로 들여쓴다. 
2️⃣ 문법적으로 의미 있는 들여쓰기는 각 수준마다 스페이스 네 개를 사용한다.
3️⃣ 표현식이 길어서 다음 줄로 이어지면 일반적인 들여쓰기 수준에 추가로 스페이스 네 개를 사용한다.
4️⃣ 파일에서 함수와 클래스는 빈 줄 두 개로 구분해야 한다.
5️⃣ 클래스에서 메서드는 빈 줄 하나로 구분해야 한다.
6️⃣ 리스트 인덱스, 함수 호출, 키워드 인수 할당에는 스페이스를 사용하지 않는다.
7️⃣ 변수 할당 앞뒤에 스페이스를 하나만 사용한다.</p>
<p>위 규칙을 적용한 샘플 코드는 다음과 같다.</p>
<pre><code>class Calculator:
    def __init__(self, value=0):  # 1️⃣ 들여쓰기는 스페이스 4개, 6️⃣ 키워드 인수 할당에는 스페이스X
        self.value = value  # 7️⃣ 변수 할당 앞뒤에 스페이스 하나 사용

    def add(self, x):  # 5️⃣ 클래스에서 메서드는 빈 줄 하나로 구분
        self.value += x
        return self.value


def calculate_expression(a, b, operation):  # 4️⃣ 파일에서 함수와 클래스는 빈 줄 두 개로 구분
    if operation == &#39;add&#39;: 
        return a + b
    elif operation == &#39;complex_operation&#39;:
        return (a + b +  # 3️⃣ 표현식이 길어지면 다음 줄로 넘어가고 추가 들여쓰기
                a * b -
                b / a)
    else:
        return &#39;Error: Unsupported operation&#39;  # 7️⃣ 연산자 앞뒤에 스페이스 하나 사용


if __name__ == &#39;__main__&#39;:  # 2️⃣ 조건문, 반복문, 함수 호출 등에서 스페이스를 적절히 사용
    calc = Calculator()  # 6️⃣ 함수 호출 시 인수와 함수명 사이에 스페이스 사용하지 않음
    result = calc.add(10)  # 6️⃣ 함수 호출 시 인수와 함수명 사이에 스페이스 사용하지 않음
    expression_result = calculate_expression(10, 5, &#39;complex_operation&#39;)  # 6️⃣ 함수 호출 시 인수와 함수명 사이에 스페이스 사용하지 않음

    print(f&quot;Calculator 결과: {result}&quot;)
    print(f&quot;수식 계산 결과: {expression_result}&quot;)
</code></pre><h3 id="네이밍naming">네이밍(naming)</h3>
<p>1️⃣ 모듈은 짧고 모두 소문자 이름을 가져야 한다. 가독성을 개선하는 경우 모듈 이름에 밑줄을 사용할 수 있다.
2️⃣ 모듈 수준 상수는 ALL_CAPS 형식을 따른다.
3️⃣ 클래스와 예외는 CapitalizedWord 형식을 따른다. 예외는 접미사 Error로 끝나야 한다.
4️⃣ 클래스의 Public 메서드, 함수, 변수, 속성은 lowercase_underscore 형식을 따른다.
5️⃣ 클래스의 Non-public 메서드와 인스턴스 변수에는 _leading_underscore 형식을 따른다.
6️⃣ 클래스의 인스턴스 메서드에서 첫 번째 파라미터의 이름은 self로 지정한다.
7️⃣ 클래스 메서드에서는 첫 번째 파라미터의 이름을 cls로 지정한다.
8️⃣ 서브 클래스에서의 변수명 충돌을 막으려면 __double_leading_score 형식을 따르는 인스턴스 변수명을 사용한다.</p>
<pre><code># 1️⃣ 파일명은 simple_module.py이라 가정한다.
ALL_CAPS_CONSTANT = 100  # 2️⃣ 모듈 수준 상수


class SampleClass:  # 3️⃣ 클래스 이름은 CamelCase
    def __init__(self, value):  # 6️⃣ 인스턴스 메서드, 첫 번째 파라미터는 self
        self.public_var = value  # 4️⃣ Public 변수
        self._private_var = value  # 5️⃣ Non-public 변수
        self.__mangled_var = value  # 8️⃣ 이름 충돌 방지 변수

    def _private_method(self):  # 5️⃣ Non-public 메서드
        if self._private_var &lt; 0:  # 음수 값에 대한 예외 처리
            raise CustomError(&quot;Value cannot be negative!&quot;)
        return self._private_var * ALL_CAPS_CONSTANT

    def public_method(self):  # 4️⃣ Public 메서드
        return self._private_method()

    @classmethod
    def class_method(cls, value):  # 7️⃣ 클래스 메서드, 첫 번째 파라미터는 cls
        return cls(value * ALL_CAPS_CONSTANT)


class CustomError(Exception):  # 3️⃣ 예외 클래스
    pass


if __name__ == &#39;__main__&#39;:
    instance = SampleClass(10)
    try:
        print(instance.public_method())
        print(SampleClass.class_method(5))  # 클래스 메서드 호출
    except CustomError as e:
        print(e)</code></pre><h3 id="표현식과-문장">표현식과 문장</h3>
<h4 id="자동-포맷팅-도구-black과-vscode-설정-방법">자동 포맷팅 도구 black과 VSCode 설정 방법</h4>
<p>파이썬 코드를 작성할 때 자동으로 PEP 8 스타일을 준수하도록 코드 포맷터를 설정할 수 있다. 대표적인 코드 포맷터는 black이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[1부] 파이썬다운 생각이란 무엇일까]]></title>
            <link>https://velog.io/@rocky-won/1%EB%B6%80-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EB%8B%A4%EC%9A%B4-%EC%83%9D%EA%B0%81%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@rocky-won/1%EB%B6%80-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EB%8B%A4%EC%9A%B4-%EC%83%9D%EA%B0%81%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Sun, 01 Sep 2024 07:00:45 GMT</pubDate>
            <description><![CDATA[<p><em>예상 읽기 시간: 5분</em></p>
<h2 id="1️⃣-개요">1️⃣ 개요</h2>
<blockquote>
<p><strong>파이썬다운 스타일은 단순함과 가독성을 극대화하기 위해 권장 패턴을 따르고, 안티 패턴을 피하며, 파이썬 고유 특성에 맞게 코딩하는 것을 의미한다.</strong></p>
</blockquote>
<p>1장은 총 13개의 절로 구성되어 있다. </p>
<ul>
<li>✅는 <strong>권장 패턴</strong> (7개)</li>
<li>❌는 <strong>안티 패턴</strong> (3개)</li>
<li>🩶는 <strong>파이썬 고유 특성</strong> (3개)</li>
</ul>
<p>각 절의 내용을 3가지 범주로 나눈다면 위와 같이 구분할 수 있다. 그리고 각 절의 주관적인 중요도는 ⭐️로 표기하였다. <strong>PEP 8 스타일 가이드는 코드 품질 관리의 핵심</strong>이며, <strong>사용 중인 파이썬 버전을 아는 것은 의존성 관리에 필수적</strong>이기에 ⭐️⭐️로 중요도를 매겼다. 스타일 가이드 준수를 위해서는 black과 flake8과 같은 정적 검사 도구를 이용하는 것이 좋으며, 의존성 관리는 poetry 같은 도구를 잘 사용하는 것이 필요하다.</p>
<p>개발에 도움되지만 사용 빈도가 낮거나, 필수적이지 않은 챕터는 ⭐️표기를 생략했다. 특히 안티 패턴과 관련된 내용은 중요하지만 습관을 잘 들이면 의식할 필요가 없어 중요도를 표기하지 않았다. 안티 패턴을 피하기 위해서는 파이썬스러운 생각을 체화하는 게 중요하기 때문이다.</p>
<h2 id="2️⃣-목차">2️⃣ 목차</h2>
<hr>
<p>✅ [chapter 2] PEP 8 스타일 가이드를 따르자 ⭐️⭐️
✅ [chapter 4] 복잡한 표현식을 사용하는 대신 헬퍼 함수를 사용하자 ⭐️
✅ [chapter 7] map과 filter 대신 리스트 컴프리헨션을 사용하자 ⭐️
✅ [chapter 9] 컴프리헨션이 클 때는 제너레이터 표현식을 고려하자 ⭐️
✅ [chapter 10] range보다는 enumerate를 사용하자 ⭐️
✅ [chapter 11] 이터레이터를 병렬로 처리하려면 zip을 사용하자 
✅ [chapter 13] try/except/else/finally에서 각 블록의 장점을 이용하자</p>
<p>❌ [chapter 6] 한 슬라이스에 start, end, stride를 함께 쓰지 말자
❌ [chapter 8] 리스트 컴프리헨션에서 표현식을 두 개 넘게 쓰지 말자
❌ [chapter 12] for와 while 루프 뒤에는 else 블록을 쓰지 말자</p>
<p>🩶 [chapter 1] 사용 중인 파이썬의 버전을 알자 ⭐️⭐️
🩶 [chapter 3] bytes, str, unicode 차이점을 알자 ⭐️
🩶 [chapter 5] 시퀀스를 슬라이스하는 방법을 알자 ⭐️</p>
<hr>
<h2 id="3️⃣-리뷰">3️⃣ 리뷰</h2>
<p>파이썬의 시퀀스 데이터 타입 및 반복문과 관련된 내용이 가장 많은 분량을 차지하고 있다(13장 중 9장). 파이썬이 다른 언어에 비해 데이터 핸들링에 유용한 이유는 시퀀스 데이터 타입을 효율적으로 지원하는 데이터 모델과 문법 덕분이다. 파이썬의 슬라이싱, 리스트 컴프리헨션, 제너레이터, zip() 함수가 대표적인 예이다.</p>
<p>복잡한 작업을 단순하고 효율적으로 표현해주는 기능들 덕분에 파이썬 개발자들은 읽기 쉽고 유지보수하기 쉬운 코드를 작성할 수 있게 되었다. 슬라이싱을 통해서 특정 요소를 보다 쉽게 추출할 수 있고, 리스트 컴프리헨션을 사용해 필터링과 변환 작업을 한 줄로 처리할 수 있으며, 제너레이터로 대용량 데이터를 메모리 효율적으로 다룰 수 있으며, zip() 함수로 여러 시퀀스를 동시에 순회할 수 있게 되었다.</p>
<p>이러한 기능들은 <a href="https://peps.python.org/pep-0020/">The Zen Of Python</a>에 명시된 설계 원칙을 반영한다. 시퀀스 데이터 타입 뿐만 아니라 파이썬의 다양한 문법적인 요소들이 해당 설계 원칙을 반영해 작성되었다. 파이썬 문법에 어느 정도 익숙해진 개발자라면, 언어 설계자들이 추구한 가치가 무엇인지에 대해서 한 번쯤 고민해보는 시간을 가져도 좋을 것이다. 언어는 가치의 구현체이기 때문이다.</p>
<pre><code>&gt;&gt;&gt; import this  # The Zen of Python, by Tim Peters</code></pre><h2 id="4️⃣-추가-조사">4️⃣ 추가 조사</h2>
<p>파이썬 프로젝트들에서 특정 Python idiom(언어적 관용 패턴)이 얼마나 자주 사용되는지를 비교한 표를 보면 List comprehension, Decorator, with 등이 널리 쓰이는 걸 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/rocky-won/post/c498cb19-99d6-493d-ae98-40ccd71d47e5/image.png" alt=""></p>
<p><a href="https://dl.acm.org/doi/pdf/10.1145/3486608.3486909">There Is More Than One Way to Zen Your Python
</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 코딩의 기술: 파이썬 초보에서 중급으로]]></title>
            <link>https://velog.io/@rocky-won/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%BD%94%EB%94%A9%EC%9D%98-%EA%B8%B0%EC%88%A0-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B4%88%EB%B3%B4%EC%97%90%EC%84%9C-%EC%A4%91%EA%B8%89%EC%9C%BC%EB%A1%9C</link>
            <guid>https://velog.io/@rocky-won/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%BD%94%EB%94%A9%EC%9D%98-%EA%B8%B0%EC%88%A0-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B4%88%EB%B3%B4%EC%97%90%EC%84%9C-%EC%A4%91%EA%B8%89%EC%9C%BC%EB%A1%9C</guid>
            <pubDate>Sun, 01 Sep 2024 06:22:54 GMT</pubDate>
            <description><![CDATA[<h2 id="시리즈-개요">시리즈 개요</h2>
<p>&lt;파이썬 코딩의 기술&gt;은 파이썬 기본 문법을 배우고 다음 수준의 자료를 찾는 사람에게 추천하는 책이다. 이 책을 읽으면 파이썬 중급 개발자로 성장하는 데 필요한 노하우를 익힐 수 있다. 파이썬을 파이썬스럽게(pythonic) 작성하기 위한 가이드, 객체 지향 프로그래밍, 병행성과 병렬성, 디버깅 및 테스트 방법 등 중요한 주제를 균형 있게 다루고 있기 때문이다. 이 책을 통해 파이썬의 관용 표현, 디자인 패턴, 성능 개선, 트러블 슈팅 방법들을 알아보자.</p>
<h2 id="책의-목차">책의 목차</h2>
<p>책의 목차는 다음과 같다. 모든 챕터가 유용하지만 상대적으로 중요도가 높다고 생각한 챕터는 ⭐️ 표기를 하였다.</p>
<ul>
<li>⭐️⭐️ 표기가 된 챕터를 이해하지 못하면 파이썬스러운 코딩에 어려움을 겪을 수 있다.</li>
<li>⭐️ 표기가 된 챕터를 이해하지 못하면 프로젝트 진행이 어렵다. </li>
<li>특별한 표기가 없는 챕터도 훌륭하지만 필요할 때 찾아봐도 늦지 않다.</li>
</ul>
<hr>
<p>책의 목차
(1장) 파이썬다운 생각 ⭐️⭐️
(2장) 함수 ⭐️
(3장) 클래스와 상속 ⭐️⭐️
(4장) 메타클래스와 속성
(5장) 병행성과 병렬성
(6장) 내장 모듈
(7장) 협력 ⭐️
(8장) 제품화 ⭐️</p>
<hr>
<h2 id="연재-계획">연재 계획</h2>
<p>앞으로는 이 책의 각 장을 살펴보며 왜 이 장이 중요한지, 그리고 어떤 내용을 다루는지에 대해 정리할 예정이다. <strong>1장 파이썬다운 생각</strong>에서는 파이썬 철학과 이를 활용한 효과적인 코딩 방법을 소개한다. 이 장을 이해하는 것은 파이썬스러운 코드를 작성하는 데 필수적이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Velog로 시작하는 개발 도서 리뷰]]></title>
            <link>https://velog.io/@rocky-won/Velog%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EA%B0%9C%EB%B0%9C-%EB%8F%84%EC%84%9C-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@rocky-won/Velog%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EA%B0%9C%EB%B0%9C-%EB%8F%84%EC%84%9C-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sat, 31 Aug 2024 18:11:10 GMT</pubDate>
            <description><![CDATA[<p>개발 공부를 위해 여러 블로그 서비스를 사용해보았지만 꾸준히 글을 쓰고 주기적으로 복습하는 게 쉽지 않다고 느꼈다. 노션의 경우 기록하고 다시 살펴보지 않는 글이 많아지니 거미줄 친 창고 같아졌다. 네이버 블로그는 목차 기능과 마크업 기능이 없어서 분량이 많은 글을 쓰기 어려웠다. 티스토리는 기능이 많지만 무언가 난잡하다는 느낌을 지울 수 없었다. 그래서 결국 velog를 시작하게 됐다. </p>
<p>velog에서의 목표는 하나다. 읽은 책 잘 정리해놓고 복습할 수 있게 만들기. 노션에 정리해둔 책들과 읽고 정리를 해놓지 않은 양서들을 시리즈화하여 체계적으로 정리하는 것이 목표다. 파이썬, 디자인 패턴, 데이터베이스, 시스템 설계 등 굵직한 주제들의 책을 아카이빙 하는 용도로 사용하려고 한다.</p>
<p>올해 연말까지의 목표는 매주 1권, 10권 가량의 책을 정리하는 것이다.</p>
]]></description>
        </item>
    </channel>
</rss>