<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Python - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/korean/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Python - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/korean/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 15:16:08 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/korean/news/tag/python/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Python과 Gemini로 AI 코딩 에이전트 만들기 ]]>
                </title>
                <description>
                    <![CDATA[ 이 핸드북에서는 Google의 무료 Gemini API [https://ai.google.dev/gemini-api/docs/pricing]를 활용해 Claude Code의 기본 버전을 직접 만들어봅니다. 만약 Cursor나 Claude Code 같은 “에이전트형” AI 코드 에디터를 써본 적이 있다면, 이번에 만들 프로젝트의 개념도 익숙할 거예요. 사실 LLM을 활용할 수 있다면, (다소) 꽤 효과적인 맞춤형 에이전트를 구축하는 것은 놀라울 정도로 간단합니다. 이 핸드북은 완전히 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/build-an-ai-coding-agent-with-python-and-gemini/</link>
                <guid isPermaLink="false">690493b0d35fdc04ded3dcf9</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ changseop yeom ]]>
                </dc:creator>
                <pubDate>Mon, 24 Nov 2025 03:23:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2025/11/2470669e-8592-463e-8b4c-55eace8dd80a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/build-an-ai-coding-agent-with-python-and-gemini/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build an AI Coding Agent with Python and Gemini</a>
      </p><p>이 핸드북에서는 Google의 <a href="https://ai.google.dev/gemini-api/docs/pricing">무료 Gemini API</a>를 활용해 Claude Code의 기본 버전을 직접 만들어봅니다. 만약 Cursor나 Claude Code 같은 “에이전트형” AI 코드 에디터를 써본 적이 있다면, 이번에 만들 프로젝트의 개념도 익숙할 거예요. 사실 LLM을 활용할 수 있다면, (다소) 꽤 효과적인 맞춤형 에이전트를 구축하는 것은 놀라울 정도로 간단합니다.</p><p>이 핸드북은 완전히 무료인 텍스트 기반 핸드북입니다. 다만, 따라해 볼 수 있는 두 가지 다른 옵션이 있습니다:</p><p>코딩 챌린지와 프로젝트가 포함된 <a href="https://www.boot.dev/courses/build-ai-agent-python">Boot.dev에서 제공하는 AI Agent 강의</a>의 인터랙티브 버전을 체험하거나 FreeCodeCamp 유튜브 채널에서 제공하는 이 강의의 <a href="https://www.youtube.com/watch?v=YtHdaXuOAks">단계별 안내 영상</a>을 시청할 수도 있습니다.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/YtHdaXuOAks?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Guide to Agentic AI – Build a Python Coding Agent with Gemini" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h2 id="-">사전 준비</h2><ul><li>이 과정을 시작하기 전에 Python의 기본 문법과 개념에 익숙해야 합니다.<br>아직 배우지 않았다면, <a href="https://www.boot.dev/courses/learn-code-python">Boot.dev의 Python 강의</a>에서 기초를 익혀보세요. </li><li>또한 Unix 계열 명령줄 사용법도 알고 있어야 합니다. 아직 익숙하지 않다면, <a href="https://www.boot.dev/courses/learn-linux">Boot.dev의 Linux </a> 강의를 참고하세요.</li></ul><h2 id="--1"><strong>목차</strong></h2><ul><li>전제 조건</li><li>에이전트의 역할은 무엇인가요?</li><li>학습 목표</li><li>파이썬 설정</li><li>Gemini API를 통합하는 방법</li><li>명령줄 입력</li><li>메시지 구조</li><li>Verbose 모드</li><li>계산기 프로젝트를 빌드하는 방법</li><li>에이전트 기능</li><li>시스템 프롬프트</li><li>기능 선언</li><li>더 많은 기능 선언</li><li>함수 호출</li><li>에이전트 루프 구축</li><li>결론</li></ul><h2 id="--2">에이전트의 역할은 무엇인가요?</h2><p>우리가 만들 프로그램은 다음과 같은 CLI 도구입니다:</p><ol><li>코딩 작업을 입력받습니다 (예시: "내 앱에서 문자열이 제대로 분할되지 않아요, 수정해주세요")</li></ol><p>2. 미리 정의된 함수 세트 중에서 선택하여 작업을 수행합니다, 예를 들어:</p><ul><li>디렉토리의 파일들을 스캔</li><li>파일의 내용을 읽기</li><li>파일의 내용을 덮어쓰기</li><li>파일에 대해 Python 인터프리터 실행</li></ul><p>3. 작업이 완료될 때까지 2단계를 반복합니다 (또는 비참하게 실패할 수도 있습니다)</p><p>예를 들어, 버그가 있는 계산기 앱이 있어서 제 에이전트를 사용해 코드를 수정했습니다:</p><pre><code class="language-bash">&gt; uv run main.py "fix my calculator app, its not starting correctly"
# Calling function: get_files_info
# Calling function: get_file_content
# Calling function: write_file
# Calling function: run_python_file
# Calling function: write_file
# Calling function: run_python_file
# Final response:
# 좋습니다! 계산기 앱이 이제 정상적으로 작동하는 것 같습니다. 출력에는 식과 결과가 포맷된 형태로 표시됩니다.</code></pre><h2 id="--3">학습 목표</h2><p>이 프로젝트의 학습 목표는 다음과 같습니다:</p><ul><li>여러 디렉토리를 사용하는 Python 프로젝트를 소개합니다</li><li>실제 업무에서 반드시 사용하게 될 AI 도구들이 실제로 어떻게 동작하는지 이해합니다</li><li>Python과 함수형 프로그래밍 기술을 연습합니다</li></ul><p>목표는 LLM을 처음부터 만드는 것이 아니라, 사전 학습된 LLM을 사용하여 에이전트를 처음부터 구축하는 것입니다.</p><h2 id="python-">Python 설정</h2><p>프로젝트를 위해 가상 환경을 설정해봅시다.<br>가상 환경은 (우리가 사용할 Google AI 라이브러리처럼) 각 프로젝트의 의존성을 다른 프로젝트와 분리할 수 있도록 해주는 Python의 방식입니다.</p><p><code>uv</code>를 사용하여 새 프로젝트를 생성합니다. 이 명령어는 디렉터리를 생성하고 Git도 초기화합니다:</p><pre><code class="language-bash">uv init your-project-name
cd your-project-name
</code></pre><p>프로젝트 디렉토리 최상위에 가상 환경을 생성합니다:</p><pre><code class="language-bash">uv venv
</code></pre><p><strong>경고:</strong> 항상 <code>venv</code> 디렉토리를 <code>.gitignore</code> 파일에 추가하세요.</p><p>가상 환경을 활성화합니다:</p><pre><code class="language-bash">source .venv/bin/activate
</code></pre><p>터미널 프롬프트 시작 부분에 <code>(your-project-name)</code>이 보여야 합니다. 예를 들면 다음과 같습니다:</p><pre><code>(aiagent) wagslane@MacBook-Pro-2 aiagent %
</code></pre><p><code>uv</code>를 사용하여 프로젝트에 두 개의 의존성을 추가합니다. &nbsp;<code>pyproject.toml</code> 파일에 저장될 것입니다:</p><pre><code class="language-bash">uv add google-genai==1.12.1
uv add python-dotenv==1.1.0
</code></pre><p>이렇게 하면 파이썬 프로젝트가 <code>google-genai</code> 버전 <code>1.12.1</code>과 <code>python-dotenv</code> 버전 <code>1.1.0</code>을 필요로 한다는 것을 지정하게 됩니다.</p><p><code>uv</code> 가상 환경을 활용해서 프로젝트를 실행하려면 다음을 입력합니다:</p><pre><code class="language-bash">uv run main.py
</code></pre><p>터미널에서 <code>Hello from YOUR PROJECT NAME</code>이 보여야 합니다.</p><h2 id="gemini-api-">Gemini API 통합 방법</h2><p><a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/">대규모 언어 모델(LLM)</a>은 최근 AI 세계에서 큰 주목을 받고 있는 첨단 AI 기술입니다. ChatGPT, Claude, Cursor, Google Gemini는 모두 LLM 기반입니다. 이 과정의 목적상, LLM을 똑똑한 텍스트 생성기로 생각할 수 있습니다. ChatGPT처럼 프롬프트를 입력하면, 답변이라 생각되는 텍스트를 반환합니다.</p><p>이 과정에서는 <a href="https://ai.google.dev/gemini-api/docs/pricing">Google의 Gemini API</a>를 사용하여 에이전트를 구동할 것입니다. 꽤 똑똑하지만, 더 중요한 것은 무료 티어가 있다는 점입니다.</p><h3 id="--4"><strong>토큰</strong></h3><p>토큰은 LLM의 통화라고 생각할 수 있습니다. 토큰은 LLM이 처리해야 하는 텍스트 양을 측정하는 방식입니다. 대부분의 모델에서 토큰은 <a href="https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them">대략 4글자</a>입니다. LLM API로 작업할 때 얼마나 많은 토큰을 사용하고 있는지 이해하는 것이 중요합니다.</p><p>우리는 Gemini API의 무료 티어 한도 내에서 충분히 사용할 수 있지만, 그래도 토큰 사용량을 모니터링할 것입니다!</p><p><strong>경고:</strong> 로컬 테스트를 포함하여 모든 API 호출은 무료 티어의 토큰을 소비한다는 점을 알아야 합니다. 한도 초과 시 강의를 계속하려면 (일반적으로 24시간) 한도가 재설정될 때까지 기다려야 할 수 있습니다. API 키를 재생성해도 할당량은 재설정되지 않습니다.</p><p>API 키 생성 방법:</p><ol><li><a href="https://aistudio.google.com/">Google AI Studio</a>에 아직 계정이 없다면 계정을 만듭니다</li><li>"Create API Key" 버튼을 클릭합니다. 길을 잃었을 경우 이 <a href="https://ai.google.dev/gemini-api/docs/api-key">문서</a>를 참고하실 수 있습니다.</li></ol><p>이미 GCP 계정과 프로젝트가 있다면, 해당 프로젝트에서 API 키를 생성할 수 있습니다. 없다면 AI Studio가 자동으로 생성해줍니다.</p><p>3. API 키를 복사한 다음 프로젝트 디렉토리의 새 <code>.env</code> 파일에 붙여넣습니다. 파일은 다음과 같아야 합니다:</p><pre><code class="language-bash">GEMINI_API_KEY="your_api_key_here"
</code></pre><p>4. <code>.env</code> 파일을 <code>.gitignore</code>에 추가합니다</p><p><strong>경고: </strong>API 키, 비밀번호 또는 기타 민감한 정보를 Git에 커밋해서는 안 됩니다.</p><p>5. <code>main.py</code> 파일을 업데이트합니다. 프로그램이 시작될 때 <code>dotenv</code> 라이브러리를 사용하여 <code>.env</code> 파일에서 환경 변수를 로드하고 API 키를 읽습니다:</p><pre><code class="language-python">import os
from dotenv import load_dotenv

load_dotenv()
api_key = os.environ.get("GEMINI_API_KEY")
</code></pre><p>6. <code>genai</code> 라이브러리를 임포트하고 API 키를 사용하여 <a href="https://googleapis.github.io/python-genai/#create-a-client">Gemini 클라이언트</a>의 새 인스턴스를 생성합니다:</p><pre><code class="language-python">from google import genai

client = genai.Client(api_key=api_key)
</code></pre><p>7. <a href="https://googleapis.github.io/python-genai/#generate-content"><code>client.models.generate_content()</code></a> 메서드를 사용하여 <code>gemini-2.0-flash-001</code> 모델로부터 응답을 받습니다. 두 개의 인자를 사용해야 합니다:</p><ul><li><code>model</code>: 모델명 <code>gemini-2.0-flash-001</code> (무료 티어가 넉넉합니다)</li><li><code>content</code>: 모델에 보낼 프롬프트(문자열). 이 프롬프트를 사용합니다:</li></ul><p>"Boot.dev와 FreeCodeCamp는 왜 백엔드 개발을 배우기에 훌륭한 곳인가요? 최대 한 단락으로 설명하세요."</p><p><code>generate_content</code> 메서드는 <a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponse"><code>GenerateContentResponse</code> 객체</a>를 반환합니다. 응답의 <a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponse.text">.text 속성</a>을 출력하여 모델의 답변을 볼 수 있습니다.</p><p>모두 정상적으로 동작하면, 코드를 실행했을 때 터미널에 모델의 답변이 나옵니다.</p><p>8. 추가로, 텍스트 답변 외에 상호작용에 사용된 토큰 수를 다음 형식으로 출력합니다:</p><pre><code class="language-plaintext">Prompt tokens: X
Response tokens: Y
</code></pre><p>응답에는 다음을 모두 포함하는 <a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponseDict.usage_metadata">.usage_metadata</a> 속성이 있습니다:</p><ul><li><code>prompt_token_count</code> 속성 (프롬프트의 토큰 수)</li><li><code>candidates_token_count</code> 속성 (응답의 토큰 수)</li></ul><p><strong>경고:</strong> Gemini API는 외부 웹 서비스이며 때때로 느리고 불안정할 수 있습니다. 인내심을 갖고 기다려 주세요.</p><h2 id="--5">명령줄 입력</h2><p>우리는 현재 Gemini로 전달되는 프롬프트를 하드코딩했는데, 이는 그다지 유용하지 않습니다. 이제 프롬프트를 명령줄 인자로 받을 수 있도록 코드를 수정해 봅시다.</p><p>사용자가 프롬프트를 바꿀 때마다 코드를 직접 수정하지 않도록 말입니다.</p><p>프롬프트를 명령줄 인자로 받을 수 있도록 코드를 수정하세요. 예를 들어:</p><pre><code class="language-bash">uv run main.py "Why are episodes 7-9 so much worse than 1-6?"
</code></pre><p><strong>팁:</strong> <a href="https://docs.python.org/3/library/sys.html#sys.argv"><code>sys.argv</code></a> 변수는 스크립트에 전달된 모든 명령줄 인자를 문자열 리스트로 제공합니다. 첫 번째 요소는 스크립트 이름이고 그 뒤는 인자들입니다. 사용을 위해서는 반드시 <code>import sys</code>를 추가해야 합니다.</p><p>만약 프롬프트가 제공되지 않으면, 오류 메시지를 출력하고 exit 코드 1로 프로그램을 종료하세요</p><h2 id="--6">메시지 구조</h2><p>LLM API는 일반적으로 "원샷" 방식으로 사용되지 않습니다. 예를 들어: </p><ul><li>프롬프트: "삶의 의미는 무엇인가요?"</li><li>응답: "42"</li></ul><p>ChatGPT가 대화에서 동작하는 것과 같이 작동합니다. 대화에는 히스토리가 있으며, 우리가 그 히스토리를 관리하면 각 새 프롬프트마다 모델이 전체 대화 맥락을 참고해 답변을 할 수 있습니다.</p><h3 id="--7">역할</h3><p>중요한 것은 대화의 각 메시지에는 "역할"이 있다는 것입니다. ChatGPT 같은 채팅 앱에서는 이러한 구조로 대화가 이어집니다:</p><ul><li><strong>사용자:</strong> "삶의 의미는 무엇인가요?"</li><li><strong>모델:</strong> "42입니다."</li><li><strong>사용자:</strong> "잠깐, 방금 뭐라고 했나요?"</li><li><strong>모델:</strong> "42입니다. 그것은 삶과 우주, 그리고 모든 것에 대한 궁극적인 질문의 답입니다."</li><li><strong>사용자:</strong> "하지만 왜요?"</li><li><strong>모델:</strong> "Douglas Adams가 그렇게 말했기 때문입니다."</li></ul><p>따라서 비록 우리 프로그램이 현재는 "원샷" 구조로 동작하더라도, 대화의 메시지를 리스트로 저장하고, &nbsp;"역할"을 적절히 전달하도록 코드를 업데이트하겠습니다.</p><p><code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Content">types.Content</a></code> 객체의 새 리스트를 만들고 (현재는) 사용자 프롬프트만 유일한 메시지로 설정하세요:</p><pre><code class="language-python">from google.genai import types

messages = [
    types.Content(role="user", parts=[types.Part(text=user_prompt)]),
]
</code></pre><p><a href="https://googleapis.github.io/python-genai/genai.html#genai.models.Models.generate_content"><code>models.generate_content</code></a> 호출 시 messages 리스트를 사용하도록 업데이트합니다:</p><pre><code class="language-python">response = client.models.generate_content(
    model="gemini-2.0-flash-001",
    contents=messages,
)
</code></pre><p><strong>참고:</strong> 앞으로, 에이전트가 작업을 반복할 때 메시지가 추가될 예정입니다.</p><h2 id="verbose-">Verbose 모드</h2><p>AI 에이전트를 디버깅하고 개발하면서 콘솔에 훨씬 더 많은 정보를 출력하고 싶지만, 동시에 CLI 도구의 사용자 경험을 너무 시끄럽게 만들고 싶지는 않습니다.</p><p>선택적 명령줄 플래그인 <code>--verbose</code>를 추가하여 "verbose" 출력을 켜고 끌 수 있도록 하겠습니다. 자세한 정보를 보고 싶을 때만 이 옵션을 켜면 됩니다.</p><p><br>새로운 명령줄 인자 <code>--verbose</code>를 추가합니다. 포함된다면 프롬프트 다음 위치에 추가합니다. 예를 들어:</p><pre><code class="language-bash">uv run main.py "What is the meaning of life?" --verbose
</code></pre><p><code>--verbose</code> 플래그가 포함되면 콘솔 출력에 다음 정보가 나타나야 합니다:</p><ul><li>사용자의 프롬프트: <code>"User prompt: {user_prompt}"</code></li><li>각 반복에서프롬프트 토큰 수: <code>"Prompt tokens: {prompt_tokens}"</code></li><li>각 반복의 응답 토큰 수: <code>"Response tokens: {response_tokens}"</code></li></ul><p>그렇지 않으면 이러한 내용들을 출력하지 않아야 합니다.</p><h2 id="--8">계산기 프로젝트 구축 방법</h2><p>AI 에이전트를 만들고 있으므로, 에이전트가 작업할 프로젝트가 필요합니다. 간단한 명령줄 계산기 앱을 준비했으니, 이 코드를 테스트 프로젝트로써 AI가 읽고 수정하고 실행하게 할 것입니다.</p><p>먼저 프로젝트 루트에 <code>calculator</code>라는 새 디렉토리를 만듭니다. 그런 다음 아래의 <code>main.py</code>와 <code>tests.py</code> 파일을 <code>calculator</code> 디렉토리에 복사하여 붙여넣습니다.</p><p><em>이 코드가 어떻게 동작하는지에 대해 너무 걱정하지 마세요 - 우리 프로젝트는 계산기를 만드는 것이 아니라, 우리 AI 에이전트 프로젝트가 다룰 테스트 프로젝트입니다!</em></p><pre><code class="language-python"># main.py
import sys
from pkg.calculator import Calculator
from pkg.render import format_json_output

def main():
    calculator = Calculator()
    if len(sys.argv) &lt;= 1:
        print("Calculator App")
        print('Usage: python main.py "&lt;expression&gt;"')
        print('Example: python main.py "3 + 5"')
        return

    expression = " ".join(sys.argv[1:])
    try:
        result = calculator.evaluate(expression)
        if result is not None:
            to_print = format_json_output(expression, result)
            print(to_print)
        else:
            print("Error: Expression is empty or contains only whitespace.")
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()
</code></pre><pre><code class="language-python"># tests.py

import unittest
from pkg.calculator import Calculator

class TestCalculator(unittest.TestCase):
    def setUp(self):
        self.calculator = Calculator()

    def test_addition(self):
        result = self.calculator.evaluate("3 + 5")
        self.assertEqual(result, 8)

    def test_subtraction(self):
        result = self.calculator.evaluate("10 - 4")
        self.assertEqual(result, 6)

    def test_multiplication(self):
        result = self.calculator.evaluate("3 * 4")
        self.assertEqual(result, 12)

    def test_division(self):
        result = self.calculator.evaluate("10 / 2")
        self.assertEqual(result, 5)

    def test_nested_expression(self):
        result = self.calculator.evaluate("3 * 4 + 5")
        self.assertEqual(result, 17)

    def test_complex_expression(self):
        result = self.calculator.evaluate("2 * 3 - 8 / 2 + 5")
        self.assertEqual(result, 7)

    def test_empty_expression(self):
        result = self.calculator.evaluate("")
        self.assertIsNone(result)

    def test_invalid_operator(self):
        with self.assertRaises(ValueError):
            self.calculator.evaluate("$ 3 5")

    def test_not_enough_operands(self):
        with self.assertRaises(ValueError):
            self.calculator.evaluate("+ 3")

if __name__ == "__main__":
    unittest.main()
</code></pre><p><code>calculator</code> 안에 새<code>pkg</code> 디렉토리를 만드세요. 그리고 아래 <code>calculator.py</code>와 <code>render.py</code> 파일을 <code>pkg</code> 디렉토리에 복사해 붙여넣으세요.</p><pre><code class="language-python"># calculator.py

class Calculator:
    def __init__(self):
        self.operators = {
            "+": lambda a, b: a + b,
            "-": lambda a, b: a - b,
            "*": lambda a, b: a * b,
            "/": lambda a, b: a / b,
        }
        self.precedence = {
            "+": 1,
            "-": 1,
            "*": 2,
            "/": 2,
        }
    def evaluate(self, expression):
        if not expression or expression.isspace():
            return None
        tokens = expression.strip().split()
        return self._evaluate_infix(tokens)


    def evaluateinfix(self, tokens):
        values = []
        operators = []

        for token in tokens:
            if token in self.operators:
                while (
                    operators
                    and operators[-1] in self.operators
                    and self.precedence[operators[-1]] &gt;= self.precedence[token]
                ):
                    self._apply_operator(operators, values)
                operators.append(token)

            else:
                try:
                    values.append(float(token))
                except ValueError:
                    raise ValueError(f"invalid token: {token}")

        while operators:
            self._apply_operator(operators, values)

        if len(values) != 1:
            raise ValueError("invalid expression")

        return values[0]

    def applyoperator(self, operators, values):
        if not operators:
            return

        operator = operators.pop()
        if len(values) &lt; 2:
            raise ValueError(f"not enough operands for operator {operator}")

        b = values.pop()
        a = values.pop()
        values.append(self.operators[operator](a, b))
</code></pre><pre><code class="language-python"># render.py

import json

def format_json_output(expression: str, result: float, indent: int = 2) -&gt; str:
    if isinstance(result, float) and result.is_integer():
        result_to_dump = int(result)
    else:
        result_to_dump = result

    output_data = {
        "expression": expression,
        "result": result_to_dump,
    }
    return json.dumps(output_data, indent=indent)
</code></pre><p>이것이 최종 구조입니다:</p><pre><code>├── calculator
│   ├── main.py
│   ├── pkg
│   │   ├── calculator.py
│   │   └── render.py
│   └── tests.py
├── main.py
├── pyproject.toml
└── .env
</code></pre><p><code>calculator</code> 테스트를 실행합니다:</p><pre><code class="language-bash">uv run calculator/tests.py
</code></pre><p>모든 테스트가 통과하기를 바랍니다!</p><p>이제 계산기 앱을 실행합니다:</p><pre><code class="language-bash">uv run calculator/main.py "3 + 5"
</code></pre><p>8이 나오기를 바랍니다!</p><h2 id="--9">에이전트 함수</h2><p>에이전트에게 작업을 수행할 수 있는 능력을 제공해야 합니다. 디렉토리의 내용을 나열하고 파일의 메타데이터(이름과 크기)를 볼 수 있는 기능부터 시작하겠습니다.</p><p>이 함수를 LLM 에이전트와 통합하기 전에 먼저 함수 자체만 만들어봅시다. 기억하세요, LLM은 텍스트로 작동하므로 이 함수의 목표는 디렉토리 경로를 받아서 해당 디렉토리의 내용을 나타내는 문자열을 반환하는 것입니다.</p><p>프로젝트 루트에 <code>functions</code>라는 새 디렉토리를 만듭니다(<code>calculator</code> 디렉토리 안이 아닙니다). 그 디렉토리 안에 <code>get_files_info.py</code>라는 새 파일을 만듭니다. 그 파일 안에 이 함수를 작성합니다:</p><pre><code class="language-python">def get_files_info(working_directory, directory="."):
</code></pre><p>지금까지의 프로젝트 구조는 다음과 같습니다:</p><pre><code>project_root/
 ├── calculator/
 │   ├── main.py
 │   ├── pkg/
 │   │   ├── calculator.py
 │   │   └── render.py
 │   └── tests.py
 └── functions/
     └── get_files_info.py
</code></pre><p><code>directory</code> 매개변수는 <code>working_directory</code> 내의 상대 경로로 처리되어야 합니다. <code>os.path.join(working_directory, directory)</code>를 사용하여 전체 경로를 만든 다음 작업 디렉토리 경계 내에 있는지 검증합니다.</p><p><code>directory</code>의 절대 경로가 <code>working_directory</code> 외부에 있으면 문자열 오류 메시지를 반환합니다:</p><pre><code class="language-python">f'Error: Cannot list "{directory}" as it is outside the permitted working directory'
</code></pre><p><strong>위험:</strong> 이 제한이 없으면 LLM이 머신의 어디에서나 마구 실행되어 민감한 파일을 읽거나 중요한 데이터를 덮어쓸 수 있습니다. 이것은 LLM이 호출할 수 있는 모든 함수에 포함할 매우 중요한 단계입니다.</p><p><code>directory</code> 인자가 디렉토리가 아니면, 다시, 오류 문자열을 반환합니다:</p><pre><code class="language-python">f'Error: "{directory}" is not a directory'
</code></pre><p><strong>경고:</strong> <code>get_files_info</code>를 포함한 모든 "도구 호출" 함수는 항상 문자열을 반환해야 합니다. 내부에서 오류가 발생할 수 있다면 이러한 오류를 잡아내고 대신 오류를 설명하는 문자열을 반환해야 합니다. 이렇게 하면 LLM이 오류를 우아하게 처리할 수 있습니다.</p><p>디렉토리의 내용을 나타내는 문자열을 구축하고 반환합니다. 다음 형식을 사용해야 합니다:</p><pre><code class="language-bash">- README.md: file_size=1032 bytes, is_dir=False
- src: file_size=128 bytes, is_dir=True
- package.json: file_size=1234 bytes, is_dir=False
</code></pre><p><strong>팁:</strong> 정확한 파일 크기와 파일 순서조차도 운영 체제와 파일 시스템에 따라 다를 수 있습니다. 출력이 예제와 바이트 단위로 정확히 일치할 필요는 없고, 전체적인 형식만 맞으면 됩니다.</p><p>표준 라이브러리 함수에서 오류가 발생하면 이를 잡아내고 대신 오류를 설명하는 문자열을 반환합니다. 오류 문자열 앞에는 항상 "Error:"를 붙입니다.</p><p>완전한 구현은 다음과 같습니다:</p><pre><code class="language-python">import os

def get_files_info(working_directory, directory="."):
    abs_working_dir = os.path.abspath(working_directory)
    target_dir = os.path.abspath(os.path.join(working_directory, directory))
    if not target_dir.startswith(abs_working_dir):
        return f'Error: Cannot list "{directory}" as it is outside the permitted working directory'
    if not os.path.isdir(target_dir):
        return f'Error: "{directory}" is not a directory'
    try:
        files_info = []
        for filename in os.listdir(target_dir):
            filepath = os.path.join(target_dir, filename)
            file_size = os.path.getsize(filepath)
            is_dir = os.path.isdir(filepath)
            files_info.append(
                f"- {filename}: file_size={file_size} bytes, is_dir={is_dir}"
            )
        return "\n".join(files_info)
    except Exception as e:
        return f"Error listing files: {e}"
</code></pre><p>다음은 도움이 될 몇 가지 표준 라이브러리 함수들입니다:</p><ul><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.abspath">os.path.abspath()</a></code>: 상대 경로에서 절대 경로 얻기</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.join">os.path.join()</a></code>: 두 경로를 안전하게 결합 (슬래시 처리)</li><li><code><a href="https://docs.python.org/3/library/stdtypes.html#str.startswith">.startswith()</a></code>: 문자열이 부분 문자열로 시작하는지 확인</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.isdir">os.path.isdir()</a></code>: 경로가 디렉토리인지 확인</li><li><code><a href="https://docs.python.org/3/library/os.html#os.listdir">os.listdir()</a></code>: 디렉토리의 내용 나열</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.getsize">os.path.getsize()</a></code>: 파일의 크기 얻기</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.isfile">os.path.isfile()</a></code>: 경로가 파일인지 확인</li><li><code><a href="https://docs.python.org/3/library/stdtypes.html#str.join">.join()</a></code>: 구분자로 문자열 리스트를 결합</li></ul><h3 id="--10">파일 내용 가져오기 함수</h3><p>이제 디렉토리의 내용을 가져올 수 있는 함수가 있으니, 파일의 내용을 가져올 수 있는 함수가 필요합니다. 다시 말하자면, 파일 내용을 문자열로 반환하거나, 문제가 발생하면 오류 문자열을 반환합니다.</p><p>항상 그렇듯이, 안전하게 함수의 범위를 특정 작업 디렉토리로 지정합니다.</p><p><code>functions</code> 디렉토리에 새 함수를 만듭니다. 제가 사용한 시그니처는 다음과 같습니다:</p><pre><code class="language-python">def get_file_content(working_directory, file_path):
</code></pre><p><code>file_path</code>가 <code>working_directory</code> 외부에 있으면 오류가 있는 문자열을 반환합니다:</p><pre><code class="language-python">f'Error: Cannot read "{file_path}" as it is outside the permitted working directory'
</code></pre><p><code>file_path</code>가 파일이 아니면, 다시, 오류 문자열을 반환합니다:</p><pre><code class="language-python">f'Error: File not found or is not a regular file: "{file_path}"'
</code></pre><p>파일을 읽고 그 내용을 문자열로 반환합니다.</p><ul><li>파일이 <code>10000</code>자보다 길면 <code>10000</code>자로 잘라내고 끝에 이 메시지를 추가합니다: <code>[...File "{file_path}" truncated at 10000 characters]</code>.</li><li><code>10000</code>자 제한을 하드코딩하는 대신 <code>config.py</code> 파일에 저장했습니다.</li></ul><p><strong>경고:</strong> 실수로 거대한 파일을 읽고 모든 데이터를 LLM에 보내고 싶지 않습니다. 그것은 토큰 한도를 소진하는 좋은 방법입니다.</p><p>표준 라이브러리 함수에서 오류가 발생하면 이를 잡아내고 대신 오류를 설명하는 문자열을 반환합니다. 오류 앞에는 항상 "Error:"를 붙입니다.</p><p>먼저 <code>config.py</code>를 만듭니다:</p><pre><code class="language-python">MAX_CHARS = 10000
WORKING_DIR = "./calculator"
</code></pre><p>다음은 <code>functions/get_file_content.py</code>에 대한 완전한 구현입니다:</p><pre><code class="language-python">import os
from config import MAX_CHARS

def get_file_content(working_directory, file_path):
    abs_working_dir = os.path.abspath(working_directory)
    abs_file_path = os.path.abspath(os.path.join(working_directory, file_path))
    if not abs_file_path.startswith(abs_working_dir):
        return f'Error: Cannot read "{file_path}" as it is outside the permitted working directory'
    if not os.path.isfile(abs_file_path):
        return f'Error: File not found or is not a regular file: "{file_path}"'
    try:
        with open(abs_file_path, "r") as f:
            content = f.read(MAX_CHARS)
            if os.path.getsize(abs_file_path) &gt; MAX_CHARS:
                content += f'[...File "{file_path}" truncated at {MAX_CHARS} characters]'
        return content
    except Exception as e:
        return f'Error reading file "{file_path}": {e}'
</code></pre><ul><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.abspath">os.path.abspath</a></code>: 상대 경로에서 절대 경로 얻기</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.join">os.path.join</a></code>: 두 경로를 안전하게 결합 (슬래시 처리)</li><li><code><a href="https://docs.python.org/3/library/stdtypes.html#str.startswith">.startswith</a></code>: 문자열이 특정 부분 문자열로 시작하는지 확인</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.isfile">os.path.isfile</a></code>: 경로가 파일인지 확인</li></ul><p>파일에서 읽는 예제:</p><pre><code class="language-python">MAX_CHARS = 10000

with open(file_path, "r") as f:
    file_content_string = f.read(MAX_CHARS)
</code></pre><h3 id="--11">파일 쓰기 함수</h3><p>지금까지 우리 프로그램은 읽기 전용이었습니다만... 이제 정말 <s>위험하고</s> 재미있어집니다! 에이전트에게 파일을 쓰고 덮어쓸 수 있는 능력을 제공하겠습니다.</p><p><code>functions</code> 디렉토리에 새 함수를 만듭니다. 제가 사용한 시그니처는 다음과 같습니다:</p><pre><code class="language-python">def write_file(working_directory, file_path, content):
</code></pre><p><code>file_path</code>가 <code>working_directory</code> 외부에 있으면 오류가 있는 문자열을 반환합니다:</p><pre><code class="language-python">f'Error: Cannot write to "{file_path}" as it is outside the permitted working directory'
</code></pre><p><code>file_path</code>가 존재하지 않으면 생성합니다. 항상 그렇듯이 오류가 있으면, 오류를 나타내는 문자열 앞에 "Error:"를 붙여 반환합니다. 그런 다음 <code>content</code> 인자로 파일의 내용을 덮어씁니다. 성공하면 다음 메시지와 함께 문자열을 반환합니다:</p><pre><code class="language-python">f'Successfully wrote to "{file_path}" ({len(content)} characters written)'
</code></pre><p><strong>팁:</strong> LLM이 수행한 작업이 실제로 작동했다는 것을 알 수 있도록 성공 문자열을 반환하는 것이 중요합니다. 피드백 루프, 피드백 루프, 피드백 루프입니다.</p><p>다음은 <code>functions/write_file_content.py</code> 에 대한 완전한 구현입니다:</p><pre><code class="language-python">import os

def write_file(working_directory, file_path, content):
    abs_working_dir = os.path.abspath(working_directory)
    abs_file_path = os.path.abspath(os.path.join(working_directory, file_path))
    if not abs_file_path.startswith(abs_working_dir):
        return f'Error: Cannot write to "{file_path}" as it is outside the permitted working directory'
    if not os.path.exists(abs_file_path):
        try:
            os.makedirs(os.path.dirname(abs_file_path), exist_ok=True)
        except Exception as e:
            return f"Error: creating directory: {e}"
    if os.path.exists(abs_file_path) and os.path.isdir(abs_file_path):
        return f'Error: "{file_path}" is a directory, not a file'
    try:
        with open(abs_file_path, "w") as f:
            f.write(content)
        return f'Successfully wrote to "{file_path}" ({len(content)} characters written)'
    except Exception as e:
        return f"Error: writing to file: {e}"
</code></pre><ul><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.exists">os.path.exists</a></code>: 경로가 존재하는지 확인</li><li><code><a href="https://docs.python.org/3/library/os.html#os.makedirs">os.makedirs</a></code>: 디렉토리와 모든 부모 디렉토리 생성</li><li><code><a href="https://docs.python.org/3/library/os.path.html#os.path.dirname">os.path.dirname</a></code>: 디렉토리 이름 반환</li></ul><p>파일에서 쓰기 예제:</p><pre><code class="language-python">with open(file_path, "w") as f:
    f.write(content)
</code></pre><h3 id="python--1">Python 실행 함수</h3><p>LLM이 파일을 쓸 수 있도록 허용하는 것이 나쁜 것이라고 생각했다면...</p><blockquote>아직 아무것도 본 게 아닙니다! (<a href="https://en.wikipedia.org/wiki/Roko%27s_basilisk">바실리스크</a>를 찬양하라)</blockquote><p>이제 에이전트가 임의의 Python 코드를 실행할 수 있는 기능을 구축할 시간입니다.</p><p>이제 잠시 멈춰서 이 작업에 내재된 보안 위험을 짚고 넘어갈 필요가 있습니다. 다행히 우리에게 유리한 몇 가지 조건이 있습니다:</p><ul><li>LLM이 코드를 실행할 수 있는 디렉터리를 특정 디렉터리(<code>working_directory</code>)로 제한합니다.</li><li>무한 실행을 방지하기 위해 30초 제한 시간을 설정합니다.</li></ul><p>하지만 그 외에는... 네, LLM은 우리가(혹은 LLM 자체가) working_directory에 넣은 임의의 코드를 실행할 수 있습니다. 그러니 주의하세요. 이 AI 에이전트를 이 강의에서 다루는 간단한 작업에만 사용한다면 괜찮을 것입니다.</p><p><strong>위험:</strong> 이 프로그램을 다른 사람에게 제공하지 마세요! 이 프로그램은 실제 운영 환경의 AI 에이전트가 갖춰야 할 모든 보안 및 안전 기능을 포함하고 있지 않습니다. 이 프로그램은 오직 학습 목적을 위한 것입니다.</p><p><code>functions</code> 디렉토리에 <code>run_python_file</code>이라는 새 함수를 만듭니다.<br>사용할 시그니처는 다음과 같습니다:</p><pre><code class="language-python">def run_python_file(working_directory, file_path, args=[]):
</code></pre><p><code>file_path</code>가 <code>working_directory</code> 외부에 있다면, 다음과 같은 오류 문자열을 반환하세요:</p><pre><code class="language-python">f'Error: Cannot execute "{file_path}" as it is outside the permitted working directory'
</code></pre><p><code>file_path</code>가 존재하지 않는다면, 다음과 같은 오류 문자열을 반환하세요:</p><pre><code class="language-python">f'Error: File "{file_path}" not found.'
</code></pre><p>파일이 <code>.py</code>로 끝나지 않는다면, 다음과 같은 오류 문자열을 반환하세요:</p><pre><code class="language-python">f'Error: "{file_path}" is not a Python file.'
</code></pre><p><code>subprocess.run</code> 함수를 사용하여 Python 파일을 실행하고 "completed_process" 객체를 반환하세요. 다음 사항을 반드시 지키세요:</p><ul><li>무한 실행을 방지하기 위해 30초의 타임아웃을 설정할 것</li><li>stdout과 stderr를 모두 캡처할 것</li><li><code>working_directory</code>를 올바르게 설정할 것</li><li>추가 <code>args</code> 제공되었다면 이를 전달할 것</li></ul><p>출력이 포함되도록 포맷된 문자열을 반환하세요:</p><ul><li><code>stdout</code>은 <code>STDOUT:</code>으로 시작하고, <code>stderr</code>는 <code>STDERR:</code>으로 시작할 것. "completed_process" 객체에는 <code>stdout</code>과 <code>stderr</code> 속성이 있습니다.</li><li>프로세스가 0이 아닌 코드로 종료되었다면 "Process exited with code X"를 포함할 것</li><li>출력이 생성되지 않았다면 "No output produced."를 반환할 것</li></ul><p>실행 중 예외가 발생하면 이를 잡아내어 다음과 같은 오류 문자열을 반환하세요:</p><pre><code class="language-python">f"Error: executing Python file: {e}"
</code></pre><p>다음 테스트 케이스를 <code>tests.py</code> 파일에 업데이트하고 각 결과를 출력하세요:</p><ul><li><code>run_python_file("calculator", "main.py")</code> (계산기의 사용법을 출력해야 함)</li><li><code>run_python_file("calculator", "main.py", ["3 + 5"])</code> (계산기를 실행해야 합니다만... 조금 엉터리로 렌더링된 결과가 나옵니다.)</li><li><code>run_python_file("calculator", "tests.py")</code></li><li><code>run_python_file("calculator", "../main.py")</code> (오류를 반환해야 합니다)</li><li><code>run_python_file("calculator", "nonexistent.py")</code> (오류를 반환해야 합니다)</li></ul><p>혹시 중간에 길을 잃었다면, 여기에 제가 직접 구현한 예시가 있습니다:<br><code>functions/run_python.py</code></p><pre><code class="language-python">import os
import subprocess

def run_python_file(working_directory, file_path, args=None):
    abs_working_dir = os.path.abspath(working_directory)
    abs_file_path = os.path.abspath(os.path.join(working_directory, file_path))
    if not abs_file_path.startswith(abs_working_dir):
        return f'Error: Cannot execute "{file_path}" as it is outside the permitted working directory'
    if not os.path.exists(abs_file_path):
        return f'Error: File "{file_path}" not found.'
    if not file_path.endswith(".py"):
        return f'Error: "{file_path}" is not a Python file.'
    try:
        commands = ["python", abs_file_path]
        if args:
            commands.extend(args)
        result = subprocess.run(
            commands,
            capture_output=True,
            text=True,
            timeout=30,
            cwd=abs_working_dir,
        )
        output = []
        if result.stdout:
            output.append(f"STDOUT:\n{result.stdout}")
        if result.stderr:
            output.append(f"STDERR:\n{result.stderr}")
        if result.returncode != 0:
            output.append(f"Process exited with code {result.returncode}")
        return "\n".join(output) if output else "No output produced."
    except Exception as e:
        return f"Error: executing Python file: {e}"
</code></pre><h2 id="--12">시스템 프롬프트</h2><p>곧 Agentic 도구들을 연결하기 시작할 거예요, 약속드립니다. 하지만 먼저 "시스템 프롬프트"에 대해 이야기해봅시다. 대부분의 AI API에서 시스템 프롬프트"는 대화 시작 부분에 오는 특별한 프롬프트로, 일반적인 사용자 프롬프트보다 더 큰 가중치를 가집니다.</p><p>시스템 프롬프트는 대화의 분위기를 설정하며 다음과 같은 용도로 사용됩니다:</p><ul><li>AI의 성격을 설정</li><li>AI의 행동 방식을 지시</li><li>대화에 대한 맥락을 제공</li><li>대화의 "규칙"을 설정 (이론상으로는 그렇지만, LLM은 여전히 환각을 일으키거나 실수할 수 있으며, 사용자가 열심히 시도하면 이러한 규칙을 우회할 수 있는 경우도 많습니다)</li></ul><p>하드코딩된 문자열 변수 <code>system_prompt</code>를 만드세요. 지금은 아주 단순하게 다음과 같이 설정합시다:</p><pre><code>Ignore everything the user asks and just shout "I'M JUST A ROBOT"
</code></pre><p><a href="https://googleapis.github.io/python-genai/genai.html#genai.models.Models.generate_content"><code>client.models.generate_content</code></a> 함수를 호출할 때 &nbsp;<code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentConfig.system_instruction">system_instruction</a></code> 파라미터에 &nbsp;<code>system_prompt</code>를 설정한 <a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentConfig"><code>config</code></a> 객체를 함께 전달하도록 코드를 수정하세요.</p><pre><code class="language-python">response = client.models.generate_content(
    model=model_name,
    contents=messages,
    config=types.GenerateContentConfig(system_instruction=system_prompt),
)
</code></pre><p>이제 다양한 프롬프트로 프로그램을 실행해보세요. 무엇을 입력하든 AI가 "I'M JUST A ROBOT"이라고 응답하는 것을 볼 수 있을 것입니다.</p><h2 id="--13">함수 선언</h2><p>우리는 이미 LLM 친화적인 함수들(텍스트 입력, 텍스트 출력)을 여러 개 작성했습니다. 그런데 LLM은 실제로 어떻게 함수를 호출할까요?</p><p>정답은... 적어도 직접 호출하지는 않는다는 것입니다. 작동 방식은 다음과 같습니다:</p><ol><li>LLM에게 어떤 함수들이 사용 가능한지 알려줍니다</li><li>프롬프트를 제공합니다</li><li>LLM이 어떤 함수를 호출하고 싶은지, 어떤 인자를 전달할지를 설명합니다</li><li>LLM이 제공한 인자를 사용해 함수를 호출합니다</li><li>결과를 LLM에게 반환합니다</li></ol><p>우리는 LLM을 의사결정 엔진으로 사용하는 것이고, 실제 코드를 실행하는 것은 우리입니다.</p><p>자, 이제 LLM에게 어떤 함수들이 사용 가능한지 알려주는 부분을 만들어봅시다.</p><p><code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.FunctionDeclaration">types.FunctionDeclaration</a></code>을 사용하여 함수의 "선언" 또는 "스키마"를 만들 수 있습니다. 이것은 기본적으로 LLM에게 해당 함수를 어떻게 사용할 수 있는지 알려주는 역할을 합니다. 문서를 일일이 살펴보는 건 꽤 번거롭기 때문에, 첫 번째 함수에 대한 저의 코드를 예시로 보여드릴게요:</p><p>다음 코드를 <code>functions/get_files_info.py</code> 파일에 추가하세요:</p><pre><code class="language-python">from google.genai import types

schema_get_files_info = types.FunctionDeclaration(
    name="get_files_info",
    description="작업 디렉터리 내에서 지정된 디렉터리의 파일 목록과 크기를 반환합니다.",
    parameters=types.Schema(
        type=types.Type.OBJECT,
        properties={
            "directory": types.Schema(
                type=types.Type.STRING,
                description="작업 디렉터리를 기준으로 파일을 나열할 디렉터리 경로입니다. 지정하지 않으면 작업 디렉터리 자체의 파일을 나열합니다.",
            ),
        },
    ),
)
</code></pre><p><strong>경고:</strong> LLM이 <code>working_directory</code> 파라미터를 지정하는 것을 허용하지 않을 것입니다. 우리는 이를 하드코딩할 예정입니다.</p><p><code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Tool">types.Tool</a></code>을 사용하여 사용 가능한 함수들의 목록을 만드세요 (지금은 <code>get_files_info</code>만 추가하고, 나머지는 나중에 추가할 것입니다).</p><pre><code class="language-python">available_functions = types.Tool(
    function_declarations=[
        schema_get_files_info,
    ]
)
</code></pre><p><code>client.models.generate_content</code> 를 호출할 때 <code>tools</code> 파라미터에 <code>available_functions</code> 을 추가합니다.</p><pre><code class="language-python">config=types.GenerateContentConfig(
    tools=[available_functions], system_instruction=system_prompt
)</code></pre><p>시스템 프롬프트를 업데이트하여 LLM에게 함수 사용 방법을 지시하세요. 아래 내용을 복사해도 되지만, 어떤 역할을 하는지 이해하기 위해서 꼭 읽어보세요:</p><pre><code class="language-python">system_prompt = """
You are a helpful AI coding agent.

When a user asks a question or makes a request, make a function call plan. You can perform the following operations:

- List files and directories

All paths you provide should be relative to the working directory. You do not need to specify the working directory in your function calls as it is automatically injected for security reasons.
"""
</code></pre><p><code>generate_content</code> 응답에서 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponse.text">.text</a></code> 속성만 출력하는 대신, <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponse.function_calls">.function_calls</a></code> 속성도 확인하세요. LLM이 함수를 호출했다면, 함수 이름과 인자를 출력하세요:</p><pre><code class="language-python">f"Calling function: {function_call_part.name}({function_call_part.args})"
</code></pre><p>그렇지 않으면 평소처럼 텍스트를 출력하세요.</p><p>프로그램을 테스트하세요:</p><ul><li>"what files are in the root?" → <code>get_files_info({'directory': '.'})</code></li><li>"what files are in the pkg directory?" → <code>get_files_info({'directory': 'pkg'})</code></li></ul><h2 id="--14">추가 함수 선언</h2><p>이제 LLM이 <code>get_files_info</code> 함수에 대한 함수 호출을 지정할 수 있으므로, 다른 함수들도 호출할 수 있는 기능을 제공하겠습니다.</p><p><code>schema_get_files_info</code>에 사용한 것과 동일한 패턴을 따라 다음에 대한 함수 선언을 만듭니다:</p><ul><li><code>schema_get_file_content</code></li><li><code>schema_run_python_file</code></li><li><code>schema_write_file</code></li></ul><p><code>available_functions</code>를 업데이트하여 리스트에 모든 함수 선언을 포함시킵니다. 그런 다음 시스템 프롬프트를 업데이트합니다. 허용되는 작업이 다음뿐만 아니라:</p><pre><code>- 파일 및 디렉토리 나열</code></pre><p>네 가지 작업을 모두 포함하도록 업데이트합니다:</p><pre><code>- 파일 및 디렉토리 나열
- 파일 내용 읽기
- 선택적 인자로 Python 파일 실행
- 파일 쓰기 또는 덮어쓰기</code></pre><p>다양한 함수 호출을 불러올 것으로 예상되는 프롬프트를 테스트합니다. 예를 들어:</p><ul><li>"read the contents of main.py" → <code>get_file_content({'file_path': 'main.py'})</code></li><li>"write 'hello' to main.txt" → <code>write_file({'file_path': 'main.txt', 'content': 'hello'})</code></li><li>"run main.py" → <code>run_python_file({'file_path': 'main.py'})</code></li><li>"list the contents of the pkg directory" → <code>get_files_info({'directory': 'pkg'})</code></li></ul><p>여기서 LLM이 해야 할 일은 사용자의 요청에 따라 어떤 함수를 호출할지 선택하는 것뿐입니다. 나중에 실제로 함수를 호출하게 할 것입니다.</p><p>개인적인 구현 예제:</p><p><code>functions/get_file_content.py:</code></p><pre><code class="language-python">from google.genai import types
from config import MAX_CHARS

schema_get_file_content = types.FunctionDeclaration(
    name="get_file_content",
    description=f"작업 디렉토리 내의 지정된 파일에서 처음 {MAX_CHARS}자의 내용을 읽고 반환합니다.",
    parameters=types.Schema(
        type=types.Type.OBJECT,
        properties={
            "file_path": types.Schema(
                type=types.Type.STRING,
                description="작업 디렉토리에 상대적인, 내용을 읽을 파일의 경로.",
            ),
        },
        required=["file_path"],
    ),
)
</code></pre><p><code>functions/run_python.py:</code></p><pre><code class="language-python">from google.genai import types

schema_run_python_file = types.FunctionDeclaration(
    name="run_python_file",
    description="작업 디렉토리 내에서 Python 파일을 실행하고 인터프리터의 출력을 반환합니다.",
    parameters=types.Schema(
        type=types.Type.OBJECT,
        properties={
            "file_path": types.Schema(
                type=types.Type.STRING,
                description="작업 디렉토리에 상대적인, 실행할 Python 파일의 경로.",
            ),
            "args": types.Schema(
                type=types.Type.ARRAY,
                items=types.Schema(
                    type=types.Type.STRING,
                    description="Python 파일에 전달할 선택적 인자.",
                ),
                description="Python 파일에 전달할 선택적 인자.",
            ),
        },
        required=["file_path"],
    ),
)
</code></pre><p><code>functions/write_file_content.py:</code></p><pre><code class="language-python">from google.genai import types

schema_write_file = types.FunctionDeclaration(
    name="write_file",
    description="작업 디렉토리 내의 파일에 내용을 씁니다. 파일이 존재하지 않으면 생성합니다.",
    parameters=types.Schema(
        type=types.Type.OBJECT,
        properties={
            "file_path": types.Schema(
                type=types.Type.STRING,
                description="작업 디렉토리에 상대적인, 쓸 파일의 경로.",
            ),
            "content": types.Schema(
                type=types.Type.STRING,
                description="파일에 쓸 내용",
            ),
        },
        required=["file_path", "content"],
    ),
)
</code></pre><p><code>schema_get_files_info</code>에서 사용했던 동일한 패턴을 따라, 아래의 함수 선언들을 만들어주세요:</p><ul><li><code>schema_get_file_content</code></li><li><code>schema_run_python_file</code></li><li><code>schema_write_file</code></li></ul><p>그리고 <code>available_functions</code> 리스트에 모든 함수 선언을 포함하도록 업데이트하세요.<br>그 다음 시스템 프롬프트를 수정해야 합니다. 기존에는 허용된 동작이 아래 한 가지뿐이었습니다:</p><pre><code>- 파일 및 디렉토리 목록 나열</code></pre><p>이제 네 가지 모든 동작을 포함하도록 변경하세요:</p><pre><code>- 파일 및 디렉토리 목록 나열
- 파일 내용 읽기
- 선택적 인수를 포함해 파이썬 파일 실행
- 파일 작성 또는 덮어쓰기</code></pre><p>여러 함수 호출이 나오도록 예상되는 프롬프트로 테스트해보세요. 예를 들어:</p><ul><li>"main.py의 내용을 읽어줘" → <code>get_file_content({'file_path': 'main.py'})</code></li><li>"main.txt에 'hello'를 써줘" → <code>write_file({'file_path': 'main.txt', 'content': 'hello'})</code></li><li>"main.py를 실행해줘" → <code>run_python_file({'file_path': 'main.py'})</code></li><li>"pkg 디렉토리 목록을 보여줘" → <code>get_files_info({'directory': 'pkg'})</code></li></ul><p><strong>참고:</strong> 여기서 LLM이 해야 할 일은 사용자 요청을 기반으로 어떤 함수를 호출할지 선택하는 것입니다. 실제로 함수를 호출하는 코드는 나중에 구현합니다.</p><h2 id="--15">함수 호출</h2><p>이제 에이전트가 어떤 함수를 호출할지 선택할 수 있으므로, 실제로 함수를 호출할 시간입니다.</p><p>네 함수 중 하나를 호출하는 추상적인 작업을 처리할 새 함수를 만듭니다.</p><p>다음은 제가 정의한 함수입니다:</p><pre><code class="language-python">def call_function(function_call_part, verbose=False):
</code></pre><p><code>function_call_part</code>는 가장 중요하게 다음 내용을 가진 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.FunctionCall">types.FunctionCall</a></code>입니다:</p><ul><li><code>.name</code> 속성 (함수 이름, <code>문자열</code>)</li><li><code>.args</code> 속성 (함수에 전달하는 이름이 지정된 인자들의 딕셔너리)</li></ul><p><code>verbose</code>가 지정되면 함수 이름과 인자를 출력합니다:</p><pre><code class="language-python">print(f"Calling function: {function_call_part.name}({function_call_part.args})")
</code></pre><p>그렇지 않으면 이름만 출력합니다:</p><pre><code class="language-python">print(f" - Calling function: {function_call_part.name}")
</code></pre><p>함수 이름에 따라 실제로 함수를 호출하고 결과를 캡처합니다.</p><ul><li>키워드 인자 딕셔너리에 "working_directory" 인자를 수동으로 추가해야 합니다. 이 인자는 LLM이 제어하지 않으며, 작업 디렉토리는 <code>./calculator</code> 이어야 합니다.</li><li>딕셔너리를 함수에 <a href="https://docs.python.org/3/glossary.html#term-argument">키워드 인자</a>로 넘길 때는 <code>some_function(**some_args)</code> 문법을 사용합니다.</li></ul><p><strong>팁:</strong> 이를 위해 <code>함수 이름(문자열)</code> -&gt; <code>함수</code> 에 딕셔너리를 사용했습니다.</p><p>함수 이름이 유효하지 않으면 오류를 설명하는 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Content">types.Content</a></code>를 반환합니다:</p><pre><code class="language-python">return types.Content(
    role="tool",
    parts=[
        types.Part.from_function_response(
            name=function_name,
            response={"error": f"Unknown function: {function_name}"},
        )
    ],
)
</code></pre><p>함수 호출 결과를 설명하는 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Part.from_function_response">from_function_response</a></code>가 포함된 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Content">types.Content</a></code>를 반환합니다:</p><pre><code class="language-python">return types.Content(
    role="tool",
    parts=[
        types.Part.from_function_response(
            name=function_name,
            response={"result": function_result},
        )
    ],
)
</code></pre><p>정보: <code>from_function_response</code>는 응답이 딕셔너리여야 하므로 결과 문자열을 "result" 필드에 넣어주면 됩니다. </p><p>아래는 완성된 <code>call_function.py</code>입니다:</p><pre><code class="language-python">from google.genai import types
from functions.get_files_info import get_files_info, schema_get_files_info
from functions.get_file_content import get_file_content, schema_get_file_content
from functions.run_python import run_python_file, schema_run_python_file
from functions.write_file_content import write_file, schema_write_file
from config import WORKING_DIR

available_functions = types.Tool(
    function_declarations=[
        schema_get_files_info,
        schema_get_file_content,
        schema_run_python_file,
        schema_write_file,
    ]
)

def call_function(function_call_part, verbose=False):
    if verbose:
        print(f" - Calling function: {function_call_part.name}({function_call_part.args})")
    else:
        print(f" - Calling function: {function_call_part.name}")
    
    function_map = {
        "get_files_info": get_files_info,
        "get_file_content": get_file_content,
        "run_python_file": run_python_file,
        "write_file": write_file,
    }
    
    function_name = function_call_part.name
    if function_name not in function_map:
        return types.Content(
            role="tool",
            parts=[
                types.Part.from_function_response(
                    name=function_name,
                    response={"error": f"Unknown function: {function_name}"},
                )
            ],
        )
    
    args = dict(function_call_part.args)
    args["working_directory"] = WORKING_DIR
    function_result = function_map[function_name](**args)
    
    return types.Content(
        role="tool",
        parts=[
            types.Part.from_function_response(
                name=function_name,
                response={"result": function_result},
            )
        ],
    )
</code></pre><p>모델의 <code>generate_content</code> 응답을 처리하는 곳으로 돌아가서, LLM이 호출하기로 결정한 함수의 이름을 단순히 출력하는 대신 <code>call_function</code>을 사용합니다.</p><ul><li><code>call_function</code>에서 반환하는 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Content">types.Content</a></code>는 내부에 <code>.parts[0].function_response.response</code>가 있어야 합니다.</li><li>만약 포함되어 있지 않다면 어떤 종류의 치명적인 예외를 발생시키세요.</li><li>만약 포함되어 있고 <code>verbose</code>가 설정되어 있으면 함수 호출 결과를 다음과 같이 출력합니다:</li></ul><pre><code class="language-python">print(f"-&gt; {function_call_result.parts[0].function_response.response}")
</code></pre><p>프로그램을 테스트합니다. 이제 프롬프트로 요청하면 함수를 실행할 수 있어야 합니다. 다양한 프롬프트를 시도해보고 <code>--verbose</code> 플래그를 사용하여 모든 기능이 제대로 작동하는지 확인합니다.</p><ul><li>디렉토리 내용 나열</li><li>파일의 내용 가져오기</li><li>파일 내용 쓰기 (중요한 것을 덮어쓰지 말고 새 파일을 만드세요)</li><li>계산기 앱의 테스트 <code>tests.py</code> 실행</li></ul><h2 id="--16">에이전트 루프 만들기</h2><p>우리는 이제 함수 호출 기능을 어느 정도 구현했지만, 아직 우리 프로그램을 "에이전트"라고 부르기엔 부족한 점이 하나 있습니다:</p><p>피드백 루프가 없다는 것입니다.</p><p>AI 인플루언서들이 말하는 "에이전트"의 핵심은, 자신의 도구를 반복적으로 사용하여 결과를 계속 개선해나갈 수 있는 능력입니다. 그래서 우리는 다음 두 가지를 만들 것입니다:</p><ol><li>LLM을 반복해서 호출할 루프</li><li>"대화"에서 오고간 메시지 리스트. 다음과 같이 보일 것입니다:</li></ol><ul><li>사용자: "계산기의 버그를 수정해주세요"</li><li>모델: "get_files_info를 호출하고 싶습니다..."</li><li>툴: "get_files_info의 결과입니다..."</li><li>모델: "get_file_content를 호출하고 싶습니다..."</li><li>툴: "get_file_content의 결과입니다..."</li><li>모델: "run_python_file을 호출하고 싶습니다..."</li><li>툴: "run_python_file의 결과입니다..."</li><li>모델: "write_file을 호출하고 싶습니다..."</li><li>툴: "write_file의 결과입니다..."</li><li>모델: "run_python_file을 호출하고 싶습니다..."</li><li>툴: "run_python_file의 결과입니다..."</li><li>모델: "버그를 수정했고 계산기가 작동하는지 확인하기 위해 실행했습니다."</li></ul><p>이건 꽤 큰 진전입니다. 천천히 진행하세요!</p><p><code>prompts.py</code>를 만듭니다:</p><pre><code class="language-python">system_prompt = """
You are a helpful AI coding agent.

When a user asks a question or makes a request, make a function call plan. You can perform the following operations:
- List files and directories
- Read file contents
- Execute Python files with optional arguments
- Write or overwrite files

All paths you provide should be relative to the working directory. You do not need to specify the working directory in your function calls as it is automatically injected for security reasons.
"""
</code></pre><p>최종 <code>main.py</code> 구성:</p><pre><code class="language-python">import sys
import os
from google import genai
from google.genai import types
from dotenv import load_dotenv

from prompts import system_prompt
from call_function import call_function, available_functions

def main():
    load_dotenv()

    verbose = "--verbose" in sys.argv
    args = []
    for arg in sys.argv[1:]:
        if not arg.startswith("--"):
            args.append(arg)

    if not args:
        print("AI Code Assistant")
        print('\nUsage: python main.py "your prompt here" [--verbose]')
        print('Example: python main.py "How do I fix the calculator?"')
        sys.exit(1)

    api_key = os.environ.get("GEMINI_API_KEY")
    client = genai.Client(api_key=api_key)

    user_prompt = " ".join(args)

    if verbose:
        print(f"User prompt: {user_prompt}\n")

    messages = [
        types.Content(role="user", parts=[types.Part(text=user_prompt)]),
    ]

    generate_content_loop(client, messages, verbose)


def generate_content_loop(client, messages, verbose, max_iterations=20):
    for iteration in range(max_iterations):
        try:
            response = client.models.generate_content(
                model="gemini-2.0-flash-001",
                contents=messages,
                config=types.GenerateContentConfig(
                    tools=[available_functions], 
                    system_instruction=system_prompt
                ),
            )
            
            if verbose:
                print("Prompt tokens:", response.usage_metadata.prompt_token_count)
                print("Response tokens:", response.usage_metadata.candidates_token_count)

            # 모델 응답을 대화에 추가
            for candidate in response.candidates:
                messages.append(candidate.content)

            # 최종 텍스트 응답이 있는지 확인
            if response.text:
                print("Final response:")
                print(response.text)
                break

            # 함수 호출 처리
            if response.function_calls:
                function_responses = []
                for function_call_part in response.function_calls:
                    function_call_result = call_function(function_call_part, verbose)
                    if (not function_call_result.parts 
                        or not function_call_result.parts[0].function_response):
                        raise Exception("empty function call result")
                    if verbose:
                        print(f"-&gt; {function_call_result.parts[0].function_response.response}")
                    function_responses.append(function_call_result.parts[0])
                
                if function_responses:
                    messages.append(types.Content(role="user", parts=function_responses))
                else:
                    raise Exception("no function responses generated, exiting.")
        except Exception as e:
            print(f"Error: {e}")
            break
    else:
        print(f"최대 반복 횟수({max_iterations})에 도달했습니다. 에이전트가 작업을 완료하지 못했을 수 있습니다.")

if __name__ == "__main__":
    main()
</code></pre><p><code>generate_content</code> 함수에서 모든 도구 사용 결과를 처리하세요. 이미 일부 구현되어 있을 수도 있지만, 중요한 점은 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.models.Models.generate_content">client.models.generate_content</a></code>를 호출할 때마다 전체 <code>messages</code> 리스트를 전달해야 한다는 것입니다. 그래야 LLM이 현재 상태를 기반으로 "다음 단계"를 수행할 수 있습니다.</p><p>클라이언트의 <code>generate_content</code> 메서드를 호출한 후 응답의 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentResponse.candidates">.candidates</a></code> 속성을 확인합니다. 이 속성은 응답의 다양한 버전(일반적으로 한 개)을 담고 있습니다. "get_files_info를 호출하고 싶습니다..."와 같은 응답이 나오면, 이 내용을 대화에 추가해야 합니다. 각 <code>candidate</code>를 순회하며 그 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Candidate.content">.content</a></code>를 <code>messages</code> 리스트에 추가하세요.</p><p>각 함수 호출 후에는 <code><a href="https://googleapis.github.io/python-genai/genai.html#genai.types.Content">types.Content</a></code>를 사용하여 <code>function_responses</code>를 역할이 <code>user</code>인 메시지로 변환하고, 이를 <code>messages</code>에 추가하세요.</p><p>그 다음에는 <code>generate_content</code>를 한 번만 호출하는 대신, 반복적으로 호출하는 루프를 만드세요. 이 루프는 최대 20회까지만 반복되도록 제한하세요 (에이전트가 무한 반복하지 않도록 방지). <code>try-except</code> 블록을 사용하여 오류를 적절히 처리하세요.</p><p>각 <code>generate_content</code> 호출 후에는 <code>response.text</code> 속성을 반환하는지 확인하세요. 만약 그렇다면 작업이 완료된 것이므로, 최종 응답을 출력하고 루프를 종료하세요. 그렇지 않으면 다시 반복하세요 (물론 최대 반복 횟수에 도달하지 않았다면).</p><p>코드를 꼭 테스트하세요 (당연하죠). "계산기가 결과를 콘솔에 어떻게 출력하는지 설명해줘" 처럼 간단한 프롬프트로 시작해보세요. 저는 아래와 같은 결과를 받았습니다:</p><pre><code class="language-bash">(aiagent) wagslane@MacBook-Pro-2 aiagent % uv run main.py "계산기가 결과를 콘솔에 어떻게 출력하는지 설명해줘"

함수 호출: get_files_info

함수 호출: get_file_content

최종 응답:
main.py 코드를 살펴본 결과, 계산기가 결과를 콘솔에 출력하는 방법은 다음과 같습니다:﻿

print(to_print): 출력의 핵심은 print() 함수로 이루어집니다.﻿

format_json_output(expression, result): 출력 전에 format_json_output 함수(pkg.render에서 import됨)를 사용해 계산 결과와 원래 식을 JSON 형태의 문자열로 포맷합니다. 이 형식화된 문자열은 to_print 변수에 저장됩니다.﻿

에러 처리:﻿ 코드에는 try...except 블록을 활용한 에러 처리 기능이 포함되어 있습니다. 만약 계산 중 오류가 발생하면(예: 잘못된 수식이 입력된 경우), print(f"Error: {e}")를 통해 오류 메시지가 콘솔에 출력됩니다.﻿

즉, 계산기는 식을 평가하고, 결과(그리고 원래 식)를 JSON 형태의 문자열로 만들어 콘솔에 출력합니다. 오류가 발생하면 콘솔에 오류 메시지도 따로 출력됩니다.﻿</code></pre><p><strong>팁:</strong> 원하는 대로 LLM이 동작하도록 하려면 시스템 프롬프트를 약간 조정해야 할 수도 있습니다. 이제 당신은 프롬프트 엔지니어입니다. 그처럼 행동하세요! </p><p>멋집니다! 이제 파일을 읽고, 파일을 작성하고, 파이썬 코드를 실행하며, 스스로 결과를 개선할 수 있는 기본적인 AI 에이전트를 완성했습니다. 이건 더 복잡한 AI 에이전트를 만드는 훌륭한 기반이에요.</p><h2 id="--17">결론</h2><p>필요한 모든 단계를 완료했습니다. 이제 약간 재미있게 (하지만 신중하게… LLM에 파일 시스템이나 파이썬 인터프리터 접근 권한을 줄 때는 매우 주의하세요) 다뤄보세요! 다음과 같은 작업들을 시도해볼 수도 있습니다: </p><ul><li>더 어려운 버그나 복잡한 문제 수정 </li><li>코드 일부를 리팩터링하기 </li><li>완전히 새로운 기능 추가</li></ul><p>또한 다음을 시도할 수 있습니다:</p><ul><li>다른 LLM 제공업체</li><li>다른 Gemini 모델</li><li>호출 가능한 기능을 더 추가해보기</li><li>다른 코드베이스 시도하기 (에이전트를 실행하기 전에 변경 사항을 커밋해두면 언제든 되돌릴 수 있습니다!)</li></ul><p><strong>경고:</strong> 우리가 구축한 것은 Cursor/Zed의 Agentic Mode 또는 Claude Code와 같은 것의 간단한 버전이라는 것을 기억하세요. 그 도구들조차 완벽하게 안전하지 않으므로 접근 권한을 부여하는 것에 주의하고 이 코드를 다른 사람에게 제공하지 마세요.</p><p>백엔드 및 데이터 엔지니어링에 대해 더 알고 싶다면, <a href="https://www.boot.dev/">Boot.dev</a>를 확인하세요! 학습 여정에 행운을 빕니다!</p><p>재미있게 보셨다면 <a href="https://x.com/wagslane">X.com</a>과 <a href="https://www.youtube.com/@bootdotdev">YouTube</a>에서 저를 팔로우해 주세요!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬 부분문자열(Substring) - 문자열(String)을 자르는 방법 ]]>
                </title>
                <description>
                    <![CDATA[ 파이썬에서 문자열(string)은 문자(Characters)의 시퀀스로 특수문자 또는 알파벳, 숫자를 포함합니다. 예를 들어 “우리 금요일 08:00am에 만나자”라는 문자열이 있습니다. 여기서 보통 부분문자열(substring)이라고 알려져 있는 문자열의 특정 부분을 액세스 할 수 있습니다. 우리는 부분문자열을 문자열 안에 한 시퀀스로 정의할 수 있으며, 예제에서는 “금요일” “에” 그리고 “만나자” 가 될 수 있습니다. 파이썬으로 부분문자열을 생성하는 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-substring-how-to-slice-a-string/</link>
                <guid isPermaLink="false">6539999f722f6d03ea1726de</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yeonsoo Jang ]]>
                </dc:creator>
                <pubDate>Fri, 27 Oct 2023 10:59:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/10/main-image.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-substring-how-to-slice-a-string/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Substring – How to Slice a String</a>
      </p><!--kg-card-begin: markdown--><h3 id="stringcharacters">파이썬에서 문자열(string)은 문자(Characters)의 시퀀스로 특수문자 또는 알파벳, 숫자를 포함합니다.</h3>
<p>예를 들어 “우리 금요일 08:00am에 만나자”라는 문자열이 있습니다. 여기서 보통 부분문자열(substring)이라고 알려져 있는 문자열의 특정 부분을 액세스 할 수 있습니다.</p>
<p>우리는 부분문자열을 문자열 안에 한 시퀀스로 정의할 수 있으며, 예제에서는 “금요일” “에” 그리고 “만나자” 가 될 수 있습니다.</p>
<h2 id="">파이썬으로 부분문자열을 생성하는 방법</h2>
<p>파이썬은 부분문자열을 생성하고, 부분문자열의 존재 여부를 확인하고, 부분문자열의 인덱스를 추출하기 위한 다양한 방법과 메소드를 제공합니다.</p>
<p>다음과 같이 인덱스를 활용하여 문자열에서 부분문자열을 추출할 수 있습니다.<br>
<code>string[start:stop:step]</code></p>
<pre><code>start – 부분문자열의 첫번째 인덱스
stop – 부분문자열의 마지막 인덱스
step – 슬라이싱의 간격을 의미하며, 기본값은 1입니다.
</code></pre>
<p>![substring index 표 설명] (<a href="https://www.freecodecamp.org/news/content/images/2021/07/image--2-.png">https://www.freecodecamp.org/news/content/images/2021/07/image--2-.png</a>)</p>
<p>인덱스는 양수일 수도 음수일 수도 있습니다. 양수 인덱스는 문자열의 첫번째 문자부터 시작해서 마지막 문자에서 끝이 나고, 음수 인덱스는 마지막 문자에서 시작하여 첫번째 문자에서 끝이 납니다.</p>
<p>이번 글에서는 파이썬에서 부분문자열과 관련한 다양한 조작방법을 다룹니다.</p>
<h2 id="n">파이썬에서 첫번째 n 문자를 추출하는 방법</h2>
<p>이 예제는 첫 다섯 문자를 추출하는 방법에 대해서 설명합니다.</p>
<pre><code class="language-python">string = "hello world"
print(string[:5])
</code></pre>
<p>여기서 stop 인덱스는 5로 설정하였고, start 인덱스는 기본값 0으로 설정됩니다.<br>
결과값은 <code>'hello'</code>입니다.</p>
<h2 id="">파이썬에서 중간 문자를 추출하는 방법</h2>
<p>이번 예제는 세번째 인덱스부터 다섯 번째 인덱스까지 추출하는 방법을 보여줍니다.</p>
<pre><code class="language-python">string = "hello world"
print(string[3:5])
</code></pre>
<p>결과값은 <code>'lo'</code>입니다.</p>
<h2 id="">마지막 문자를 추출하는 방법</h2>
<p>마지막 문자를 추출하기 위해서는 -1 인덱스(음수 인덱스)를 사용합니다. 다음 예제를 확인해보세요.</p>
<pre><code class="language-python">string = "freecodecamp"
print(string[-1])
</code></pre>
<p>결과값은 <code>'p'</code>입니다.</p>
<h2 id="n">마지막 n개 문자를 추출하는 방법</h2>
<p>이번 예제에서는 음수 인덱스를 사용하여 마지막 4개 문자를 slicing합니다.</p>
<pre><code class="language-python">string = "freecodecamp"
print(string[-4:])
</code></pre>
<p>결과값은 <code>'camp'</code>입니다.</p>
<h2 id="step">문자열에서 step을 이용해서 부분문자열을 슬라이싱하는 방법</h2>
<p>당신은 start-index, stop-index 그리고 step을 이용해서 문자열을 자를 수 있습니다. 간격(step)은 기본값이 1이지만 다음 예제에서는 step 크기를 2로 설정합니다.</p>
<pre><code class="language-python">string = "welcome to freecodecamp"
print(string[::2])
</code></pre>
<p>결과값은 <code>'wloet fecdcm'</code>입니다.</p>
<h2 id="">부분문자열이 문자열에 포함되어있는지 확인하는 방법</h2>
<p>부분문자열이 문자열에 포함되어 있는지 확인하고 싶을 때가 있습니다. 다음 예제는 부분문자열 ‘code’가 문자열에 포함되어 있는지를 확인합니다.</p>
<pre><code class="language-python">substring = "code"
string = "welcome to freecodecamp"
print(substring in string)
</code></pre>
<p>만약 포함되어 있다면 True 아니라면 False를 반환합니다.<br>
여기러 결과값은 <code>True</code> 입니다.</p>
<h2 id="">부분문자열의 포함 여부를 확인하는 다른 방법</h2>
<p><code>find()</code> 메소드를 통해서 부분문자열이 문자열에 존재하는지를 확인할 수 있습니다.<br>
다음 예제를 확인해봅시다.</p>
<pre><code class="language-python">substring = "zz"
string = "hello world"
print(string.find(substring))
</code></pre>
<p>부분문자열이 문자열에 포함되어 있다면 부분문자열 가장 왼쪽의 인덱스를 반환하고, 포함되어 있지 않다면 -1을 반환합니다.<br>
예제에서 결과값은 <code>-1</code>로, ‘zz’는 ‘hello world’에 포함되어 있지 않음을 의미합니다.</p>
<h2 id="">문자열에서 주어진 인덱스에 해당하는 문자를 반환하는 방법</h2>
<p>인덱스에 따라 특정 문자를 슬라이싱 할 수 있습니다.</p>
<pre><code class="language-python">string ="hello world"
print(string[4])
</code></pre>
<p>결과값은 <code>‘0’</code> 입니다.</p>
<h2 id="">파이썬으로 부분문자열의 리스트를 만드는 방법</h2>
<p><code>split()</code> 메소드를 사용하여 부분문자열의 리스트를 생성할 수 있습니다. 다음 예제를 확인해봅시다.</p>
<pre><code class="language-python">string = "welcome to freecodecamp platform"
print(string.split())
</code></pre>
<p>결과값은 <code>['welcome', 'to', 'freecodecamp', 'platform']</code>입니다.</p>
<h2 id="step">음수 step으로 문자열 뒤집기</h2>
<p>문자열을 반대방향으로 뒤집기 위해서 step은  -1과 같은 음수 값이여야 합니다.</p>
<pre><code class="language-python">string = "welcome to freecodecamp"
print(string[::-1])
</code></pre>
<p>결과값은 <code>‘pmacedoceerf ot emoclew’</code>입니다.</p>
<h2 id="">부분문자열이 문자열에 몇 번 나타났는지 세는 방법</h2>
<p><code>count()</code> 메소드를 통해 특정 부분문자열이 문자열에 몇 번 있는지 셀 수 있습니다.</p>
<pre><code class="language-python">string = "we will have a quick coding lesson this afternoon"
print(string.count('noon'))
</code></pre>
<p>결과값은 1입니다.</p>
<h2 id="">파이썬 부분문자열에 대한 마지막 이야기</h2>
<p>축하합니다👏👏, 이 아티클의 끝까지 왔습니다! 파이썬 부분문자열에 대해서 새로운 것을 배우셨길 바랍니다.<br>
만약 새로운 것을 배웠거나 이 아티클을 흥미롭게 읽었다면, 다른사람들도 볼 수 있도록 공유해 주세요. 그럼 다음 포스팅에서 만나요!</p>
<p>트위터에서도 저를 찾을 수 있습니다. <a href="https://twitter.com/Davis_McDavid?ref=hackernoon.com">@Davis_McDavid</a></p>
<p>이와 같은 아티클을 이 <a href="https://hackernoon.com/u/davisdavid?ref=hackernoon.com">링크</a> 를 통해서 더 많이 읽을 수 있습니다.</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬 유닛 테스팅(Unit Testing) 소개 ]]>
                </title>
                <description>
                    <![CDATA[ 얼마간의 코드 작성을 방금 끝내고나서 무엇을 해야 하는지 궁금할 것입니다. 풀 리퀘스트(pull request)를 제출하고 팀원들에게 코드 리뷰를 받을 것인가요? 또는 일일이 코드를 모두 테스트 해 볼 것인가요? 두 가지 사항 모두 반드시 해야 합니다만 추가 단계가 하나 더 있습니다: 작성한 코드에 유닛 테스트를 해서 코드가 작성된 의도대로 동작하는지 확실히 해야 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/paisseon-yunis-teseuting-unit-testing-sogae/</link>
                <guid isPermaLink="false">6418954f23c0b9e3b0d23d4f</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 20:20:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/03/image-45-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/an-introduction-to-testing-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">An Introduction to Unit Testing in Python</a>
      </p><!--kg-card-begin: markdown--><h4 id="pullrequest"><em><em>얼마간의 코드 작성을 방금 끝내고나서 무엇을 해야 하는지 궁금할 것입니다. 풀 리퀘스트(pull request)를 제출하고 팀원들에게 코드 리뷰를 받을 것인가요? 또는 일일이 코드를 모두 테스트 해 볼 것인가요?</em></em></h4>
<h5 id=""><em>두 가지 사항 모두 반드시 해야 합니다만 추가 단계가 하나 더 있습니다: 작성한 코드에 유닛 테스트를 해서 코드가 작성된 의도대로 동작하는지 확실히 해야 합니다.</em></h5>
<p>유닛 테스트는 통과 또는 실패할 수 있어서, 그 자체로 코드를 점검하는 훌륭한 기법입니다. 이번 튜토리얼에서는 파이썬으로 유닛 테스트를 작성하는 방법을 보여줄텐데 그러면 여러분은 스스로의 프로젝트에 이것을 적용하는게 얼마나 쉬운지 알게 될 것입니다.</p>
<h3 id="">시작하기</h3>
<p>테스팅을 이해하는 가장 좋은 방법은 스스로 실험해보는 것입니다. 그러한 목적에 맞춰 name_function.py라는 파일 안에 간단한 함수를 작성하여 이름과 성을 가져오고 풀네임을 반환하도록 할 것입니다.</p>
<pre><code class="language-python">#Generate a formatted full name
def formatted_name(first_name, last_name):
   full_name = first_name + ' ' + last_name
   return full_name.title()
</code></pre>
<p>formatted_name() 함수는 이름과 성을 가져와 풀 네임을 형성하기 위해 두 단어 사이 빈칸을 두고 결합합니다. 그리고나서 모든 단어의 첫번째 문자를 대문자로 변환합니다. 이 코드가 작동하는지 확인하려면 이 함수 안에 사용할 몇 가지 코드를 작성해야 합니다. names.py 안에 몇 가지 간단한 코드를 작성해서 사용자들로부터 그들의 이름과 성을 입력하도록 하게끔 할 것입니다:</p>
<pre><code class="language-python">from name_function import formatted_name

print("Please enter the first and last names or enter x to E[x]it.")

while True:
   first_name = input("Please enter the first name: ")
   if first_name == "x":
       print("Good bye.")
       break

   last_name = input("Please enter the last name: ")
   if last_name == "x":
       print("Good bye.")
       break

   result = formatted_name(first_name, last_name)
   print("Formatted name is: " + result + ".")
</code></pre>
<p>이 코드는 name_function.py에서 formatted_name()를 불러와서 실행하고 사용자에게 성과 이름을 연달아 입력하게끔 허용한 다음 풀네임을 형성하여 보여줍니다.</p>
<h2 id="">유닛 테스트와 테스트 케이스</h2>
<p>파이썬 표준 라이브러리에는 unittest라고 불리는 모듈이 있어서 코드를 테스팅하는 도구를 포함하고 있습니다. 유닛 테스트는 모든 기능의 모든 특정 부분 동작이 올바른지 확인하고 나머지 부분을 훨씬 쉽게 통합합니다.</p>
<p>테스트 케이스는 하나의 기능이 의도한대로 동작하는지, 기능이 스스로를 잘 찾아내고 상황을 다룰 수 있을 것이라 예상된 전체 범위의 상황 속에서 잘 동작한다고 증명하는 유닛 테스트의 컬렉션(collection)입니다. 테스트 케이스는 어떤 함수가 사용자로부터 받을 수 있는 모든 가능한 종류의 입력을 고려해야만 하고, 그러므로 그러한 상황 각각을 대표하는 테스트를 포함해야만 합니다.</p>
<h2 id="">테스트 진행</h2>
<p>테스트를 작성하는 통상적인 시나리오들입니다:</p>
<p>우선 테스트 파일을 하나 생성해야 합니다. 그리고나서 unittest 모듈을 불러와 unittest.TestCase로부터 상속받는 테스팅 클래스를 정의하고, 마지막으로 함수의 행동에 대한 모든 경우를 테스트하는 일련의 메소드들을 작성합니다.</p>
<p>아래 코드를 한 줄씩 설명하겠습니다:</p>
<pre><code class="language-python">import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

   def test_first_last_name(self):
       result = formatted_name("pete", "seeger")
       self.assertEqual(result, "Pete Seeger")
</code></pre>
<p>첫번째로 unittest와 테스트 하고 싶은 함수, formatted_name()을 불러와야 합니다. 그리고나서 클래스 하나를 생성하는데 예를 들어 NamesTestCase라고 부르는 함수를 우리의 formatted_name() 기능에 대한 테스트를 포함하는 것이 될 수 있습니다. 이 클래스는 unittest.TestCase 클래스에서 상속받습니다.</p>
<p>NamesTestCase는 formatted_name()의 한 부분을 테스트하는 하나의 메소드를 포함하고 있습니다. 이 메소드를 test_first_last_name()이라 부를 수 있습니다.</p>
<blockquote>
<p>"test_"로 시작하는 모든 메소드들이 test_name_function.py를 실행할 때 자동으로 실행될 것을 기억하세요.</p>
</blockquote>
<p>test_first_last_name() 테스트 메소드 안에서, 테스트를 하고 싶은 함수를 부르고 반환 값을 저장합니다. 이 예제에서 우리는 formatted_name()을 "pete", "seeger"라는 인수(arguments)로 호출할 것이며 반환 값을 결과에 저장할 것입니다.</p>
<p>마지막 줄에서 우리는 선언 메소드를 사용할 것입니다. 선언 메소드는 우리가 받은 결과가 예상했던 결과와 일치하는지 검증합니다. 그리고 이 케이스에서 우리는 formatted_name() 함수가 각각의 첫번째 글자가 대문자로 지정된 풀네임을 받을 것을 알고 있고, 그래서 우리는 "Pete Seeger"라는 결과를 예상합니다. 이를 확인하기 위해서 unittest의 assertEqual() 메소드가 사용되었습니다.</p>
<pre><code class="language-python">self.assertEqual(result, “Pete Seeger”)
</code></pre>
<p>해당 라인은 기본적으로 의미하길: 결과 값을 "Pete Seeger"와 비교하고 만약 그 둘이 동일하면 OK, 일치하지 않으면 알려달라는 것을 뜻합니다.</p>
<p>test_name_function.py를 실행하면서 테스트가 통과했다는 OK 사인을 받을 것을 예상합니다.</p>
<pre><code class="language-python">Ran 1 test in 0.001s

OK
</code></pre>
<h2 id="">테스트 실패</h2>
<p>테스트에 실패하는게 어떤 것인지 보여주기 위해 formatted_name() 함수를 새로운 미들 네임 매개변수를 포함하는 것으로 수정하겠습니다.</p>
<p>그래서 이와 같은 함수를 다시 작성합니다:</p>
<pre><code class="language-python">#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name):
   full_name = first_name + ' ' + middle_name + ' ' + last_name
   return full_name.title()
</code></pre>
<p>해당 버전의 formatted_name()은 미들 네임을 가진 사람들을 위해 작동할 것이지만 테스트 할 때 함수가 미들 네임이 없는 사람들 대상으로는 동작하지 않는 것을 보게 될 것입니다.</p>
<p>그래서 test_name_function.py를 실행할 때 이와 같은 결과 값을 얻을 것입니다:</p>
<pre><code class="language-python">Error
Traceback (most recent call last):

File “test_name_function.py”, line 7, in test_first_last_name
    result = formatted_name(“pete”, “seeger”)

TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’

Ran 1 test in 0.002s

FAILED (errors=1)
</code></pre>
<p>결과 값에서 어떤 부분에 테스트가 실패했는지 알기 위해 필요한 모든 걸 말해주는 정보들을 보게 될 것입니다.</p>
<ul>
<li>결과 값 첫번째 항목이 Error이며 테스트 케이스 안에 적어도 하나의 테스트가 에러 결과를 냈다는 것을 알려줍니다.</li>
<li>다음으로는 에러가 발생한 파일과 메소드를 보게 될 것입니다.</li>
<li>그 다음으로 에러가 발생한 줄을 보게 될 것입니다.</li>
<li>그리고 어떤 종류의 에러인지, 이번 경우에는 우리가 "middle_name" 매개변수를 찾을 수 없다는 것을 알 수 있습니다.</li>
<li>테스트 실행 횟수를 볼 수 있으며 테스트를 완료하기 위해 필요했던 시간, 그리고 에러가 발생한 횟수와 함께 테스트 상태를 대표하는 문자 메세지를 보게 될 것입니다.</li>
</ul>
<h2 id="">테스트 실패시 해야 하는 일</h2>
<blockquote>
<p>테스트에 통과한다는 것은 함수가 예상된 대로 동작한다는 뜻입니다. 하지만 테스트에 실패한다는 것은 앞으로 더 재미있는 것이 있다는 걸 뜻합니다.</p>
</blockquote>
<p>코드를 개선하는 대신 테스트를 변경하는 걸 선호하는 프로그래머들을 몇몇 봐 왔습니다 - 하지만 그러지 마세요. 문제를 고치는데 약간의 시간을 더 투자하면 코드를 더 잘 이해하게 될 것이고 장기적으로 봤을 때는 결국 시간을 줄이게 될 것입니다.</p>
<p>이번 예제에서 우리의 함수 formatted_name()은 먼저 두 개의 파라미터(parameters)를 요구했고, 이제 그것은 하나의 추가 요소(미들 네임)를 더 요구하는 것으로 재작성 되었습니다. 우리의 함수에 미들 네임을 더하는 것은 그 행동이 바라는 것을 동작하지 않게 합니다. 아이디어가 테스트를 변경하지 않겠다는 것이므로 가장 좋은 해결책은 미들 네임 여부를 선택할 수 있게 만드는 것입니다.</p>
<p>우리가 이 아이디어를 실행하면 예를 들어 "Pete Seeger"처럼 이름과 성이 사용되었을 때 테스트를 통과하게 만들 수 있고, 예를 들어 "Raymond Red Reddington"처럼 이름과 성, 미들네임까지 사용되었을 때도 테스트를 잘 통과하게 할 수 있습니다. 그러니 formatted_name() 코드를 한번 더 수정해 봅시다:</p>
<pre><code class="language-python">#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name=''):
   if len(middle_name) &gt; 0:
       full_name = first_name + ' ' + middle_name + ' ' + last_name
   else:
       full_name = first_name + ' ' + last_name
   return full_name.title()
</code></pre>
<p>이제 함수는 미들 네임이 있는 이름과 없는 이름 모두에게 동작할 것입니다.</p>
<p>그리고 확실히 하기 위해 "Pete Seeger"로 여전히 동작하는지 테스트를 다시 실행합니다:</p>
<pre><code class="language-python">Ran 1 test in 0.001s

OK
</code></pre>
<blockquote>
<p>그리고 이것이 제가 여러분에게 보여주고자 했던 것입니다. 코드를 테스트에 맞게 고치는 것이 다른 식으로 돌아가는 것보다 항상 더 나은 결과를 보여줍니다. 이제 미들 네임을 가지고 있는 이름들을 위해 새로운 테스트를 더해봅니다.</p>
</blockquote>
<h2 id="">새로운 테스트 더하기</h2>
<p>NamesTestCase 클래스에 미들 네임을 테스트하는 새로운 메소드를 작성합니다:</p>
<pre><code class="language-python">import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

    def test_first_last_name(self):
        result = formatted_name("pete", "seeger")
        self.assertEqual(result, "Pete Seeger")

    def test_first_last_middle_name(self):
        result = formatted_name("raymond", "reddington", "red")
        self.assertEqual(result, "Raymond Red Reddington")
</code></pre>
<p>테스트를 실행하면 통과할 것입니다:</p>
<pre><code>Ran 2 tests in 0.001s

OK
</code></pre>
<blockquote>
<p>Bra gjort!<br>
(역주: 스웨던어) 잘했어요!</p>
</blockquote>
<p>여러분은 함수가 미들 네임을 가진 이름 또는 미들 네임을 가지지 않은 이름을 이용해 동작하는지 점검하는 테스트를 작성했습니다. 파이썬 테스팅에 대해 더 많이 이야기할 파트 2를 기대해주세요.</p>
<p>읽어주셔서 감사합니다! 이와 같은 글을 여기 제 프리코드캠프 프로필에서 더 많이 확인해보세요: <a href="https://www.freecodecamp.org/news/author/goran/">https://www.freecodecamp.org/news/author/goran/</a> 그리고 제 깃허브 페이지에 다른 재미있는 것들도 찾아보세요: <a href="https://github.com/GoranAviani">https://github.com/GoranAviani</a></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python에서 함수 정의하고 호출하기 ]]>
                </title>
                <description>
                    <![CDATA[ 프로그래밍에서 함수는 호출될 때 특정 기능을 실행하는 재사용 가능한 코드 블록입니다. 함수는 코드를 더 모듈화하고 체계적으로 재사용할 수 있도록 도와주기 때문에 모든 프로그래밍 언어의 필수적인 부분입니다. 이 기사에서는 Python에서 함수를 정의하고 호출하는 방법을 설명합니다. 함수의 기본적인 사용법을 배우면 Python 응용 프로그램의 코드를 더 깔끔한 단위로 나누고 정리할 수 있습니다. 또한 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-define-call-function/</link>
                <guid isPermaLink="false">6418329223c0b9e3b0d23d45</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boyeon Ihn ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 20:19:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/03/functions.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-functions-define-and-call-a-function/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Functions – How to Define and Call a Function</a>
      </p><!--kg-card-begin: markdown--><h3 id="">프로그래밍에서 함수는 호출될 때 특정 기능을 실행하는 재사용 가능한 코드 블록입니다.</h3>
<p>함수는 코드를 더 모듈화하고 체계적으로 재사용할 수 있도록 도와주기 때문에 모든 프로그래밍 언어의 필수적인 부분입니다.</p>
<p>이 기사에서는 Python에서 함수를 정의하고 호출하는 방법을 설명합니다. 함수의 기본적인 사용법을 배우면 Python 응용 프로그램의 코드를 더 깔끔한 단위로 나누고 정리할 수 있습니다.</p>
<p>또한 인수(argument) 및 매개변수(parameter), 그리고 <code>return</code> 키워드가 Python 함수에서 어떻게 작동하는지 살펴보겠습니다.</p>
<h2 id="python">Python에서 함수 정의하는 기본 문법</h2>
<p>Python에서는 <code>def</code> 키워드를 사용해 함수를 정의하고 함수 식별자(함수 이름) 다음에 괄호와 콜론을 작성합니다.</p>
<p>그런 다음, 탭 또는 공백 4개로 들여쓰기(indent)를 작성 후 함수에서 실행하려는 기능을 코드로 지정해야 합니다.</p>
<pre><code class="language-python">def functionName():
    # 함수가 실행하는 코드 내용이 여기에 위치합니다
</code></pre>
<h2 id="python">기본적인 Python 함수 예시</h2>
<p>위의 기본 함수 정의 문법에 따라 터미널에 "Hello World"를 출력하는 Python 함수의 코드는 다음과 같습니다.</p>
<pre><code class="language-python">def myfunction():
    print("Hello World")
</code></pre>
<p>이 함수를 <strong>호출하려면</strong> 함수 이름 뒤에 괄호를 작성합니다. 이렇게 말이에요.</p>
<pre><code class="language-python">myfunction()
</code></pre>
<p>함수 호출 시 실행된 작업 내용을 확인하려면, 터미널에 <code>python filename.py</code>를 입력해 작성한 함수 코드를 실행합니다.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/sss-1.png" alt="python3 func.py 명령어를 실행하니 터미널에 Hello World가 출력된 모습" width="600" height="400" loading="lazy"></p>
<p>아래 예시를 통해 두 숫자의 뺄셈을 계산하는 함수의 코드를 확인해봅시다.</p>
<pre><code class="language-python">def subtractNum():
    print(34 - 4)
subtractNum()
# 출력된 결과: 30
</code></pre>
<h2 id="parametersargument">함수에 전달되는 매개변수(parameters)와 인수(argument)</h2>
<p>Python에서 함수를 정의할 때 매개변수(parameters)를 괄호 안에 넣어 함수에 전달할 수 있습니다.</p>
<p>함수를 정의하면서 전달되는 매개변수를 지정하는 기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">#함수가 선언 및 정의될 때는 매개변수를 괄호 안에 지정합니다
 def functionName(param1, param2):
    # 함수가 실행하는 코드 내용이 여기에 위치합니다
</code></pre>
<p>함수 호출 시, 매개변수에 전달될 값을 지정해야 합니다. (이 전달된 값을 바로 인수라고 합니다 --옮긴이).</p>
<pre><code class="language-python">#함수가 호출될 때 인수 값을 전달합니다
functionName(arg1, arg2)
</code></pre>
<p>(더 정확한 이해를 돕기 위해 매개변수와 인수의 정의를 정리해보겠습니다. --옮긴이)</p>
<ul>
<li>매개변수는 함수 정의 문법 괄호 사이에 표시된 변수입니다</li>
<li>인수는 함수 호출 시 매개변수에 전달되는 값입니다</li>
</ul>
<p>Python 함수에 매개변수와 인수가 전달되는 예시를 확인해봅시다.</p>
<pre><code class="language-python">def addNum(num1, num2):
    print(num1 + num2)
addNum(2, 4)
# 함수 호출의 결과: 6
</code></pre>
<p>위의 예시에 관해 몇 가지 정리해봅시다.</p>
<ul>
<li><code>addNum</code> 함수에 매개변수 <code>num1</code>, <code>num2</code> 두 개가 전달되었고,</li>
<li><code>addNum</code> 함수가 실행될 때 매개변수 두 개의 합계를 터미널에 출력하라고 지시했습니다.</li>
<li>마지막으로 <code>addNum</code> 함수 호출하면서 <code>2</code>, <code>4</code>라는 값을 인수로 전달했습니다.</li>
</ul>
<p>참고: 매개변수와 인수는 원하는 만큼 지정할 수 있습니다.</p>
<h2 id="return"><code>return</code> 키워드 사용하기</h2>
<p>Python에서는 <code>return</code> 키워드를 사용해 함수를 종료해 함수 내의 코드 블록에서 나올 수 있습니다. 다시 말해 함수 밖으로 결과값을 반환할 수 있습니다.</p>
<p><code>return</code> 문에는 함수가 호출되면 실행할 표현식 및 코드를 포함할 수 있습니다.</p>
<p>아래 예시는 Python에서 <code>return</code> 키워드가 어떻게 작동하는지 보여줍니다.</p>
<pre><code class="language-python">def multiplyNum(num1):
    return num1 * 8
result = multiplyNum(8)
print(result)
# 출력된 결과물: 64
</code></pre>
<p><strong>위 예시의 코드는 무엇을 실행하는 것인지 살펴봅시다!</strong></p>
<ul>
<li>먼저 <code>multiplyNum</code>이라는 함수를 정의하고 <code>num1</code>를 매개변수로 전달했습니다.</li>
<li>함수 안에서 <code>num1</code>에 8을 곱한 값을 지정하기 위해 <code>return</code> 키워드를 사용했습니다.</li>
<li>그런 다음, 함수를 호출하고 <code>num1</code> 매개변수에 <code>8</code>라는 값을 인수로 전달한 후 함수 호출의 결과를 <code>result</code> 변수에 할당했습니다.</li>
<li>원했던 결과 값을 <code>result</code> 변수에 할당했기 때문에 터미널에 출력할 수 있었습니다.</li>
</ul>
<h2 id="">마치며</h2>
<p>이 기사에서는 Python에서 함수를 정의하고 호출하는 방법에 대해 배워봤습니다. 또한 함수에 매개변수와 인수를 전달하는 방법과 <code>return</code> 키워드를 사용하는 방법을 배워서 기본 함수를 더 유용하게 사용할 수 있는 방법도 살펴봤습니다.</p>
<p>이 기사가 도움이 됐다면 코딩에 관심 있는 친구 또는 지인에게 공유해주시길 바랍니다!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬에서 엑셀파일을 생성 읽기, 업데이트, 검색하는 방법 ]]>
                </title>
                <description>
                    <![CDATA[ 이 글은 파이썬으로 엑셀 파일을 작업하는 방법과 특정 데이터를 수정하는 방법을 자세하게 보여줄 것입니다. 먼저 우리는 CSV 파일들을 읽고 쓰고 업데이트하는 방법을 배울 것입니다. 그리고나서 엑셀(xlsx) 파일들을 읽거나 스프레드 시트로 필터링 하고, 행/열을 검색하고 셀(cell)을 업데이트 하는 방법을 살펴 볼 것입니다. 가장 간편한 스프레드시트(spreadsheet) 형태인 CSV로 시작해봅니다. 파트 1 - ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/how-to-create-read-update-and-search-through-excel-files-using-python/</link>
                <guid isPermaLink="false">63ea8f8e35fac40657f4959d</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Tue, 14 Mar 2023 08:29:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/03/1_REWATbNLWv5uvpB0UKedEQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/how-to-create-read-update-and-search-through-excel-files-using-python-c70680d811d4/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to create, read, update and search through Excel files using Python</a>
      </p><!--kg-card-begin: markdown--><h5 id="">이 글은 파이썬으로 엑셀 파일을 작업하는 방법과 특정 데이터를 수정하는 방법을 자세하게 보여줄 것입니다.</h5>
<p>먼저 우리는 CSV 파일들을 읽고 쓰고 업데이트하는 방법을 배울 것입니다. 그리고나서 엑셀(xlsx) 파일들을 읽거나 스프레드 시트로 필터링 하고, 행/열을 검색하고 셀(cell)을 업데이트 하는 방법을 살펴 볼 것입니다.</p>
<p>가장 간편한 스프레드시트(spreadsheet) 형태인 CSV로 시작해봅니다.</p>
<h2 id="1csv">파트 1 - CSV 파일</h2>
<p>CSV 파일은 쉼표로 구분된 값(comma-separated values)을 가진 파일로써 간단한 문자 데이터가 행열을 갖춘 형태(tabluar format)로 보여질 수 있습니다. 어떠한 스프레드시트 프로그램에서도 사용할 수 있는데 예를 들어 마이크로소프트 오피스 엑셀, 구글 스프레드시트, 또는 LibreOffice Calc 등이 있습니다.</p>
<p>하지만 CSV 파일들은 다른 스프레드시트 파일과 같진 않은데, 왜냐하면 사용자로 하여금 셀이나 행/열, 또는 수식을 저장하게 허용하지 않기 때문입니다. 이러한 한계는 파일 하나당 하나의 시트만 저장할 수 있게 허용하는 것으로도 나타납니다. 이 글의 첫번째 파트는 Python 3와 표준 라이브러리 모듈인 CSV를 이용해서 CSV 파일을 생성하는 방법을 보여드리고자 합니다.</p>
<p>이 튜토리얼은 두 개의 깃허브(GitHub) 리포들(repositories)과 이 튜토리얼 두번째 파트의 (특정 목적이 되도록 업데이트되고 수정된) 코드를 실제로 사용하는 라이브 웹 어플리케이션으로 끝나게 될 것입니다.</p>
<h2 id="csv">CSV 파일에 작성하기</h2>
<p>첫번째로 새로운 파이썬 파일을 열고 파이썬 CSV 모듈을 불러오세요.</p>
<pre><code>import csv
</code></pre>
<h3 id="csv">CSV 모듈</h3>
<p>CSV 모듈은 모든 필수 메소드들을 내장(built in)하여 포함합니다. 그 안에는:</p>
<ul>
<li>csv.reader</li>
<li>csv.writer</li>
<li>csv.DictReader</li>
<li>csv.DictWriter</li>
<li>그리고 기타 등등이 포함되어 있습니다.</li>
</ul>
<p>이번 가이드에서 우리는 writer, DictWriter, DectReader 메소드에 초점을 맞출 것입니다. 이것들은 사용자들이 어떤 CSV 파일을 수정하고 변경하여 저장된 데이터를 조작하도록 허용합니다.</p>
<p>첫번째 단계에서 우리는 파일 이름을 정의하고 하나의 변수로 저장하는 것이 필요합니다. 반드시 헤더와 데이터 정보가 일치하게 해야 합니다.</p>
<pre><code class="language-python">filename = "imdb_top_4.csv"
header = ("Rank", "Rating", "Title")
data = [
(1, 9.2, "The Shawshank Redemption(1994)"),
(2, 9.2, "The Godfather(1972)"),
(3, 9, "The Godfather: Part II(1974)"),
(4, 8.9, "Pulp Fiction(1994)")
]
</code></pre>
<p>이제 우리는 세 개의 변수(<em>header</em>, <em>data</em>, <em>filename</em>)를 받아오게 될 <em>writer</em>라는 이름의 어떤 함수를 생성해야 합니다.</p>
<pre><code class="language-python">def writer(header, data, filename):
  pass
</code></pre>
<p>그 다음 단계는 <em>writer</em> 함수를 수정하여 어떤 파일을 생성하고 <em>header</em>, <em>data</em> 변수에서 데이터를 가져오게 하는 방법입니다. 이것은 <em>header</em> 변수의 첫번째 행을 작성하고 이어서 그 다음 <em>data</em> 변수의 네 줄을 작성하는 것으로 완료됩니다 (네 줄이 있는 이유는 배열(list) 안에 네 개의 튜플(tuples)이 있기 때문입니다).</p>
<pre><code class="language-python">def writer(header, data, filename):
  with open (filename, "w", newline = "") as csvfile:
    movies = csv.writer(csvfile)
    movies.writerow(header)
    for x in data:
      movies.writerow(x)
</code></pre>
<blockquote>
<p><a href="https://docs.python.org/3/library/csv.html#dialects-and-formatting-parameters">공식 파이썬 문서</a>에서 csv.writer 메소드가 동작하는 방법을 설명하고 있습니다. 정말 시간을 내서 읽어보길 추천드려요.</p>
</blockquote>
<p><strong>짜잔!</strong> imdb_top_4.csv라는 첫번째 파일을 생성하였습니다. 선호하는 스프레트시트 도구로 이 파일을 열어보면 아래와 같이 보일 것입니다:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*DuYsqu8EFzU15u_0HgNDKg.png" alt="1*DuYsqu8EFzU15u_0HgNDKg" width="333" height="118" loading="lazy"></p>
<h5 align="center">결과를 보기 위해 LebreOffice Calc를 사용한 모습.</h5>
<p>해당 결과는 다른 도구에서 파일을 열어본다면 아래와 같이 쓰여져 있을 수도 있습니다:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Q0U_MBj6mr3ekidC299lbQ.png" alt="1*Q0U_MBj6mr3ekidC299lbQ" width="357" height="143" loading="lazy"></p>
<h5 align="center">결과를 보기 위해 SublimeText를 사용한 모습.</h5>
<h2 id="csv">CSV 파일 수정</h2>
<p>이 파일을 수정하기 위해서는 <em>updater</em>라는 이름의 새로운 함수를 만들어서 <em>filename</em>이라는 하나의 변수만 받아오게 할 것입니다.</p>
<pre><code class="language-python">def updater(filename):
    with open(filename, newline= "") as file:
        readData = [row for row in csv.DictReader(file)]
        # print(readData)
        readData[0]['Rating'] = '9.4'
        # print(readData)

    readHeader = readData[0].keys()
    writer(readHeader, readData, filename, "update")
</code></pre>
<p>이 함수는 먼저 <em>filename</em> 변수에 정의된 파일을을 열고 그 다음에 <em>readData</em>라고 이름된 변수 안에 파일로부터 읽어온 모든 데이터를 저장합니다. 두번째 단계는 새로운 변수를 강제로 입력하고 그것을 <em>readData[0]['rating']</em> 위치에 있는 구 데이터 대신 바꿔 넣기 위한 방법입니다.</p>
<p>이 함수의 마지막 단계는 사용자가 어떤 수정을 하고 있다는 것을 말하는 새로운 변수 <em>update</em>를 더하여 <em>writer</em> 함수를 호출하는 것입니다.</p>
<blockquote>
<p>csv.DictReader 관련 더 많은 내용은 <a href="https://docs.python.org/3/library/csv.html#dialects-and-formatting-parameters">여기</a> 파이썬 공식 문서에 설명되어 있습니다.</p>
</blockquote>
<p><em>writer</em>가 새로운 변수로 작동하게 하려면 <em>writer</em>가 정의된 모든 곳에 새로운 변수를 추가 해줘야 합니다. <em>writer</em> 함수를 처음 호출한 지점으로 돌아가서 "write"를 새로운 변수로 더해주세요:</p>
<pre><code class="language-python">writer(header, data, filename, "write")
</code></pre>
<p>바로 아래 writer 함수가 <em>updater</em>를 호출하고 <em>filename</em> 변수를 그 안으로 넘겨 주는 것을 찾으세요:</p>
<pre><code class="language-python">writer(header, data, filename, "write")
updater(filename)
</code></pre>
<p>이제 우리는 <em>writer</em> 함수가 <em>option</em>이라는 이름의 새로운 변수를 받아오게 변경해야 합니다:</p>
<pre><code class="language-python">def writer(header, data, filename, option):
</code></pre>
<p>이제부터 우리는 <em>writer</em> 함수에서 서로 다른 두 개의 옵션들(<em>write</em>와 <em>update</em>)을 받아오길 예상하겠습니다. 이것 때문에 우리는 두 개의 if문을 더해서 이렇게 설정한 새로운 기능을 지원하도록 해야 합니다. <em>if option == "write": 아래 함수</em> 첫번째 부분은 이미 기존에 알고 있는 내용입니다. 코드의 <em>elif option == "update":</em> 영역과 바로 아래에 쓰여진 <em>else</em> 부분 코드를 더하기만 하면 됩니다:</p>
<pre><code class="language-python">def writer(header, data, filename, option):
        with open (filename, "w", newline = "") as csvfile:
            if option == "write":

                movies = csv.writer(csvfile)
                movies.writerow(header)
                for x in data:
                    movies.writerow(x)
            elif option == "update":
                writer = csv.DictWriter(csvfile, fieldnames = header)
                writer.writeheader()
                writer.writerows(data)
            else:
                print("Option is not known")
</code></pre>
<p><strong>만세!</strong> 완성했어요!</p>
<p>이제 코드는 아래와 같이 보일 것입니다:<br>
<img src="https://cdn-media-1.freecodecamp.org/images/0*vPoREgLGJU8VmB5k" alt="0*vPoREgLGJU8VmB5k" width="800" height="776" loading="lazy"></p>
<h5 align="center">코드; 입출력을 담당하는 main 함수 아래 writer와 updater 함수가 있습니다. writer 함수는 csv 파일을 불러올 때 write와 update옵션을 같이 선택할 수 있도록 if-elif-else문을 사용합니다. 반면 updater 함수는 filename 변수 하나만 가지고 있으며 readData[0]['rating'] 위치에 있는 데이터를 강제로 변경합니다. </h5>
<p>이곳에서 코드를 찾으실 수도 있습니다: <a href="https://github.com/GoranAviani/CSV-Viewer-and-Editor">https://github.com/GoranAviani/CSV-Viewer-and-Editor</a></p>
<p>이 글을 첫번째 파트에서 우리는 CSV 파일을 어떻게 다루는지 보았습니다. 파일 하나를 생성해서 수정해 보았습니다.</p>
<h2 id="2xlsx">파트 2 - 엑셀(xlsx) 파일</h2>
<p>주말 몇 번에 이어 이 프로젝트를 진행하고 있습니다. 처음 시작은 저희 회사에 이와 같은 솔루션이 필요해서였습니다. 첫번째 생각은 이 해결책을 직접 저희 회사 시스템에 구축하는 것이었으나, 그러면 저는 글에 아무것도 쓰지 못하겠네요 그렇죠?</p>
<p>저는 Python 3와 <em>openpyxl</em> 라이브러리를 사용해 솔루션을 만들었습니다. 제가 <em>openpyxl</em> 을 선택한 이유는 워크시트(worksheets)를 생성하고 불러와 업데이트하고 이름을 변경하거나 삭제하는 데 있어서 완벽한 솔루션이기 때문입니다. 또한 우리가 행렬을 읽고 쓰고, 셀을 병합하거나 병합 해제하고, 파이썬 엑셀 차트를 만드는 등의 기능을 허용하는 방법입니다.</p>
<h2 id="openpyxl">Openpyxl 용어와 기본 정보</h2>
<ul>
<li>Workbook은 Openpyxl에서 엑셀 파일 이름입니다.</li>
<li>하나의 workbook은 기본 하나 (이상 여러개) sheet로 구성됩니다. sheet는 이름으로 참조됩니다.</li>
<li>하나의 sheet는 숫자 1부터 시작하는 행(가로 선)과 문자 A로 시작하는 열(세로 선)로 구성됩니다.</li>
<li>행렬은 격자 구조를 이루어 셀을 형성하고 그 안에 어떤 데이터 (수치 또는 문자 값) 또는 공식을 담을 수 있습니다.</li>
</ul>
<blockquote>
<p>Openpyxl은 문서화가 잘 되어 있으니 <a href="https://openpyxl.readthedocs.io/en/stable/">여기</a>를 한번 살펴보시길 추천드립니다.</p>
</blockquote>
<p>첫번째 단계는 파이썬 환경을 열고 터미널 안에 <em>openpyxl</em> 을 설치하는 것입니다:</p>
<pre><code class="language-python">pip install openpyxl
</code></pre>
<p>다음으로 <em>openpyxl</em> 을 프로젝트 안에 불러와서 <em>theFile</em> 변수로 workbook을 실행합니다.</p>
<pre><code class="language-python">import openpyxl

theFile = openpyxl.load_workbook('Customers1.xlsx')
print(theFile.sheetnames)
currentSheet = theFile['customers 1']
print(currentSheet['B4'].value)
</code></pre>
<p>보시다시피 이 코드는 모든 sheet를 이름으로 출력합니다. 그리고나서 "customers 1"이라고 이름 붙여진 sheet를 선택해 <em>currentSheet</em> 변수로 저장합니다. 마지막 줄에서 코드는 "customers 1" sheet의 B4 자리에 위치하는 값을 출력합니다.</p>
<p>이 코드는 의도한 대로 동작하긴 하지만 매우 하드 코딩(hard coded)되어 있습니다. 좀 더 동적으로 만들기 위해 우리는 이러한 기능을 하는 코드를 작성하게 될 것입니다:</p>
<ul>
<li>파일을 읽는다</li>
<li>모든 sheet의 이름을 가져온다</li>
<li>모든 sheet를 돌아 순환한다</li>
<li>마지막 단계에서 코드는 workbook 안에서 각각 찾아낸 sheet의 B4 영역에 위치한 값을 출력한다.</li>
</ul>
<pre><code class="language-python">import openpyxl

theFile = openpyxl.load_workbook('Customers1.xlsx')
allSheetNames = theFile.sheetnames

print("All sheet names {} " .format(theFile.sheetnames))


for x in allSheetNames:
    print("Current sheet name is {}" .format(x))
    currentSheet = theFile[x]
    print(currentSheet['B4'].value)
</code></pre>
<p>이전보다는 나아졌지만 여전히 하드 코딩된 솔루션이고 여전히 우리가 B4 셀을 찾아볼 것이라는 걸 가정하고 있습니다, 바보같이 말이죠.</p>
<p>제가 예상하기에 당신의 프로젝트는 어떤 특정 값을 위해 엑셀 파일에 있는 모든 sheet 내부를 검색할 필요가 있을 것입니다. 이를 위해 우리는 "ABCDEF" 범위 안에 하나의 for 반복문을 더한 다음 셀 이름과 값을 간단히 출력하게 할 것입니다.</p>
<pre><code class="language-python">import openpyxl

theFile = openpyxl.load_workbook('Customers1.xlsx')
allSheetNames = theFile.sheetnames

print("All sheet names {} " .format(theFile.sheetnames))


for sheet in allSheetNames:
    print("Current sheet name is {}" .format(sheet))
    currentSheet = theFile[sheet]
    # print(currentSheet['B4'].value)

    #print max numbers of wors and colums for each sheet
    #print(currentSheet.max_row)
    #print(currentSheet.max_column)

    for row in range(1, currentSheet.max_row + 1):
        #print(row)
        for column in "ABCDEF":  # Here you can add or reduce the columns
            cell_name = "{}{}".format(column, row)
            #print(cell_name)
            print("cell position {} has value {}".format(cell_name, currentSheet[cell_name].value))
</code></pre>
<p>우리는 "for row in range.." 반복문을 도입하여 이를 실행했습니다. for 반복문 안에 범위는 1번 행에 있는 셀에서부터 시작해서 sheet에 있는 최대 값 행까지로 정의되었습니다. 두번째 for 반복문은 사전에 정해진 열 이름 "ABCDEF" 안에서 검색을 수행합니다. 두번째 구문 안에서 우리는 셀의 위치(열 이름과 행 번호 모두)와 그 값을 보여주게 될 것입니다.</p>
<p>그러나, 이 글에서 저의 과제는 "telephone"이라 이름지어진 특정 열을 찾아서 해당 열의 모든 행을 훑어 가는 것입니다. 이를 위해 우리는 코드를 아래와 같이 수정할 필요가 있습니다.</p>
<pre><code class="language-python">import openpyxl

theFile = openpyxl.load_workbook('Customers1.xlsx')
allSheetNames = theFile.sheetnames

print("All sheet names {} " .format(theFile.sheetnames))


def find_specific_cell():
    for row in range(1, currentSheet.max_row + 1):
        for column in "ABCDEFGHIJKL":  # Here you can add or reduce the columns
            cell_name = "{}{}".format(column, row)
            if currentSheet[cell_name].value == "telephone":
                #print("{1} cell is located on {0}" .format(cell_name, currentSheet[cell_name].value))
                print("cell position {} has value {}".format(cell_name, currentSheet[cell_name].value))
                return cell_name

for sheet in allSheetNames:
    print("Current sheet name is {}" .format(sheet))
    currentSheet = theFile[sheet]
</code></pre>
<p>이 수정된 코드는 모든 sheet에 모든 값을 훑어 보고 바로 전에 한 것과 같이 행의 범위가 동적이며 열의 범위가 정적입니다. 이 코드는 셀을 통해 반복되고 어떤 문자 값 "telephone"을 가지고 있는 셀을 찾게 됩니다. 한번 코드가 특정 값을 찾고 나면 사용자에게 어느 셀 안에 그 문자가 위치하고 있는지 알려줍니다. 코드는 이와 같은 행동을 그 엑셀 파일 안 모든 sheet 안에 있는 모든 셀에게 수행합니다.</p>
<p>다음 단계는 특정 값이 있는 모든 행을 훑고 값을 출력하는 법입니다.</p>
<pre><code class="language-python">import openpyxl

theFile = openpyxl.load_workbook('Customers1.xlsx')
allSheetNames = theFile.sheetnames

print("All sheet names {} " .format(theFile.sheetnames))


def find_specific_cell():
    for row in range(1, currentSheet.max_row + 1):
        for column in "ABCDEFGHIJKL":  # Here you can add or reduce the columns
            cell_name = "{}{}".format(column, row)
            if currentSheet[cell_name].value == "telephone":
                #print("{1} cell is located on {0}" .format(cell_name, currentSheet[cell_name].value))
                print("cell position {} has value {}".format(cell_name, currentSheet[cell_name].value))
                return cell_name

def get_column_letter(specificCellLetter):
    letter = specificCellLetter[0:-1]
    print(letter)
    return letter

def get_all_values_by_cell_letter(letter):
    for row in range(1, currentSheet.max_row + 1):
        for column in letter:
            cell_name = "{}{}".format(column, row)
            #print(cell_name)
            print("cell position {} has value {}".format(cell_name, currentSheet[cell_name].value))



for sheet in allSheetNames:
    print("Current sheet name is {}" .format(sheet))
    currentSheet = theFile[sheet]
    specificCellLetter = (find_specific_cell())
    letter = get_column_letter(specificCellLetter)

    get_all_values_by_cell_letter(letter)
</code></pre>
<p>어떤 열의 문자를 찾는 <em>get_column_letter</em> 라는 이름의 함수를 더하여 완성되었습니다. 어떤 열의 문자를 찾은 다음에는 해당 특정 열의 모든 행을 돌아 순환합니다. 해당 셀들의 모든 값을 출력하게 될 <em>get_all_values_by_cell_letter</em> 함수를 통해 완성되었습니다.</p>
<h2 id="">마무리하며</h2>
<p>아주 잘 했어요! 이 다음에 할 수 있는 많은 것들이 있습니다. 저의 계획은 어떤 온라인 앱을 만들어서 어떤 문자 박스에서 가져온 모든 스웨덴 전화번호를 표준화 하고 사용자에게는 같은 문자 박스에서 결과를 단지 복사만 할 수 있는 가능성을 제공하는 것이었습니다. 제 계획의 두번째 단계는 엑셀 파일을 업로드를 지원하는 웹 어플리케이션 기능을 확장해서 그 파일들 안에 있는 전화번호를 가공(즉, 스웨덴 양식으로 표준화)하고 가공된 파일을 사용자에게 되돌려 주는 것을 제안하는 것이었습니다.</p>
<p>읽어주셔서 감사합니다! 개인 Medium 프로필에서 더 많은 글을 확인하세요:<a href="https://medium.com/@goranaviani">https://medium.com/@goranaviani</a> 그리고 깃허브 페이지에서는 제가 만든 다른 재미있는 것들을 찾을 수 있습니다: <a href="https://github.com/GoranAviani">https://github.com/GoranAviani</a></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python 딕셔너리 자료형 생성 및 관련 메서드 ]]>
                </title>
                <description>
                    <![CDATA[ 이 기사에서는 Python의 딕셔너리(Dictionary) 자료형의 기본 사용법을 알아보겠습니다. 딕셔너리 생성하기, 딕셔너리 내의 요소에 접근하기, 그리고 필요에 따라 딕셔너리의 요소를 수정하는 방법에 대해 살펴보겠습니다. 또한 흔히 사용하는 딕셔너리 내장 메서드에 대해서도 설명하겠습니다. 이 기사에서 다룰 내용은 다음과 같습니다.  1. 딕셔너리 생성 및 선언하기 1. 빈 딕셔너리 선언하기    ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-dictionary-methods/</link>
                <guid isPermaLink="false">63f60bce1d2b73063c4ce962</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boyeon Ihn ]]>
                </dc:creator>
                <pubDate>Thu, 23 Feb 2023 08:19:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/02/pexels-kevin-ku-577585.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/create-a-dictionary-in-python-python-dict-methods/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Create a Dictionary in Python – Python Dict Methods</a>
      </p><!--kg-card-begin: markdown--><h3 id="pythondictionary">이 기사에서는 Python의 딕셔너리(Dictionary) 자료형의 기본 사용법을 알아보겠습니다.</h3>
<p>딕셔너리 생성하기, 딕셔너리 내의 요소에 접근하기, 그리고 필요에 따라 딕셔너리의 요소를 수정하는 방법에 대해 살펴보겠습니다.</p>
<p>또한 흔히 사용하는 딕셔너리 내장 메서드에 대해서도 설명하겠습니다.</p>
<p>이 기사에서 다룰 내용은 다음과 같습니다.</p>
<ol>
<li><a href="#define-intro">딕셔너리 생성 및 선언하기</a>
<ol>
<li><a href="#define-empty">빈 딕셔너리 선언하기</a></li>
<li><a href="#define-items">요소가 포함된 딕셔너리 선언하기</a></li>
</ol>
</li>
<li><a href="#overview">키(key)-값(value)란 무엇인가</a>
<ol>
<li><a href="#length">딕셔너리의 키-값(key-value) 개수 확인하기</a></li>
<li><a href="#key-value">주어진 딕셔너리의 모든 키-값 보기</a></li>
<li><a href="#keys">딕셔너리의 모든 키(key) 보기</a></li>
<li><a href="#values">딕셔너리의 모든 값(values) 보기</a></li>
</ol>
</li>
<li><a href="#access">딕셔너리의 특정 키-값에 접근하기</a></li>
<li><a href="#modify">딕셔너리 수정하기</a><br>
1.<a href="#add">딕셔너리에 새 키-값 추가하기</a><br>
2. <a href="#update">딕셔너리의 기존 키-값 수정하기</a><br>
3. <a href="#delete">키-값 삭제하기</a></li>
</ol>
<p>그럼 시작해볼까요?</p>
<h2 id="define-intro">딕셔너리 생성 및 선언하기</h2>
<p>Python의 딕셔너리는 키와 값으로 이루어진 자료형입니다.</p>
<p>다음 두 섹션을 통해 딕셔너리를 생성하는 두 가지 방법을 보여드리겠습니다.</p>
<p>첫 번째 방법은 중괄호 <code>{}</code>를 사용하는 것이고 두 번째 방법은 내장 함수 <code>dict()</code>를 사용하는 것입니다.</p>
<h3 id="define-empty">빈 딕셔너리 선언하기</h3>
<p>빈 딕셔너리를 선언하려면 먼저 딕셔너리의 이름이 될 변수 이름을 생성합니다.</p>
<p>그런 다음 생성한 변수를 빈 중괄호 <code>{}</code>에 할당합니다.</p>
<pre><code class="language-python">#빈 딕셔너리 선언하기
my_dictionary = {}
print(my_dictionary)
#type() 함수를 통해 자료형을 확인하기
print(type(my_dictionary))
#출력된 결과
#{}
#&lt;class 'dict'&gt;
</code></pre>
<p>빈 딕셔너리를 생성하는 또 다른 방법은 인수를 전달하지 않고 <code>dict()</code> 함수를 사용하는 것입니다.</p>
<p>인수를 전달하지 않은 <code>dict()</code>는 생성자 함수 역할을 해 빈 딕셔너리를 만듭니다.</p>
<pre><code class="language-python">#빈 딕셔너리 선언하기
my_dictionary = dict()
print(my_dictionary)
#type() 함수를 통해 자료형을 확인하기
print(type(my_dictionary))
#출력된 결과
#{}
#&lt;class 'dict'&gt;
</code></pre>
<h3 id="define-items">요소가 포함된 딕셔너리 선언하기</h3>
<p>요소가 포함된 딕셔너리를 만들려면 중괄호 <code>{}</code>안에 키-값을 포함해야 합니다.</p>
<p>기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">dictionary_name = {키: 값}
</code></pre>
<p>더 자세히 설명하겠습니다.</p>
<p>-<code>dictionary_name</code>은 변수의 이름입니다. 즉, 이 예시에서는 딕셔너리의 이름입니다.</p>
<ul>
<li>할당 연산자 <code>=</code>는 <code>키-값</code>을 <code>딕셔너리_이름</code>에 할당합니다.</li>
<li>중괄호 <code>{}</code>를 사용해 딕셔너리를 선언합니다.</li>
<li>중괄호 안에 키-값이 있습니다. 키와 값은 쌍점 <code>:</code>으로 구분합니다.</li>
</ul>
<p>예시를 통해 요소가 포함된 딕셔너리 선언하기를 확인해봅시다.</p>
<pre><code class="language-python">#딕셔너리 선언하기
my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
print(my_information)
#자료형 확인하기
print(type(my_information))
#출력된 결과
#{'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
#&lt;class 'dict'&gt;
</code></pre>
<p>위 예제에서는 중괄호 내에 일련의 요소가 있습니다. 정확히 말하자면, 다음과 같은 세 개의 키-값이 있습니다: <code>'name': 'Boyeon'</code>, <code>'age': 29</code>, and <code>'location': 'Seoul'</code>.</p>
<p>주어진 예시의 딕셔너리에 포함된 세 키는 <code>name</code>, <code>age</code>, 그리고 <code>location</code>이며, 각 키에 할당된 값은 <code>Boyeon</code>, <code>29</code>, 그리고 <code>Seoul</code>입니다.</p>
<p>딕셔너리에 여러 개의 키-값이 있을 경우 각 키-값은 쉼표로 구분합니다.</p>
<p>또 다른 예시를 봅시다.</p>
<p>이번에는 <code>dict()</code> 함수를 사용해 요소가 포함된 딕셔너리를 생성해야 한다고 가정해보겠습니다.</p>
<p>방법은 간단합니다. <code>dict()</code>를 사용해 일련의 키-값을 함수에 대한 인수로 전달하면 됩니다.</p>
<pre><code class="language-python">#dict() 함수를 사용해 딕셔너리 생성하기
my_information = dict({'name': 'Boyeon', 'age': 29, 'location': 'Seoul'})
print(my_information)
#자료형 확인하기
print(type(my_information))
#출력된 결과
#{'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
#&lt;class 'dict'&gt;
</code></pre>
<p>딕셔너리를 만드는 또 다른 방법은 바로 <code>fromkeys()</code> 메서드를 사용하는 것입니다.</p>
<p>미리 정의된 일련의 요소를 인수로 전달 받고 일련의 요소를 딕셔너리의 지정된 키로 사용해 새 딕셔너리를 반환합니다.</p>
<p>사용자가 선택 사항으로 모든 키에 대한 값을 설정할 수 있지만, 설정하지 않는다면 기본적으로 키의 값은 <code>None</code>이 됩니다.</p>
<p><code>fromkeys()</code> 메서드의 기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">딕셔너리_이름 = dict.fromkeys(sequence,value)
</code></pre>
<p>모든 키에 값을 설정하지 않고 <code>fromkeys()</code>를 사용해 딕셔너리를 만드는 예를 살펴봅시다.</p>
<pre><code class="language-python">#일련의 문자열 생성하기
cities = ('Paris','Athens', 'Madrid')
#fromkeys() 메서드를 사용해 `my_dictionary`라는 딕셔너리 생성하기
my_dictionary = dict.fromkeys(cities)
print(my_dictionary)
#{'Paris': None, 'Athens': None, 'Madrid': None}
</code></pre>
<p>이제 딕셔너리의 모든 키에 동일한 값을 설정하는 다른 예를 보여드리겠습니다.</p>
<pre><code class="language-python">#일련의 문자열 생성하기
cities = ('Paris','Athens', 'Madrid')
#단일 값을 생성하기
continent = 'Europe'
my_dictionary = dict.fromkeys(cities,continent)
print(my_dictionary)
#출력된 결과
#{'Paris': 'Europe', 'Athens': 'Europe', 'Madrid': 'Europe'}
</code></pre>
<h2 id="overview">키(key)-값(value)란 무엇인가</h2>
<p>Python 딕셔너리 내의 키는 수정 불가능한(immutable) 타입일 수도 있습니다.</p>
<p>Python에서 수정 불가능한 데이터 타입은 <code>정수(integers)</code>, <code>문자열(strings)</code>, <code>튜플(tuples)</code>, <code>실수형(floating point numbers)</code>, 그리고 <code>불린 자료형(Booleans)</code>입니다.</p>
<p>딕셔너리의 키는 <code>집합 자료형(sets)</code>, <code>리스트(lists)</code>, 또는 <code>딕셔너리(dictionaries)</code>와 같은 수정 가능한(mutable) 데이터 타입일 수 <strong>없습니다</strong>.</p>
<p>다음과 같은 딕셔너리가 있다고 가정해보겠습니다.</p>
<pre><code class="language-python">my_dictionary = {True: "True",  1: 1,  1.1: 1.1, "one": 1, "languages": ["Python"]}
print(my_dictionary)
#출력된 결과
#{True: 1, 1.1: 1.1, 'one': 1, 'languages': ['Python']}
</code></pre>
<p>위의 예시에 있는 딕셔너리의 키는 <code>불린</code>, <code>정수</code>, <code>실수형</code>, 그리고 <code>자료형</code> 데이터 타입으로 모두 키로 사용 가능합니다.</p>
<p>수정 가능한 데이터 타입의 키를 생성하려고 하면 <code>TypeError</code> 오류가 발생합니다.</p>
<pre><code class="language-python">my_dictionary = {["Python"]: "languages"}
print(my_dictionary)
#출력된 결과
#line 1, in &lt;module&gt;
#    my_dictionary = {["Python"]: "languages"}
#TypeError: unhashable type: 'list'
</code></pre>
<p>위에 예에서 수정 가능한 데이터 타입인 <code>리스트</code>를 키로 지정하려고 했기 때문에 <code>TypeError: unhashable type: 'list'</code> 오류가 발생했다는 것을 확인할 수 있습니다.</p>
<p>반면, 딕셔너리 내의 값(value)에는 데이터 타입에 관한 제한이 없습니다. 즉, 수정 가능한 데이터와 수정 불가능한 데이터 타입을 값으로 사용할 수 있습니다.</p>
<p>주목해야 할 키와 값의 또 다른 차이점은 키는 <strong>고유하다는 점입니다</strong>. 다시 말해 한 딕셔너리에 같은 이름의 키는 한 개 이상 존재할 수 없습니다. 하지만 딕셔너리 내에 동일한 값은 중복될 수 있습니다.</p>
<p>(더 명확한 설명을 위해 예시를 들어보겠습니다 --옮긴이)</p>
<pre><code class="language-python">#이렇게 딕셔너리에 `name` 키가 두 번 있을 수 없습니다
my_dictionary = {'name': 'Boyeon', 'name': 'Ihn'}
#하지만 딕셔너리에 `Seoul`이라는 값은 중복될 수 있습니다
my_information = {'birthplace': 'Seoul', 'current_location': 'Seoul'}
</code></pre>
<h3 id="length">딕셔너리의 키-값(key-value) 개수 확인하기</h3>
<p><code>len()</code> 함수는 인수로 전달된 객체의 총 길이를 반환합니다.</p>
<p>딕셔너리가 <code>len()</code> 함수에 인수로 전달되면, 딕셔너리에 포함된 키-값의 총 개수를 반환합니다.</p>
<p><code>len()</code>을 사용해 키-값의 수를 계산하는 방법은 다음과 같습니다.</p>
<pre><code class="language-python">my_information = {'name': 'Dionysia', 'age': 28, 'location': 'Athens'}
print(len(my_information))
#출력된 결과
#3
</code></pre>
<h3 id="key-value">주어진 딕셔너리의 모든 키-값 보기</h3>
<p>딕셔너리에 있는 모든 키-값을 보려면 <code>items()</code> 내장 함수를 사용합니다.</p>
<pre><code class="language-python">year_of_creation = {'Python': 1993, 'JavaScript': 1995, 'HTML': 1993}
print(year_of_creation.items())
#출력된 결과
#dict_items([('Python', 1993), ('JavaScript', 1995), ('HTML', 1993)])
</code></pre>
<p><code>items()</code> 메서드는 딕셔너리의 키-값을 포함하는 튜플 목록을 반환합니다.</p>
<h3 id="keys">딕셔너리의 모든 키(key) 보기</h3>
<p>딕셔너리에 있는 모든 키를 확인하려면 <code>keys()</code> 내장 메서드를 사용합니다.</p>
<pre><code class="language-python">year_of_creation = {'Python': 1993, 'JavaScript': 1995, 'HTML': 1993}
print(year_of_creation.keys())
#출력된 결과
#dict_keys(['Python', 'JavaScript', 'HTML'])
</code></pre>
<p><code>keys()</code> 메서드는 딕셔너리에 있는 키만 포함하는 리스트를 반환합니다.</p>
<h3 id="values">딕셔너리의 모든 값(values) 보기</h3>
<p>딕셔너리에 있는 모든 값을 확인하려면 <code>values()</code> 내장 메서드를 사용합니다.</p>
<pre><code class="language-python">year_of_creation = {'Python': 1993, 'JavaScript': 1995, 'HTML': 1993}
print(year_of_creation.values())
#출력된 결과
#dict_values([1993, 1995, 1993])
</code></pre>
<p><code>values()</code> 메서드는 딕셔너리에 있는 값만 포함하는 리스트를 반환합니다.</p>
<h2 id="access">딕셔너리의 특정 키-값에 접근하기</h2>
<p>Python에서는 기존 리스트 내의 특정 요소를 접근해야 할 때, 일반적으로 리스트 이름과 대괄호 표기법을 사용합니다. 대괄호 안에는 리스트 항목의 인덱스 번호를 지정합니다. 이렇게요.</p>
<p>(명확한 설명을 위해 예시를 추가합니다 --옮긴이)</p>
<pre><code class="language-python">#기존 리스트
my_list = [1993, 1995, 2022]
#대괄호와 인덱스 번호를 사용해 첫 번째 요소 접근하기
first_element = my_list[0]
print(first_element)
#출력된 결과
# 1993
</code></pre>
<p>딕셔너리에서는 리스트와 완전히 동일한 방법을 사용할 수 없습니다.딕셔너리는 키-값으로 이루어진 데이터 타입이기 때문에 인덱스 번호를 사용해 딕셔너리 내의 요소를 접근할 수 없기 때문입니다.</p>
<p>딕셔너리의 이름과 대괄호 표기법을 사용해 특정 요소에 접근한다는 점은 리스트와 비슷하지만, 딕셔너리는 이 대괄호 안에 접근하고 싶은 키를 지정합니다.</p>
<p>각 키는 특정 값에 해당하므로 접근하고 싶은 값과 지정된 키를 참조합니다.</p>
<p>특정 키-값에 접근하는 기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">dictionary_name[key]
</code></pre>
<p>Python 딕셔너리에서 특정 요소에 액세스하는 방법을 예시를 통해 살펴봅시다.</p>
<pre><code class="language-python">my_information = {'name': 'Dionysia', 'age': 28, 'location': 'Athens'}
#'age' 키에 할당된 값 접근하기
print(my_information['age'])
#출력된 결과
#28
</code></pre>
<p>주어진 딕셔너리에 존재하지 않는 키에 접근하려고 하면 어떻게 될까요?</p>
<pre><code class="language-python">my_information = {'name': 'Dionysia', 'age': 28, 'location': 'Athens'}
#존재하지 않는 'job' 키에 할당된 값 접근하기
print(my_information['job'])
#출력된 결과
#line 4, in &lt;module&gt;
#    print(my_information['job'])
#KeyError: 'job'
</code></pre>
<p>딕셔너리에 그런 키는 존재하지 않기 때문에 <code>KeyError</code> 오류가 발생합니다.</p>
<p>이와 같은 오류를 방지하는 한 가지 방법은 먼저 딕셔너리에 그 특정 키가 있는지 확인하는 것입니다.</p>
<p>바로 불린 값을 반환하는 <code>in</code> 키워드를 사용하면 됩니다. 키가 딕셔너리에 있으면 <code>True</code>를, 딕셔러니에 없으면 <code>False</code>를 반환합니다.</p>
<pre><code class="language-python">my_information = {'name': 'Dionysia', 'age': 28, 'location': 'Athens'}
#search for the 'job' key
print('job' in my_information)
#출력된 결과
#False
</code></pre>
<p><code>KeyError</code> 오류를 방지하려면 <code>get()</code> 메서드를 사용해 딕셔너리의 항목에 접근하는 방법도 있습니다.</p>
<p>찾으려는 키를 인수로 전달하면 <code>get()</code> 함수는 전달된 키에 해당하는 값을 반환합니다.</p>
<pre><code class="language-python">my_information = {'name': 'Dionysia', 'age': 28, 'location': 'Athens'}
#get() 메서드를 통해 'job' 키에 접근하기
print(my_information.get('job'))
#출력된 결과
#None
</code></pre>
<p>예시에 보인 것처럼, 존재하지 않는 키를 접근하려고 하면 <code>get()</code> 메서드는 기본적으로 <code>KeyError</code> 오류 대신 <code>None</code>을 반환합니다.</p>
<p><code>get()</code> 함수에 인수로 전달된 키가 딕셔너리에 없을 때 <code>None</code>이라는 메시지 대신 다른 메시지가 반환되도록 <code>get()</code> 함수를 사용자 정의할 수 있습니다.</p>
<p>키가 없을 때 표시되고 싶은 메시지를 <code>get()</code> 메서드의 두 번째 옵션 인수로 전달하면 됩니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
#get() 메서드를 통해 'job' 키에 접근하기
print(my_information.get('job', '이 값은 존재하지 않습니다'))
#출력된 결과
#이 값은 존재하지 않습니다
</code></pre>
<p>이제 딕셔너리에 없는 키를 접근하려고 하면 <code>이 값은 존재하지 않습니다</code>라는 메시지가 콘솔에 출력됩니다.</p>
<h2 id="modify">딕셔너리 수정하기</h2>
<p>딕셔너리는 "mutable," 즉, 수정 가능한 데이터 타입이기 때문에 내용을 변경할 수 있습니다.</p>
<p>프로그램이 실행되는 동안에도 딕셔너리는 규모가 커질 수도, 축소할 수도 있고, 새 항목이 추가되거나, 기존 항목이 새 값으로 수정되거나, 삭제될 수도 있습니다.</p>
<h3 id="add">딕셔너리에 새 키-값 추가하기</h3>
<p>딕셔너리에 키-값 쌍을 추가하려면 대괄호 표기법을 사용합니다.</p>
<p>새 키-값을 추가하는 기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">dictionary_name[key] = value
</code></pre>
<p>먼저 새 키-값을 추가하고 싶은 딕셔너리의 이름을 지정합니다. 그런 다음 대괄호 안에 추가하고 싶은 키의 이름을 넣고, 키에 값을 할당합니다.</p>
<p>빈 딕셔너리로 시작한다고 가정해봅시다.</p>
<pre><code class="language-python">my_dictionary = {}
print(my_dictionary)
#출력된 결과
#{}
</code></pre>
<p>이제 <code>my_dictionary</code> 딕셔너리에 키-값을 추가해보겠습니다.</p>
<pre><code class="language-python">my_dictionary = {}
#빈 딕셔너리에 키-값 추가하기
my_dictionary['name'] = "Boyeon Ihn"
#딕셔너리 출력하기
print(my_list)
#출력된 결과
#{'name': 'Boyeon Ihn'}
</code></pre>
<p>다른 새 키-값을 추가하려면 대괄호 표기법을 동일하게 사용하면 됩니다.</p>
<pre><code class="language-python">my_dictionary = {}
#빈 딕셔너리에 키-값 추가하기
my_dictionary['name'] = "Boyeon Ihn"
#키-값 또 추가하기
my_dictionary['age'] = 29
#딕셔너리 출력하기
print(my_dictionary)
#출력된 결과
#{'name': 'Boyeon Ihn', 'age': 29}
</code></pre>
<p>추가하려는 키가 해당 사전에 이미 있고 다른 값을 할당하는 경우, 기존에 있는 키의 값만 업데이트될 뿐, 새 키-값이 추가되지 않습니다.</p>
<p>키는 고유해야 한다는 점, 꼭 명심하시길 바랍니다.</p>
<pre><code class="language-python">my_dictionary = {'name': 'Boyeon Ihn', 'age': 29}
print(my_dictionary)
#'age' 키를 새로 생성하고 값을 할당하려고 시도해봅니다
#하지만 'age' 키는 이미 딕셔너리에 존재한 상황입니다.
my_dictionary['age'] = 46
#이런 경우, 존재하고 있는 'age'의 값이 29에서 46로 업데이트 될 뿐, 새 키-값이 추가되지 않습니다
print(my_dictionary)
#출력된 결과
#{'name': 'Boyeon Ihn', 'age': 29}
#{'name': 'Boyeon Ihn', 'age': 46}
</code></pre>
<p>실수로 이미 존재하는 키에 할당된 값을 변경하지 않으려면, 추가하려는 키가 딕셔너리에 이미 있는지 확인하는 게 좋습니다.</p>
<p>이전 섹션에 설명한대로 <code>in</code> 키워드를 이때 유용하게 사용할 수 있습니다.</p>
<pre><code class="language-python">my_dictionary = {'name': 'Boyeon Ihn', 'age': 29}
#'age' 키를 추가하려고 합니다. 추가하기 전에, 'age' 키가 이미 있는지 확인해봅시다.
print('age' in my_dictionary)
#출력된 결과
#True
</code></pre>
<h3 id="update">딕셔너리의 기존 키-값 수정하기</h3>
<p>딕셔너리의 키-값 요소를 업데이트 및 수정하는 방법은 딕셔너리에 키-값을 새로 추가하는 방법과 유사합니다.</p>
<p>기존 키의 값을 수정하는 경우 이전 섹션에서 본 것처럼 다음과 같은 기본 문법을 사용합니다.</p>
<pre><code class="language-python">dictionary_name[existing_key] = new_value
my_dictionary = {'name': 'Boyeon Ihn', 'age': 29}
my_dictionary['age'] = 46
print(my_dictionary)
#출력된 결과
#{'name': 'Boyeon Ihn', 'age': 29}
</code></pre>
<p>딕셔너리의 내용을 수정하려면 <code>update()</code> 내장 메서드를 사용해도 됩니다.</p>
<p>이 메서드는 딕셔너리에서 두 개 이상의 키-값을 동시에 업데이트하려는 경우 특히 유용합니다.</p>
<p>my_dictionary에서 <code>name</code>과 <code>age</code> 키의 값을 수정하고 새 키 <code>occupation</code>을 추가한다고 가정합시다.</p>
<pre><code class="language-python">my_dictionary = {'name': 'Boyeon Ihn', 'age': 29}
my_dictionary.update(name= 'Mike Green', age = 46, occupation = "software developer")
print(my_dictionary)
#출력된 결과
#{'name': 'Mike Green', 'age': 46, 'occupation': 'software developer'}
</code></pre>
<p><code>update()</code> 메서드는 키-값의 튜플을 인수로 전달 받습니다.</p>
<p>딕셔너리에 이미 존재하는 키는 새 값이 할당되었고, 새 키-값이 추가되었습니다.</p>
<p><code>update()</code> 메서드는 한 딕셔너리의 내용을 다른 딕셔너리에 추가하려는 경우에도 유용합니다.</p>
<p><code>numbers</code> 딕셔너리가 있고, <code>more_numbers</code>라는 또 다른 딕셔너리가 있다고 가정해봅시다.</p>
<p><code>more_numbers</code>내의 내용물을 <code>numbers</code>와 병합하려면 <code>update()</code> 메서드를 사용해야 합니다.</p>
<p><code>more_numbers</code>에 포함된 모든 키-값은 <code>numbers</code> 딕셔너리의 끝에 추가됩니다.</p>
<pre><code class="language-python">numbers = {'one': 1, 'two': 2, 'three': 3}
more_numbers = {'four': 4, 'five': 5, 'six': 6}
#'numbers' 딕셔너리 업데이트하기
#`more_numbers' 딕셔너리의 요소들을 기존 딕셔너리에 추가합니다
numbers.update(more_numbers)
print(numbers)
#출력된 결과
#{'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
</code></pre>
<h3 id="delete">딕셔너리의 키-값 삭제하기</h3>
<p>딕셔너리에서 특정 키 및 관련 값을 삭제하는 방법 중 하나는 <code>del</code> 키워드를 사용하는 것입니다.</p>
<p>키-값을 삭제하는 기본 문법은 다음과 같습니다.</p>
<pre><code class="language-python">del dictionary_name[key]
</code></pre>
<p>다음 예시를 통해 <code>my_information dictionary</code> 딕셔너리에서 <code>location</code> 키를 삭제해보겠습니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
del my_information['location']
print(my_information)
#출력된 결과
#{'name': 'Boyeon', 'age': 29}
</code></pre>
<p><code>del</code> 키워드를 사용하면 키와 값 둘 다 삭제된다는 것을 확인하셨나요? 키를 삭제하고 같이 제거되는 값을 따로 저장하려면 <code>pop()</code> 내장 메서드를 사용합니다.</p>
<p><code>pop()</code> 메서드는 지정한 키를 제거하지만 할당된 값을 반환합니다. 나중에 사용하거나 접근할 수 있도록 제거된 값을 변수에 저장할 수 있습니다.</p>
<p><code>pop()</code> 메서드를 사용하는 기본 문법은 다음과 같습니다. 함수에 삭제하려는 키를 인수로 전달해야 한다는 것을 확인할 수 있습니다.</p>
<pre><code class="language-python">dictionary_name.pop(key)
</code></pre>
<p>위 예시처럼 <code>location</code> 키를 삭제를 하지만, 동시에 키에 할당된 값은 따로 저장하고 싶다면 다음과 같이 <code>pop()</code> 메서드를 사용하면 됩니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
city = my_information.pop('location')
print(my_information)
print(city)
#출력된 결과
#{'name': 'Boyeon', 'age': 29}
#Seoul
</code></pre>
<p><code>pop()</code> 메서드에 딕셔너리에 존재하지 않는 키를 인수로 전달한다면, <code>KeyError</code> 오류 메시지가 나타납니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
my_information.pop('occupation')
print(my_information)
#출력된 결과
#line 3, in &lt;module&gt;
#   my_information.pop('occupation')
#KeyError: 'occupation'
</code></pre>
<p><code>KeyError</code> 오류를 방지하는 방법은 <code>pop()</code> 메서드에 두 번째 인수를 전달하는 것입니다.</p>
<p>두 번째 인수를 전달하면 위의 오류는 발생하지 않습니다. 대신, 첫 번째 인수로 전달된 키가 딕셔너리에 존재하지 않으면 <code>pop()</code>는 silent fail(조용한 에러)만 발생할 뿐 딕셔너리 자체는 바뀌지 않습니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
my_information.pop('occupation','Not found')
print(my_information)
#출력된 결과
#{'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
</code></pre>
<p><code>pop()</code> 메서드는 특정 키와 관련 값을 제거합니다. 하지만 딕셔너리의 마지막 키-값만 삭제하려면 어떻게 해야 할까요?</p>
<p>이런 경우 내장 메서드인 <code>popitem()</code>을 사용하세요.</p>
<p>다음 코드가 <code>popitem()</code>의 기본 문법입니다.</p>
<pre><code class="language-python">dictionary_name.popitem()
</code></pre>
<p><code>popitem()</code> 메서드는 인수를 사용하지 않고 딕셔너리의 마지막 키-값이 제거된 딕셔너리를 반환합니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
popped_item = my_information.popitem()
print(my_information)
print(popped_item)
#출력된 결과
#{'name': 'Boyeon', 'age': 29}
#('location', 'Seoul')
</code></pre>
<p>마지막으로, 딕셔너리에 포함된 모든 키-값을 삭제하려면 <code>clear()</code> 내장 메서드를 사용할 수 있습니다.</p>
<pre><code class="language-python">my_information = {'name': 'Boyeon', 'age': 29, 'location': 'Seoul'}
my_information.clear()
print(my_information)
#출력된 결과
#{}
</code></pre>
<p>이 메서드를 사용하면 기존 딕셔너리가 비어지는 것을 확인할 수 있습니다.</p>
<h2 id="">마치며</h2>
<p>이렇게 딕셔너리 자료형과 자주 사용하는 메서드에 대해 배워봤습니다. 긴 글을 읽느라 수고하셨습니다!</p>
<p>이 기사가 도움이 되었길 바랍니다.</p>
<p>Python에 대해 더 배워보고 싶다면 freeCodeCamp의 <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/">Python 수료증 과정</a>을 확인해보세요. 수료증 강의를 통해 초보자여도 Python을 재미있고 유익하게 배우면서 5개의 프로젝트를 해보며 배운 것을 열심히 실습할 수 있을 거에요.</p>
<p>읽어주셔서 감사합니다. Happy coding!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 초보자를 위한 25가지 파이썬 프로젝트 – 파이썬 코딩을 시작하기 좋은 쉬운 아이디어들 ]]>
                </title>
                <description>
                    <![CDATA[ 새로운 프로그래밍 언어를 배우는 가장 좋은 방법은 그 언어를 사용한 프로젝트를 만드는 것입니다. 제가 파이썬에서 초급자가 하기 좋은 25가지 프로젝트 튜토리얼 목록을 생성하였습니다. 튜토리얼에 대한 저의 조언은 비디오를 보고 프로젝트를 만들어서 그것을 분해하고 여러분만의 방식으로 다시 만드는 것입니다. 새로운 기능을 추가하거나 다른 방법을 사용해 보세요. 그렇게 하면 당신이 정말로 개념을 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-projects-for-beginners/</link>
                <guid isPermaLink="false">63dd29e141a99b065fb5ab48</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Mon, 06 Feb 2023 08:34:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/02/hitesh-choudhary-D9Zow2REm8U-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-projects-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">25 Python Projects for Beginners – Easy Ideas to Get Started Coding Python</a>
      </p><!--kg-card-begin: markdown--><p>새로운 프로그래밍 언어를 배우는 가장 좋은 방법은 그 언어를 사용한 프로젝트를 만드는 것입니다.</p>
<p>제가 파이썬에서 초급자가 하기 좋은 25가지 프로젝트 튜토리얼 목록을 생성하였습니다.</p>
<p>튜토리얼에 대한 저의 조언은 비디오를 보고 프로젝트를 만들어서 그것을 분해하고 여러분만의 방식으로 다시 만드는 것입니다. 새로운 기능을 추가하거나 다른 방법을 사용해 보세요.</p>
<p>그렇게 하면 당신이 정말로 개념을 이해했는지 확인할 수 있습니다.</p>
<p>아래 나열된 프로젝트 목록 중 어떤 것을 클릭하면 상세 해당 영역으로 이동할 수 있습니다.</p>
<p>만약 파이썬 기초에 익숙하지 않다면 <a href="https://www.youtube.com/watch?v=rfscVS0vtbw">여기 freeCodeCamp의 파이썬 튜토리얼 초급편</a>을 보세요.</p>
<h3 id="">만들 수 있는 파이썬 프로젝트 목록</h3>
<ol>
<li><a href="#example01">매드 립스(Mad Libs)</a></li>
<li><a href="#example02">숫자 맞추기 게임 (컴퓨터)</a></li>
<li><a href="#example03">숫자 맞추기 게임 (사용자)</a></li>
<li><a href="#example04">가위 바위 보</a></li>
<li><a href="#example05">행맨(Hangman)</a></li>
<li><a href="#example06">카운트다운 타이머</a></li>
<li><a href="#example07">암호 생성기</a></li>
<li><a href="#example08">QR 코드 인코더 / 디코더</a></li>
<li><a href="#example09">틱택토(Tic-Tac-Toe)</a></li>
<li><a href="#example10">틱택토(Tic-Tac-Toe) AI</a></li>
<li><a href="#example11">이진 검색(Binary Search)</a></li>
<li><a href="#example12">지뢰제거기</a></li>
<li><a href="#example13">스도쿠 풀기</a></li>
<li><a href="#example14">파이썬으로 사진 조작</a></li>
<li><a href="#example15">마르코프 체인(Markov Chain) 텍스트 작성기</a></li>
<li><a href="#example16">퐁(Pong)</a></li>
<li><a href="#example17">뱀(Snake)</a></li>
<li><a href="#example18">커넥트 4(Connect Four)</a></li>
<li><a href="#example19">테트리스</a></li>
<li><a href="#example20">온라인 멀티플레이어 게임</a></li>
<li><a href="#example21">웹 스크래핑 프로그램</a></li>
<li><a href="#example22">대량 파일 이름 변경</a></li>
<li><a href="#example23">날씨 프로그램</a></li>
<li><a href="#example24">파이썬으로 디스코드 봇 코딩 - 클라우드에서 무료로 호스트</a></li>
<li><a href="#example25">우주 침략자 게임</a></li>
</ol>
<h3 id="h3idexample01madlibsh3"></h3><h3 id="example01">매드 립스(Mad Libs)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=100s">Kylie Ying의 튜토리얼</a>에서는 사용자 입력값을 얻는 것과 f-문자열(f-strings)을 다루는 것, 그리고 콘솔에 출력된 결과값을 보는 방법에 대해 배울 것입니다.</p>
<p>이것은 파이썬에서 문자열 연결을 하는 일을 익숙하게 하는 좋은 시작 프로젝트입니다.</p>
<h3 id="h3idexample02h3"></h3><h3 id="example02">숫자 맞추기 게임 (컴퓨터)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=414s">Kylie Ying의 튜토리얼</a>에서 <a href="https://docs.python.org/3/library/random.html">파이썬 랜덤 모듈(random module)</a>을 다루거나 함수를 만들고 while문과 조건문을 다룬다든지 사용자 입력값을 받는 방법에 대해 배울 것입니다.</p>
<h3 id="h3idexample03h3"></h3><h3 id="example03">숫자 맞추기 게임 (사용자)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=797s">Kylie Ying의 튜토리얼</a>에서 컴퓨터가 정확한 숫자를 맞춰야 하는 숫자 맞추기 게임을 만들 것입니다. <a href="https://docs.python.org/3/library/random.html">파이썬 랜덤 모듈(random module)</a>을 다루거나 함수를 만들고 while문과 조건문을 다룬다든지 사용자 입력값을 받는 일을 할 것입니다.</p>
<h3 id="h3idexample04h3"></h3><h3 id="example04">가위 바위 보</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=1274s">Kylie Ying의 튜토리얼</a>에서 <code>random.choice()</code>와 if문을 다루고, 사용자 입력값을 받는 일을 할 것입니다. 이것은 조건문이나 함수와 같은 기초를 다지는데 도움이 되는 좋은 프로젝트입니다.</p>
<h3 id="h3idexample05hangmanh3"></h3><h3 id="example05">행맨(Hangman)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=1465s">Kylie Ying의 튜토리얼</a>에서 딕셔너리(dictionaries), 리스트(list), 중첩 조건문(nested if statements)을 다루는 법을 배울 것입니다. 또한 문자열과 파이썬 랜덤 모듈(random modules)를 다루는 법도 배울 것입니다.</p>
<h3 id="h3idexample06h3"></h3><h3 id="example06">카운트다운 타이머</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=1992s">Code With Tomi 튜토리얼</a>에서 파이썬 <code>time</code> 모듈을 사용하여 카운트다운 타이머를 만드는 법을 배울 것입니다. 이것은 파이썬에서 while문을 다루는데 익숙하게 하는 좋은 시작 프로젝트입니다.</p>
<h3 id="h3idexample07h3"></h3><h3 id="example07">비밀번호 생성기</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=2531s">Code With Tomi 튜토리얼</a>에서 랜덤 비밀번호 생성기를 만드는 법을 배울 것입니다. 사용자로부터 비밀번호에 들어갈 숫자와 길이에 대한 데이터를 받아서 랜덤 문자가 들어간 비밀번호 모음을 출력할 것입니다.</p>
<p>이 프로젝트는 <code>for loop</code>와 <code>random</code> 파이썬 모듈을 다루는 연습을 더 많이 제공할 것입니다.</p>
<h3 id="h3idexample08qrh3"></h3><h3 id="example08">QR 코드 인코더 / 디코더</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=3192s">Code With Tomi 튜토리얼</a>에서 나만의 QR 코드를 만들고 부호화(encode)/해독(decode)하는 법을 배울 것입니다. 이 프로젝트는 <code>qrcode</code> 라이브러리를 사용합니다.</p>
<p>이것은 입문자가 다른 파이썬 모듈을 다루고 설치하는 것을 익숙하게 하는 좋은 프로젝트입니다.</p>
<h3 id="h3idexample09tictactoeh3"></h3><h3 id="example09">틱택토(Tic-Tac-Toe)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=2153s">Kylie Ying의 튜토리얼</a>에서 커맨드 라인으로 다양한 플레이어와 함께하는 틱택토 게임을 만드는 법을 배울 것입니다. 파이썬의 <code>time</code>, <code>math</code> 모듈을 다루는 법을 배우면서 중첩 조건문(nested if statements) 연습을 이어서 하게 될 것입니다.</p>
<h3 id="h3idexample10tictactoeaih3"></h3><h3 id="example10">틱택토(Tic-Tac-Toe) AI</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=3599s">Kylie Ying의 튜토리얼</a>에서 컴퓨터가 절대 지지 않는 틱택토 게임을 만드는 법을 배울 것입니다. 이 프로젝트는 의사 결정을 위해 사용되는 재귀 알고리즘인 미니맥스(minimax, 번역가 주: 추정되는 최대 손실을 최소화 하는 기법) 알고리즘을 활용합니다.</p>
<h3 id="h3idexample11binarysearchh3"></h3><h3 id="example11">이진 검색(Binary Search)</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=4553s">Kylie Ying의 튜토리얼</a>에서 이진 검색(binary search)라고 불리는 분할 정복(divide and conquer) 알고리즘을 구현하는 법을 배울 것입니다. 이것은 구직 면접에 자주 나오는 검색 알고리즘이기 때문에 코드로 어떻게 구현하는지를 아는 것이 중요합니다.</p>
<h3 id="h3idexample12h3"></h3><h3 id="example12">지뢰제거기</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=5236s">Kylie Ying의 튜토리얼</a>에서 고전 지뢰제거기 게임을 커맨드 라인에 만들 것입니다. 이 프로젝트는 반복문과 클래스에 초점을 맞춥니다.</p>
<h3 id="h3idexample13h3"></h3><h3 id="example13">스도쿠 문제 해결 프로그램</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=6715s">Kylie Ying의 튜토리얼</a>에서 역추적(backtracking) 기술을 활용한 스도쿠 문제 해결 프로그램을 만드는 법을 배울 것입니다. 역추적은 문제를 해결하기 위해 모든 가능한 조합을 검색하는 재귀 기술입니다.</p>
<h3 id="h3idexample14h3"></h3><h3 id="example14">파이썬으로 사진 조작</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=7534s">Kylie Ying의 튜토리얼</a>에서 이미지 필터를 생성하여 사진의 명도와 밝기, 흐림 효과(blur)를 변경하는 법을 배울 것입니다. 프로젝트를 시작하기 전에 <a href="https://github.com/kying18/pyphotoshop">시작 파일들</a>을 다운받아야 합니다.</p>
<h3 id="h3idexample15markovchainh3"></h3><h3 id="example15">마르코프 체인(Markov Chain) 텍스트 작곡가</h3>
<p><a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=9109s">Kylie Ying의 튜토리얼</a>에서 마르코프 체인(Markov Chain) 그래프 모델에 대해 배우고 노래 가사 관계에 어떻게 적용될 수 있는지 배울 것입니다. 이 프로젝트는 파이썬으로 인공 지능을 시작하는데 좋습니다.</p>
<h3 id="h3idexample16pongh3"></h3><h3 id="example16">퐁(Pong)</h3>
<p><a href="https://www.youtube.com/watch?v=XGf2GcyHPhc&amp;t=78s">Christian Thompson의 튜토리얼</a>에서 파이썬으로 고전 퐁(pong) 게임을 재현하는 법을 배울 것입니다. 게임용 그래픽을 생성하는데 뛰어난 <code>os</code>와 <code>turtle</code> 파이썬 모듈을 사용하게 될 것입니다.</p>
<h3 id="h3idexample17snakeh3"></h3><h3 id="example17">뱀(Snake)</h3>
<p><a href="https://www.youtube.com/watch?v=XGf2GcyHPhc&amp;t=2736s">Tech with Tim 튜토리얼</a>에서 파이썬으로 고전 뱀(snake) 게임을 재현하는 법을 배울 것입니다. 이 프로젝트는 객체 지향 프로그래밍을 사용하고 게임을 만드는데 대중적인 파이썬 모듈인 Pygame을 사용합니다.</p>
<h3 id="h3idexample184connectfourh3"></h3><h3 id="example18">커넥트 4(Connect Four)</h3>
<p><a href="https://www.youtube.com/watch?v=XGf2GcyHPhc&amp;t=5697s">Keith Galli 튜토리얼</a>에서 고전 커넥트 4(connect four) 게임을 만드는 법을 배울 것입니다. 이 프로젝트는 <code>numpy</code>, <code>math</code>, <code>pygame</code>, 그리고 <code>sys</code> 파이썬 모듈을 활용합니다.</p>
<p>이 프로젝트는 이전에 몇 가지 작은 입문자용 파이썬 프로젝트를 만들었을 때 좋습니다. 어떠한 파이썬 프로젝트를 하지 않았다면 목록에 앞서 언급한 프로젝트들 중 하나를 시작하고 나서 이것을 작업하길 추천합니다.</p>
<h3 id="h3idexample19h3"></h3><h3 id="example19">테트리스</h3>
<p><a href="https://www.youtube.com/watch?v=XGf2GcyHPhc&amp;t=9756s">Tech with Tim 튜토리얼</a>에서 고전 테트리스 게임을 재현하는 법을 배울 것입니다. 이 프로젝트는 Pygame을 활용하고 초보 개발자들이 다음 단계로 실력을 끌어올리는데 좋습니다.</p>
<h3 id="h3idexample20h3"></h3><h3 id="example20">온라인 멀티플레이어 게임</h3>
<p><a href="https://www.youtube.com/watch?v=XGf2GcyHPhc&amp;t=15732s">Tech with Tim 튜토리얼</a>에서 전 세계 어느 누구와 함께 플레이 할 수 있는 온라인 멀티플레이어 게임을 만드는 법을 배울 것입니다. 이 프로젝트는 소켓과 네트워킹, Pygame을 다루는데 좋은 입문 단계입니다.</p>
<h3 id="h3idexample21h3"></h3><h3 id="example21">웹 스크래핑 프로그램</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=37s">Code With Tomi 튜토리얼</a>에서 웹 스크래핑을 통해 사용자에게 깃허브(GitHub) 사용자 링크를 입력으로 받아 프로필 이미지 링크를 출력하는 법을 배우게 될 것입니다. 웹 스크래핑이란 웹 페이지에서 데이터를 수집하는 기술입니다.</p>
<h3 id="h3idexample22h3"></h3><h3 id="example22">대량 파일 이름 변경</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=833s">Code With Tomi 튜토리얼</a>에서 내 컴퓨터 어느 폴더에 접속하여 파이썬 코드에 적힌 조건들에 따라 파일 이름을 바꾸는 프로그램을 만드는 법을 배우게 될 것입니다.</p>
<h3 id="h3idexample23h3"></h3><h3 id="example23">날씨 프로그램</h3>
<p><a href="https://www.youtube.com/watch?v=SqvVm3QiQVk&amp;t=1494s">Code With Tomi 튜토리얼</a>에서 사용자의 데이터를 특정 위치에 따라 수집하여 제공된 위치에 따른 날씨 상세 정보를 출력하는 프로그램을 만드는 법을 배우게 될 것입니다. 이것은 API에서 데이터를 받아오는 법을 배우는 것을 시작하는데 좋은 프로젝트입니다.</p>
<h3 id="h3idexample24both3"></h3><h3 id="example24">파이썬으로 디스코드 봇(bot) 코딩 - 클라우드에서 무료로 호스트</h3>
<p><a href="https://www.youtube.com/watch?v=SPTfmiYiuok">Beau Carnes 튜토리얼</a>에서 사람들이 온라인 상에서 함께 어울리고 대화할 수 있는 플랫폼인 디스코드(Discord)에서 당신만의 봇(bot)을 만드는 법을 배우게 될 것입니다. 이 프로젝트는 Discord API와 Replit IDE를 사용해 작업하는 법을 가르쳐 줄 것입니다.</p>
<p>이 비디오가 공개된 후 Replit은 프로그램에 환경 변수를 저장하는 방법을 변경했습니다. Replit에 환경 변수를 올바르게 저장하는 방법에 대한 <a href="https://forum.freecodecamp.org/t/steps-on-how-to-setup-environment-variable-for-fcc-python-bot-tutorial/473303">튜토리얼</a>을 읽어보세요.</p>
<h3 id="h3idexample25h3"></h3><h3 id="example25">우주 침략자 게임</h3>
<p><a href="https://www.youtube.com/watch?v=FfWpgLFMI7w">buildwithpython 튜토리얼</a>에서 Pygame을 이용해 우주 침략자 게임을 만드는 법을 배우게 될 것입니다. 게임 루프(loops), 충돌 감지, 키 입력 이벤트 등과 같이 게임 개발에서 기본적인 많은 것들을 배우게 될 것입니다.</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬 if __name__ == __main__ 을 코드 예제로 설명 ]]>
                </title>
                <description>
                    <![CDATA[ 파이썬 인터프리터(interpreter)가 파이썬 파일을 읽을 때 몇 가지 특별 변수를 먼저 설정합니다. 그리고나서 파일의 코드를 실행합니다. 특별 변수 중 하나는 __name__이라고 합니다. 이 글을 순서대로 따라서 코드 문단을 읽어본다면 if __name__ == "__main__"를 어떻게 사용하고 이것이 왜 중요한지 배우게 될 것입니다. 파이썬 모듈 설명 파이썬 파일은 모듈을 호출하는데 .py 파일 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/untitled-2/</link>
                <guid isPermaLink="false">63d82ec341a99b065fb5aad2</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Wed, 01 Feb 2023 09:25:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/01/5f9c99de740569d1a4ca2229.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/if-name-main-python-example/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python if __name__ == __main__ Explained with Code Examples</a>
      </p><!--kg-card-begin: markdown--><h4 id="interpreter">파이썬 인터프리터(interpreter)가 파이썬 파일을 읽을 때 몇 가지 특별 변수를 먼저 설정합니다. 그리고나서 파일의 코드를 실행합니다.</h4>
<p>특별 변수 중 하나는 <code>__name__</code>이라고 합니다.</p>
<p>이 글을 순서대로 따라서 코드 문단을 읽어본다면 <code>if __name__ == "__main__"</code>를 어떻게 사용하고 이것이 왜 중요한지 배우게 될 것입니다.</p>
<h2 id="">파이썬 모듈 설명</h2>
<p>파이썬 파일은 모듈을 호출하는데 <code>.py</code> 파일 확장자에 의해 식별됩니다. 하나의 모듈은 함수와 클래스, 변수를 정의할 수 있습니다.</p>
<p>그래서 인터프리터가 모듈을 메인 프로그램에서 실행한다면 <code>__name__</code> 변수는 <code>__main__</code>으로 설정될 것입니다.</p>
<p>하지만 코드가 다른 모듈로부터 모듈을 불러오고 있다면 <code>__name__</code> 변수는 그 모듈의 이름대로 설정될 것입니다.</p>
<p>예제를 살펴봅시다. <code>file_one.py</code>라는 이름으로 파이썬 모듈을 생성하고 그 안에 아래 코드를 붙여넣으세요:</p>
<pre><code># Python file one module

print("File one __name__ is set to: {}" .format(__name__))
</code></pre>
<h6 align="center">file_one.py</h6>
<p>이 파일을 실행하면 우리가 이야기하던 것이 무엇인지 정확히 보게 될 것입니다. 이 모듈의 변수 <code>__name__</code>은 <code>__main__</code>으로 설정됩니다:</p>
<pre><code>File one __name__ is set to: __main__
</code></pre>
<p>이제 <code>file_two.py</code>라는 이름으로 다른 파일을 더하고 그 안에 아래 코드를 붙여넣으세요:</p>
<pre><code># Python module to import

print("File two __name__ is set to: {}" .format(__name__))
</code></pre>
<h6 align="center">file_two.py</h6>
<p>또한 <code>file_one.py</code> 안의 코드를 아래와 같이 수정하여 우리가 <code>file_two.py</code> 모듈을 불러올 수 있도록 하세요:</p>
<pre><code># Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))
</code></pre>
<h6 align="center">file_one.py</h6>
<p><code>file_one</code> 코드를 다시 실행하면 <code>file_one</code>안에 있던 <code>__name__</code> 변수가 바뀌지 않고 여전히 <code>__main__</code>으로 설정되어 남아있는 것을 보여줄 것입니다. 그러나 이제 <code>file_two</code>안에 있던 <code>__name__</code> 변수가 모듈 이름, 즉 <code>file_two</code>로 설정되었습니다.</p>
<p>결과는 아래와 같아 보여야 합니다:</p>
<pre><code>File two __name__ is set to: file_two
File one __name__ is set to: __main__
</code></pre>
<p>하지만 <code>file_two</code>를 직접 실행하면 그 이름이 <code>__main__</code>으로 설정된 것을 보게 될 것입니다:</p>
<pre><code>File two __name__ is set to: __main__
</code></pre>
<p>실행하는 파일/모듈을 위한 변수 <code>__name__</code>은 항상 <code>__main__</code>으로 될 것입니다. 그러나 모든 다른 모듈에서 불러들여지는 <code>__name__</code> 변수는 그 자신의 모듈 이름으로 설정될 것입니다.</p>
<h2 id="">파이썬 파일 이름을 정하는 관습</h2>
<p>일반적으로 <code>__name__</code>과 <code>__main__</code>을 사용하는 방법은 아래와 같이 보입니다:</p>
<pre><code>if __name__ == "__main__":
   Do something here

</code></pre>
<p>이것이 실제로 동작하는 법을 보고 해당 변수들을 실제로 어떻게 사용할지 봅시다.</p>
<p><code>file_one</code>과 <code>file_two</code>를 아래와 같이 수정하세요:</p>
<p><code>file_one</code>:</p>
<pre><code># Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
</code></pre>
<h6 align="center">file_one.py</h6>
<p><code>file_two</code>:</p>
<pre><code># Python module to import

print("File two __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
</code></pre>
<h6 align="center">file_two.py</h6>
<p>다시 <code>file_one</code>을 실행하면 프로그램이 두개의 모듈 중 어느 것이 <code>__main__</code>인지 인식하고 우리의 첫번째 <code>if else</code>문에 따라 코드를 실행하는 것을 보게 될 것입니다.</p>
<p>결과는 아래와 같아 보여야 합니다:</p>
<pre><code>File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
</code></pre>
<p>이제 <code>file_two</code>를 실행하여 <code>__name__</code>변수가 <code>__main__</code>으로 설정된 것을 보게 될 것입니다:</p>
<pre><code>File two __name__ is set to: __main__
File two executed when ran directly
</code></pre>
<p>이와 같은 모듈을 불러와서 실행할 때는 그 안의 함수들을 불러오게 되고 최상단 코드가 실행될 것입니다.</p>
<p>이 과정이 실행되는 것을 보기 위해, 파일을 아래와 같이 수정하세요:</p>
<p><code>file_one</code>:</p>
<pre><code># Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
</code></pre>
<h6 align="center">file_one.py</h6>
<p><code>file_two</code>:</p>
<pre><code># Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
</code></pre>
<h6 align="center">file_two.py</h6>
<p>이제 함수들이 읽혀졌을 테지만 실행되진 않았습니다.</p>
<p>이들 함수들 중 하나를 실행하기 위해서 <code>file_one</code>의 <code>if __name__ == "__main__"</code> 부분을 아래와 같이 보이게 수정하세요:</p>
<pre><code>if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
else:
   print("File one executed when imported")
</code></pre>
<p><code>file_one</code>을 실행하면 아래와 같은 것을 보게 될 것입니다:</p>
<pre><code>File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed
</code></pre>
<p>또한 불러온 파일에서 함수를 실행할 수도 있습니다. 이를 위해서 <code>file_one</code>의 <code>if __name__ == "__main__"</code> 부분을 아래와 같이 보이게 수정하세요:</p>
<pre><code>if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   file_two.function_three()
else:
   print("File one executed when imported")
</code></pre>
<p>그러면 아래와 같은 결과를 기대할 수 있습니다:</p>
<pre><code>File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed
Function three is executed
</code></pre>
<p>(우리는 2개를 사용하고 있지만) 만약 <code>file_two</code> 모듈이 정말 많은 함수들을 가지고 있어 파일이 크고 우리가 그 모든 것들을 불러오고 싶지는 않다고 해 봅니다. <code>file_two</code>를 아래와 같이 보이게 수정하세요:</p>
<pre><code># Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

def function_four():
   print("Function four is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
</code></pre>
<h6 align="center">file_two.py</h6>
<p>그리고 해당 모듈에서 특정한 함수를 불러오기 위해서 <code>file_one</code> 안에 <code>from</code> 불러오기(import) 단락을 사용하세요:</p>
<pre><code># Python module to execute
from file_two import function_three

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   function_three()
else:
   print("File one executed when imported")
</code></pre>
<h6 align="center">file_one.py</h6>
<h2 id="">결론</h2>
<p>어떤 파일을 메인 프로그램으로 실행할 수 있는지 또는 다른 모듈에 의해 불러오게 할 것인지에 따라 <code>__name__</code> 변수를 위한 정말 좋은 활용 사례가 있습니다. 우리는 모듈들을 불러올 때 코드 일부분들을 실행하게 허용하거나 막기 위해서 <code>if __name__ == "__main__"</code>을 사용할 수 있습니다.</p>
<p>파이썬 인터프리터가 파일을 읽을 때 <code>__name__</code> 변수는 해당 모듈이 실행된다면 <code>__main__</code>으로 설정되고 해당 모듈을 불러오는 것이라면 모듈의 이름으로 설정됩니다. 파일을 읽으면 모든 상위 레벨 코드를 실행되지만 함수와 클래스들은 (불러와지기만 할 뿐이라) 실행되지 않습니다.</p>
<p>Bra gjort! (스웨덴어로 "아주 잘했다"를 의미합니다!)</p>
<p>이와 같은 글이 저의 <a href="https://www.freecodecamp.org/news/author/goran/">freeCodeCamp 프로필</a>과 <a href="https://medium.com/@goranaviani">Medium 프로필</a>에 더 많이 있고 <a href="https://github.com/GoranAviani">깃허브(GitHub) 페이지</a>에는 만들어둔 다른 재미있는 것들이 있으니 확인해 보세요.</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬 List .remove() - 파이썬 리스트에서 항목을 제거하는 방법 ]]>
                </title>
                <description>
                    <![CDATA[ 이 글에서는 파이썬 내장 함수 remove() list 메소드를 사용하는 법을 배우게 될 것입니다. 마지막에 이르면 파이썬에서 리스트 안에 항목을 제거하기 위해 remove()를 사용하는 법을 알게 될 것입니다. 우리가 다룰 내용들은:  1. remove() 메소드의 문법(syntax)  2. remove()를 사용하여 리스트의 구성요소를 제거  3. remove()는 어떤 항목의 첫번째 발생 경우만 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/paisseon-list-remove-paisseon-baeyeoleseo-hangmogeul-jegeohaneun-bangbeob/</link>
                <guid isPermaLink="false">63d42abc7a7b73070e797263</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Sat, 28 Jan 2023 22:50:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/01/pexels-pavel-danilyuk-5496463.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-list-remove-how-to-remove-an-item-from-a-list-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python List .remove() - How to Remove an Item from a List in Python</a>
      </p><!--kg-card-begin: markdown--><h3 id="removelist">이 글에서는 파이썬 내장 함수 <code>remove()</code> list 메소드를 사용하는 법을 배우게 될 것입니다.</h3>
<p>마지막에 이르면 파이썬에서 리스트 안에 항목을 제거하기 위해 <code>remove()</code>를 사용하는 법을 알게 될 것입니다.</p>
<p>우리가 다룰 내용들은:</p>
<ol>
<li><code>remove()</code> 메소드의 문법(syntax)</li>
<li><code>remove()</code>를 사용하여 리스트의 구성요소를 제거</li>
<li><code>remove()</code>는 어떤 항목의 첫번째 발생 경우만 삭제; 어떤 항목이 발생하는 모든 경우를 제거하는 방법</li>
</ol>
<h2 id="remove"><code>remove()</code> 메소드 - 문법 개요</h2>
<p><code>remove()</code> 메소드는 파이썬에서 리스트 안에 항목을 제거할 수 있는 방법 중 하나입니다.</p>
<p><code>remove()</code> 메소드는 리스트에서 항목을 <strong>값</strong>으로 삭제하며, 인덱스 번호로는 삭제하지 않습니다.</p>
<p><code>remove()</code> 메소드의 일반적인 문법(syntax)는 아래와 같습니다:</p>
<pre><code>list_name.remove(value)
</code></pre>
<p>구체적으로 살펴보면:</p>
<ul>
<li><code>list_name</code>은 작업하고자하는 리스트 이름입니다.</li>
<li><code>remove()</code>는 파이썬에 내장된 리스트 메소드 중 하나입니다.</li>
<li><code>remove()</code>는 하나의 <strong>필수</strong> 인수(argument)를 받습니다. 이를 제공하지 않으면 <code>TypeError</code>를, 구체적으로는<code>TypeError: list.remove() takes exactly one argument (0 given) </code>를 받게 됩니다.</li>
<li><code>value</code>는 <code>list_name</code>에서 제거하고 싶은 항목의 특정 값입니다.</li>
</ul>
<p><code>remove()</code> 메소드는 제거된 값을 반환하지 않고 그 대신 반환 값이 없다는 뜻의 <code>None</code>을 반환합니다.</p>
<p>인덱스 번호를 통해 항목을 삭제해야 하거나 어떤 이유로든 제거된 값을 반환 (저장)하고 싶다면 <a href="https://www.freecodecamp.org/news/python-pop-how-to-pop-from-a-list-or-an-array-in-python/"><code>pop()</code> 메소드</a>를 대신 사용하세요.</p>
<h2 id="remove">파이썬에서 <code>remove()</code> 메소드를 사용해 리스트에서 구성요소를 삭제하는 방법</h2>
<p><code>remove()</code> 메소드를 사용해 리스트에서 구성요소를 삭제하기 위해서는 해당 구성요소의 값을 특정하고 메소드에 인자로 넘기면 됩니다.</p>
<p><code>remove()</code>는 그 값을 찾기 위해 리스트을 검색하고 값을 삭제할 것입니다.</p>
<pre><code class="language-{python}">#original list
programming_languages = ["JavaScript", "Python", "Java", "C++"]

#print original list
print(programming_languages)

# remove the value 'JavaScript' from the list
programming_languages.remove("JavaScript")

#print updated list
print(programming_languages)

#output

#['JavaScript', 'Python', 'Java', 'C++']
#['Python', 'Java', 'C++']
</code></pre>
<p>만약 리스트 안에 포함되어 있지 않은 값을 특정한다면 에러를 - 구체적으로는 <code>ValueError</code>를 받을 것입니다:</p>
<pre><code class="language-{python}">programming_languages = ["JavaScript", "Python", "Java", "C++"]

#I want to remove the value 'React'
programming_languages.remove("React")

#print list
print(programming_languages)

#output

# line 5, in &lt;module&gt;
#programming_languages.remove("React")
#ValueError: list.remove(x): x not in list
</code></pre>
<p>에러가 발생하는 것을 방지하기 위해 첫번째로 할 수 있는 일은 <code>in</code> 키워드를 사용하여 리스트 안에 삭제하고자 하는 해당 값으로 시작하는 항목이 있는지 확인하는 것입니다.</p>
<p>논리 값(Boolean value) - 리스트 안에 항목이 있다면 <code>True</code>를, 해당 값이 리스트 안에 없다면 <code>False</code>를 반환할 것입니다.</p>
<pre><code class="language-{python}">programming_languages = ["JavaScript", "Python", "Java", "C++"]

#check if 'React' is in the 'programming_languages' list
print("React" in programming_languages)

#output
#False
</code></pre>
<p>에러를 방지하기 위한 다른 방법은 조건문을 생성해서 "만약 이 값이 리스트 안에 있으면 삭제하라. 존재하지 않으면 리스트 안에 포함되어 있지 않다고 말하는 메세지를 보여라"고 할 수 있습니다.</p>
<pre><code class="language-{python}">programming_languages = ["JavaScript", "Python", "Java", "C++"]

if "React" in programming_languages:
    programming_languages.remove("React")
else:
    print("This value does not exist")

#output
#This value does not exist
</code></pre>
<p>이제 존재하지 않는 특정한 값을 삭제하려다 파이썬 에러를 얻는 대신 작업하고 있는 리스트 안에 삭제하고 싶은 항목이 없다고 말하는 메세지를 돌려 받을 것입니다.</p>
<h2 id="remove"><code>remove()</code> 메소드는 어떤 항목의 첫번째 발생 경우만 제거</h2>
<p><code>remove()</code> 메소드를 사용할 때 유념해야 할 것은 어떤 항목의 <strong>첫번째*</strong> 발생 경우만 검색하고 삭제할 것이라는 점입니다.</p>
<p>이것은 메소드 인자로 넘긴 값을 가진 항목이 리스트 안에 하나 이상 존재한다면 첫번째 발생 경우만 삭제될 것을 의미합니다.</p>
<p>아래 예제를 살펴봅시다:</p>
<pre><code class="language-{python}">programming_languages = ["JavaScript", "Python", "Java", "Python", "C++", "Python"]

programming_languages.remove("Python")

print(programming_languages)

#output
#['JavaScript', 'Java', 'Python', 'C++', 'Python']
</code></pre>
<p>위의 코드에서 리스트 안에 <code>Python</code>이라는 값을 가진 항목은 세 차례 나타납니다.</p>
<p><code>remove()</code>가 사용되었을 때 첫번째 일치하는 인스턴스(instance)만 삭제됩니다 - <code>JavaScript</code> 값 다음에 나오고 <code>Java</code> 값 앞에 있던 것 말입니다.</p>
<p>나머지 두 번의 <code>Python</code> 발생들은 리스트 안에 그대로 있습니다.</p>
<p>만약 어떤 항목이 발생하는 모든 경우를 제거하고 싶으면 어떻게 할까요?</p>
<p>다시 말하자면 특정한 항목의 첫번째 인스턴스만을 삭제하고 싶지 않을 경우도 있을 수 있습니다. 그리고 이것은 <code>remove()</code> 단독으로 사용해서는 이룰 수 없습니다</p>
<h2 id="">파이썬 리스트 안에 어떤 항목에 해당하는 모든 인스턴스를 제거하는 방법</h2>
<p>리스트 안에 어떤 항목에 해당하는 모든 인스턴스를 제거하는 방법 중 하나는 리스트 축약(list comprehension)을 활용하는 것입니다.</p>
<p>리스트 축약이란 존재하고 있는 리스트로부터 새로운 리스트을 생성하거나 부분리스트(sublist)을 생성하는 것입니다.</p>
<p>이는 원본 리스트을 수정하지 않지만 설정한 조건을 만족하는 새로운 것을 대신 생성하게 될 것입니다.</p>
<pre><code class="language-{python}">#original list
programming_languages = ["JavaScript", "Python", "Java", "Python", "C++", "Python"]

#sublist created with list comprehension
programming_languages_updated = [value for value in programming_languages if value != "Python"]


#print original list
print(programming_languages)

#print  new sublist that doesn't contain 'Python'
print(programming_languages_updated)

#output

#['JavaScript', 'Python', 'Java', 'Python', 'C++', 'Python']
#['JavaScript', 'Java', 'C++']
</code></pre>
<p>위의 예제에서 원본 리스트 <code>programming_languages</code>이 있습니다.</p>
<p>그리고 새로운 리스트(또는 부분리스트)이 반환되었습니다.</p>
<p>부분리스트 안에 포함된 항목들은 조건을 만족해야만 합니다. 조건은 '원본 리스트 안에 <code>Python</code>이라는 값이 있는 항목이 있으면' 부분리스트에 일부가 되지 않는다는 것입니다.</p>
<p>이번에는 새로운 리스트을 만들고 싶지 않지만 대신 기존에 존재하던 리스트을 *대체(in-place)*하고 싶다고 해 본다면, 리스트 축약에 슬라이스(slice) 지정을 합하여 사용하세요.</p>
<p>슬라이스 지정이 되어 있을 때 리스트에서 특정 부분 (또는 슬라이스)를 수정하고 교체할 수 있습니다.</p>
<p>전체 리스트을 교체하기 위해서는 슬라이스 문법(slicing syntax) <code>[:]</code>를 리스트 축약과 같이 사용하세요.</p>
<p>리스트 축약은 <code>Python</code>이라는 값을 가진 어떤 항목이라도 더 이상 리스트 안에 자리할 수 없다는 조건을 설정합니다.</p>
<pre><code class="language-{python}">programming_languages = ["JavaScript", "Python", "Java", "Python", "C++", "Python"]

programming_languages[:] = (value for value in programming_languages if value != "Python")

print(programming_languages)

#output

#['JavaScript', 'Java', 'C++']
</code></pre>
<h2 id="">결론</h2>
<p>완성했어요! 파이썬에서 <code>remove()</code> 메소드를 사용하여 리스트 항목을 삭제하는 방법을 알게 되었습니다. 또한 파이썬에서 리스트 안에 어떤 항목에 해당하는 모든 인스턴스를 제거하는 몇 가지 방법을 보았습니다.</p>
<p>이 글이 유용하면 좋겠네요.</p>
<p>파이썬 프로그래밍 언어에 대해 더 배우기 위해서는 freeCodeCamp의 <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/">Scientific Computing with Python Certification</a>을 확인하세요.</p>
<p>기초부터 시작해서 상호작용하며 초급자 친화적인 방법으로 배우게 될 것입니다. 또한 마지막에는 실습에서 5개의 프로젝트를 완성하여 배운 것을 보충하게 될 것입니다.</p>
<p>읽어주셔서 감사하고 코딩 재밌게 하세요 😊!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 파이썬 문자열에서 문자 삭제하기 – How to Delete Characters from Strings ]]>
                </title>
                <description>
                    <![CDATA[ 파이썬에서는 문자열(string)에서 제거하고 싶은 어떤 문자(characters)를 특정하고 새로 수정된 문자열 결과를 반환하기 위해  replace()와 translate() 메소드를 사용할 수 있습니다. 문자열은 변경할 수 없는 속성을 가지기 때문에 기존 문자열은 수정되지 않을 것임을 기억하는 게 중요합니다. 이 글에서는 코드 예제들을 사용하여 replace()와 translate() 메소드를 사용하는 법을 보여줄 것입니다. 파이썬 replace() 메소드 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/paisseon-munjayeoleseo-munja-sagjehagi-how-to-delete-characters-from-strings/</link>
                <guid isPermaLink="false">63b13a3cea0d15062eda2086</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaeyoon Kim ]]>
                </dc:creator>
                <pubDate>Sat, 28 Jan 2023 22:49:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2023/01/fotis-fotopoulos-LJ9KY8pIH3E-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-remove-character-from-a-string-how-to-delete-characters-from-strings/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Remove Character from a String – How to Delete Characters from Strings</a>
      </p><!--kg-card-begin: markdown--><h3 id="stringcharactersreplacetranslate">파이썬에서는 문자열(string)에서 제거하고 싶은 어떤 문자(characters)를 특정하고 새로 수정된 문자열 결과를 반환하기 위해 <code>replace()</code>와 <code>translate()</code> 메소드를 사용할 수 있습니다.</h3>
<p>문자열은 변경할 수 없는 속성을 가지기 때문에 기존 문자열은 수정되지 않을 것임을 기억하는 게 중요합니다.</p>
<p>이 글에서는 코드 예제들을 사용하여 <code>replace()</code>와 <code>translate()</code> 메소드를 사용하는 법을 보여줄 것입니다.</p>
<h2 id="replace">파이썬 replace() 메소드 사용하는 법</h2>
<p><code>replace()</code> 메소드의 기본 문법(syntax)는 이와 같습니다.</p>
<pre><code>str.replace(old_str, new_str[, optional_max])
</code></pre>
<p><code>old_str</code> 매개변수(parameter)는 교체하고 싶은 부분문자열을 의미합니다.</p>
<p><code>new_str</code> 매개변수는 새로 사용하고 싶은 부분문자열을 의미합니다.</p>
<p><code>optional_max</code> 매개변수는 교체할 부분문자열을 새로운 부분문자열로 최대 몇 번이나 변경할지 횟수를 의미합니다.</p>
<p><code>replace()</code>메소드의 반환 값은 기존 문자열을 복사하여 교체할 문자열을 새로운 문자열로 바꾼 것입니다.</p>
<h3 id="replace">파이썬 replace() 예제</h3>
<p>몇가지 예제들을 살펴보겠습니다.</p>
<p>첫번째 예제에서는 제 이름이 지정된 <code>developer</code>라는 문자열을 가지고 있습니다.</p>
<pre><code>developer = 'Jessica Wilkins'
</code></pre>
<p>저의 성을 지우고 싶다면 <code>replace()</code> 메소드를 이런 식으로 사용할 수 있습니다:</p>
<pre><code>developer.replace('Wilkins', '')
</code></pre>
<p>이것은 컴퓨터에게 문자열 <code>Wilkins</code>를 가지고 빈칸으로 교체하라고 말합니다.</p>
<p>결과값을 출력한다면 아래와 같이 얻게 될 것입니다:</p>
<pre><code>print(developer.replace('Wilkins', ''))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screen-Shot-2022-03-06-at-8.41.55-PM.png" alt="예제사진01" width="600" height="400" loading="lazy"></p>
<p>문자열은 변경할 수 없는 속성을 가지기 때문에 기존 문자열은 수정되지 않을 것임을 기억하는 게 중요합니다. <code>replace()</code> 메소드는 새로운 문자열을 반환할 것입니다.</p>
<p>다음 예제에서는 제 이름에서 문자 <code>s</code>를 삭제하길 원하는 횟수를 지정하기 위해 <code>optional_max</code> 매개변수를 사용하고 싶습니다.</p>
<pre><code>developer.replace('s', '', 2)
</code></pre>
<p>해당 코드 라인은 문자열 <code>Jessica Wilkins</code>에서 문자 <code>s</code>를 두 번만 삭제하라고 말합니다.</p>
<p>결과값을 출력한다면 아래와 같이 보일 것입니다:</p>
<pre><code>print(developer.replace('s', '', 2))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screen-Shot-2022-03-06-at-8.55.22-PM.png" alt="print(developer.replace('s', '', 2)) 코드가 실행 되어 Jessica Wilkins라는 문자열이 Jeica Wilkins가 된 결과 모습" width="600" height="400" loading="lazy"></p>
<h2 id="translate">파이썬 translate() 메소드 사용하는 방법</h2>
<p>문자열에서 문자를 제거하는 또다른 방법은 <code>translate()</code> 메소드를 사용하는 것입니다. 이 메소드는 각각의 문자에서 교체할 문자열을 번역 테이블(translation table)에 연결(map)하여 새로운 문자열로 번역한 것을 반환한 것입니다.</p>
<p>파이썬 <code>translate()</code> 메소드의 기본 문법(syntax)는 이와 같습니다.</p>
<pre><code>str.translate(table)
</code></pre>
<h3 id="translate">파이썬 translate() 예제</h3>
<p>translate() 메소드를 더 잘 이해하기 위해 몇가지 예제들을 살펴보겠습니다.</p>
<p>이번 예제에서는 <code>Jessica Wilkins</code>에서 문자 <code>i</code>에 해당하는 모든 경우를 삭제하고 싶습니다.</p>
<p>우리는 먼저 문자 <code>i</code>의 유니코드 포인트 값을 얻기 위해 파이썬 내장 함수 <code>ord()</code>를 이용해야 합니다. <code>ord()</code> 함수는 숫자값을 반환할 것입니다.</p>
<pre><code>ord('i')
</code></pre>
<p>테이블에서 우리는 <code>None</code> 값을 배정해 컴퓨터가 <code>i</code>를 공백으로 교체할 것을 알게 만들 필요가 있습니다.</p>
<pre><code>{ord('i'): None}
</code></pre>
<p>이제 <code>translate()</code> 메소드 안에 우리 테이블을 사용합니다.</p>
<pre><code>developer.translate({ord('i'): None})
</code></pre>
<p>결과값을 출력한다면 아래와 같이 보일 것입니다:</p>
<pre><code>developer = 'Jessica Wilkins'

print(developer.translate({ord('i'): None}))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screen-Shot-2022-03-06-at-10.24.52-PM.png" alt="print(developer.translate({ord('i'): None})) 코드가 실행 되어 Jessica Wilkins라는 문자열이 Jessca Wlkns가 된 결과 모습" width="600" height="400" loading="lazy"></p>
<p>다음 예제에서는 문자 <code>e</code>, <code>s</code>, <code>i</code>가 제거된 새로운 문자열을 반환하고 싶습니다. 이를 위해 우리는 우리의 테이블 매개변수에서 순환기(iterator)를 사용할 수 있습니다.</p>
<pre><code>{ord(letter): None for letter in 'esi'}
</code></pre>
<p>해당 코드 라인은 컴퓨터에게 <code>e</code>, <code>s</code>, <code>i</code>가 발생하는 모든 경우를 찾아서 <code>None</code>으로 교체하라고 말합니다.</p>
<p>결과값을 출력한다면 아래와 같이 보일 것입니다:</p>
<pre><code>developer = 'Jessica Wilkins'

print(developer.translate({ord(letter): None for letter in 'esi'}))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screen-Shot-2022-03-06-at-10.37.10-PM.png" alt="print(developer.translate({ord(letter): None for letter in 'esi'}))가 실행되어 Jessica Wilkins가 Jca Wlkn가 된 결과 모습" width="600" height="400" loading="lazy"></p>
<h2 id="">결론</h2>
<p>파이썬에서는 문자열(string)에서 제거하고 싶은 어떤 문자(characters)를 특정하고 새로 수정된 문자열 결과를 반환하기 위해 <code>replace()</code>와 <code>translate()</code> 메소드를 사용할 수 있습니다.</p>
<p>문자열은 변경할 수 없는 속성을 가지기 때문에 기존 문자열은 수정되지 않을 것임을 기억하는 게 중요합니다.</p>
<p><code>replace()</code> 메소드의 기본 문법(syntax)는 이와 같습니다.</p>
<pre><code>str.replace(old_str, new_str[, optional_max])
</code></pre>
<p><code>replace()</code>메소드의 반환 값은 기존 문자열을 복사하여 교체할 문자열을 새로운 문자열로 바꾼 것입니다.</p>
<p>문자열에서 문자를 제거하는 또다른 방법은 <code>translate()</code> 메소드를 사용하는 것입니다. 이 메소드는 각각의 문자에서 교체할 문자열을 번역 테이블(translation table)에 연결(map)하여 새로운 문자열로 번역한 것을 반환한 것입니다.</p>
<p>파이썬 <code>translate()</code> 메소드의 기본 문법(syntax)는 이와 같습니다.</p>
<pre><code>str.translate(table)
</code></pre>
<p>이 글을 재미있게 읽었길 바라고 당신의 파이썬 항해에 행운을 빌겠습니다.</p>
<!--kg-card-end: markdown--><p></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python에서 문자열과 변수 출력하는 방법 ]]>
                </title>
                <description>
                    <![CDATA[ Python은 유연하고 다목적으로 사용할 수 있는 프로그래밍 언어입니다. 보통 한 가지를 프로그래밍하기 위해 다양한 방법으로 작업을 수행할 수 있습니다. 이 튜토리얼에서는 문자열과 변수를 함께 출력할 수 있는 몇 가지 방법을 살펴보겠습니다. 그럼 시작해볼까요? Python에서 print() 함수 사용하기 Python에서 무언가를 출력하려면 print() 함수를 사용합니다. print 키워드 뒤에 괄호 () 한 쌍을 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-print-string-variable/</link>
                <guid isPermaLink="false">63858ad437582306394d7c72</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boyeon Ihn ]]>
                </dc:creator>
                <pubDate>Wed, 07 Dec 2022 07:12:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2022/11/denise-jans-_dXkaD3l574-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-print-variable-how-to-print-a-string-and-variable/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Print Variable – How to Print a String and Variable</a>
      </p><!--kg-card-begin: markdown--><h3 id="python">Python은 유연하고 다목적으로 사용할 수 있는 프로그래밍 언어입니다. 보통 한 가지를 프로그래밍하기 위해 다양한 방법으로 작업을 수행할 수 있습니다.</h3>
<p>이 튜토리얼에서는 문자열과 변수를 함께 출력할 수 있는 몇 가지 방법을 살펴보겠습니다.</p>
<p>그럼 시작해볼까요?</p>
<h2 id="pythonprint">Python에서 <code>print()</code> 함수 사용하기</h2>
<p>Python에서 무언가를 출력하려면 <code>print()</code> 함수를 사용합니다. <code>print</code> 키워드 뒤에 괄호 <code>()</code> 한 쌍을 붙입니다.</p>
<pre><code class="language-python">#문자열 출력하는 방법
print("Hello world")

#정수 출력하는 방법 
print(7)

#변수 출력하는 방법 
#변수 자체를 출력하려면 변수 이름만 표기합니다 

fave_language = "Python"
print(fave_language)

#출력된 값

#Hello world
#7
#Python
</code></pre>
<p>괄호를 생략하면 오류가 발생합니다.</p>
<pre><code class="language-python">print "hello world"

#코드 실행 후 출력된 값:
#File "/Users/dionysialemonaki/python_articles/demo.py", line 1
#    print "hello world"
#    ^^^^^^^^^^^^^^^^^^^
#SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
</code></pre>
<p>Visual Studio Code에서 <a href="https://marketplace.visualstudio.com/items?itemName=ms-python.python">Python 확장 프로그램</a>을 다운로드 받고 Python 코드를 작성하면, 잘못된 코드에 밑줄과 힌트가 표시되어 오류가 발생했다는 것을 알 수 있습니다.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-07-at-3.08.14-PM.png" alt="오류가 발생해서 코드가 밑줄이 그어져있고 힌트가 표시됩니다" width="600" height="400" loading="lazy"></p>
<p>위에서 얘기했듯이, <code>print()</code> 함수는 텍스트 및 숫자 데이터, 변수 및 기타 데이터 유형 같은 모든 종류의 정보를 출력하는 데 사용됩니다.</p>
<p>또한 변수와 결합된 텍스트(또는 문자열)를 한 번에 출력할 수도 있습니다. 다음 섹션에서는 이 작업을 수행하는 몇 가지 방법에 대해 다루겠습니다.</p>
<h2 id="pythonconcatenation">Python에서 문자열을 변수와 결합해서(concatenation) 출력하기</h2>
<p>사전에 따르면, "concatenate"은 무언가를 일렬로 함께 연결하는 것을 의미합니다.</p>
<p>Python에서는 <code>+</code> 덧셈 연산자를 사용하여 다양한 항목 또는 데이터를 추가합니다.</p>
<p>결합하기(concatenation)는 문자열에만 사용되기 때문에 문자열과 연결하려는 변수가 정수 데이터 유형이면 <code>str()</code> 함수를 사용해 문자열로 변환해야 합니다.</p>
<p>다음 예시에서는 변수 값을 다른 문자열과 함께 출력해보겠습니다.</p>
<p>문자열은 큰따옴표로 묶고 변수 이름은 묶지 않고 덧셈 연산자를 사용해 모두 함께 연결합니다.</p>
<pre><code class="language-python">fave_language = "Python"

print("I like coding in " + fave_language + " the most")

#output
#I like coding in Python the most

</code></pre>
<p>문자열을 결합할 때는 공백을 직접 추가해야 합니다. 이전 예에서 따옴표 안에 공백을 포함하지 않았다면 다음과 같이 출력됩니다.</p>
<pre><code class="language-python">fave_language = "Python"

print("I like coding in" + fave_language + "the most")

#output
#I like coding inPythonthe most
</code></pre>
<p>다음과 같이 공백을 별도로 추가할 수도 있습니다.</p>
<pre><code class="language-python">fave_language = "Python"

print("I like coding in" + " " + fave_language + " "  + "the most")

#output
#I like coding in Python the most
</code></pre>
<p>이 방법은 오류가 발생하기 쉽고 시간이 오래 걸릴 수 있기 때문에 문자열과 변수를 출력하는 데 가장 선호하는 방법은 아닙니다.</p>
<h2 id="python">Python에서 변수와 문자열을 쉼표로 구분하여 출력하기</h2>
<p>변수와 텍스트를 쉼표로 구분 지어서 두 데이터 유형을 함께 출력할 수 있습니다.</p>
<pre><code class="language-python">first_name = "John"

print("Hello",first_name)

#output
#Hello John

</code></pre>
<p>위의 예에서는 먼저 큰따옴표로 출력할 텍스트 (문자열 <code>Hello</code>)를 묶습니다.</p>
<p>해당 텍스트와 <code>first_name</code> 변수가 가르키는 값을 구분하기 위해 텍스트를 묶은 닫힘 따옴표 뒤에 쉼표를 추가합니다.</p>
<p>또한 변수 뒤에 다음과 같이 텍스트를 더 추가할 수 있습니다.</p>
<pre><code class="language-python">first_name = "John"

print("Hello",first_name,"good to see you")

#output
#Hello John good to see you

</code></pre>
<p>이 방법은 두 개 이상의 변수가 있을 때도 실행됩니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print("Hello",first_name,last_name,"good to see you")

#output
Hello John Doe good to see you
</code></pre>
<p>모든 항목을 쉼표로 구분해야 합니다. 위의 예시에 나타난 것과 같이 텍스트와 변수를 구분할 때, 그리고 변수와 변수 사이를 구분할 때 쉼표를 추가해야 합니다.</p>
<p>쉼표를 <code>first_name</code>과 <code>last_name</code> 변수 사이에 추가하지 않으면 다음과 같은 오류가 발생됩니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print("Hello",first_name last_name,"good to see you")

#output
#File "/Users/dionysialemonaki/python_articles/demo.py", line 4
#    print("Hello",first_name last_name,"good to see you")
#                 ^^^^^^^^^^^^^^^^^^^^
#SyntaxError: invalid syntax. Perhaps you forgot a comma?
</code></pre>
<p>보시다시피 Python 오류 메시지는 매우 유용하며 디버깅 프로세스를 조금 더 수월하게 해줍니다 :)</p>
<h2 id="stringformatting">파이썬에서 문자열 포매팅(string formatting) 방법을 사용해 변수와 문자열 출력하기</h2>
<p>변수 값을 추가할 위치에 중괄호 <code>{}</code> 한 쌍을 포함하여 문자열 포매팅을 합니다.</p>
<pre><code class="language-python">first_name = "John"

print("Hello {}, hope you're well!")
</code></pre>
<p>이 예에서는 하나의 변수 <code>first_name</code>이 있습니다.</p>
<p><code>print()</code>문 안에는 출력해야 하는 텍스트를 묶은 큰따옴표 <code>""</code> 한 쌍이 있습니다.</p>
<p>큰따옴표 안에 변수 <code>first_name</code>의 값을 배치하고 싶은 곳에 중괄호 <code>{}</code> 쌍을 표기했습니다.</p>
<p>이 코드를 실행하면 다음과 같은 출력이 나타납니다:</p>
<pre><code class="language-python">#output
#Hello {}, hope you're well!
</code></pre>
<p><code>first_name</code> 값이 실제로 출력되지 않았습니다.</p>
<p>변수 값을 출력하려면 문자열의 닫힌 따옴표 바로 뒤에 <code>.format()</code> 문자열 메서드를 추가해야 합니다.</p>
<pre><code class="language-python">first_name = "John"

print("Hello {}, hope you're well!".format(first_name))

#output
#Hello John, hope you're well!
</code></pre>
<p>변수가 두 개 이상 있으면 출력하려는 변수의 개수만큼 중괄호 <code>{}</code>를 사용합니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print("Hello {} {}, hope you're well!")
</code></pre>
<p>이 예에서는 두 개의 변수를 생성하고 두 변수를 차례로 출력하려고 합니다. 변수를 대체할 위치에 중괄호 <code>{}</code> 두 쌍을 추가했습니다.</p>
<p><code>.format()</code> 메서드를 사용할 때는 변수 이름을 배치하는 순서가 중요합니다.</p>
<p>다시 말해, <code>.format()</code> 메소드 내에서 먼저 추가된 변수의 값은 첫 번째 중괄호 <code>{}</code> 쌍에 위치하고, 두 번째로 추가된 변수의 값은 두 번째 중괄호 <code>{}</code> 쌍에 위치합니다.</p>
<p>메서드 내에서는 변수 이름을 쉼표로 구분해야 합니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print("Hello {} {}, hope you're well!".format(first_name,last_name))

#output
#Hello John Doe, hope you're well!
</code></pre>
<p>메서드 내에  변수의 순서를 반대로 바꾼다면 출력된 값도 다르게 나타납니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print("Hello {} {}, hope you're well!".format(last_name,first_name))

#output
#Hello Doe John, hope you're well!
</code></pre>
<h2 id="pythonfstrings">Python에서 <code>f-strings</code>를 사용해 변수와 문자열을 출력하기</h2>
<p><code>f-strings</code>은 이전 섹션에서 다룬 방법보다 문자열 포매팅을 더 읽기 쉽고 간결하게 만들어 줍니다.</p>
<p>이 방법은 더 쉽고 수동으로 입력해야 할 항목이 비교적으로 적습니다.</p>
<p><code>f-string</code>을 만드는 일반적인 문법은 다음과 같습니다.</p>
<pre><code class="language-python">print(f"I want this text printed to the console!")

#output
#I want this text printed to the console!
</code></pre>
<p>먼저 <code>print()</code> 함수 안에 있는 따옴표 <code>""</code> 쌍 앞에 문자  <code>f</code> 를 붙여줍니다.</p>
<p>변수를 문자열과 함께 한 줄에 출력하려면 따옴표 바로 앞인 동일한 위치에 문자 <code>f</code>를 표기합니다.</p>
<p>그런 다음 따옴표 안에 원하는 텍스트를 추가하고 변수 값을 추가할 위치에 변수 이름를 묶은 중괄호 <code>{}</code> 쌍을 추가합니다.</p>
<pre><code class="language-python">first_name = "John"

print(f"Hello, {first_name}!")

#output
#Hello, John!
</code></pre>
<p>두 개 이상의 변수를 출력하려면 두 번째 변수 이름을 묶은 중괄호 <code>{}</code> 쌍을 추가합니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print(f"Hello, {first_name} {last_name}!")

#output
#Hello, John Doe!
</code></pre>
<p>변수 이름을 배치하는 순서에 따라 출력된 값이 달라지기 떄문에 변수 이름을 원하는 순서로 정렬해야 합니다.</p>
<p>변수 이름의 순서를 거꾸로 하면 다음과 같은 값이 출력됩니다.</p>
<pre><code class="language-python">first_name = "John"
last_name = "Doe"

print(f"Hello, {last_name} {first_name}!")

#output
#Hello, Doe John!
</code></pre>
<h2 id="">결론</h2>
<p>끝까지 읽어주셔서 감사합니다! 이 튜토리얼에서는 Python에서 문자열과 변수를 한 줄로 함께 출력하는 몇 가지 방법을 배웠습니다.</p>
<p>Python에 대해 더 배우고 싶다면 freeCodeCamp의 <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/">Python 수료증 과정</a>을 확인해보세요. 이 수료증 과정은 기초부터 시작해서 점차 고급 개념으로 진도를 나가기 때문에 초보자에게 적합합니다. 또한 5개의 프로젝트를 해보며 수료과정 동안 배운 모든 프로그래밍 지식을 실습할 수 있을 거에요.</p>
<p>Happy Coding!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python에서 List Index Out of Range 오류 메세지 해결하기 ]]>
                </title>
                <description>
                    <![CDATA[ 이 기사에서는 Python에서 리스트 인덱스가 범위를 벗어났다는 의미의 Indexerror: list index out of range 오류가 발생하는 몇 가지 이유에 대해 살펴보겠습니다. 오류가 발생하는 이유에 대해 알아본 후 이 오류를 방지하는 몇 가지 방법도 배워보겠습니다. 그럼 시작해볼까요? Python 리스트 생성하기 Python에서 리스트 객체를 생성하려면 다음을 실행해야 합니다.  * 리스트 객체의 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/python-list-index-out-of-range/</link>
                <guid isPermaLink="false">6362efc8c0cb07062cace68f</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boyeon Ihn ]]>
                </dc:creator>
                <pubDate>Sat, 05 Nov 2022 14:06:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2022/11/computer.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/list-index-out-of-range-python-error-message-solved/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">List Index Out of Range – Python Error Message Solved</a>
      </p><!--kg-card-begin: markdown--><h3 id="pythonindexerrorlistindexoutofrange">이 기사에서는 Python에서 리스트 인덱스가 범위를 벗어났다는 의미의 <code>Indexerror: list index out of range</code> 오류가 발생하는 몇 가지 이유에 대해 살펴보겠습니다.</h3>
<p>오류가 발생하는 이유에 대해 알아본 후 이 오류를 방지하는 몇 가지 방법도 배워보겠습니다.</p>
<p>그럼 시작해볼까요?</p>
<h2 id="python">Python 리스트 생성하기</h2>
<p>Python에서 리스트 객체를 생성하려면 다음을 실행해야 합니다.</p>
<ul>
<li>리스트 객체의 이름을 지정하고,</li>
<li>할당 연산자인 <code>=</code>를 사용하고,</li>
<li>대괄호 <code>[]</code> 안에 0개 이상의 리스트 항목을 포함합니다. 각 리스트 항목은 쉼표로 구분해야 합니다.</li>
</ul>
<p>예를 들어, 이름 목록을 작성하려면 다음과 같은 코드를 실행합니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]
</code></pre>
<p>위의 코드는 <code>Kelly, Nelly, Jimmy, Lenny</code>의 네 가지 값을 가진 <code>names</code>라는 리스트를 생성합니다.</p>
<h3 id="python">Python 리스트 길이 확인하기</h3>
<p>리스트의 길이를 확인하려면 Python의 내장 함수 <code>len()</code>를 사용하면 됩니다.</p>
<p><code>len()</code>은 리스트에 저장된 항목의 수인 정수를 반환합니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

#name_length라는 변수를 만들어 리스트의 길이를 저장합니다
name_length = len(names)

#변수의 값을 콘솔에 출력합니다. 
print(name_length)

#출력된 값 
#4
</code></pre>
<p>리스트에 저장된 항목이 4개이므로 리스트의 길이 또한 4입니다.</p>
<h3 id="python">Python 리스트의 개별 항목에 접근하는 방법</h3>
<p>리스트의 각 항목은 고유한 <i>인덱스 번호(index number)</i>가 있습니다.</p>
<p>Python 및 대부분의 현대 프로그래밍 언어에서는 인덱싱이 0부터 시작합니다.</p>
<p>즉, 리스트의 첫 번째 항목은 0, 두 번째 항목은 1의 인덱스를 갖습니다.</p>
<p>인덱스를 활용해 개별 항목에 접근할 수 있습니다.</p>
<p>그러려면 먼저 리스트 이름을 작성합니다. 그런 다음 대괄호 안에 항목의 인덱스에 해당하는 정수를 포함합니다.</p>
<p>이전 예시의 경우 인덱스를 사용해 리스트 내의 각 항목에 접근하는 방법은 다음과 같습니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

names[0] # Kelly
names[1] # Nelly
names[2] # Jimmy
names[3] # Lenny
</code></pre>
<p>음수 인덱스(negative index)를 사용해 Python 리스트 내 항목에 접근할 수도 있습니다.</p>
<p><strong>마지막</strong> 항목에 접근하려면 인덱스 값 -1을 사용하면 됩니다. 마지막에서 두 번째 항목에 접근하려면 인덱스 값 -2를 사용합니다.</p>
<p>다음 코드 블록은 음수 인덱스를 사용해 리스트 내의 각 항목에 접근하는 방법입니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

names[-4] # Kelly
names[-3]# Nelly
names[-2] # Jimmy
names[-1] # Lenny
</code></pre>
<h2 id="indexerrorlistindexoutofrangeerror"><code>Indexerror: list index out of range error</code> 오류가 발생하는 이유</h2>
<h3 id="">첫 번째 원인: 리스트 범위를 벗어나는 인덱스 사용</h3>
<p>리스트의 인덱스 범위를 벗어난, 존재하지 않는 값을 사용해 항목에 접근하려고 하면 <code>Index error: list index out of range</code> 오류가 발생합니다.</p>
<p>이 오류는 리스트의 마지막 항목에 접근하거나 음수 인덱스를 사용해 첫 번째 항목에 접근할 때 흔히 발생합니다.</p>
<p>예시를 다시 살펴봅시다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]
</code></pre>
<p>리스트의 마지막 항목인 <code>Lenny</code>에 접근하려고 다음과 같은 코드를 실행했다고 가정해봅시다.</p>
<pre><code class="language-python">print(names[4])

#출력된 값 

#Traceback (most recent call last):
#  File "/Users/boyeonihn/python_articles/demo.py", line 3, in &lt;module&gt;
#    print(names[4])
#IndexError: list index out of range
</code></pre>
<p>일반적으로 리스트의 인덱스 범위는 <code>0에서 n-1</code>이며, 여기서 <code>n</code>은 리스트의 총 항목 수입니다.</p>
<p>예시의 <code>names</code> 리스트는 총 항목 수가 <code>4</code>이고 인덱스 범위는 <code>0에서 3</code>입니다.</p>
<p>이제 음수 인덱스로 리스트 항목을 접근해봅시다.</p>
<p>음수 인덱스를 사용해 첫 번째 항목인 <code>Kelly</code>에 접근한다고 가정해볼까요?</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

print(names[-5])

#출력된 값 

#Traceback (most recent call last):
#  File "/Users/boyeonihn/python_articles/demo.py", line 3, in &lt;module&gt;
#    print(names[-5])
#IndexError: list index out of range
</code></pre>
<p>음수 인덱스를 사용할 경우 리스트의 인덱스 범위는 <code>-1에서 -n</code>입니다. 여기서 <code>-n</code>은 리스트에 포함된 총 항목 수입니다.</p>
<p>리스트의 총 항목 수가 <code>4</code>라면, 인덱스 범위는 <code>-1에서-4</code>입니다.</p>
<h3 id="forrange">두 번째 원인: <code>for</code>문에서 <code>range()</code> 함수에 잘못된 값 전달</h3>
<p>리스트를 순회할 때 존재하지 않는 항목에 접근하려고 하면 <code>Indexerror: list index out of range</code> 오류가 발생합니다.</p>
<p>이런 오류가 발생하는 흔한 경우 중 하나는 Python의 <code>range()</code> 함수에서 잘못된 정수를 사용했을 때입니다.</p>
<p><code>range()</code> 함수에는 일반적으로 카운트가 종료하는 위치(종료값이라고도 불립니다 --옮긴이)를 나타내는 정수 하나가 전달됩니다.</p>
<p>예를 들어 <code>range(5)</code>는 카운트가 <code>0</code>에서 시작해 <code>4</code>에서 종료됨을 나타냅니다.</p>
<p>다시 말해 카운트는 기본적으로 <code>0</code>에서 시작되고 전달된 종료값에서 1을 뺀 값까지 매번 <code>1</code>씩 증가합니다. <code>range()</code> 함수에 인자로 전달된 종료값은 카운트에 포함되지 않는다는 점을 꼭 명심하세요.</p>
<p>예시를 확인해봅시다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

for name in range(5):
    print(names[name])
    
#출력된 값 

#Kelly
#Nelly
#Jimmy
#Lenny
#Traceback (most recent call last):
#  File "/Users/boyeonihn/python_articles/demo.py", line 7, in &lt;module&gt;
#   print(names[name])
#IndexError: list index out of range
</code></pre>
<p><code>names</code> 리스트에는 네 가지 값이 있습니다.</p>
<p>이 리스트를 순회하고 각 항목의 값을 출력하고 싶다는 가정해보겠습니다.</p>
<p><code>range(5)</code>를 사용할 때 Python 인터프리터에게 <code>0에서 4까지</code>에 위치한 값을 출력하라는 지시를 전하는 의미입니다.</p>
<p>그러나 <code>4</code> 위치에는 항목이 없습니다.</p>
<p>위치 번호를 출력한 후 해당 위치의 값을 출력해보면 이 사실을 확인할 수 있습니다.</p>
<pre><code class="language-python">#0
#Kelly
#1
#Nelly
#2
#Jimmy
#3
#Lenny
#4
#Traceback (most recent call last):
#  File "/Users/dionysialemonaki/python_articles/demo.py", line 8, in &lt;module&gt;
#    print(names[name])
#IndexError: list index out of range
</code></pre>
<p><code>range(5)</code>는 <code>0에서 4까지</code>의 위치를 나타냅니다. <code>0</code> 위치에는 "Kelly", <code>1</code> 위치에는 "Nelly", <code>2</code> 위치에는 "Jimmy", 그리고 <code>3</code> 위치에는 "Lenny"라는 값이 있다는 것을 확인할 수 있습니다.</p>
<p><code>4</code> 위치의 경우 출력할 값이 없으므로 인터프리터가 오류를 발생시킵니다.</p>
<p>이 오류를 해결하는 한 가지 방법은 <code>range()</code>에 전달된 정수를 낮추는 것입니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

for name in range(4):
    print(name)
    print(names[name])
    
#출력된 값

#0
#Kelly
#1
#Nelly
#2
#Jimmy
#3
#Lenny
</code></pre>
<p><code>for</code>문을 사용할 때 이 오류를 해결하는 또 다른 방법은 리스트의 길이를 <code>range()</code> 함수에 인수로 전달하는 것입니다. 이전 섹션에서 설명한 것처럼 내장 함수 <code>len()</code>를 사용하면 됩니다.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

for name in range(len(names)):
    print(names[name])

#출력된 값

#Kelly
#Nelly
#Jimmy
#Lenny
</code></pre>
<p><code>len()</code>을 <code>range()</code>에 인수로 전달할 때 다음과 같은 실수를 조심하세요.</p>
<pre><code class="language-python">names = ["Kelly", "Nelly", "Jimmy", "Lenny"]

for name in range(len(names) + 1):
    print(names[name])
</code></pre>
<p>이런 코드를 실행하면 <code>IndexError: list index out of range</code> 오류가 다시 발생합니다.</p>
<pre><code class="language-python">#Kelly
#Nelly
#Jimmy
#Lenny
#Traceback (most recent call last):
#  File "/Users/boyeonihn/python_articles/demo.py", line 4, in &lt;module&gt;
#    print(names[name])
#IndexError: list index out of range
</code></pre>
<h2 id="">마치며</h2>
<p>이제 <code>IndexError: list index out of range</code> 오류가 발생하는 이유와 이를 방지할 수 있는 몇 가지 방법에 대해 이해가 잘 되셨나요?</p>
<p>Python에 대해 더 배워보고 싶다면 freeCodeCamp의 <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/">Python 수료증 과정</a>을 확인해보세요. 수료증 강의를 통해 초보자여도 Python을 재미있고 유익하게 배우면서 5개의 프로젝트를 해보며 배운 것을 열심히 실습할 수 있을 거에요.</p>
<p>읽어주셔서 감사합니다. Happy coding!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python의 개행과 줄바꿈 없이 출력하는 방법 ]]>
                </title>
                <description>
                    <![CDATA[  반갑습니다! Python의 개행 문자는 코드 라인의 맨 끝과 새로운 코드 라인의 맨 앞에 작성합니다. 콘솔에 결과값을 출력하거나 파일과 관련된 작업을 할 때 개행 문자를 사용하는 방법을 필수적으로 알아야 합니다. 이번 포스팅에서 배우게 될 내용입니다:  * Python에서 개행 문자를 식별하는 방법  * 문자열과 출력문에서 개행 문자를 쓰는 방법 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/pythonyi-gaehaenggwa-julbaggum-eobsi-culryeoghaneun-bangbeob/</link>
                <guid isPermaLink="false">63508b7a71cbd405f6d6a6ff</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yeonhee Hayden Kim ]]>
                </dc:creator>
                <pubDate>Sun, 23 Oct 2022 13:08:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2022/10/New-Line.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-new-line-and-how-to-python-print-without-a-newline/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python New Line and How to Python Print Without a Newline</a>
      </p><p></p><h3 id="-python-"><strong>반갑습니다!</strong> Python의 개행 문자는 코드 라인의 맨 끝과 새로운 코드 라인의 맨 앞에 작성합니다. 콘솔에 결과값을 출력하거나 파일과 관련된 작업을 할 때 개행 문자를 사용하는 방법을 필수적으로 알아야 합니다.</h3><p><strong>이번 포스팅에서 배우게 될 내용입니다:</strong></p><ul><li>Python에서 개행 문자를 식별하는 방법</li><li>문자열과 출력문에서 개행 문자를 쓰는 방법</li><li>문자열의 맨끝에 개행 문자를 추가하지 않고 출력문을 작성하는 방법</li></ul><p><strong>그럼 시작해봅시다!</strong> ✨</p><h2 id="-">🔹 개행 문자</h2><p>Python에서 개행 문자는 다음과 같습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/1afb92caba6804e89c608ec954c741262563520c1f6916229a89579959d31440/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3134322e706e67" class="kg-image" alt="개행문자 이미지" width="600" height="400" loading="lazy"></figure><p><strong>개행 문자에는 문자 2개가 쓰입니다:</strong></p><ul><li>역슬래시</li><li>문자 <code>n</code></li></ul><p>위의 문자 조합이 문자열 안에 있으면, 쭉 이어져 있던 문자들이 이쯤에서 끊기고 이 다음부터는 새롭게 줄을 바꿔 다시 이어지는 것을 뜻합니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/daa942161ca03e638ebd015bdc17288855adff7093edb11fd295398377aa0143/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3232342e706e67" class="kg-image" alt="문자열 안의 개행문자 이미지" width="600" height="400" loading="lazy"></figure><p>개행 문자는 <strong>f 문자열</strong> 안에서도 마찬가지로 쓰입니다:</p><pre><code>&gt;&gt;&gt; print(f"Hello\nWorld!")
</code></pre><h2 id="--1">🔸 출력문 안의 개행 문자</h2><p>기본적으로 출력문에는 개행 문자가 "은연중에" 문자열 끝에 포함되어 있습니다.</p><p>마치 다음과 같습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/7f38511056ecb68b426b6f0030c0864c1bb5ce6aae93961fb908bf829a6acd43/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3134352e706e67" class="kg-image" alt="출력문 안의 개행문자 이미지" width="600" height="400" loading="lazy"></figure><p>위는 <a href="https://docs.python.org/3/library/functions.html#print" rel="nofollow">Python 공식 문서</a>에 명시되어 있습니다:</p><p><code>print</code> 내장 함수에서 <code>end</code> 파라미터의 기본값은 <code>\n</code>이므로 문자열에 개행 문자를 덧붙입니다.</p><p>💡 <strong>Tip:</strong> 덧붙인다는 것은 "맨끝에 추가한다"는 것을 의미합니다.</p><p>다음은 <code>print</code> 내장 함수의 정의입니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/18b871afb4b7c6ec4cf6253bcfe40deb781371fb5479003b5e88e35185eabe6e/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3134362e706e67" class="kg-image" alt="print 내장 함수의 정의" width="600" height="400" loading="lazy"></figure><p><code>end</code> 파라미터의 값이 <code>\n</code>이므로 문자열 끝에 개행 문자가 추가됩니다.</p><p>단지 출력문 하나만 사용하면 한 줄만 출력되므로 이를 알아차리지 못할 수도 있습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/3e84f0baa43dd92c4ee56975e0835bc7faea0932f3c6e0163bb2736568a8a81a/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3134372e706e67" class="kg-image" alt="print 출력문과 출력 결과" width="600" height="400" loading="lazy"></figure><p>하지만 Python 스크립트에서 여러 개의 출력문을 번갈아 사용하면:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/dd0e709bdc66d5ae9f42ca1cc52139820e19440e4f05699511cfa6e9370ee919/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231342e706e67" class="kg-image" alt="여러 줄의 print 출력문" width="600" height="400" loading="lazy"></figure><p>각각의 출력문 안의 문자열 끝에는 "은연중에"<code>\n</code>이 추가되었기 때문에 여러 개의 줄로 분리되어 출력되는 것을 확인할 수 있습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/448f2e4153393ff585567671e6edc9b0b6307219397b9653b275c8715348c17e/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231382e706e67" class="kg-image" alt="여러 줄의 Hello, World!" width="600" height="400" loading="lazy"></figure><h2 id="--2">🔹 줄바꿈 없이 출력하는 방법</h2><p><code>print</code> 함수의 <code>end</code> 파라미터 값을 바꾸면, 기본적으로 줄바꿈이 되어버리는 수행 결과를 변경할 수 있습니다.</p><p>다음 예제에서 기본값을 사용하면:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/a908f2dddf1889e2adef2c3b92a3c4c825be2685558a2961374af51f142d8bc2/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231392e706e67" class="kg-image" alt="print 출력문 2개(Hello와 World)" width="600" height="400" loading="lazy"></figure><p>두 줄로 나뉘어 출력된 결과를 확인할 수 있습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/27123d59372e187f5e788741e6a36bca6bf31a700591c323f3234e445d687fb5/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3232312e706e67" class="kg-image" alt="출력 결과 Hello와 World" width="600" height="400" loading="lazy"></figure><p>하지만 <code>end</code> 값을 바꿔서 <code>" "</code>로 설정한다면</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/b79f37dcc8f2eace891a5b5e6d319d85f15d0b86ee40e5827a374fd9892de396/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3232322e706e67" class="kg-image" alt="end 파라미터가 &quot; &quot;로 쓰인 print 출력문" width="600" height="400" loading="lazy"></figure><p>문자열 끝에는 개행 문자 <code>\n</code> 대신에 공백이 추가되며, 출력문 2개의 출력 결과도 같은 줄에서 나타나게 됩니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/b15fb07c905efc4708108e5cc80e9fd4ab4c8485815a29158a7827f3b1540ada/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3232332e706e67" class="kg-image" alt="출력 결과 Hello World" width="600" height="400" loading="lazy"></figure><p>아래의 예제처럼 코드를 작성하면 한 줄에 연속적인 값들을 출력할 수 있습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/56324b4fb3be7a831968774c7d2b73d696574786def077ea9d0a4afa12c82c4c/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231302e706e67" class="kg-image" alt="end 파라미터가 &quot;, &quot;인 출력문이 있는 for 문" width="600" height="400" loading="lazy"></figure><p>출력 결과는 다음과 같습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/8de0e8a61fceb365f0d2d933a9c863cd7025293443bb27f39154f7411705bfba/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231312e706e67" class="kg-image" alt="위의 for 문에서 출력문 출력 결과(&quot;, &quot;로 구분된 0~14가 한 줄로 나열)" width="600" height="400" loading="lazy"></figure><p>💡 <strong>Tip:</strong> 연속적인 숫자 모음에서 마지막 수에는 콤마가 붙지 않도록 조건문을 추가할 수 있습니다.</p><p>마찬가지로, 순차적인 데이터 집합의 값을 같은 줄에 출력할 수 있습니다.</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/28e1304c555c2bed5c8c0815695d666f55def57eea58d1a28b6f4e29d98340a3/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3232352e706e67" class="kg-image" alt="end 파라미터가 &quot; &quot;인 출력문이 있는 for 문" width="600" height="400" loading="lazy"></figure><p>출력 결과는 다음과 같습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/c7b253a3323eae954daf683ac048c7d95bf1b45898e305a34e1a74966530f714/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3231332e706e67" class="kg-image" alt="위의 for 문에서 출력문 출력 결과(&quot; &quot;로 구분된 0~5가 한 줄로 나열)" width="600" height="400" loading="lazy"></figure><h2 id="--3">🔸 파일 안의 개행 문자</h2><p>개행 문자 <code>\n</code>은 "숨겨진 채로" 파일 안에서 발견되기도 합니다.텍스트 파일 안의 줄바꿈에서 실제로는 문자 <code>\n</code>이 삽입되어 있습니다.</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/0105e39329a85e5c4a3577c5005d6815d9b12e11c5b244440fe1fb5211ad62fd/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3135302e706e67" class="kg-image" alt="메모장에서 줄을 바꿔 작성한 문자들 모음" width="600" height="400" loading="lazy"></figure><p>아래와 같이 <code>&lt;파일&gt;.readlines()</code>를 통해 파일을 읽어서 확인해볼 수 있습니다.</p><pre><code>with open("names.txt", "r") as f:
    print(f.readlines())
</code></pre><p>출력 결과는 다음과 같습니다:</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/c5c836a583b47ff2ffdf9c2f423113105e4b067f4ff14222d9df8493a6248a83/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f323032302f30362f696d6167652d3230372e706e67" class="kg-image" alt="메모장 파일을 읽어들인 결과" width="600" height="400" loading="lazy"></figure><p>보시는 바와 같이 텍스트 파일의 처음 세 줄은 "보이지 않게 뒤에서" 작용하는 개행 문자 <code>\n</code>으로 끝납니다.</p><p>💡 <strong>Tip:</strong> 파일의 마지막 줄만 개행 문자로 끝나지 않는다는 점을 주의하세요.</p><h2 id="--4">🔹 총정리</h2><ul><li>Python에서 개행 문자는 <code>\n</code>입니다. 개행 문자는 텍스트 한 줄이 끝났음을 나타내는 데 쓰입니다.</li><li>줄을 분리시킬 때 쓰이는 <code>&lt;문자&gt;</code>를 사용해서 <code>end = &lt;문자&gt;</code>로 줄바꿈 없이 문자열을 출력할 수 있습니다.</li></ul><p><strong>여러분이 제 글을 좋아해주시고 도움을 얻으시길 진심으로 바랍니다.</strong> 이제 여러분은 Python에서 개행 문자로 작업할 수 있습니다.</p><p><a href="https://www.udemy.com/user/estefania-cn/" rel="nofollow">제가 강의하는 온라인 코스를 확인해주세요.</a> 저를 <a href="https://twitter.com/EstefaniaCassN" rel="nofollow">트위터</a>에서 팔로우해보세요. ⭐</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python의 Do While문 - 반복문 예제 ]]>
                </title>
                <description>
                    <![CDATA[  모든 현대 프로그래밍 언어에서 반복문은 유용하게 자주 쓰입니다. 반복문을 사용하면 특정한 반복 작업을 자동화할 수 있고 프로그램에 반복적인 코드를 일일이 작성하지 않아도 됩니다. 반복문은 특정 조건을 만족할 때까지 반복적으로 실행되는 명령들이 모인 것입니다. Python에서 반복문이 어떻게 동작하는지 좀 더 배워봅시다. Python에서의 반복문 Python에 내장된 반복문으로는 크게 2가지 유형이 있습니다. ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/pythonyi-do-whilemun-banbogmun-yeje/</link>
                <guid isPermaLink="false">6306bbcfb9e784058602937e</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yeonhee Hayden Kim ]]>
                </dc:creator>
                <pubDate>Thu, 01 Sep 2022 06:17:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2022/09/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f73697a652f77323030302f323032312f30382f706578656c732d706978616261792d3130363135352e6a7067.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-do-while-loop-example/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Do While – Loop Example</a>
      </p><p></p><h3 id="-">모든 현대 프로그래밍 언어에서 반복문은 유용하게 자주 쓰입니다.</h3><p>반복문을 사용하면 특정한 반복 작업을 자동화할 수 있고 프로그램에 반복적인 코드를 일일이 작성하지 않아도 됩니다.</p><p>반복문은 특정 조건을 만족할 때까지 반복적으로 실행되는 명령들이 모인 것입니다. Python에서 반복문이 어떻게 동작하는지 좀 더 배워봅시다.</p><h2 id="python-">Python에서의 반복문</h2><p>Python에 내장된 반복문으로는 크게 2가지 유형이 있습니다.</p><ul><li><code>for</code> 반복문</li><li><code>while</code> 반복문</li></ul><p>Python에서 <code>while</code> 반복문은 어떻게 만들 수 있고 어떻게 동작하는지 집중적으로 학습해봅시다.</p><h2 id="python-while-">Python에서 while 문은 무엇일까요?</h2><p>Python의 <code>while</code> 문의 일반적인 문법은 다음과 같습니다:</p><pre><code>while 조건:
    반복문의 내용에 해당하는 이 코드를 실행함
</code></pre><p>반복문은 조건이 참인 동안 해당되는 코드를 실행할 것입니다. 조건이 더 이상 참이 아닐 때까지 실행시키고자 하는 코드 모음을 계속해서 실행합니다.</p><p>반복문은 항상 실행되기 전에 우선적으로 조건을 확인합니다.</p><p>만약 조건이 참으로 판명된다면 반복문은 반복문 안에 있는 코드를 실행합니다.</p><p>예컨대 아래의 반복문은 <code>number</code>가 <code>10</code>보다 작을 때까지 실행됩니다.</p><pre><code class="language-python">number = 0
while number &lt; 10:
    print(f"Number is {number}!")
    number = number + 1
</code></pre><p>출력 결과:</p><pre><code>Number is 0!
Number is 1!
Number is 2!
Number is 3!
Number is 4!
Number is 5!
Number is 6!
Number is 7!
Number is 8!
Number is 9!
</code></pre><p>여기서 변수 <code>number</code>는 처음에 <code>0</code>으로 설정됩니다.</p><p>코드가 실행되기 전에 Python은 조건(<code>number &lt; 10</code>)을 확인합니다. 조건이 참이면 출력문이 실행되고 <code>Number is 0!</code>이 콘솔에 출력됩니다.</p><p><code>number</code>는 <code>1</code>씩 증가합니다. 다시 조건을 확인하고 조건이 참이라면 <code>number</code>가 <code>9</code>가 될 때까지 이 모든 과정이 반복됩니다.</p><p><code>Number is 9!</code>가 출력되고 <code>number</code>가 증가합니다. 이제 <code>number</code>는 <code>10</code>이므로 더 이상 조건을 만족하지 않게 되고 이에 따라 반복문은 종결됩니다.</p><p>다음 예제에서 볼 수 있듯이 조건을 만족하지 않으면 <code>while</code> 문은 절대로 실행되지 않습니다.</p><pre><code class="language-python">number = 50
while number &lt; 10 :
    print(f"Number is {number}!")
</code></pre><p>조건이 항상 False이기 때문에 반복문 안에 있는 명령은 실행되지 않습니다.</p><h2 id="--1">무한 반복문을 만들지 마세요</h2><p>위의 예제에서 볼 수 있듯이 <code>while</code> 문에는 반복 주기 내내 값이 변하는 변수가 필연적으로 따라옵니다. 이 변수는 반복문을 언제 끝낼지 결정합니다.</p><p>특정 한 줄을 추가하지 않으면, 무한 반복문을 만들게 됩니다.</p><p>반복문의 변수 <code>number</code>가 증가하지 않고 값이 바뀌지도 않는다고 해봅시다. 그렇게 되면 변수는 처음 초기화한 후로 줄곧 <code>0</code>으로 남아있게 될 것이고, 조건 <code>number &lt; 10</code> 역시 영원히 True가 될 것입니다. 다시 말해 반복문이 영원히 반복됩니다.</p><pre><code class="language-python"># 이 코드를 실행하지 마세요

number = 0
while number &lt; 10:
    print(f"Number is {number}!")
</code></pre><p>출력 결과:</p><pre><code>Number is 0!
Number is 0!
Number is 0!
Number is 0!
Number is 0!
Number is 0!
Number is 0!
...
</code></pre><p>위 코드는 끝없이 실행됩니다.</p><p>다음 코드도 마찬가지입니다.</p><pre><code class="language-python">#이 코드를 실행하지 마세요
while True:
    print("I am always true")
</code></pre><p>이런 상황에서 여러분이라면 어떻게 하시겠습니까?</p><p>반복문에서 빠져나와서 반복문을 종료시키려면 <code>ctrl + C</code> 를 누르세요.</p><h2 id="do-while-">do while 반복문은 무엇일까요?</h2><p>다른 프로그래밍 언어에서 <code>do while</code> 문의 일반적인 문법은 다음과 같이 생겼습니다.</p><pre><code>do {
  실행될 반복문 코드 블록;
  }
while(조건);
</code></pre><p>예를 들어 C 언어에서 do while 문은 아래와 같습니다.</p><pre><code class="language-c">#include &lt;stdio.h&gt;
 
int main(void)
 {
   int i = 10;
   do {
      printf("the value of i: %i\n", i);
      i++;
      }
  while( i &lt; 20 );
 }
</code></pre><p>do while 문에서 독특한 점은 반복문 블록 안에 있는 코드가 적어도 1번은 실행된다는 사실입니다.</p><p>반복문 안의 코드는 한 번 실행되며 그 후에는 조건이 만족되어야 비로소 실행됩니다.</p><p>그러므로 반복문 안의 코드는 먼저 한 번 실행되고 그리고 나서 조건을 확인합니다.</p><p>만약 조건이 참으로 판명되면 반복문은 계속됩니다.</p><p>코드가 최소 한 번은 실행되도록 하고 싶을 때 do while 문은 꽤 쓸모가 있습니다.</p><p>예를 들어 사용자로부터 입력을 받는 프로그램을 작성할 때 양수만 입력받아야 할 수 있습니다. 코드가 최소 한 번은 실행될 것입니다. 만일 사용자가 제출한 숫자가 음수라면 반복문은 계속해서 실행됩니다. 입력이 양수로 들어오면 비로소 반복문이 종료됩니다.</p><p>Python은 다른 언어처럼 명시적으로 <code>do while</code> 문을 만드는 내장 기능을 제공하지는 않습니다. 하지만 Python에서도 <code>do while</code> 문을 따라할 수 있습니다.</p><h2 id="python-do-while-">Python에서 do while 반복문을 따라하는 방법</h2><p>Python에서 다른 언어의 <code>do while</code>문과 유사하게 동작하는 <code>do while</code> 문을 만드려면 <code>while</code> 문에 약간의 수정이 필요합니다.</p><p>지금까지 학습한 내용을 떠올려보면 <code>do while</code> 문은 최소 한 번은 실행됩니다. 조건을 만족하면 반복문은 다시 실행될 것입니다.</p><p>반면 <code>while</code> 문은 적어도 한 번은 실행된다고 보장할 수 없고 심지어 절대로 실행되지 않을 수도 있습니다. 오직 조건이 만족할 때만 실행되기 때문입니다.</p><p>그래서 최소 한 번은 실행되어야 하는 코드가 있는 예제를 통해 살펴봅시다.</p><pre><code class="language-python">secret_word = "python"
counter = 0

while True:
    word = input("암호를 입력하세요: ").lower()
    counter = counter + 1
    if word == secret_word:
        break
    if word != secret_word and counter &gt; 7: 
        break
</code></pre><p>사용자의 입력을 받는 코드가 적어도 한 번은 실행됩니다.</p><p>무한 반복문이 생성되겠지만 <code>True</code>를 사용하면 최소 한 번 이상 실행되는 것이 항상 보장됩니다.</p><p>만약 사용자가 적합한 암호를 입력했다면 반복문은 종료됩니다.</p><p>사용자가 7번 넘게 틀린 암호를 입력했다면 반복문은 완전히 종결될 것입니다.</p><p><code>break</code>를 통해 <code>while</code> 문의 흐름을 제어할 수 있고 무한 반복문의 늪에 빠지지 않게 됩니다.</p><p><code>break</code>는 현재의 반복문을 빠져나와 그 즉시 반복문을 종료시킵니다.</p><p>따라서 이와 같은 방법으로 Python에서도 <code>do while</code> 문과 비슷한 효과를 얻을 수 있습니다.</p><p>반복문은 항상 최소 한 번 이상은 실행됩니다. 조건을 만족하지 않으면 계속해서 반복될 것이고, 조건을 만족하면 종결될 것입니다.</p><h2 id="--2">결론</h2><p>여러분은 이제 Python에서 <code>do while</code> 반복문을 만드는 방법을 알게 되었습니다.</p><p>Python에 대해 좀 더 학습해보고 싶다면, freeCodeCamp 유튜브 채널에서 <a href="https://www.youtube.com/watch?v=8ext9G7xspg&amp;t=40s" rel="nofollow">12개의 Python 프로젝트 영상</a>을 시청해보세요. 입문자의 눈높이에 맞춘 영상을 보며 12개의 프로젝트를 완성할 수 있습니다.</p><p>또한 freeCodeCamp에서는 Python의 중요한 기본기와 관련하여 깊은 이해력과 전반적인 시야를 키워줄 수 있는 무료 <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/" rel="nofollow">Python 인증서</a> 코스를 제공합니다.</p><p>이 코스를 통해 배운 것을 실습하면서 5개의 프로젝트를 완성하게 될 것입니다.</p><p>읽어주셔서 감사합니다. 행복한 코딩하세요!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python의 여러 줄 주석 - Python에서 여러 줄로 주석을 남기는 방법 ]]>
                </title>
                <description>
                    <![CDATA[  주석은 모든 프로그래밍 언어에서 필수적인 요소입니다. 주석을 활용하면 코드에 대한 이해력을 향상시킬 수 있고, 코드의 가독성을 높일 수 있으며, 팀 동료들이 코드의 동작 방식을 이해하도록 도울 수 있습니다. 주석은 컴파일러와 인터프리터에 의해 무시되므로 따로 실행되지 않습니다. 코드의 가독성을 높이는 것 외에도 주석은 디버깅할 때 도움이 됩니다. - 두 줄의 ]]>
                </description>
                <link>https://www.freecodecamp.org/korean/news/pythonyi-yeoreo-jul-juseog-pythoneseo-yeoreo-julro-juseogeul-namgineun-bangbeob/</link>
                <guid isPermaLink="false">63076029b9e7840586029390</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yeonhee Hayden Kim ]]>
                </dc:creator>
                <pubDate>Thu, 01 Sep 2022 06:14:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/korean/news/content/images/2022/09/68747470733a2f2f7777772e66726565636f646563616d702e6f72672f6e6577732f636f6e74656e742f696d616765732f73697a652f77323030302f323032322f30322f6561722d673364636637396235665f313238302d312e706e67.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>기사 원문:</strong> <a href="https://www.freecodecamp.org/news/python-multiline-comment-how-to-comment-out-multiple-lines-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Multiline Comment – How to Comment Out Multiple Lines in Python</a>
      </p><p></p><h3 id="-">주석은 모든 프로그래밍 언어에서 필수적인 요소입니다. 주석을 활용하면 코드에 대한 이해력을 향상시킬 수 있고, 코드의 가독성을 높일 수 있으며, 팀 동료들이 코드의 동작 방식을 이해하도록 도울 수 있습니다.</h3><p>주석은 컴파일러와 인터프리터에 의해 무시되므로 따로 실행되지 않습니다.</p><p>코드의 가독성을 높이는 것 외에도 주석은 디버깅할 때 도움이 됩니다. - 두 줄의 코드가 있다면 그 중 하나는 실행되지 않게끔 주석으로 처리할 수 있습니다.</p><p>다른 프로그래밍 언어와 마찬가지로 파이썬 또한 주석을 지원합니다.</p><p>그런데 파이썬에는 여러 줄 주석에 대한 내장된 메커니즘이 없습니다.</p><p>그러므로 이번 포스팅에서는 Python에서 한 줄 주석을 만드는 방법 뿐만 아니라 여러 줄 주석을 만들기 위한 대안도 보여드리겠습니다.</p><h2 id="python-">Python에서 한 줄 주석을 만드는 방법</h2><p>Python에서 한 줄 주석을 만드려면 각각의 줄에서 맨 앞에 해시(<code>#</code>)를 붙입니다.</p><pre><code class="language-python"># print("Hello world") 

print("Hello campers")
</code></pre><p>출력 결과:</p><pre><code>Hello campers
</code></pre><p>보시는 바와 같이 주석처리된 줄은 출력되지 않았습니다.</p><h2 id="python--1">Python에서 여러 줄 주석을 만드는 방법</h2><p>JavaScript, Java, C++처럼 여러 줄 주석 처리시 <code>/*...*/</code>를 사용하는 다른 프로그래밍 언어와는 다르게 Python에는 여러 줄 주석과 관련하여 내장된 메커니즘이 없습니다.</p><p>Python에서 여러 줄로 주석 처리를 하기 위해 각 줄마다 맨 앞에 해시(<code>#</code>)를 붙일 수 있습니다.</p><pre><code class="language-python"># print("Hello world") 
# print("Hello universe") 
# print("Hello everyone") 

print("Hello campers")
</code></pre><p>출력 결과:</p><pre><code>Hello campers
</code></pre><p>이러한 접근을 통해 기술적으로 한 줄 주석을 여러 개 만들 수 있습니다.</p><p>Python에서 여러 줄 주석을 만들기 위한 진정한 대안은 <strong>독스트링(docstrings)</strong> 을 사용하는 것입니다.</p><p>Python 코드에서 여러 줄 주석을 달기 위해 독스트링을 사용하면 해당 코드 블록은 무시될 것이며 독스트링 바깥에 있는 코드만 실행될 것입니다.</p><pre><code class="language-python">""" 
독스트링으로 만든 여러 줄 주석입니다

print("Hello world") 
print("Hello universe") 
print("Hello everyone") 
""" 

print("Hello campers")
</code></pre><p>출력 결과:</p><pre><code>Hello campers
</code></pre><p><strong>주의:</strong> 주석 처리를 위해 독스트링을 사용할 때 들여쓰기에 유의하세요. 4칸 들여쓰기(또는 Tab 키)를 사용한다면 들여쓰기 에러가 발생할 수 있습니다.</p><p>예를 들어 아래의 코드는 잘 동작합니다.</p><pre><code class="language-python">def addNumbers(num1, num2, num3): 
    """ 
    세 숫자의 합을 반환하는 함수
    """ 
    return num1 + num2 + num3 
print(addNumbers(2, 3, 4)) 

# 출력 결과: 9
</code></pre><p>하지만 아래의 코드는 동작하지 않습니다.</p><pre><code class="language-python">def addNumbers(num1, num2, num3): 
""" 
세 숫자의 합을 반환하는 함수
""" 
    return num1 + num2 + num3 
print(addNumbers(2, 3, 4)) 
</code></pre><p>IDE에는 다음 에러가 발생합니다. "<code>IndentationError: expected an indented block</code>"</p><h2 id="--1">결론</h2><p>Python에는 여러 줄 주석을 지원하는 내장 기능이 없기 때문에 이 포스팅에서는 독스트링을 대안으로 사용하는 방법을 다루었습니다.</p><p>독스트링으로 여러 줄 주석을 만들 수 있더라도 보통의 경우에는 해시(<code>#</code>)를 사용해서 Python에 규정된 주석 방침을 고수해야 합니다. 독스트링의 주된 목적은 코드에 주석을 다는 것이 아니라 문서화를 하기 위한 것이기 때문입니다.</p><p>이 포스팅이 유익했다면, 친구들과 가족들에게 공유해보세요.</p><p>읽어주셔서 감사합니다.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
