<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>soyoung2022.log</title>
        <link>https://velog.io/</link>
        <description>Major in IT Engineering(2021.03~)</description>
        <lastBuildDate>Sat, 27 Jul 2024 10:41:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. soyoung2022.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ddo_0" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[RAG/Langchain - (1) ChatOpenAI, invoke, stream, batch]]></title>
            <link>https://velog.io/@ddo_0/RAGLangchain-1-ChatOpenAI-invoke-stream-batch</link>
            <guid>https://velog.io/@ddo_0/RAGLangchain-1-ChatOpenAI-invoke-stream-batch</guid>
            <pubDate>Sat, 27 Jul 2024 10:41:59 GMT</pubDate>
            <description><![CDATA[<h3 id="chatopenai">ChatOpenAI</h3>
<blockquote>
<p>랭체인에서 ChatOpenAI를 이용하면 OpenAI에서 제공하는 채팅 전용 LLM(Large Language Model)을 사용할 수 있다.</p>
</blockquote>
<ul>
<li>temperature : 0~2 사이의 값 / 높은 값일수록 출력의 무작위성 높아짐 &amp; 낮은 값일수록 출력 결정론적이게 됨 </li>
<li>max_tokens : 출력될 문장의 최대 토큰 개수</li>
<li>model_name : 적용할 모델 ex. &#39;gpt-4&#39;, &#39;gpt-3.5-turbo&#39;, &#39;gpt-4-turbo&#39;</li>
</ul>
<pre><code class="language-python">from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    temperature=0,
    max_tokens=256,
    model_name=&#39;gpt-4&#39;
)

query = &quot;대한민국의 가을은 몇 월부터 몇 월까지야?&quot;

response = llm.invoke(query) # reponse = content + response_metadata

print(f&quot;답변 내용 : {response.content}&quot;) # llm 답변이 출력됨 
print(f&quot;메타 데이터 : {response.response_metadata}&quot;) # model_name, token_usage 등이 출력됨 </code></pre>
<ul>
<li>답변을 실시간으로 받고 싶다면 invoke() 대신 stream()을 사용하면 됨 - streaming option</li>
</ul>
<pre><code class="language-python">from langchain_openai import ChatOpenAI
from langchain_teddynote.messages import stream_response

llm = ChatOpenAI(
    temperature=0,
    max_tokens=256,
    model_name=&#39;gpt-4&#39;
)

query = &quot;대한민국의 대표 음식 5가지를 알려줘&quot;
response = llm.stream(query)
for token in response:
    print(token.content, end=&quot;&quot;, flush=True)

query = &quot;호주의 대표 도시 3개를 고르고 각 도시에 대한 간단한 소개를 해줘.&quot;
response = llm.stream(query)
stream_response(response)</code></pre>
<h3 id="invoke-stream-batch-함수">invoke, stream, batch 함수</h3>
<blockquote>
<p>사용자 정의 체인을 쉽게 만들도록 대부분의 컴포넌트에 Runnable 프로토콜을 구현해 놓았으며, 이 중 invoke, stream, batch는 다음과 같은 역할을 수행하는 표준 인터페이스이다. </p>
</blockquote>
<ul>
<li>invoke : 입력에 대한 체인 호출(응답)</li>
<li>stream : 응답 청크 스트리밍(실시간 출력)</li>
<li>batch : 입력 여러 개(배치)에 대한 체인 호출(배치 처리하는 응답)</li>
</ul>
<pre><code class="language-python">from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(
    temperature=0.2,
    model_name=&quot;gpt-4-turbo&quot;
)
prompt = PromptTemplate.from_template(&quot;{location}에 대해 소개하는 글을 2문장으로 작성해줘.&quot;)
chain = prompt | llm | StrOutputParser() # create chain

# invoke
chain.invoke({&quot;location&quot;: &quot;서울&quot;})

# stream
for token in chain.stream({&quot;location&quot;: &quot;서울&quot;}):
    print(token, end=&quot;&quot;, flush=True)

# batch 
chain.batch([{&quot;location&quot; : &quot;서울&quot;}, {&quot;location&quot; : &quot;캘리포니아&quot;}])</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[RAG/Langchain (0) - 시작!!]]></title>
            <link>https://velog.io/@ddo_0/RAGLangchain-0-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@ddo_0/RAGLangchain-0-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Sat, 27 Jul 2024 10:41:33 GMT</pubDate>
            <description><![CDATA[<p>개강 전까지 한 달하고 조금의 시간이 남아서 시작한 RAG, Langchain 공부! RAG는 원래 알고 있었지만, Langchain은 저번에 SKT AI fellowship 6기를 지원할 때 알게 되었는데 공부해서 졸프 때 사용해보면 재밌을 것 같아서 이번 기회에 공부해보기로 했다.</p>
<p>사용하는 교재는 &quot;랭체인으로 LLM 기반의 AI 서비스 개발하기&quot;이고, 사용하는 인터넷 교재는 &quot;<a href="https://wikidocs.net/book/14314">위키독스 - 랭체인LangChain 노트</a>&quot;이다. </p>
<p>기본적으로 정리는 노션에 해서 많은 내용을 올리지는 않을 텐데, 보통 구글링하면서 공부한 내용을 중심으로 올릴 것 같다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Paper #1] A large annotated corpus for learning natural language inference (emnlp 2015) 리뷰]]></title>
            <link>https://velog.io/@ddo_0/Paper-1-A-large-annotated-corpus-for-learning-natural-language-inference-emnlp-2015-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@ddo_0/Paper-1-A-large-annotated-corpus-for-learning-natural-language-inference-emnlp-2015-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Fri, 25 Aug 2023 12:08:56 GMT</pubDate>
            <description><![CDATA[<h2 id="정한-이유">정한 이유</h2>
<p>이번에 Downstream Task 하나를 추가로 해보는 과정에서 NLI 데이터셋을 가지고 해볼까 하는데, NLI dataset 찾아보니 SNLI가 나와서 읽어보려 한다. </p>
<h2 id="논문-pdf-링크">논문 pdf 링크</h2>
<p><a href="https://nlp.stanford.edu/pubs/snli_paper.pdf">&#39;A large annotated corpus for learning natural language inference&#39;</a></p>
<h2 id="리뷰">리뷰</h2>
<h3 id="abstract">Abstract</h3>
<ul>
<li>entailment, contradiction을 이해하는 것 → 자연어를 이해하는 데 기본적인 요소</li>
<li>entailment, contradiction에 대한 추론 → semantic representation의 발전을 위한 중요한 실험 대상</li>
</ul>
<p>→ 하지만, 이 분야의 ML 연구는 대규모 리소스의 부족으로 인해 제한 받았음. 이 문제를 해결하기 위해 SNLI(Standford Natural Language Inference)를 제안하려고 함. </p>
<ul>
<li>SNLI는 인간이 작성한 레이블 달린 57만 개 문장 쌍의 모음으로 구성된다. </li>
</ul>
<p>→ 2배 가량이 커진 것으로, 이는 lexicalized classifier들이 일부 복잡한 entailment model보다 더 나은 성능을 발휘할 수 있게 하고 신경망 기반 모델이 처음으로 NLI에서 경쟁력 있는 결과를 낼 수 있게 함. </p>
<h3 id="introduction">Introduction</h3>
<ul>
<li><p>entailment and contradiction의 의미적 개념 → 자연어의 모든 측면에 중요한 역할을 함</p>
</li>
<li><p>어휘 ~ 전체 텍스트 내용까지 이러한 의미적 개념 → 중심 역할을 함</p>
</li>
<li><p>symbolic logic, knowledge bases, neural networks 등 다양한 기술을 활용하여 NLI를 다뤄왔는데, NLI는 (2015년 기준) 최근 몇 년 동안 distributed words와 phrase representation을 이용하는 접근 방식에 있어 중요한 testing ground로 작용함</p>
</li>
<li><p>Distributed Representation(분산 표현)은 similarity(유사도)를 기반으로 한 relations를 파악하는 데 능하고, simple dimension of meaning을 모델링하는 데 효과적임이 입증됨. 하지만, 이러한 분산 표현이 NLI가 필요로 하는 범위의 논리 및 상식 추론을 지원할 수 있는지는 덜 명확함 
ex. NLI에 대한 분산 표현의 성능을 평가하는 것이 목표였던 SemEval 2014 task에서 최고 성능을 낸 시스템들은 추가적인 feature와 reasoning capability(추론 능력)에 크게 의존적이었음</p>
</li>
<li><p>이 논문의 목표는 NLI에 대해 학습 중심 접근 방식의 경험적 평가를 제공해, NLI를 semantic representation에 대해 도메인-일반적인 평가 도구로 발전시키는 것이다. </p>
</li>
<li><p>하지만, 기존의 NLI 말뭉치는 다음과 같은 단점을 지님</p>
<ul>
<li>현대의 집약적이고 광범위한 모델을 학습시키기에는 너무 작음</li>
<li>많은 말뭉치는 알고리즘적으로 생성된 문장을 포함함</li>
<li>주석 퀄리티에 상당한 영향을 주는 event-entity coreference의 불확실성에 종종 둘러싸임</li>
</ul>
</li>
</ul>
<p>→ 이러한 문제를 해결하기 위해 이 논문에서는 SNLI 말뭉치를 제안하고자 함</p>
<ul>
<li>SNLI는 다음과 같은 특징을 가짐<ul>
<li>570,152 쌍의 문장으로 구성됨</li>
<li>labels : entailment, contradiction, semantic independence</li>
<li>이와 유사한 기존 말뭉치보다 2배 정도 큼</li>
<li>다른 자료들과 달리, 모든 문장과 레이블이 실제 상황을 기반으로 한 자연스러운 맥락에서 인간에 의해 작성됨 (예제 중 56,941개에 대해 각 레이블에 대해 추가적으로 4명의 판단을 수집 → 이 중 98%는 3명의 판단이 일치, 58%는 모든 5명(기존 포함)의 판단이 일치함)</li>
</ul>
</li>
</ul>
<h3 id="a-new-corpus-for-nli">A new corpus for NLI</h3>
<ul>
<li><p>논문이 나오기 전까지 주석이 달린 NLI 말뭉치의 주요 출처는 RTE(Recognizing Textual Entailment) challenge 태스크였음
→ 고품질/수작업 레이블링된 데이터 세트였음
→ 하지만, 크기가 너무 작았음
→ 크기 측면에서 한 단계 더 나아간 SemEval 2014 작업인 SICK(Sentences Involving Compositional Knowledge)조차도 훈련 데이터로 4,500개만 존재했음
→ (sentence-level entailment) Denotation Graph entailment set, (outside of sentence-level entailment) Levy et al.(2014), second release of the Paraphrase Database도 비슷하게 뭔가 한계?가 있었음</p>
<ul>
<li>Denotation Graph entailment set : entailment sentence 예제 수백만개를 가졌으나 모두 automatic-method로 라벨링되어 노이즈가 많아 오로지 supplementary training data로만 이용할 수 있었음</li>
<li>Levy et al.(2014) : 반자동으로 주석이 달린 entailment 예시들(주어-동사-목적어 relation triples) 가짐</li>
<li>second release of the Paraphrase Database : 단어와 짧은 구문들 쌍의 대규모 말뭉치에 대해 자동 생성된 주석 포함함</li>
</ul>
</li>
<li><p>이렇게 기존에 존재하는 리소스들은 심지어 인간이 직접 제공한 주석들만 사용하는 프로젝트에도 영향을 끼치는 issue가 있었음</p>
</li>
<li><p><em>→ event와 entity coreference의 indeterminacies(불확실성) ⇉ correct semantic label의 불확실성으로 이어짐*</em></p>
<p>   event coreference
   ex. &quot;A boat sank in the Pacific Ocean&quot; &amp; &quot;A boat sank in the Atlantic Ocean.&quot; 
   → 접근 방식 1) 두 문장이 같은 하나의 event를 가리킨다고 가정 : contradiction으로 라벨링
   → 접근 방식 2) 위와 같은 가정이 없다고 가정 : 합리적으로 생각했을 때 neutral로 라벨링
   ⇉ 위와 같은 문제를 해결하기 위해 위 2가지 접근 방식 중 하나를 정하여 모든 접근 방식을 통일해야 하지만, 이는 문제가 존재한다. </p>
<p>   접근 방식 통일 시 발생하는 문제</p>
<ul>
<li><p>opt not to assume that events are coreferent → broad universal assertioin을 만드는 문장들 사이에서 contradiction만을 발견할 것임</p>
</li>
<li><p>opt to assume coreference → counterintuitive prediction이 나올 것임
  ex. &quot;Ruth Bader Ginsburg was appointed to the US Supreme Court&quot; &amp; &quot;I had a sandwich for lunch today&quot;
  coreference를 가정하면 위 쌍은 neutral이 아니라 contradiction으로 라벨링될 것임</p>
<p>entity coreference
ex. &quot;A tourist visited New York&quot; &amp; &quot;A tourist visited the city&quot;
→ New York과 the city 간 coreference를 가정하면 entailment 라벨링이 타당할 것임
→ 하지만 그 가정이 없으면 the city가 특정한 unknown city를 가리킬 수 있으므로 neutral로 라벨링될 것임</p>
</li>
</ul>
</li>
</ul>
<p><strong>👉🏻 라벨링 관련 indeterminacy(불확정성) 문제는 coreference question이 해결되어야지만 해결 가능함</strong></p>
<ul>
<li>SNLI은 size, quality, indeterminacy 문제에 대응하려고 노력함<ol>
<li>예제들은 특정 시나리오에 근거하여 만들어졌으며, 각 예제의 전제(premise)와 가설(hypothesis) 문장은 동일한 관점에서 해당 시나리오를 묘사하도록 제한되었음
→ event and entity coreference를 다루는 데 있어 큰 도움이 될 것임</li>
<li>참가자들에게 task setting 내에서 완전히 새로운 문장을 생성할 수 있는 자유를 부여하는 프롬프트를 제공
→ 일관성을 희생하지 않으면서 더 풍부한 예제를 얻을 수 있음</li>
<li>result sentence의 subset은 validation task로 보내짐
→ 동일한 데이터에 대해 신뢰성 있는 주석 집합을 제공하기 위해
→ 추론적 불확실성 영역을 식별하기 위해</li>
</ol>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/6d243c50-353c-4b01-b649-cf5555a4a449/image.png" alt=""></p>
<h4 id="data-collection">Data collection</h4>
<ul>
<li>데이터 수집을 위해 Amazon Mechanical Turk을 사용함</li>
<li>각 HIT(개별 작업)에서 각 worker : 기존의 말뭉치로부터 가져온 premise scene descriptions을 제시받고 entailment, contradiction, neutral 이 3개의 레이블들 각각에 대한 hypothesis sentence를 제시하도록 요청받음(이는 데이터에서 3개의 클래스들이 서로 balance를 유지하는 데 도움을 줌) 아래 Figure 1이 worker들에게 제공되는 instruction임</li>
</ul>
<p align="center">
<img src="https://velog.velcdn.com/images/ddo_0/post/7476c7f2-34d9-44fb-b56a-272fd0760723/image.png" width="50%"></p>

<ul>
<li>약 2,500명의 worker가 참여함</li>
<li>premise : Flickr30k 말뭉치에서의 caption 160,000개를 사용함<ul>
<li>이 캡션은 30,000개 이미지로부터 논문의 접근 방식에 알맞게 구성한 캡션임</li>
<li>각 문장 쌍의 라벨이 가능한 텍스트에 기반해 recover될 수 있도록 하기 위해 말뭉치 수집 과정 중에 이미지는 전혀 사용하지 않음</li>
</ul>
</li>
</ul>
<p align="center">
<img src="https://velog.velcdn.com/images/ddo_0/post/c355e559-416e-48a8-96b7-24a46f26efdc/image.png" width="50%">
<img src="https://velog.velcdn.com/images/ddo_0/post/6725401a-2623-4f29-bbec-392192488e3f/image.png" width="70%" height="50%"> </p>

<ul>
<li>Table 2는 수집된 corpus의 통계적 정보를 나타냄. </li>
<li>Figure 2는 source hypothesis와 새롭게 수집된 premise들의 문장 길이 분포를 나타냄</li>
<li>발견한 것<ol>
<li>premise는 길이 측면에서 다양하지만, hypothesis는 명확한 판단을 내릴 수 있는 상태인 동시에 가능한 짧은 길이였음 (Figure 2를 보면 대략 7단어 정도에서 많이 모여있는 것을 볼 수 있음)</li>
<li>sources의 sentence들은 모두 단편적인 것이 아니라 문법적으로 완전한 형태였음(Parser output을 보면 Premise, Hypothesis 모두 &#39;S&#39;-rooted parses 비율이 높음 ⇉ 파싱 트리 형태를 말하는 듯)</li>
</ol>
</li>
</ul>
<h4 id="data-validation">Data validation</h4>
<ul>
<li>데이터 10%에 대해 추가적인 validation phase를 진행함<ol>
<li>말뭉치 quality를 측정하기 위함</li>
<li>유용한 testing, validation set을 구성하기 위함</li>
</ol>
</li>
<li>SICK에서 entailment sentence에 레이블링할 때 사용한 Mechanical Turk 라벨링 태스크와 동일한 방식을 따름<ul>
<li>문장 쌍이 5개씩 묶여 있는 배치들을 worker에게 제시 → worker는 주어진 문장 쌍에 라벨링하도록 함 → 각 문장 쌍은 4명의 annotator에게 라벨링됨 → 원래 존재했던 라벨 1개를 포함해 총 5개의 라벨을 얻음(Figure 1.에 나온 형태와 비슷함)</li>
<li>&quot;gold label&quot;을 정함 → gold label은 5개 라벨 중 최소 3개 이상이 일치한 경우를 가리킴</li>
<li>만약 그러한 일치가 없었다면(2%의 경우 이랬음) 라벨에 &#39;-&#39;를 마킹함(이러한 데이터는 도움이 되지 않을 것이라 판단해 training, evaluation 모두에 이용하지 않았음)</li>
</ul>
</li>
</ul>
<p>⇉ 이러한 검증 결과는 아래 Table 3에 나타남</p>
<p align="center">
<img src="https://velog.velcdn.com/images/ddo_0/post/464d056f-f763-4a94-a9fe-08e1fde33e31/image.png" width="50%"></p>

<ul>
<li><em>Fliess 𝒦 점수는 아마 플라이스 카파 점수를 말하는 것 같음(겹치는 문서에서 여러 사용자 어노테이터가 얼마나 일관되게 동일한 어노테이션을 적용했는지 나타내는 수치로, 최고값은 1이고 최저값은 0임)</em></li>
</ul>
<h4 id="the-distributed-corpus">The distributed corpus</h4>
<ul>
<li>distributed corpus는 Stanford PCFG 파서 3.5.2 (Klein and Manning, 2003)가 생성한 parse가 포함되어 있음(이는 표준 훈련 세트와 Brown Corpus (Francis and Kucera 1979)에서 훈련되었으며, 이를 통해 기술적 문장과 설명에 나타난 명사 구문의 parse 품질을 개선할 수 있었음)</li>
</ul>
<h3 id="our-data-as-a-platform-for-evaluation">Our Data as a platform for evaluation</h3>
<ul>
<li>위에서 만들어진 데이터셋은 가장 먼저 NLI task를 수행하는 모델을 개발하는 데 사용됨</li>
<li>데이터는 품질을 비교할 만한 기존의 데이터에 비해 크기가 컸음 → 이전에는 NLI task에 잘 사용되지 않았고 별로 성능이 좋지도 않았던 training paramter-rich model을 선택함 <em>ex. 신경망 모델</em><ul>
<li><strong>다음 3가지 모델 성능 평가할 예정</strong></li>
</ul>
<ol>
<li>잘 알려진 NLI 시스템인 Excitement Open Platform의 모델</li>
<li>강력하면서도 단순한, lexicalized &amp; unlexicalized 특성을 모두 활용하는 classifier model의 변형</li>
<li>baseline model &amp; neural network sequence model을 포함하는 분산 표현 모델</li>
</ol>
</li>
</ul>
<h4 id="excitement-open-platform-model">Excitement Open Platform Model</h4>
<ul>
<li>Excitement Open Platform: RTE research를 위한 오픈 소스 플랫폼<ul>
<li>EOP는 common lexical resources와 evaluation sets를 공유하며 NLI 시스템을 빠르게 개발할 수 있는 도구임</li>
</ul>
</li>
<li>2가지 알고리즘을 평가할 예정<ol>
<li>edit-distance based algorithm(편집 거리 알고리즘)</li>
<li>classifier-based algorithm<ul>
<li>이 경우, 기본 형태와 EOP의 전체 어휘 집합으로 보강된 형태 모두 평가됨</li>
</ul>
</li>
</ol>
</li>
</ul>
<p>_cf) RTE(Recognizing Textual Entailment) : 텍스트 데이터에서는 같은 의미의 내용이 다른 표현으로 쓰여 있는 경우가 많은데, 다른 표현이 같은 의미라는 것을 인식하는 기술을 RTE라 한다. _</p>
<p align="center">
<img src="https://velog.velcdn.com/images/ddo_0/post/2bd1af26-dddb-42e8-8c5e-30dd7a28696a/image.png" width="50%"></p>

<ul>
<li>목표 : 최신 RTE 성능을 측정하기 보다는 먼저 classifying NLI corpus inference 태스크의 어려움을 이해해보고자 함 → 같은 시스템을 여러 데이터 세트에 적용함으로써 접근해보고자 함</li>
<li>사용한 데이터 세트 3개는 다음과 같음<ol>
<li>own test set(SNLI)</li>
<li>SICK test data</li>
<li>standard RTE-3 test set</li>
</ol>
</li>
<li>결과는 Table 4에 나와있음<ul>
<li>각 모델은 각 corpus의 training set을 이용해 개별적으로 학습됨</li>
<li>모든 모델은 2-class entailment에 기반해 평가됨 → SICK, SNLI와 같이 3가지 클래스 기반으로 하는 데이터셋은 contradiction과 neutral(unknown)이 non-entailment로 convert됨</li>
<li>edit-distance based : stop words 제거 후 training set에서 대소문자를 구분하지 않는 edit-distance 연산의 가중치를 조정함</li>
<li>플랫폼에서 기본적으로 제공하는 classifier외에도 WordNet (Miller, 1995)과 VerbOcean (Chklovski and Pantel, 2004)의 정보를 포함하고, tree patterns and dependency tree skeletons에 기반을 둔 features를 활용한 많은 variants를 학습함</li>
</ul>
</li>
</ul>
<h4 id="lexicalized-classifier">Lexicalized Classifier</h4>
<ul>
<li><p>a simple lexicalized classifier를 평가할 예정 </p>
<ul>
<li>복잡한 언어 이해 대신 non-specialized model이 rich lexicalized features를 활용하는 ability를 탐구</li>
<li>classifier는 6가지 feature type들을 implement할 예정</li>
</ul>
</li>
<li><p>6 feature types(3 lexicalized &amp; 3 unlexicalized)</p>
<ol>
<li><strong>BLEU(Bilingual Evaluation Understudy Score) score</strong>
: 기계 번역 결과와 사람이 직접 번역한 결과가 얼마나 유사한지 비교하여 번역에 대한 성능을 측정하는 방법</li>
</ol>
<ul>
<li>N-gram에 기반한 측정 기준</li>
<li>값이 높을수록 좋음</li>
</ul>
<ol start="2">
<li><strong>length difference from premise and hypothesis</strong>
: 실수값 feature에 해당됨</li>
<li><strong>overlap between words in the premise and hypothesis</strong>
: 모든 단어/명사/동사/형용사/부사에 대한 overlap, 그리고 발생 가능한 overlap의 absolute count와 percentage를 측정</li>
<li><strong>indicator for every unigram and bigram in the hypothesis</strong>
: bigram - 연속된 2개 단어를 하나의 단어로 사용하는 것</li>
<li><strong>Cross-unigrams</strong>
: POS tag(품사 태그)를 공유하는 premise, hypothesis 간 단어 쌍에 대해 구함</li>
</ol>
<ul>
<li>two words의 indicator feature라 볼 수 있음</li>
</ul>
<ol start="6">
<li><strong>Cross-bigrams</strong>
: premise, hypothesis 간 bigrams들중 두 번째 단어에서 POS tag를 공유하는 쌍들에 대해 구함</li>
</ol>
<ul>
<li>two bigrams의 indicator feature라 볼 수 있음</li>
</ul>
</li>
</ul>
<p align="center"><img src="https://velog.velcdn.com/images/ddo_0/post/3c7d3024-997a-4b25-9e81-e77a3270d360/image.png" width="50%"></p>

<ul>
<li>Table 5에 결과가 보여짐<ul>
<li>cross-bigram feature를 제거하거나 모든 lexicalized feature를 제거하는 연구도 수행 후 결과 제시함</li>
<li>특히 논문에서 제시한 대규모 말뭉치 사용에서는 lexicalized feature를 사용하는 것만으로 상당한 정확도 향상을 확인할 수 있음</li>
<li>sparse cross-bigram feature를 사용할 때도 마찬가지임 ⇉ classifier가 explicit negations와 adjective modification 같은 구조를 자동으로 인식하도록 학습하는 것에 가치가 있음을 알려주는 결과임</li>
<li>classifier가 alignment나 tree transformation에 대한 개념 없이 이렇게 잘 동작하는 것은 놀라울 일임</li>
</ul>
</li>
</ul>
<p>👉🏻 물론 더 풍부한 모델이 더 나은 성능을 내겠지만, 이 결과들은 충분한 데이터가 주어진 경우 노이즈가 있는 part-of-speech(품사) overlap contraint를 가진 cross bigram이 효과적인 모델을 생성할 수 있다는 것을 의미함</p>
<blockquote>
<p>cf) <strong>ablation study</strong> : 딥러닝 리서치 분야에서 사용되는 용어 → 제안한 요소가 모델에 어떠한 영향을 미치는지 확인하고 싶을 때, 이 요소를 포함한 모델과 포함하지 않은 모델을 비교하는 것을 말한다. 이는 system casuality(인과관계)를 간단히 알아볼 수 있어 연구에서 중요한 역할을 한다. </p>
</blockquote>
<h4 id="sentence-embeddings-and-nli">Sentence embeddings and NLI</h4>
<ul>
<li>SNLI는 sentence meaning에 대한 distributed representation을 만드는 neural network model을 학습시킬 만큼 large &amp; diverse함</li>
<li>이번 섹션 : 말뭉치에 대한 3가지 모델의 performance 비교 예정<ol>
<li><strong>baseline sentence embedding model</strong></li>
<li><strong>a plain RNN</strong></li>
<li><strong>an LSTM RNN</strong></li>
</ol>
</li>
<li>informative sentence representation을 만드는 부분에 집중하기 위해 NLI 분류 태스크의 중간 단계로써 sentence embedding을 사용할 것임<ol>
<li>각 모델은 다른 문장의 context 등을 이용하지 않고 two senetences에서 각각에 대한 vector representation을 만든다. </li>
<li>만들어진 2개의 vectors는 해당 벡터를 받아서 쌍에 대한 label을 예측하는 model에 전달됨</li>
</ol>
</li>
</ul>
<p align="center">
  <img src="https://velog.velcdn.com/images/ddo_0/post/52f1f8ca-75f3-4c52-ad2f-91f164f7d6ea/image.png" width="50%">
</p>

<ul>
<li>neural network classifier 구조는 위 그림과 같음<ul>
<li>premise, hypothesis를 입력으로 받은 후 100 차원의 sentence representation을 출력으로 내보내는 모델을 활용해 나온 벡터를 합쳐 입력으로 전달함</li>
<li>200 차원 tanh 레이어 3개가 쌓여 있음</li>
<li>맨 위에는 3-way softmax classifier가 존재함</li>
</ul>
</li>
</ul>
<blockquote>
<p><em>cf) 3-way softmax classifier : 3개의 클래스, 즉 3개의 뉴런이 존재하는 softmax classifier를 가리킴</em></p>
</blockquote>
<ul>
<li>baseline sentence embedding model은 각 문장에 있는 모든 words embedding의 합(sum)을 사용함</li>
<li>모든 모델의 word embedding은 840B 토큰 버전의 300차원 GloVe vecotr들로 초기화됨 + 훈련의 일부로 fine-tuning됨</li>
<li>모든 모델은 300차원을 저차원으로 맵핑하기 위해 추가적인 tanh neural network layer를 가짐</li>
<li>development set에서 더 이상 성능 향상이 없을 때까지 학습이 진행됨</li>
<li>optimizer : AdaDelta, Regularization : L2</li>
<li>dropout은 sentence embedding models의 input, output에만 적용함(내부에는 적용 X) 
❉ fixed dropout rate</li>
</ul>
<p align="center">
  <img src="https://velog.velcdn.com/images/ddo_0/post/1ad0d3fc-c6fb-4fca-aac5-d1a5df96f24c/image.png" width="50%">
</p>

<ul>
<li>Table 6 : accracy in 3-class classification <ol>
<li>100d sum of words
: lexicalized classifier보다 성능이 떨어짐</li>
</ol>
<ul>
<li>sum of words는 pre-trained word embedding을 사용해 드문 단어를 더 잘 처리할 수 있지만, lexicalized classifier의 bigram feature가 제공하는 word order sensitivity를 제공하지는 못함</li>
</ul>
<ol start="2">
<li>100d RNN
: 제일 성능 좋지 X</li>
<li>100d LSTM RNN
: test 성능이 lexicalized classifier과 비슷함</li>
</ol>
<ul>
<li>LSTM RNN model은 iteration이 멈추는 부분 주변에서 0.5% 정도의 테스트 정확도 차이가 발생함</li>
</ul>
</li>
</ul>
<p>→ Lexicalized model과 다르게 이번에 테스트한 3가지 모델은 훈련 ⟷ 테스트 간 정확도 차이가 크지 않다. <em>(만약, 모델이 더 크면 연구가 상당히 의미있을 수 있음을 시사한다고 함)</em></p>
<h4 id="analysis-and-discussion">Analysis and Discussion</h4>
<p align="center">
  <img src="https://velog.velcdn.com/images/ddo_0/post/b5e08722-3817-4d7f-9ce0-8296a7788b13/image.png" width="50%">
</p>

<ul>
<li><p>Figure 4 : training data 양을 다르게 하여 학습했을 때의 learning curve임</p>
<ul>
<li>corpus의 large size가 lexicalized, lstm model 모두에게 중요함을 나타냄</li>
<li>lstm의 가파른 학습 곡선 → 임의의 structured representations of sentence meaning을 학습하는 lstm의 능력은 lstm이 여전히 더 큰 데이터셋에서 constrained-lexicalized model보다 우위를 지닐 수 있음을 말함</li>
<li>놀라운 결과는 오직 training pairs 100개를 가지고 lexicalized model이 unlexicalized model 성능을 능가했다는 사실임<ul>
<li>100개의 예제로 학습된 classifier의 top weighted features는 high precision entailments를 가짐
<em>ex. playing → outsides(most scenes are outdoors), a banana → person eating</em></li>
</ul>
</li>
<li>만약 상대적으로 작은 suprious한 entailments가 높은 가중치를 얻었다면 entailments를 식별하는 정확도가 높이 올라갈 수 있었을 것임</li>
</ul>
</li>
<li><p>위에서 다뤄진 모든 모델에 대해서 공통적으로 나타나는 error에는 드러나는 패턴이 있음</p>
<ul>
<li>large corpus &amp; GloVe initialized에 의한 distributed information에도 불구하고 여전히 많은 lexical information이 잘못 분석되고 있었고 이는 incorrect prediction으로 이어졌음
ex. training set에 흔한 <em>surf/beach &amp; runner/sprinter</em> 단어에 대해 independent하다고 예측</li>
<li>word가 아니라 phrase level → compositional semantics에 대한 관심이 이후 좋은 결과를 가져올 것임을 시사함</li>
<li>지속적으로 나타는 문제들 중 많은 것이 world knowledge &amp; context-specific inferences에 의존하는 추론에 깊게 연관되어 있음
ex. A race car driver leaps from a burning car/A race car driver escaping danger → classifier &amp; LSTM 모두 neutral로 예측(answer=entailment)</li>
<li>아래 예시들과 같이 문장끼리 완전히 다른 의미인데 인과관계를 잘못 예측하는 경우도 많았음
ex1. A woman prepares ingredients for a bowl of soup/A soup bowl prepares a woman
ex2. A man wearing padded arm protection is being bitten by a German shepherd dog/A man bit a dog</li>
</ul>
</li>
</ul>
<h3 id="transfer-learning-with-sick">Transfer learning with SICK</h3>
<p>❉ LSTM과 같은 신경망 모델을 SNLI에서 성공적으로 훈련시키려면 해당 모델은 영어로 된 장면 설명의 넓은 범위의 정확한 representation을 인코딩하고 그 관계들을 통해 entailment classifier를 구축해야 함</p>
<ul>
<li>이번 section에서는 간단한 transfer learning method(Pratt et al., 1991)를 이용해 SICK entailment task를 수행함<ul>
<li>SNLI에서 훈련된 LSTM RNN 모델의 매개변수를 가져와서 새로운 모델을 초기화하고, 이 모델은  이후에 SICK의 훈련 부분만을 사용하여 훈련됨</li>
<li>새로 초기화되는 파라미터는 softmax layer의 파라미터와 SNLI에는 없지만 SICK에서 나오는 단어들에 대한 embedding(GloVe로 채워짐)이다. </li>
<li>L2 Regularization 강도만 다시 조정하고 원래 모델을 훈련할 때 사용된 모델 하이퍼파라미터와 동일한 하이퍼파라미터를 사용함</li>
</ul>
</li>
</ul>
<p align="center">
<img src="https://velog.velcdn.com/images/ddo_0/post/0a39ec5d-eb6f-4b62-bb02-4e5a6b9a6f56/image.png" width="50%"></p>

<ol>
<li>training on SICK alone
: SICK만을 훈련한 경우 성능이 좋지 않음</li>
<li>model trained on SNLI
: SNLI에서 훈련한 모델은 SICK 데이터에서 테스트할 때 예측에 실패하는 경우가 많음</li>
</ol>
<ul>
<li>neutral을 contradiction으로 잘못 분류하는 경우가 더 많음</li>
<li>이는 레이블링 작업이 어떻게 제시되었는지에 따른 미묘한 차이로 인한 것일 수 있음</li>
</ul>
<ol start="3">
<li>transferring SNLI representations 
: 최고의 성능을 냄 </li>
</ol>
<ul>
<li>large high-quality corpus → sentence meaning 대한 representaion-learning model을 훈련하여 inference task에서 best hand-engineered된 모델과 경쟁할 수 있음을 시사함</li>
</ul>
<h3 id="conclusion">Conclusion</h3>
<ul>
<li>자연어는 추론의 강력한 수단 &amp; 언어의 의미에 대한 거의 모든 질문은 문맥에서의 entailment와 contradiction에 대한 질문으로 축소될 수 있음</li>
<li>NLI = an ideal testing ground for theories of semantic representation → 현존하는 NLI resources의 본질적인 한계로 인해 쉽지 않음</li>
<li>a new, largescale, naturalistic corpus of sentence pairs labeled
for entailment, contradiction, and independence를 이용해 논문에서는 이 문제를 해결하려 함 → corpus를 이용해 다양한 모델을 평가함<ol>
<li>simple lexicalized models &amp; neural network models 성능이 잘 나옴</li>
<li>neural network model이 corpus에 대해 학습한 representations은 standard challenge dataset의 성능을 꽤 향상시킬 수 있음을 알게 됨</li>
</ol>
</li>
<li>SNLI = semantic representation에 ML을 계속 적용하는 데 유용한 훈련 데이터가 되길 바람</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD 준비 #3] 데이터모델링의 이해_1장(2) 엔티티/속성/관계]]></title>
            <link>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-3-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%AA%A8%EB%8D%B8%EB%A7%81%EC%9D%98-%EC%9D%B4%ED%95%B41%EC%9E%A52-%EC%97%94%ED%8B%B0%ED%8B%B0%EC%86%8D%EC%84%B1%EA%B4%80%EA%B3%84</link>
            <guid>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-3-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%AA%A8%EB%8D%B8%EB%A7%81%EC%9D%98-%EC%9D%B4%ED%95%B41%EC%9E%A52-%EC%97%94%ED%8B%B0%ED%8B%B0%EC%86%8D%EC%84%B1%EA%B4%80%EA%B3%84</guid>
            <pubDate>Thu, 10 Aug 2023 16:22:37 GMT</pubDate>
            <description><![CDATA[<h2 id="erdentity-relationship-diagram">ERD(Entity-Relationship Diagram)</h2>
<blockquote>
<p>&#39;Entity 개체&#39;와 &#39;Relationship 관계&#39;를 중점적으로 표시하는 데이터베이스 구조를 한 눈에 알아보기 위해 그리는 다이어그램이다. 개체 관계도라고도 불리며 요구분석 사항에서 얻은 엔티티와 속성들의 관계를 그림으로 표현한 것이다.</p>
</blockquote>
<ul>
<li>데이터베이스 설계 단계 중 개념적 모델링 단계에서 ERD를 작성한다. </li>
<li>ER Model을 도식화하여 표현하는 방법이 ERD이다. </li>
<li>현재 가장 인기가 많은 RDB 테이블 구조로 사상하기 쉬워 자주 사용된다. </li>
</ul>
<h3 id="erd-표기법">ERD 표기법</h3>
<p>: ERD 표기법에는 Peter-Chen 표기법(엔티티-직사각형, 속성-타원형, 릴레이션-마름모로 표현), 까마귀 발 표기법, IE 표기법과 Baker 표기법이 존재한다. (실무에서는 IE 표기법을 많이 사용한다.)</p>
<h4 id="엔티티">엔티티</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/981d799c-1841-4946-acd5-7ca9aa5c895a/image.png" alt=""></p>
<ul>
<li>위 그림과 같이 직사각형으로 엔티티를 표기한다. </li>
<li>약한 엔티티는 모서리가 둥근 직사각형으로 표기한다. </li>
</ul>
<h4 id="속성">속성</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/3e8c56b8-9073-4630-bff5-19c41a032d6d/image.png" alt=""></p>
<ul>
<li>Entity 이름 하단 좌측에 PK, FK 등의 정보를 표기하고, 우측에는 속성 이름을 표기한다.</li>
</ul>
<p>❉ 원으로 표현되기도 한다. </p>
<h4 id="관계">관계</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/63e87c86-2e72-40fd-9dba-f5f3e01089d0/image.png" alt=""></p>
<ol>
<li><strong>식별 관계</strong>
: 부모 테이블의 기본키나 유니크키를 자식 테이블이 기본 키로 사용하는 경우 식별 관계라 한다. </li>
</ol>
<ul>
<li>부모 테이블에 무조건 데이터가 하나 이상 존재해야 자식 테이블 데이터가 생성될 수 있다. </li>
<li>즉 자식 데이터가 있으면 적어도 부모 데이터가 하나 이상 존재하며, 부모 테이블에 자식 테이블이 종속된다. </li>
<li>ERD에서 <strong>실선</strong>으로 표기한다. 
<em>ex. 학생 ⟷ 성적</em></li>
</ul>
<ol start="2">
<li><strong>비식별 관계</strong>
: 부모 테이블의 기본키나 유니크키를 자식 테이블이 외래 키로 사용하는 경우 비식별 관계라 한다. </li>
</ol>
<ul>
<li>자식 데이터는 부모 데이터가 없어도 독립적으로 생성될 수 있다. </li>
<li>부모와의 의존성이 상대적으로 적어 조금 더 자유롭게 데이터 생성과 수정이 가능하다. </li>
<li>ERD에서 <strong>점선</strong>으로 표기한다. 
<em>ex. 학생 ⟷ 과목</em></li>
</ul>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/34bb834e-feab-4c47-888b-ac7de1573c7e/image.png" alt=""></p>
<ol start="3">
<li><strong>전체 참여 관계</strong></li>
</ol>
<ul>
<li>두 개의 실선으로 표현한다.</li>
</ul>
<ol start="4">
<li><strong>부분 참여 관계</strong></li>
</ol>
<ul>
<li>한 개의 실선으로 표현한다. </li>
</ul>
<p>❉ 마름모로 표현되기도 한다. </p>
<h4 id="mapping-cardinality사상-원소수">Mapping Cardinality(사상 원소수)</h4>
<p>: 특정 엔티티가 다른 엔티티와 관계를 맺을 때 해당 관계를 설명하기 위해 나오는 개념이다. </p>
<ol>
<li><p>1:1 관계
: 대통령과 국가의 관계는 1:1이라 볼 수 있다. </p>
</li>
<li><p>1:N, N:1 관계
: 학생과 학급의 관계를 보자. 한 학생은 하나의 학급에만 속할 수 있고 하나의 학급은 여러 학생을 포함할 수 있다. 따라서 학생과 학급의 Mapping Cardinality는 N:1이라 할 수 있다. </p>
</li>
<li><p>N:M 관계
: 드라마와 배우 사이의 관계를 떠올려보면 쉽다. 한 배우는 여러 드라마에 나올 수 있고, 한 드라마는 여러 배우를 포함할 수 있다. 따라서 1:1 관계로도 1:N 관계로도 나타낼 수 없는 이런 관계를 N:M 관계라 한다. </p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/b4ecb877-ac01-404d-8efb-9ecf1a196d24/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/12eda6d6-c1d6-4c69-a781-6d4624c17b19/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/10b71be4-8549-4ff9-af00-04215c3d1e4a/image.png" alt=""></p>
<h3 id="erd-작성-순서">ERD 작성 순서</h3>
<ol>
<li>엔티티 그리기</li>
<li>엔티티를 적절하게 배치하기</li>
<li>엔티티 간 관계 설정하기</li>
<li>관계명 기술하기(❉ 관계 명칭은 관계 표현에 있어 매우 중요한 부분에 해당됨)</li>
<li>관계의 참여도 기술하기</li>
<li>관계의 필수여부 기술하기</li>
</ol>
<h2 id="엔티티-1">엔티티</h2>
<h3 id="엔티티-분류">엔티티 분류</h3>
<h4 id="분류-기준1-유무형에-따른-엔티티">분류 기준1. 유무형에 따른 엔티티</h4>
<ol>
<li><p><strong>유형 엔티티</strong>
: 물리적 형태가 있고 안정적이며 지속적으로 활용되는 엔티티이다. 
<em>ex. 사원/강사/물품/···</em></p>
</li>
<li><p><strong>개념 엔티티</strong>
: 물리적 형태가 있는 것이 아니라 관리해야 할 개념적 정보가 존재하는 엔티티이다. 
<em>ex. 조직/보험 상품/···</em></p>
</li>
<li><p><strong>사건 엔티티</strong>
: 업무를 수행함에 따라 발생하는 엔티티로, 발생량이 상대적으로 많으며 각종 통계자료에 이용될 수 있다. 
<em>ex. 주문/청구/미납/···</em></p>
</li>
</ol>
<h4 id="분류-기준2-발생-시점에-따른-엔티티">분류 기준2. 발생 시점에 따른 엔티티</h4>
<ol>
<li><p><strong>기본 엔티티 = 키 엔티티</strong>
: 업무에 원래 존재하는 정보로서 다른 엔티티와의 관계에 의해 생성되지 않고 독립적으로 생성이 가능하다. 기본 엔티티는 타 엔티티의 부모 역할을 한다. 또한, 다른 엔티티로부터 주식별자를 상속받지 않고 고유한 주식별자를 가진다. 
<em>ex. 사원/부서/고객/상품/자재/···</em></p>
</li>
<li><p><strong>중심 엔티티 = 메인 엔티티</strong>
: 기본 엔티티로부터 발생되고 업무에 있어서 중심적인 역할을 한다. 많은 데이터가 발생되고 다른 엔터티와의 관계를 통해 많은 행위 엔터티를 생성한다.
<em>ex. 계약/사고/주문/청구/매출/···</em></p>
</li>
<li><p><strong>행위 엔티티</strong>
: 두 개 이상의 부모 엔티티로부터 발생되고 자주 내용이 바뀌거나 데이터량이 증가된다. 분석 초기 단계보다는 상세 설계 단계나 프로세스와 상관 모델링을 진행하며 도출될 수 있다. 
<em>ex. 사원 변경 이력/주문 목록/···</em></p>
</li>
</ol>
<h3 id="엔티티-특징">엔티티 특징</h3>
<ul>
<li>반드시 해당 업무에서 필요하고 관리하고자 하는 정보이어야 한다. 
ex. 환자/토익 응시 횟수/···</li>
<li>유일한 식별자에 의해 식별이 가능해야 한다. </li>
<li>영속적으로 존재하는 인스턴스의 집합이어야 한다. </li>
<li>2개 이상의 인스턴스와 2개 이상의 속성이 존재해야 한다. (소위, 면적으로 표현되어야 한다.)</li>
<li>엔티티는 업무 프로세스에 의해 이용되어야 한다. </li>
<li>엔티티는 다른 엔티티와 최소 한 개 이상의 관계가 있어야 한다. </li>
<li>단, 공통코드/통계성 엔티티는 관계를 생략할 수 있다. </li>
<li>속성을 포함해야 한다. </li>
</ul>
<h3 id="엔티티-명명-규칙">엔티티 명명 규칙</h3>
<ol>
<li>가능하면 현업 업무에서 사용하는 용어 사용하기</li>
<li>가능하면 약어 사용하지 않기</li>
<li>단수 명사 사용</li>
<li>모든 엔티티에서 유일한 이름 부여하기</li>
<li>엔티티가 생성되는 의미대로 이름을 자연스럽게 부여하기</li>
</ol>
<h2 id="속성-1">속성</h2>
<p>: 속성은 업무에서 필요로 하는 인스턴스에서 관리하고자 하는, 의미상 더 이상 분리되지 않는 최소의 데이터 단위를 부르는 말이다. </p>
<h3 id="특징">특징</h3>
<ul>
<li>한 개의 엔터티는 2개 이상의 인스턴스 집합이다.</li>
<li>한 개의 엔터티는 2개 이상의 속성을 가진다.</li>
<li>한 개의 속성은 1개의 속성값을 가진다. (여러 개의 속성값 X)</li>
<li>속성도 집합이다.</li>
<li>엔티티에 대한 자세하고 구체적인 정보를 나타낸다. </li>
</ul>
<h3 id="엔티티-구성-방식에-따른-분류">엔티티 구성 방식에 따른 분류</h3>
<ol>
<li><strong>PK 속성</strong>
: 엔티티를 식별할 수 있는 속성이다. </li>
<li><strong>FK 속성</strong>
: 다른 엔티티와의 관계에서 포함된 속성이다. </li>
<li><strong>일반 속성</strong>
: 엔티티에 포함되어 있지만 PK, FK 속성이 아닌 속성이다. </li>
</ol>
<h3 id="속성의-특성에-따른-분류">속성의 특성에 따른 분류</h3>
<blockquote>
<p>속성은 업무분석을 통해 바로 정의한 기본 속성, 원래 업무상 존재하지 않았지만 설계하면서 도출해낸 설계 속성, 다른 속성으로부터 계산되거나 변형되어 생성되는 파생 속성 3가지로 분류할 수 있다. </p>
</blockquote>
<ol>
<li><strong>기본 속성</strong>
: 업무로부터 추출한 모든 일반적인 속성 </li>
<li><strong>설계 속성</strong>
: 업무를 규칙화하기 위해 새로 만들거나 변형/정의하는 속성 (ex. 일련 번호/코드성 속성)</li>
<li><strong>파생 속성</strong>
: 다른 속성에 영향을 받아 생성되는 속성으로 보통 다른 속성으로부터 계산된 값들이 이에 해당한다. 데이터 정합성 유지를 위해 유의할 점이 많으면 가급적 파생 속성은 적을수록 좋다. (ex. 합)</li>
</ol>
<h3 id="도메인">도메인</h3>
<p>: 속성에 대한 데이터 타입, 크기, 제약사항 지정</p>
<h3 id="속성-명명-규칙">속성 명명 규칙</h3>
<ul>
<li>해당 업무에서 사용하는 이름 부여하기</li>
<li>서술식 속성명은 금지</li>
<li>약어 사용 금지</li>
<li>구체적으로 명명해 데이터 모델에서 유일성 확보하기</li>
</ul>
<h2 id="관계-1">관계</h2>
<p>: 엔티티나 인스턴스 간 논리적인 연관성
ex. 선생님 - 가르친다(관계) - 학생</p>
<h3 id="페어링">페어링</h3>
<p>: 엔터티 안에 인스턴스가 개별적으로 관계를 가지는 것</p>
<h3 id="uml통합모델링언어에서의-관계">UML(통합모델링언어)에서의 관계</h3>
<ol>
<li><strong>연관관계(실선)</strong> 
: 항상 이용하는 관계 (ex. 소속된다.)</li>
<li><strong>의존관계(점선)</strong> 
: 상대 행위에 의해 발생하는 관계 (ex. 주문한다.)</li>
</ol>
<h3 id="관계선택성관계선택사양">관계선택성(관계선택사양)</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/73546019-c73b-40ff-acdd-294f8dd661da/image.png" alt=""></p>
<ol>
<li><strong>필수 관계</strong>
: 엔티티가 관계에 항상 참여하면 필수 관계이다. </li>
<li><strong>선택 관계</strong>
: 엔티티가 관계에 선택적으로 참여하면(참여할 수도 있고 아닐 수도 있으면) 선택 관계이다. </li>
</ol>
<h3 id="관계-체크사항">관계 체크사항</h3>
<p>: 2개의 엔티티 사이에서 관계를 정의할 때 다음 규칙을 체크해본다. </p>
<ol>
<li>2개의 엔터티 사이에 관심있는 연관 규칙이 존재하는가?</li>
<li>2개의 엔터티 사이에 정보의 조합이 발생되는가?</li>
<li>업무기술서, 장표에 관계연결에 대한 규칙 서술되어 있는가? </li>
<li>업무기술서, 장표에 관계연결을 가능케 하는 동사가 있는가?</li>
</ol>
<h3 id="식별비식별-관계-장단점">식별/비식별 관계 장단점</h3>
<ol>
<li><strong>식별 관계 장점</strong></li>
</ol>
<ul>
<li>데이터 정합성 유지를 DB에서 한 번 더 할 수 있음</li>
<li>자식 테이블에 데이터가 존재하면 무조건 부모 테이블에 데이터가 존재함을 보장할 수 있음</li>
</ul>
<ol start="2">
<li><strong>식별 관계 단점</strong></li>
</ol>
<ul>
<li>요구사항이 변경되었을 때 구조 변경이 필요한 경우 이 과정이 어려움</li>
</ul>
<ol start="3">
<li><strong>비식별 관계 장점</strong></li>
</ol>
<ul>
<li>변경되는 요구사항들을 유동적으로 수용할 수 있음</li>
<li>부모 데이터와 독립적인 자식 데이터를 생성할 수 있음</li>
</ul>
<ol start="4">
<li><strong>비식별 관계 단점</strong></li>
</ol>
<ul>
<li>데이터 정합성을 지키기 위한 별도의 비즈니스 로직이 필요함</li>
<li>자식 데이터가 존재해도 부모 데이터가 존재하지 않을 수 있음</li>
<li>데이터 무결성을 보장하지 않음</li>
</ul>
<h3 id="참여-제약조건participant-constraint">참여 제약조건(Participant Constraint)</h3>
<blockquote>
<p>관계를 맺는 두 엔티티에 대해 한 엔티티가 다른 엔티티에 의존하는지 여부를 나타내는 제약 조건이다. </p>
</blockquote>
<ol>
<li><strong>전체 참여 관계</strong>
: 전체 개체가 참여하는 관계이다. 
ex1. (교수 → 학과 : 전체 참여) 교수와 학과 엔티티는 &#39;소속&#39;이라는 관계가 있는데, 이 관계에 대해 모든 교수는 소속 학과가 있어야 한다는 전제 하에 교수는 학과에 전체 참여하는 관계를 가진다. 
ex2. (과목 → 학생 : 전체 참여) 과목은 무조건 학생을 가지고 있어야 한다. </li>
<li><strong>부분 참여 관계</strong>
: 일부 개체만 참여하는 관계이다. 
ex1. (학생 → 과목 : 부분 참여) 휴학생은 아무런 과목을 수강하지 않는다. </li>
</ol>
<h3 id="존재-존속existence-dependence">존재 존속(existence dependence)</h3>
<p>: A가 반드시 있어야만 B가 존재할때 <strong>B는 A의 존재 존속</strong>이라고 합니다.</p>
<ul>
<li>A를 주 개체, B를 종속 개체라 한다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 493회 7/30(일) 토익 시험 후기 ] 첫 토익 3주 독학 960점]]></title>
            <link>https://velog.io/@ddo_0/493%ED%9A%8C-730%EC%9D%BC-%ED%86%A0%EC%9D%B5-%EC%8B%9C%ED%97%98-%ED%9B%84%EA%B8%B0-%EC%B2%AB-%ED%86%A0%EC%9D%B5-3%EC%A3%BC-%EB%8F%85%ED%95%99-960%EC%A0%90</link>
            <guid>https://velog.io/@ddo_0/493%ED%9A%8C-730%EC%9D%BC-%ED%86%A0%EC%9D%B5-%EC%8B%9C%ED%97%98-%ED%9B%84%EA%B8%B0-%EC%B2%AB-%ED%86%A0%EC%9D%B5-3%EC%A3%BC-%EB%8F%85%ED%95%99-960%EC%A0%90</guid>
            <pubDate>Wed, 09 Aug 2023 06:50:35 GMT</pubDate>
            <description><![CDATA[<h3 id="시험">시험</h3>
<p>시험 날짜 : 7/30 일요일 (시험 시작 10:10 ~ 시험 종료 12:10, 입실은 9:50에 마감)</p>
<p>시험 성적 발표 : 8/9 수요일 12시</p>
<h3 id="시험-성적">시험 성적</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/76c12f0f-2255-41fe-bdc6-61861ef9a5e9/image.jpeg" alt="">
혹시 몰라 수험 번호는 가렸다.(LC 485/495, RC 475/495)</p>
<h3 id="시험-후기">시험 후기</h3>
<p><strong>📌 9:00 - 9:30 am</strong></p>
<p>집에서 30분 정도 떨어진 시험장에 가서 시험을 봤다. 9시 20분까지 입실이라 9시 정도에 가서 자리 확인을 하고 에어팟으로 유튜브에 토익 리스닝을 쳐서 아무거나 들었다. 리스닝을 토익 시험 때 처음 들으면 잘 안 들릴 것 같아서 들었는데 도움이 꽤 된 것 같다. </p>
<p>*<em>📌 9:30 - 9:45 am *</em></p>
<p>감독관 선생님께서 OMR을 나눠주시고 인적사항이나 수험번호 등을 적었다. 토익을 처음 봐서 어떻게 해야 할 지 몰랐는데 생각보다 방송이 친절하게 나오고 감독관 선생님께서 돌아다니시면서 질문도 잘 받아주셔서 편했다. </p>
<p><strong>📌 9:45 - 9:50 am &#39;휴식 시간&#39;</strong></p>
<p>화장실에 가는 사람들도 있고 늦게 온 사람들은 OMR에 수험번호랑 이름 등을 마킹하는 것 같았다. </p>
<p>❉ 입실 통제는 9:50 am부터 시작된다고 한다. </p>
<p><strong>📌 9:50 - 10:05 am &#39;신분 확인 시간&#39;</strong></p>
<p>주민등록증을 가지고 가서 책상에 올려두고 있었더니 감독관 선생님께서 돌아다니면서 확인을 하셨다. </p>
<p><strong>📌 10:05 - 10:10 am &#39;문제지 배부/파본 확인 시간&#39;</strong></p>
<p>한 번 시험이 시작되면 그 후에 문제지 교환이 안 된다고 하니 이 시간에 잘 확인을 해야 할 것 같다. </p>
<p><strong>📌 10:10 - 10:55 am &#39;리스닝 시간&#39;(45m)</strong></p>
<p><strong>PART 1</strong></p>
<p>파트 1 이전에 디렉션이 나올 때 파트 5(리딩 시작 파트)로 넘어가서 몇몇 문제를 풀다 디렉션이 거의 끝날 때 다시 리스닝 페이지로 넘어왔다. 리스닝에서 문장이 나올 때는 리딩을 풀지 않고 오로지 리스닝만 들으려고 했다. 대신 파트 1에서 보기를 읽어줄 때 앞 보기에 정답이 확실하면 찍고 뒤에 파트 5로 다시 가서 풀었었다. 여기서 파트 5 한 페이지 정도를 푼 것 같다. </p>
<p><strong>PART 2</strong></p>
<p>파트 2는 평소에 조금 어려워했던 부분이라 리딩 부분은 한 문제도 안 풀고 그냥 리스닝에 집중했다. </p>
<p><strong>PART 3, 4</strong></p>
<p>파트 3, 4는 파트1, 2보다 긴 지문이 나오는 부분이고 딸린 문제 수가 많아서 디렉션이 나올 때만 리딩 문제를 풀고 그렇지 않으면 먼저 문제와 보기를 읽어두고 리스닝을 들었다. 문제랑 보기를 읽어둬야지 지문을 듣고 바로 답을 체크할 수 있기 때문이다. </p>
<p><strong>📌 10:55 am - 12:10 pm &#39;리딩 시간&#39;(75m)</strong></p>
<p><strong>PART 5</strong></p>
<p>이 부분은 항상 리딩만 풀 때 10분 이내로 풀었었기 때문에 리스닝 때 절반 정도를 풀어두고 리딩이 시작하자마자 5분 정도 써서 남은 문제를 다 풀었다. </p>
<p><strong>PART 6</strong></p>
<p>토익 준비 초반에는 항상 다 맞았었는데 막판으로 갈 수록 틀리는 문제들이 많아져서 걱정했던 부분인데 풀 때도 문장 삽입 문제 하나가 헷갈렸었다. 그래도 너무 많은 시간을 쓰면 안 될 것 같아서 찍고 넘어갔다. 대신 나중에 다시 보기 위해 문제 번호에 체크를 해두고 넘어갔다. 총 15분 정도를 썼었다. </p>
<p><strong>PART 7</strong></p>
<p>리딩 마지막 파트인데 이 부분이 평소 기출 문제보다는 빠른 속도로 풀렸다. 30-35분 정도 걸렸다. 파트 5,6보다 훨씬 쉽다고 느꼈었다. </p>
<p>20분 정도 남았는데 남은 시간에는 리딩 헷갈리는 문제를 다시 봤다. </p>
<h3 id="시험-준비-과정">시험 준비 과정</h3>
<p><strong>📌 사용한 문제집</strong>
<img src="https://velog.velcdn.com/images/ddo_0/post/d8c9fbe7-4e9c-4d1e-a5ea-809a76db6b81/image.png" alt=""></p>
<p>나는 YBM ets 토익 정기시험 기출문제집 1000 Vol.3 Reading, Listening 문제집을 사서 이것만 풀었다. 보통 해커스나 YBM 둘 중 하나를 많이 푸는 것 같은데 기출 푸는 게 더 효과적이라는 말이 많아서 그냥 이 문제집으로 샀다. 그리고 Vol.1, Vol.2, Vol.3 이렇게 3개가 있는데 1,2보다는 3이 어렵다 들어서 3을 샀다. 리스닝 리딩 각각 기출 7회 + 예상 문제 3회가 있는 문제집인데, 3주동안 기출은 다 풀고 예상은 반 정도 풀었다. 리스닝은 아래 링크에 들어가서 로그인하고 책 인증하면 파일 다운로드 받아 들을 수 있다. </p>
<p><a href="https://www.ybmbooks.com/reader/reader_read.asp?id=2482&amp;seq=2924">토익 기출문제집 Vol.3 리스닝 듣기 파일 링크</a></p>
<p><strong>📌 리스닝 공부</strong></p>
<p>리스닝은 정말 꾸준한 게 중요하다. 그리고 토익은 개인적으로 리딩보다 리스닝이 점수 올리기가 쉽다! 처음에 기출 1회 풀었을 때는 리스닝에서 15개씩 틀렸었는데 꾸준히 풀다 보니 마지막 기출에서는 2개 정도 틀린 것 같다. </p>
<p><strong>PART 1</strong></p>
<p>파트1은 그림이 주어지고 그 그림에 알맞는 설명을 하는 보기들이 나오는데, 기출을 풀다보니 나오는 단어들이 많이 반복되는 것 같았다. 명사에서는 utensil이라든가 walkway라던가 bulletin board라던가 동사에서는 lean, stroll 등이 자주 나왔었다. 이렇게 자주 나오는 단어들을 따로 노션에 표로 적어두고 가끔 생각날 때마다 봤다. 이런 단어들만 알면 무난한 파트이고 가끔 어려운 문제가 나오면 소거법이 도움되는 것 같다. 확실하게 답이 아닌 빼고 보면 하나만 남을 때가 있는데 그냥 그게 정답이라 생각하고 넘어간 후 채점하고 나서 정답인 보기를 다시 보고 모르는 단어를 찾거나 안 들린 부분을 다시 들었다. </p>
<p><strong>PART 2</strong></p>
<p>파트 2는 리스닝 공부할 초중반에 가장 많이 틀렸었던 부분이다. 일단 초반에는 토익에서 대답하는 방식에 대해 잘 몰랐다. ((처음이니까 당연함,,)) 그래서 막 지금 &#39;공장에 새로 들어온 기계는 어떤가요&#39; 라고 물어보면 &#39;저는 어제 일하기 시작했어요&#39;와 같은 대답이 나오는 문제들이 있다는 걸 알고는 문제를 듣고 확실히 틀린 것을 지우고 보기를 들었을 때 속으로 의역하는 연습을 했다. &#39;어제 일하기 시작했어요 = 저는 잘 몰라요, 제가 그쪽을 지나가요 = 데려다 드릴까요?&#39; 이렇게 말이다. 또 이런 문제를 제외하고는 잘 안 들리는 게 문제였으니.. 이것 때문에 유튜브에 &#39;토익 파트 2 리스닝&#39;이라고 쳐서 나온 영상을 보기 시작했다. 특히 도움이 많이 되었던 게 아무튼 토익에서 올려둔 파트 2 리스닝 영상인데, 같은 문장이 여러 번 반복해서 나와서 처음에는 그냥 듣고 이런 의미인가? 생각하고 문장이 나오면 맞나 확인하고 다시 들어보는 과정을 반복했다. </p>
<p><strong>PART 3, 4</strong></p>
<p>파트 3, 4는 앞 파트보다 지문이 길고 한 지문에 문제가 3개씩 존재한다. 이 파트는 처음에 풀어보니 문제랑 보기를 미리 읽는 게 도움이 되는 것 같았다. 그래서 문제랑 보기를 미리 읽고 지문을 들을 때 문제를 생각하면서 들을 수 있게 했다. 또, 파트 3는 거의 모든 문제가 3문제 순서대로 지문에 등장한다. 그래서 순서대로 정보가 나온다 생각하고 들으면 좋다. 파트3, 4는 말하는 사람들의 직업 물어보는 거나 그 사람들이 어디에 있느냐 묻거나 speaker가 listener에게 제안한 것은 뭔지 물어보는 질문들이 많다. 질문 유형이 거의 정해져 있으니 지문을 들을 때 그 정보를 위주로 듣는 연습을 하면 좋다. </p>
<p><strong>📌 리딩 공부</strong></p>
<p><strong>PART 5</strong></p>
<p>문법을 공부한 지 너무 오래돼서 처음에 진짜 많이 틀렸다. 그래서 개념을 한 번 훑어야겠다고 생각하고 유튜브에 토익 문법 정리를 쳐서 영상을 2가지  정도 봤다. 둘 다 도움이 많이 되었는데, 아래 영상들이니 개념 한 번 정리하고 싶은 분들은 보면 좋을 것 같다. 특히 2번째 영상은 더보기를 보면 구글 드라이브 링크가 있는데 거기에 자료들을 다 정리해서 올려주셨다. 다 보지는 못했지만 접속사/접속부사/접치사 문제를 자꾸 틀려서 그 부분을 봤는데 도움이 정말 많이 되었다! </p>
<p><strong>PART 6, 7</strong></p>
<p>파트 6는 문제보다 지문을 먼저 읽고 빈칸이 나오면 멈춰서 문제를 풀고 파트 7은 문제를 먼저 보고 지문을 읽는 연습을 했다. 특히 파트 7 마지막 부분은 문제가 5문제이고 지문이 3개로 긴데, 이때는 문제를 읽으면서 앞 지문에서 먼저 나오는 문제들을 잘라놓고 앞 지문 읽고 해당되는 문제들 풀고 뒷 지문 읽고 해당되는 문제를 풀었다. 보통은 앞 지문에서 2문제, 뒤 문제에서 2문제, 지문들 연계로 1문제 정도가 나오는 것 같다. (꼭 그런 것은 아니지만 풀었을 때 이런 형태가 많았다.) → ex. 문제에서 In this email 아니면 In the article 이라고 나오는데 그러면 email, article로 나오는 지문에 해당되는 문제구나! 라고 알 수 있기 때문에 이걸 활용했다. </p>
<p><strong>📌 토익 문제 풀 때 팁</strong></p>
<ul>
<li><p>리스닝, 리딩을 왔다갔다 할 때 왼손(안 쓰는 손)으로 리스닝 페이지 잡아두기</p>
</li>
<li><p>리스닝 지문이 나올 때는 리스닝에만 집중하기</p>
</li>
<li><p>파트 1은 자주 나오는 단어 외우고 발음 여러 가지로 들어보기</p>
</li>
<li><p>파트 2에서 문제 지문이 나올 때는 핵심 키워드 기억하고 보기 듣기 </p>
<ul>
<li>ex. &#39;오늘 미팅에서 발표할 사람은 누구인가요?&#39; → 누가 발표</li>
<li>의문사 나오면 의문사 기억하기 → where, who, why 등</li>
</ul>
</li>
<li><p>파트 3,4에서 문제, 보기 미리 읽고 생각하기</p>
</li>
<li><p>파트 5는 보기 먼저 보고 어떤 문제인지 파악 → 그 문제에 맞게 풀기</p>
<ul>
<li>ex. 동사들이 보기로 나옴 → 동사 있는지 파악 → 동사 없으면 동사 자리에 넣는 진짜 동사 찾기, 진짜 동사 있으면 빈칸 자리 앞 뒤로 주어 목적어 등 확인하기 등</li>
</ul>
</li>
<li><p>파트 6는 지문 읽어가다가 빈칸 나오면 보기 읽고 찍고 넘어가기</p>
</li>
<li><p>파트 7은 문제 먼저 읽고 보기 대충 본 다음에 지문 읽기</p>
<ul>
<li>마지막 부분은 지문이 보통 3개씩 있는데, 서로 연관되어서 나오는 질문이 거의 무조건 하나씩 나오니 그 점 기억하면서 지문 읽기 </li>
<li>ex. 영수증에 나오는 Martin의 결제 정보 = credit card ⟷ email에 언급된 환불 수단 = 결제했을 당시 사용한 수단을 통해 환불된다고 나옴 → &#39;Martin은 신용 카드로 환불받는다&#39; 라는 보기가 나옴 → 정답이 됨</li>
</ul>
</li>
<li><p>OMR 마킹  : 리스닝은 문제가 끝났을 때마다 바로 체크하기, 리딩은 한 파트가 끝날 때마다 체크하기</p>
</li>
<li><p>리스닝 : 1문제 못 들어도 다음 문제 맞는다는 생각으로 넘어가기, 리딩 : 1문제에 너무 오랜 시간 쏟지 않기</p>
</li>
</ul>
<hr>
<p>첫 시험만에 960이 나올 줄은 몰랐지만 나와서 기분이 좋다🥳 앞으로 1년은 좀 쉬고 내년 여름이나 겨울에 다시 보려고 한다. 그때는 만점을 목표로..ㅎㅎ 일단 꾸준히 토익 시험을 보기 전까지 영어를 접하는 게 중요한 것 같다.</p>
<p>이 글 읽으시는 모든 분들은 다 토익 만점 받으세요!!!!! 그리고 혹시라도 토익 관련해서 궁금한 점이나 질문 있으시면 댓글 남겨주세요!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD 준비 #2] 데이터모델링의 이해_1장(1) 데이터 모델의 이해]]></title>
            <link>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-2-1%EA%B3%BC%EB%AA%A9%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</link>
            <guid>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-2-1%EA%B3%BC%EB%AA%A9%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</guid>
            <pubDate>Tue, 08 Aug 2023 15:31:19 GMT</pubDate>
            <description><![CDATA[<p><em><strong>1과목 중 &#39;데이터 모델링&#39; 관련 정리</strong></em></p>
<h3 id="특징">특징</h3>
<blockquote>
<p>&#39;데이터 모델링 = 현실세계의 것들을 데이터 모델로 표현하는 것&#39;이라고 생각하면 된다. </p>
</blockquote>
<p>📌 <strong>추상화/단순화/명확화</strong> 이 3가지가 데이터 모델링 특징에서 자주 나오는 키워드이다. (용어가 명확화 → 정확화 이렇게 바뀌어 나오거나 당연히 풀어쓸 수 있다는 점,,)</p>
<h3 id="중요성-및-유의점">중요성 및 유의점</h3>
<ol>
<li>중복 최소화하기</li>
<li>비유연성 버리기</li>
<li>비일관성 버리기</li>
</ol>
<p>각각이 의미하는 바는 다음과 같다. </p>
<p><strong>1. 중복</strong>
: 같은 시간 같은 데이터 제공해야 함.
*<em>2 비유연성 *</em>
: 사소한 업무변화에 의해 Data model이 자꾸 변경되면 안됨. 데이터 정의를 사용 프로세스와 분리하는 것이 필요함.
*<em>3. 비일관성 *</em>
: 데이터 간 상호 연관 관계를 명확히 정의해야 함.</p>
<h3 id="종류">종류</h3>
<ol>
<li>개념적 데이터 모델링<ul>
<li>포괄적/업무 중심적/추상화 수준이 높음</li>
</ul>
</li>
<li>논리적 데이터 모델링<ul>
<li>시스템 구축/Key, 속성, 관계 등을 표현/재사용성 높음</li>
</ul>
</li>
<li>물리적 데이터 모델링<ul>
<li>데이터베이스 이식/성능, 저장 등 물리적인 성격을 고려하여 설계함</li>
</ul>
</li>
</ol>
<h3 id="관점">관점</h3>
<ul>
<li>데이터 관점 </li>
<li>프로세스 관점 </li>
<li>데이터와 프로세스 관점 (=상관관점)</li>
</ul>
<h3 id="데이터베이스-스키마-구조독립성-요소">데이터베이스 스키마 구조/독립성 요소</h3>
<ol>
<li><strong>외부 스키마</strong> : 사용자 한 명이 보는 <em>사용자 관점</em>(개인) DB 스키마</li>
<li><strong>개념 스키마</strong> : 모든 <em>사용자 관점을 통합_한 전체 DB + _설계</em> 이야기</li>
<li><strong>내부 스키마</strong> : 물리적 장치에서 데이터가 실제적으로 저장된 것. 개발자 관점 + 저장 키워드</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD 준비 #1] 연산 순서 및 DML, DDL, TCL, DCL 정리]]></title>
            <link>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-1-%EC%97%B0%EC%82%B0-%EC%88%9C%EC%84%9C-%EB%B0%8F-DML-DDL-TCL-DCL-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-1-%EC%97%B0%EC%82%B0-%EC%88%9C%EC%84%9C-%EB%B0%8F-DML-DDL-TCL-DCL-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 08 Aug 2023 15:12:55 GMT</pubDate>
            <description><![CDATA[<h3 id="연산-순서">연산 순서</h3>
<p>FROM - WHERE - GROUP BY - HAVING - SELECT - ORDER BY</p>
<h3 id="sql-문법-종류">SQL 문법 종류</h3>
<h4 id="데이터-조작-언어-dmldata-manipulation-language">데이터 조작 언어 DML(Data Manipulation Language)</h4>
<blockquote>
<p>데이터베이스의 내부 데이터를 관리하기 위함. 주로 데이터를 조회/추가/변경/삭제 등의 작업을 수행하기 위해 사용한다.</p>
</blockquote>
<ol>
<li>SELECT - 선택</li>
<li>INSERT - 삽입</li>
<li>DELETE - 삭제</li>
<li>UPDATE - 수정</li>
</ol>
<h4 id="데이터-정의-언어-ddldata-definition-language">데이터 정의 언어 DDL(Data Definition Language)</h4>
<blockquote>
<p>테이블 및 컬럼을 정의하는 명령어로 이들의 생성, 수정, 삭제 등을 수행한다. </p>
</blockquote>
<ol>
<li>CREATE</li>
<li>ALTER</li>
<li>MODIFY</li>
<li>DROP</li>
<li>RENAME</li>
<li>TRUNCATE</li>
</ol>
<h4 id="트랜잭션-제어-언어-tcltransaction-control-language">트랜잭션 제어 언어 TCL(Transaction Control Language)</h4>
<blockquote>
<p>DCL과 비슷하게 무언가를 &#39;제어&#39;함. 하지만 대상이 DCL과 데이터가 아니라 트랜잭션이라는 점에서 다르다. </p>
</blockquote>
<ol>
<li>ROLLBACK</li>
<li>COMMIT</li>
</ol>
<h4 id="데이터-제어-언어-dcldata-control-language">데이터 제어 언어 DCL(Data Control Language)</h4>
<blockquote>
<p>데이터 관리를 목적으로 하며 무결성, 회복, 병행 제어, 보안 등을 정의하는데 사용함. 데이터베이스에 접근하여 읽거나 쓰는 것을 제한할 수 있는 권한을 부여하거나 박탈할 수 있고, 트랜잭션을 명시하거나 조작할 수 있다.</p>
</blockquote>
<ol>
<li>GRANT</li>
<li>REVOKE</li>
</ol>
<h4 id="기타">기타</h4>
<ul>
<li>DDL은 즉시 반영(Auto Commit)이 되지만 DML은 즉시 반영되지 않는다. 
→ 즉 DML은 ROLLBACK으로 다시 되돌릴 수 있음</li>
<li>DML은 타깃 테이블을 버퍼 메모리에 두고 수행해 변경 사항이 실시간 반영되지 않는다. 
→ commit 명령어로 트랜잭션을 종료해야 변경 사항들이 테이블에 실제로 반영된다. </li>
<li>DCL은 데이터 보호를 위한 데이터 보안, 데이터 정확성을 위한 무결성 유지 역할을 수행하며 시스템 장애에 대비한 회복과 병행수행을 제어한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD 준비 #0] 50회 SQLD 시험 준비 시작!]]></title>
            <link>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-0-50%ED%9A%8C-SQLD-%EC%8B%9C%ED%97%98-%EC%A4%80%EB%B9%84-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@ddo_0/SQLD-%EC%A4%80%EB%B9%84-0-50%ED%9A%8C-SQLD-%EC%8B%9C%ED%97%98-%EC%A4%80%EB%B9%84-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Tue, 08 Aug 2023 15:12:37 GMT</pubDate>
            <description><![CDATA[<p>남은 방학 때 자격증 하나를 따려고 고민 중이었는데 마침 저번 학기에 데이터베이스 수업을 듣기도 했고 그때 사둔 노랑이 문제집도 있어서 SQLD 시험 접수를 어제 했다...ㅋㅋㅋ 시험이 한 달 정도 남았는데 일단 1주는 개념 전체적으로 보고 2주는 노랑이 문제집이랑 시중에 나온 문제 풀고 마지막 주에는 기출 돌리고 시험 보려고 한다. 
개념을 그냥 눈으로 볼까 하다가 간단하게라도 블로그에 적어놓으면 나중에 다시 보기 편하지 않을까 싶어 적어보려 한다. 조금씩 주제를 나눠 적어봐야지. </p>
<p>아 근데 왜 SQLD 시험장은 우리 집 근처에 없지??? 집에서 1시간 넘은 거리로 시험 보러 간다..^^ 끝나고 가족들이랑 맛있는 거 먹고 와야지ㅎㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인공지능 챗봇 4차 과제]_기능 개선 및 최종 기획 구현기획안 완성하기
]]></title>
            <link>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-4%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EA%B8%B0%EB%8A%A5-%EA%B0%9C%EC%84%A0-%EB%B0%8F-%EC%B5%9C%EC%A2%85-%EA%B8%B0%ED%9A%8D-%EA%B5%AC%ED%98%84%EA%B8%B0%ED%9A%8D%EC%95%88-%EC%99%84%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-4%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EA%B8%B0%EB%8A%A5-%EA%B0%9C%EC%84%A0-%EB%B0%8F-%EC%B5%9C%EC%A2%85-%EA%B8%B0%ED%9A%8D-%EA%B5%AC%ED%98%84%EA%B8%B0%ED%9A%8D%EC%95%88-%EC%99%84%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 07 Aug 2023 14:25:59 GMT</pubDate>
            <description><![CDATA[<h2 id="최종-기획안">최종 기획안</h2>
<p><em>*<em>cf) 피피티 무단 도용은 금지합니다. *</em></em>
<img src="https://velog.velcdn.com/images/ddo_0/post/3db3389a-cb3c-46e7-ba70-7aec05fa328a/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/3b8bb6a9-e745-4b5e-bc1a-09273d2f1647/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/60574265-a998-42d0-a104-b731ecbe6825/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/5dadf216-5653-465f-9f26-e15f00f695b7/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/9e9aee62-9010-4ff1-b258-c38c3627de6f/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/375fd6da-324d-409b-8e95-eb5e83ccaadb/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/be3f3706-aaea-41f1-b1d0-f4b020dfb743/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/05f9a682-ab58-4e31-9a77-b5d3499d8d52/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/eb59c074-e926-46b2-9750-a0278cdd6474/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/04898729-4a32-4eaa-8dbf-679f9ae03304/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/c1d5764d-c3b4-42bc-8a45-bee3d44f364f/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/df091bb4-e9f0-4be7-b2f3-feff1bdf070d/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/5a4e10f6-75a4-48b1-9375-12b30a7c6d66/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/88a200d1-22c0-4296-8625-9ea50c6c7551/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/49f81696-e720-48c4-88e4-e7c9e7c0ad09/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/f07cd249-2e53-4c90-b91c-3edceadd0dbb/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/d4431398-e9cb-434d-bd03-41ad7ac14edb/image.png" alt=""></p>
<h2 id="후기">후기</h2>
<blockquote>
<p>이번에 학교를 통해 처음으로 코멘토 프로그램에 참여했다. 다양한 클래스가 있었는데 그 중 인공지능 챗봇 만들기에 관심을 가진 것은, 현재 공부하고 있고 목표로 하는 분야가 인공지능이기도 하고 챗봇을 평소에 꽤 많이 사용했기 때문에 그 동작 원리에 대해 궁금하기도 했기 때문이다. 결론적으로, 이번 프로그램을 통해서 많은 것을 배웠다. 정말 챗지피티와 같이 우리가 현재 말하는 인공지능적인 기능이 결합된 것은 아니지만, 시나리오형 챗봇 개발을 통해 어떤 과정으로 챗봇을 구성하고 기능을 만들어가는지 그 과정을 오히려 더 명확하게 알 수 있었던 것 같다. 또한, 구글 Dialogflow는 처음 써봤는데 생각보다 편한 점도, 불편하다고 느껴진 점도 있었다. 확실히 기획이란 게 생각한 대로 구현되면 좋은데 그렇지만은 않다는 것을 작년에 한 프로젝트에 이어서 이번에도 느꼈다. 특히 정해진 툴을 사용해서 개발하면 더욱 그런 것 같다. 0부터 직접 코딩해나가면 오히려 원하는 대로 구성하기가 수월하지만, 그렇지 않으면 쉽지 않다.. 그리고 컴퓨터 전공을 하면서 피피티를 만드는 경험이 많이는 없었다. 확실히 타과보다 적었던 것 같긴 하다(보고서는 많지만..ㅎㅎ). 근데 이번 기회를 통해 어떻게 하면 피피티를 깔끔하게, 그리고 눈에 띄게 구성할 수 있는지도 배울 수 있었다. 멘토님께서 특히 피피티가 눈에 들어올 때 어떻게 해야 좋은지, 어떻게 하면 더 좋은 인상을 받는 피피티를 만들 수 있을지 자세히 설명해주셔서 도움이 많이 되었다. 이번 프로그램을 통해 기획이란 게 획기적인 아이디어를 내는 것이 아니라, 생각과 현실적인 구상을 논리적으로 일목요연하게 표현하는 것임을 배웠다. 
다음에도 좋은 기회가 된다면 코멘토에서 열리는 다른 프로그램에도 참여해보고 싶다! </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[맥북-AWS EC2 연결 후기]Operation/Connection timed out 발생 ]]></title>
            <link>https://velog.io/@ddo_0/%EB%A7%A5%EB%B6%81-AWS-EC2-%EC%97%B0%EA%B2%B0-%ED%9B%84%EA%B8%B0OperationConnection-timed-out-%EB%B0%9C%EC%83%9D</link>
            <guid>https://velog.io/@ddo_0/%EB%A7%A5%EB%B6%81-AWS-EC2-%EC%97%B0%EA%B2%B0-%ED%9B%84%EA%B8%B0OperationConnection-timed-out-%EB%B0%9C%EC%83%9D</guid>
            <pubDate>Mon, 31 Jul 2023 13:13:41 GMT</pubDate>
            <description><![CDATA[<h3 id="기억해">기억해!!!!!</h3>
<p>오늘 맥북으로 AWS 인스턴스에 연결하다가 너무 삽질해서 쓰는 글이다..
혹시라도 누군가 나처럼 오랜 시간 고생하지 말라고..🤦🏻‍♀️</p>
<p>누군가 AWS 인스턴스에 터미널에서 연결하는데 Port22:Operation/Connection timed out이 발생한다..? </p>
<ol>
<li>일단 컴퓨터 방화벽 확인하고, 맥북은 sharing 부분에서 원격 로그인 체크되어 있는지 확인해주세요.. </li>
<li>이것도 다 되어있으면 자신이 명령어로 적은 ssh -i ...에서 퍼블릭/프라이빗 IPv4 잘 썼는지 AWS에 로그인해서 다시 한 번 확인해주세요..</li>
<li>진짜 다 했는데 안 된 것 같다..? 그리고 지금 공유기가 SK 브로드밴드이다..? 그러면 노트북에 와이파이 쓰지 말고 <strong>핫스팟 연결</strong>해서 다시 해보세요.. </li>
</ol>
<p>👉🏻 1,2번 말고 3번 먼저 해보고 안되면 1,2번 해봐도 괜찮을 것 같아요.. 1,2번하고 다른 시도들도 다 했는데 안 되면 저처럼 3시간을 날릴 수 있습니다... </p>
<p>저저번 학기에 전공 과제할 때도 분명 putty 연결이 와이파이로 안 되었던 것 같아서 혹시 몰라 핫스팟으로 바꿨더니 바로 됨... 
미래의 내가 또 까먹을 수 있으니 기억하라고 적는 글!!</p>
<p>정리하자면,</p>
<ol>
<li>.ssh 폴더로 가서 터미널 탭 키기(터미널에서 cd로 가도 상관 X)</li>
<li>ssh -i 로 시작하는 명령어 치기(근데 여기서 ubuntu@뒤에 퍼블릭 IPv4는 매번 바뀌니까 AWS 로그인해서 확인하기)</li>
<li>2번에서 yes 누르고 새로운 터미널 창(.ssh 폴더에서 열기)에 ssh -i pem파일명(.pem포함) -p 포트 ubuntu@... 명령어 치기(...은 config 파일에서 Host 뒤에 적은 접속할 호스트 이름)</li>
<li>초록색 글씨로 ubuntu@어쩌고저쩌고 나옴 -&gt; 연결된 거임 </li>
<li>나올 때는 exit 치기</li>
</ol>
<h3 id="기억하라고-적는-추가-정보">기억하라고 적는 추가 정보</h3>
<blockquote>
<p>.ssh/config 파일에 적은 내용들 정리</p>
</blockquote>
<pre><code>Host hostname
    HostName XXX.XXX.XXX.XXX
    User ubuntu
    Port 22
    IdentityFile ~/.ssh/XXXXXXX.pem</code></pre><ul>
<li>Host : 접속할 호스트 이름 </li>
<li>HostName : 접속할 호스트의 IP 주소 </li>
<li>User : 접속할 호스트의 유저 이름 </li>
<li>Port : SSH로 접속할 포트(기본 포트 = 22를 사용하면 생략 가능)</li>
<li>IdentityFile : 호스트 접속 시 사용되는 키의 경로(AWS에서 발급받은 pem 파일이 여기에 해당됨)</li>
</ul>
<blockquote>
<p>config 수정</p>
</blockquote>
<ol>
<li>해당 config 파일 있는 경로 가서 터미널 키기</li>
<li>vi config 명령어 사용해서 파일 열기 </li>
<li>수정 후 :wq 치고 나오기 (:w가 저장이고 :q가 종료=나오기라고 알고 있음..)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인공지능 챗봇 3차 과제]_구글 Dialogflow로 챗봇 구축하기]]></title>
            <link>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-3%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EA%B5%AC%EA%B8%80-Dialogflow%EB%A1%9C-%EC%B1%97%EB%B4%87-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-3%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EA%B5%AC%EA%B8%80-Dialogflow%EB%A1%9C-%EC%B1%97%EB%B4%87-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 28 Jul 2023 11:13:07 GMT</pubDate>
            <description><![CDATA[<h3 id="후기">후기</h3>
<blockquote>
<p>구글 Dialogflow를 처음 사용해봐 어려웠지만, 공식 문서를 참고하고 몇 번 시도해보니 사용하기가 수월했다. 그리고 하면서 느낀 점이, 코딩을 생각하면서 작성한 시나리오가 생각보다 Dialogflow에서 구축이 힘들다는 것이다. 따라서 Dialogflow에서의 구축을 위해 기존에 정의한 데이터 표를 여기서 엔티티 표로 다시 정의했다. 이에 따라 변경된 시나리오는 아래 피피티에서 글로 설명해봤다. 수정한 시나리오 사진은 최종 기획안에 넣으려 한다. 구축 결과도 테스팅 사진을 넣을까 했는데 찾아보니 Web Demo를 이용하면 아래 피피티에서처럼 직접 챗봇 이용하는 것처럼 화면이 나오길래 해당 화면을 사용했다. </p>
</blockquote>
<ul>
<li>확실히 직접 코딩하면 원하는 부분까지 마음대로 만들 수 있다는 장점이 있다는 걸 느꼈다. </li>
<li>아무래도 제공되는 서비스와 동작 원리를 기반으로 시나리오를 구현해야 하므로 제약사항들이 있었다. </li>
<li>그래도 시스템에서 기본적으로 제공되는 sys.phone-number, sys.person과 같은 파라미터가 있어 엔티티 정의 시 편리했다. </li>
</ul>
<h3 id="최종-피피티">최종 피피티</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/9cd9dadd-1c8b-4113-bb9c-8a8b459c76cd/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/ae2e7633-b76a-4eef-917d-3262f3b31c60/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/2e7ca80b-8675-4f25-aa76-5d94d61db7cd/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/6c38f69b-2990-4298-8ea3-72727bceea3e/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/32d5b7bd-03fe-4cd2-a3f5-8f5fca27c557/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/f2e2c563-909c-43fe-a73c-f18311c6dc09/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/2126a717-c3a8-4faf-92b8-b82f49efc729/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/c79ae311-b072-4f2c-b02b-5572bd04682a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인공지능 챗봇 2차 과제]_챗봇 예약 서비스에 대한 시나리오 작성]]></title>
            <link>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-2%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EC%B1%97%EB%B4%87-%EC%98%88%EC%95%BD-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%9C%EB%82%98%EB%A6%AC%EC%98%A4-%EC%9E%91%EC%84%B1</link>
            <guid>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-2%EC%B0%A8-%EA%B3%BC%EC%A0%9C%EC%B1%97%EB%B4%87-%EC%98%88%EC%95%BD-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%9C%EB%82%98%EB%A6%AC%EC%98%A4-%EC%9E%91%EC%84%B1</guid>
            <pubDate>Mon, 24 Jul 2023 05:13:17 GMT</pubDate>
            <description><![CDATA[<h3 id="최종-피피티">최종 피피티</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/15f42fbe-1f90-493d-bd13-7b9544ce5bac/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/85c6f8bd-3a36-45b8-93dc-4e121da45576/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/9e0b2f6d-1627-493b-a16d-9985d75ec3e8/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/e41917ae-8af0-47b0-b5c3-4a528e21945c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 2022 KAKAO INTERNSHIP 1번 성격 유형 검사하기 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2022-KAKAO-INTERNSHIP-1%EB%B2%88-%EC%84%B1%EA%B2%A9-%EC%9C%A0%ED%98%95-%EA%B2%80%EC%82%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2022-KAKAO-INTERNSHIP-1%EB%B2%88-%EC%84%B1%EA%B2%A9-%EC%9C%A0%ED%98%95-%EA%B2%80%EC%82%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Fri, 21 Jul 2023 05:32:22 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://school.programmers.co.kr/learn/courses/30/lessons/118666">프로그래머스 2022 KAKAO INTERNSHIP 1번 성격 유형 검사하기</a></p>
<blockquote>
<p>성격 유형 지표를 저장한 survey와 검사자가 정한 선택을 나타내는 choices를 전달받은 후, 문제에 주어진 점수를 매겨 검사자의 최종 성격 유형을 리턴하는 문제이다. </p>
</blockquote>
<h3 id="✨-코드">✨ 코드</h3>
<pre><code class="language-python">def select(metric, choice):
    if metric[choice[0]] == metric[choice[1]]:
        return choice[0]
    elif metric[choice[0]] &gt; metric[choice[1]]:
        return choice[0]
    else:
        return choice[1]

def solution(survey, choices):
    answer = &#39;&#39;
    metric = {&#39;R&#39;: 0, &#39;T&#39;: 0, &#39;C&#39;: 0, &#39;F&#39; : 0, &#39;J&#39; : 0, &#39;M&#39;: 0, &#39;A&#39; : 0, &#39;N&#39; : 0}
    score = {1: 3, 2:2, 3:1, 4:0, 5:1, 6:2, 7:3}
    for i in range(len(survey)):
        c1, c2 = survey[i][0], survey[i][1]
        if choices[i] &gt; 4:
            metric[c2] += score[choices[i]]
        elif choices[i] &lt; 4:
            metric[c1] += score[choices[i]]
    answer += select(metric, &#39;RT&#39;)
    answer += select(metric, &#39;CF&#39;)
    answer += select(metric, &#39;JM&#39;)
    answer += select(metric, &#39;AN&#39;)
    return answer</code></pre>
<h3 id="✨-풀이">✨ 풀이</h3>
<ul>
<li><p>문제를 다 읽고 가장 먼저 생각난 거는 딕셔너리 활용하는 것이다. 각 지표에 대한 점수를 저장하는 딕셔너리 metric과 문제에서 주어진 각 선택지에 대한 점수를 저장한 딕셔너리인 score를 만들었다. 이후 각 survey의 원소(검사를 받는 성격 유형 지표)에 대해 4보다 크면 2번째 성격 유형 지표(c2)에 점수를 더하고, 4보다 작으면 1번째 성격 유형 지표(c1)에 점수를 더하도록 했다. → 문제에 주어진 내용이다. </p>
</li>
<li><p>최종 metric 딕셔너리가 결정되면 RT, CF, JM, AN의 지표들 중 하나씩을 결정하기 위해 select 함수를 호출하도록 했다. 점수를 비교해 더 큰 쪽의 지표 하나를 리턴하고, 만약 점수가 같으면 사전 순 중 앞쪽(알파벳 순으로 전달되므로 결국 choice[0]과 같음)을 리턴하도록 했다. </p>
</li>
</ul>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>대략 20분 정도 걸려서 푼 것 같다. 문제 읽고 이해하는데 거의 12<del>3분이었고,, 푸는 데 7</del>8분 정도였다. Lv.1이라고 적혀져 있었던 만큼 가장 풀기 쉬웠던 문제이다. 다른 사람들의 경우 한글로 푸신 분도 있었고, survey 원소가 알파벳 순이 아니면 [::-1]을 사용해 역순으로 바꾼 후 주어진 점수-4를 빼서 코드를 작성하신 분도 있었다. 굉장히 다양한 풀이가 있었던 것 같다. 개인적으로는 앞에서 말한 것 중 두번째 코드가 굉장히 기억에 남는다. 
내일은 2번 Lv.2인 두 큐 합 같게 만들기를 풀어봐야겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 17827번 - 달팽이 리스트 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-17827%EB%B2%88-%EB%8B%AC%ED%8C%BD%EC%9D%B4-%EB%A6%AC%EC%8A%A4%ED%8A%B8-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-17827%EB%B2%88-%EB%8B%AC%ED%8C%BD%EC%9D%B4-%EB%A6%AC%EC%8A%A4%ED%8A%B8-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Mon, 17 Jul 2023 09:27:58 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/17827">백준 17827번 - 달팽이 리스트</a></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/f9523c71-b3eb-4cd9-95bd-9f934f30e373/image.png" alt=""></p>
<h3 id="✨-핵심">✨ 핵심</h3>
<ul>
<li>문제 자체는 단순한 편 → 시간 초과 조심하기</li>
<li>인덱스 범위 초과만 조심하면 됨</li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline
output = sys.stdout.write

N, M, V = map(int, input().split())
node_list = input().split()
for i in range(M):
    K = int(input())
    if K &gt;= N:
        output(node_list[(V-1)+int((K-(V-1))%(N-(V-1)))]+&quot;\n&quot;) 
    else:
        output(node_list[K]+&quot;\n&quot;)</code></pre>
<ul>
<li>반복문에서 K(몇 번 이동했는지에 대한 수) 입력 받으면 K가 리스트 인덱스 범위인 0~(N-1)에 포함되지 않는지 포함되는지 if, else 문으로 구분해 케이스를 나눠 계산했다.<ul>
<li>범위 안에 있으면 그냥 K 인덱스에 해당하는 숫자 출력하면 된다.</li>
<li>범위 밖에 있으면 인덱스를 범위 안에 들어오도록 계산해 출력하면 된다.
  → (V-1) = 달팽이 리스트에서 사이클에 포함되지 않는 노드의 수
→ (K-(V-1))%(N-(V-1)) = K에서 V-1을 빼주면 이제 달팽이 리스트에서 사이클에 포함되지 않는 노드들을 신경쓸 필요가 없다. 그 값을 &quot;N-(V-1) = 사이클에 포함되는 노드들의 수&quot;로 나눠 나머지를 구하면, 그 나머지는 사이클에서 V번 노드에서 몇 번 이동한 것인지를 나타내는 수가 된다. 
→ 위 2개를 더해 최종적으로 범위 안의 인덱스로 변환한다. </li>
</ul>
</li>
<li>입력, 출력은 저번에 다른 문제 풀 때 시간 초과 해결하려고 찾아본 내용을 이번에 그대로 써봤다. </li>
</ul>
<h3 id="✨-결과">✨ 결과</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/9d475a0c-dbe0-4f2e-832a-0d28cab52b16/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>맨 처음에는 while문을 써봤는데 역시나 시간 초과..가 발생해 그냥 반복문을 없앨 수 있게 계산식으로 바꿔서 작성했다. 제출하고 가장 뿌듯한 건 pypy3로 제출한 사람들 중에 제일 시간이 적게 걸렸다는 것!!! 아마 문제 제출해서 맞은 사람들 중에 시간 제일 적게 걸린 경우는 처음인 것 같다. 뿌듯하니까 밑에 남겨놔야지 🥳 
이제 1,2학년 때 풀다가 포기했던 문제들을 거의 다 풀고 1~2문제 정도 남은 것 같다. 남은 문제들 다 풀면 유형별로 풀어보기도 하고 다른 사이트 문제도 풀어봐야겠다. </p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/0afea260-bf3d-4d1f-999d-f4ee44c7fc56/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 11441번 - 합 구하기 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-11441%EB%B2%88-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-11441%EB%B2%88-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Sun, 16 Jul 2023 13:38:16 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/11441">백준 11441번 - 합 구하기</a></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/202cdd93-0223-43c3-8a15-66b0eaf3eeba/image.png" alt=""></p>
<h3 id="✨-핵심">✨ 핵심</h3>
<ul>
<li>문제 제한 시간이 1초라는 것</li>
<li>1번째 수 == 인덱스 0</li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<h4 id="간단-풀이">간단 풀이</h4>
<blockquote>
<p>문제 봤을 때 그냥 바로 떠오른 대로 풀어본 방식으로,문제에서 주어진 숫자들 입력받고 인덱스 (i-1)<del>(j-1)까지 슬라이싱한 후 sum을 이용해 i번째</del>j번째 숫자들의 합을 구한 코드이다. </p>
</blockquote>
<pre><code class="language-python">import sys
input = sys.stdin.readline
N = int(input())
nums = list(map(int, input().split()))
for _ in range(int(input())):
    i, j = map(int, input().split())
    print(sum(nums[i-1:j]))</code></pre>
<h4 id="시간-단축-풀이">시간 단축 풀이</h4>
<blockquote>
<p>시간을 단축하기 위해서는 어떻게 할까 고민했는데 일단 합을 구하는 과정이 중복되지 않도록 ans라는 배열에 1<del>n번째 숫자들의 합을 ans[n]에 저장하도록 하고, 이후에 i, j를 입력받으면 `ans[j](1</del>j번째까지의 숫자 합)<code>에서</code>ans<a href="1~(i-1">i-1</a>번째까지의 숫자 합)`을 빼서 i~j번째까지의 숫자 합을 구해 출력하도록 한다. </p>
</blockquote>
<ul>
<li>이때 핵심은 입출력에 print, input 함수를 사용하지 않고 sys 모듈 임포트해서 sys.stdin.readline, sys.stdout.write을 사용하는 것이다. </li>
</ul>
<pre><code class="language-python">import sys
input = sys.stdin.readline
N = int(input())
nums = list(map(int, input().split()))
ans = [0]*(N+1)
for i in range(1, N+1):
    ans[i] = ans[i-1]+nums[i-1]
for _ in range(int(input())):
    i, j = map(int, input().split())
    sys.stdout.write(str(ans[j]-ans[i-1])+&quot;\n&quot;)</code></pre>
<h3 id="✨-결과">✨ 결과</h3>
<h4 id="간단-풀이-1">간단 풀이</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/ba142cd4-6dc8-4d9f-ae1c-56ccb18d1796/image.png" alt=""></p>
<h4 id="시간-단축-풀이-1">시간 단축 풀이</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/edc1ebe0-c6a5-4d6b-b03a-f0617ea38cc3/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>생각과 달리 첫 번째 풀이가 시간 초과에 걸리지 않았다. 대신 시간이 오래 걸린 건 사실이지만,, 궁금해서 첫 번째 풀이에서 print 대신 sys.stdin.write을 써봤는데 오히려 print를 사용했을 때와 달리 시간 초과가 발생했다. 왜 그런지는 모르겠지만,, 찾아보니까 제출 시간에 따라 결과가 다르게 나올 수도 있다고 한다. 안정적으로 두 번째 방식으로 푸는 게 더 나을 듯 싶다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인공지능 챗봇 1차 과제]_챗봇 서비스에 대한 사전 조사]]></title>
            <link>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-1%EC%B0%A8-%EA%B3%BC%EC%A0%9C-%EC%B1%97%EB%B4%87-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%82%AC%EC%A0%84-%EC%A1%B0%EC%82%AC</link>
            <guid>https://velog.io/@ddo_0/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EC%B1%97%EB%B4%87-1%EC%B0%A8-%EA%B3%BC%EC%A0%9C-%EC%B1%97%EB%B4%87-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%82%AC%EC%A0%84-%EC%A1%B0%EC%82%AC</guid>
            <pubDate>Sun, 16 Jul 2023 08:06:58 GMT</pubDate>
            <description><![CDATA[<h2 id="최종-기획안-피피티">최종 기획안 피피티</h2>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/a2c67b98-0f67-479c-a89a-1763a2d4b1a0/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/56eaf7e9-69d3-42d1-8c50-5e2a1fda0c8b/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/d7dcb4bf-b2a0-4677-a0be-558b12430bcb/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/9e2deee8-466b-4573-ad52-252e1cd70f82/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/105a3405-229a-46a8-8860-244d6d371855/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/fb910b92-e938-4328-8832-44263e7f582e/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/aea9ccd1-1d32-400a-9984-872a0b0bbad8/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/cdea75c4-3a47-41c2-99a4-0fbaddeae981/image.png" alt="">
<img src="https://velog.velcdn.com/images/ddo_0/post/6c03691d-3644-489f-8f98-c7cb5b79e07a/image.png" alt=""></p>
<hr>
<h2 id="자료조사--초안">자료조사 &amp; 초안</h2>
<h3 id="챗봇chatbot">챗봇(Chatbot)</h3>
<blockquote>
<p>주로 고객의 질문을 이해하고 이에 <strong>자동으로 응답</strong>하는 로봇</p>
</blockquote>
<h3 id="챗봇의-유형">챗봇의 유형</h3>
<ol>
<li>대화형 </li>
</ol>
<ul>
<li>NLP(자연어 처리; Natural Language Process)를 기반으로 자연스럽게 대화할 수 있는 챗봇</li>
<li>답변 &amp; 특정 서비스 추천 &amp; 이벤트 발생(서비스 실행 등) 가능</li>
<li>많은 양의 데이터 확보 필요 &amp; 오랜 기간 소요 → 구축 난이도 높다.</li>
<li><em>흔히 매체를 통해 접하는 인공지능 챗봇의 유형</em></li>
</ul>
<ol start="2">
<li>트리형 (버튼)</li>
</ol>
<ul>
<li>정해진 트리 구조를 따라 답변을 얻은, 인공지능 기반인 대화형과는 다른 방식</li>
<li>최종 답변을 위한 경우의 수는 이미 정해져 있음 → 구축이 쉽다.</li>
<li><em>‘자주하는 질문 서비스’에 많이 사용하는 유형으로, 소규모 업체, 제공해야 할 정보의 구조화가 잘 되어 있는 회사에게 추천</em></li>
</ul>
<ol start="3">
<li>추천형</li>
</ol>
<ul>
<li>표면적으로는 대화형 방식에 가깝지만 답변 제공 방식이 다른 추천형 방식</li>
<li>대화 형태의 답변 X → 사전에 정의된 답변들을 특정 알고리즘에 따라 나타낸다.<ul>
<li>우선순위별로/리스트 형태로 보여주기</li>
</ul>
</li>
<li>고객의 요구를 충족할 확률이 높다.</li>
<li><em>대화형 챗봇으로 가기 위한 중간 과정으로도 사용한다.</em></li>
</ul>
<ol start="4">
<li>시나리오형</li>
</ol>
<ul>
<li>원하는 서비스 제공을 위해 정해진 시나리오를 수행하는 챗봇</li>
<li>고객에게 답변 수행에 필요한 정보를 모두 받기 → 최종 답변 전달</li>
<li>순서/단계가 존재 → 고객 이탈율 분석을 통해 고객 경험을 단계별로 향상시킬 수 있다.</li>
<li><em>제공해야 할 서비스나 결과물이 정해져 있을 때 사용한다.</em></li>
</ul>
<ol start="5">
<li>결합형 </li>
</ol>
<ul>
<li><p>앞서 본 4가지 유형의 챗봇을 결합해 설계한 챗봇</p>
</li>
<li><p>최근 출시되는 챗봇들이 선택하는 방식 중 하나</p>
</li>
<li><p>다양한 유형의 챗봇 장점을 수용할 수 있다.</p>
<table>
<thead>
<tr>
<th></th>
<th>대화형</th>
<th>트리형</th>
<th>추천형</th>
<th>시나리오형</th>
</tr>
</thead>
<tbody><tr>
<td>비용</td>
<td>매우 높음</td>
<td>매우 낮음</td>
<td>보통</td>
<td>보통</td>
</tr>
<tr>
<td>전문성</td>
<td>매우 높음</td>
<td>낮음</td>
<td>보통</td>
<td>보통</td>
</tr>
<tr>
<td>시간</td>
<td>매우 높음</td>
<td>보통</td>
<td>많음</td>
<td>보통</td>
</tr>
</tbody></table>
</li>
</ul>
<h3 id="현재-비즈니스에-적용되는-챗봇-사례-보기">현재 비즈니스에 적용되는 챗봇 사례 보기</h3>
<ol>
<li><p><strong>카카오 &amp; 카카오뱅크</strong></p>
<blockquote>
<p>인공지능 기술 &amp; 대화형 답변 기반의 챗봇을 운영 중이다.</p>
</blockquote>
</li>
</ol>
<ul>
<li><p>구축</p>
<ul>
<li>상담 직원들이 직접 답변을 설계해 고객 응대에 필요한 챗봇을 구축</li>
<li>카카오뱅크 → 고객의 질문 의도에 맞게 답변을 했는지 매일 챗봇 상담 이력을 샘플링해 챗봇 기능을 업데이트</li>
</ul>
</li>
<li><p>효과</p>
<ul>
<li><p><strong>심야 &amp; 주말</strong>에도 손쉽게 사용 가능</p>
</li>
<li><p>카카오 → 구독 경제 모델을 적용해 챗봇으로 <strong>개인화된 컨텐츠 서비스</strong>를 제공
  <em>ex) 카카오 뉴스봇, 카카오 프로야구봇</em></p>
</li>
<li><p>챗봇의 고객 상담 문의 처리 비율 </p>
<table>
<thead>
<tr>
<th></th>
<th>카카오</th>
<th>카카오뱅크</th>
</tr>
</thead>
<tbody><tr>
<td>처리 비율(%)</td>
<td>89.7</td>
<td>34.1</td>
</tr>
</tbody></table>
</li>
</ul>
</li>
</ul>
<ol start="2">
<li><strong>듀오링고 - 챗봇을 활용한 외국어 교육 서비스</strong></li>
</ol>
<ul>
<li>구축<ul>
<li>특정상황을 가정한 인물과 실시간 대화가 가능하도록 ex) 요리사, 경찰관 등</li>
<li>인공지능 기반 개발</li>
</ul>
</li>
<li>효과<ul>
<li>전 세계 <strong>5억 명 이상</strong>의 사람들이 사용 중    </li>
<li>2022년 4분기 매출액 1억 2600만 달러 → 전년도와 비교했을 때 <strong>39% 증가</strong></li>
<li>2023년 유료 가입자 <strong>67% 급증</strong> → 총 420만 명 돌파</li>
</ul>
</li>
</ul>
<ol start="3">
<li><p><strong>의료챗봇 전문 기업 웨저</strong></p>
<blockquote>
<p>병원 내 민원 처리와 예약 변경 및 취소를 도와주는 챗봇 → 현재 6개 대학병원에서 사용 중</p>
</blockquote>
</li>
</ol>
<ul>
<li><p>구축</p>
<ul>
<li>대학병원에 내원하는 환자들의 문의 사항들을 수개월간 정리 분석한 질문 및 답변 데이터 리스트를 학습</li>
<li>카카오톡 채널과 네이버톡톡 플랫폼에서 상담챗봇을 운영 중
  → 병원 내 전산 시스템과 연동하여 <strong>진료 및 입원 예약 업무</strong>를 빠르게 처리할 수 있다. </li>
</ul>
</li>
<li><p>효과</p>
<ul>
<li>월평균 <strong>10,000명 이상</strong>이 챗봇 서비스 사용 중</li>
<li>예약 변경 및 취소 전화 문의가 <strong>10%</strong> <strong>이상 감소</strong></li>
</ul>
</li>
</ul>
<h3 id="챗봇의-장단점">챗봇의 장단점</h3>
<p><strong>장점</strong></p>
<ul>
<li><p><strong>단순 반복 업무 최적화</strong></p>
<p>  → <strong>반복되는</strong> 고객 문의나 <strong>시나리오를 쉽게 정의할 수 있는 예약, 쇼핑, 구매 등</strong>의 업무를 자동화하여 처리 가능</p>
</li>
<li><p><strong>경제성</strong></p>
<p>  → <strong>비용 절감</strong> 효과(고객 응대에 들어가는 인력과 비용을 절감할 수 있다.)</p>
</li>
</ul>
<pre><code>`(2016년 챗봇익스플레이너)` 상담자의 **업무 중 70%를 챗봇에 넘김**으로써, 은행은 고객 지원비용을 **30%까지 절감**할 수 있다.


`(2017년 주피터리서치)` 고객 문의 건당 소요 시간을 **4분 정도 줄일 수 있고**, 이는 건당 원가가 0.50달러에서 0.70달러로 절감되는 효과를 가진다. </code></pre><ul>
<li><p><strong>접근성</strong></p>
<p>  → <strong>365일 24시간</strong> 내내 고객 문의에 빠르게 답변 가능</p>
</li>
<li><p><strong>데이터 수집</strong>으로 <strong>새로운 수익 창출</strong> 가능</p>
<p>  → 챗봇으로 전달되는 고객의 질문 및 데이터를 수집하고 고객에게 새로운 영업 기회 포착 가능</p>
</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li><p><strong>많은 데이터</strong> 필요로 함</p>
<p>  → 인공지능 기술을 기반으로 하는 챗봇은 빅데이터 기반으로 학습되어야 한다. 일반적으로 데이터가 많을수록 성능이 좋아지기 때문이다.</p>
<p>  ⇒ 기업이 가지고 있는 데이터가 충분하다면 문제가 되지 않는 부분이기도 하다. </p>
</li>
<li><p><strong>제한된 답변</strong></p>
<p>  → 시나리오형 챗봇의 경우 시나리오에 없는 답변은 불가능하거나 추천형 챗봇의 경우 사전에 존재하는 답변들 외의 답변은 불가능함 (유연한 답변 처리가 어려울 때도 있음)</p>
<p>  ⇒ 아직까지 각 회사별로 고객 상담사가 일부 존재하는 이유이기도 하다. </p>
</li>
</ul>
<h3 id="제안하고자-하는-결합형-챗봇">제안하고자 하는 “결합형” 챗봇</h3>
<blockquote>
<p>기능마다 여러 유형의 챗봇을 사용해 각각의 장점을 취하고, 개발 비용과 시간은 최대한 줄일 수 있도록 한다.</p>
</blockquote>
<ul>
<li>시나리오형 → 콘도 예약 진행 시 사용 가능 + 비용/전문성/시간 모두 보통<ul>
<li>고객으로부터 정해진 데이터를 입력받아 진행하면 되는 기능에는 시나리오형 챗봇이 적합하다고 생각됨</li>
</ul>
</li>
<li>추천형 → 콘도의 객실 설명, 예약 진행, 취소, 예약 확인, 예약 변경 등을 위해 사용자가 선택할 수 있는 메뉴를 제시한다.<ul>
<li>콘도 예약 서비스에서는 고객이 문의하거나 원하는 상담 유형이 어느 정도 정해진다고 생각되므로, 이러한 내용을 정리해 메뉴로 제공해주는 것(보통 시간이 많이 소요되지만, 서비스 유형이 많지 않아 괜찮을 것으로 판단됨)</li>
</ul>
</li>
</ul>
<hr>
<p>&lt; 출처 &gt;</p>
<p><a href="https://www.hanbit.co.kr/media/channel/view.html?cms_code=CMS2582741322">https://www.hanbit.co.kr/media/channel/view.html?cms_code=CMS2582741322</a></p>
<p><a href="https://www.bloter.net/news/articleView.html?idxno=23693">https://www.bloter.net/news/articleView.html?idxno=23693</a></p>
<p><a href="https://www.keris.or.kr/common/fileDownload.do?fileKey=74c11f8e9c1e7290934dc2e1460f1eeb&amp;dwlTy=pblcte">https://www.keris.or.kr/common/fileDownload.do?fileKey=74c11f8e9c1e7290934dc2e1460f1eeb&amp;dwlTy=pblcte</a></p>
<p><a href="http://webzine.koita.or.kr/202211-innovation/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%ED%99%9C%EC%9A%A9%ED%95%9C-%EA%B5%90%EC%9C%A1-%ED%98%81%EC%8B%A0">http://webzine.koita.or.kr/202211-innovation/인공지능-활용한-교육-혁신</a></p>
<p><a href="https://testcenter.zendesk.com/hc/ko/articles/360011072871-%EB%93%80%EC%98%A4%EB%A7%81%EA%B3%A0%EB%8A%94-%EC%96%B4%EB%96%A4-%EC%95%B1%EC%9D%B8%EA%B0%80%EC%9A%94-">https://testcenter.zendesk.com/hc/ko/articles/360011072871-듀오링고는-어떤-앱인가요-</a></p>
<p><a href="https://www.edaily.co.kr/news/read?newsId=01866326635573824&amp;mediaCodeNo=257">https://www.edaily.co.kr/news/read?newsId=01866326635573824&amp;mediaCodeNo=257</a></p>
<p><a href="https://www.2e.co.kr/news/articleView.html?idxno=301644">https://www.2e.co.kr/news/articleView.html?idxno=301644</a></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 2712번 - 미국 스타일 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-2712%EB%B2%88-%EB%AF%B8%EA%B5%AD-%EC%8A%A4%ED%83%80%EC%9D%BC-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-2712%EB%B2%88-%EB%AF%B8%EA%B5%AD-%EC%8A%A4%ED%83%80%EC%9D%BC-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Sat, 15 Jul 2023 04:10:40 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/2712">백준 2712번 - 미국 스타일</a></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/93414e1f-8a6c-46b4-acbc-4b1efe55241c/image.png" alt=""></p>
<h3 id="✨-핵심">✨ 핵심</h3>
<ul>
<li>소수점 4자리에서 반올림 
  → <strong>round(실수, 4) 사용</strong></li>
<li>소수점 아래 4자리까지는 무조건 출력해야 함(0으로라도 채워야 함) 
  → <strong>{:.4f}.format(round(실수, 4)) 사용</strong></li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<pre><code class="language-python">T = int(input())
translator = {&#39;kg&#39;: [&#39;lb&#39;, 2.2046], &#39;lb&#39;: [&#39;kg&#39;, 0.4536], &#39;l&#39;: [&#39;g&#39;, 0.2642], &#39;g&#39;: [&#39;l&#39;, 3.7854]}
answer = &quot;&quot;
for i in range(T):
    num, unit = input().split() 
    answer += str(&#39;{:.4f}&#39;.format(round(float(num)*translator[unit][1], 4))) + &quot; &quot; + translator[unit][0] + &quot;\n&quot;
print(answer)</code></pre>
<h3 id="✨-결과">✨ 결과</h3>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/b0503ea3-c037-4a85-bbe9-e4ffd6baa2d9/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>풀고나서 보니 이 문제는 사실 if, elif로 나눠서 계산해도 괜찮을 것 같긴 하다. 이 문제도 1년 전에 풀어보고 틀려서 냅둔 후에 다시 풀어본 문제인데, 시간이 지나니까 이제 브론즈 문제는 봤을 때 어떤 부분을 신경써야 할 지랑 어떤 방식으로 풀어봐야 할 지 어느 정도는 알 것 같다는 느낌이 들었다! 앞으로도 꾸준히 하루에 1문제라도 풀려고 해야지</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1929번 - 소수 구하기 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1929%EB%B2%88-%EC%86%8C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1929%EB%B2%88-%EC%86%8C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Sat, 15 Jul 2023 03:13:43 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/1929">백준 1929번 - 소수 구하기</a></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/96d93c14-2679-469b-8e03-07dbf250aff0/image.png" alt=""></p>
<h3 id="✨-주의할-점">✨ 주의할 점</h3>
<ul>
<li>소수에 1은 포함되지 않는다. (이것 때문에 이번에 첫 번째 제출했을 때 틀렸다..ㅜㅜ)</li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<h4 id="제일-처음-생각한-풀이">제일 처음 생각한 풀이</h4>
<pre><code class="language-python">import math

M, N = map(int, input().split())
if M == 1: M += 1 # 1은 소수가 될 수 없으므로 제외
for i in range(M, N+1): # M~N까지 반복
    flag = True 
    for j in range(2, int(math.sqrt(i)+1)): # 조금이라도 시간 단축하기 위해 제곱근 사용
        if i % j == 0: # 한 번이라도 j에 의해 나눠 떨어지면 flag=False &amp; break
            flag = False
            break
    if flag: # 반복문을 다 돌고 빠져나오면 flag=True인 상태 → 소수
        print(i)</code></pre>
<h4 id="제출-후-다시-생각해본-풀이">제출 후 다시 생각해본 풀이</h4>
<pre><code class="language-python">M, N = map(int, input().split())
nums = [1]*(N+1)
nums[0] = 0
nums[1] = 0

for i in range(2, int(N**0.5+1)):
    if nums[i]:
        j = 2
        while i*j &lt;= N:
            nums[i*j]=0
            j+=1
for i in range(M, N+1):
    if nums[i]:
        print(i)</code></pre>
<ul>
<li><a href="https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1241%EB%B2%88-%EB%A8%B8%EB%A6%AC-%ED%86%A1%ED%86%A1-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC">백준 1241번 설명</a> 에서 시간 단축한 풀이가 있는데, 그 방식과 비슷하게 다시 작성한 코드이다. </li>
<li>굳이 M<del>N까지의 수들에 대해서 소수인지 확인하는 것이 아니라, 0</del>N까지의 수에 대해서 0, 1은 소수가 아니라는 의미로 0을 nums 리스트에 저장하고 2부터 N**0.5+1까지의 수에 대해 nums[i]가 1이면(소수이면) N보다 작거나 같은 i의 배수들에 소수가 아니라는 의미로 0을 대입해주는 것이다. </li>
<li>마지막으로 M~N 범위의 nums 리스트에서 값이 1인 인덱스를 출력해준다. (소수 리스트)</li>
</ul>
<h3 id="✨-결과">✨ 결과</h3>
<h4 id="첫번째-풀이">첫번째 풀이</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/f38599c7-94e6-479e-9f48-42d7a5ef1b06/image.png" alt=""></p>
<h4 id="두번째-풀이">두번째 풀이</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/afff4145-3cc1-4b47-bdf8-ba13d4b23e45/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>이 문제는 1년 전에 도전했다가 틀리고 냅뒀던 문제인데,, 이번에 못 풀었던 문제들 하나씩 풀어가면서 다시 풀게 된 문제이다. 이번에 알고리즘 수업을 들어서인지 이 문제는 3분??만에 푼 것 같다. 그리고 최대한 시간을 줄여보고 싶어서 내 기준으로 제일 먼저 생각난 제곱근,,을 사용해봤다. 제출한 후에는 바로 직전에 풀었었던 1241번에서 시간 단축한 풀이에서 사용한 방식과 비슷하게 생각해 다시 풀었었다. 시간 단축이 정말 많이 되었다,, 아무래도 첫번째 풀이는 O((N-M+1)*(int(sqrt(i)+1)-2)) 시간복잡도를 가지는 반면, 두번째 풀이는 O(N-M+1)이나 그 위 반복문이 가지는 시간복잡도를 취하기 때문에 더 빠르지 않나 싶다. ((핵심은 첫번째 코드는 M부터 N까지의 수에 대해 매 반복에서 해당 수들이 소수인지 판별하는 것을 반복할 때 겹치는 부분이 존재하는 것이고 두번째 코드는 그렇지 않다는 것이다.))</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1241번 - 머리 톡톡 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1241%EB%B2%88-%EB%A8%B8%EB%A6%AC-%ED%86%A1%ED%86%A1-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1241%EB%B2%88-%EB%A8%B8%EB%A6%AC-%ED%86%A1%ED%86%A1-by-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Sat, 15 Jul 2023 02:26:52 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/1241">백준 1241번 - 머리 톡톡</a></p>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/66a3d28a-38c1-4c66-accd-443246cd0689/image.png" alt=""></p>
<h3 id="✨-주의할-점">✨ 주의할 점</h3>
<ul>
<li>문제를 푸는 것 자체는 쉬운데 <strong>시간 제한</strong> 때문에 여러 방법을 이용하지 못하는 경우가 생긴다. </li>
<li>자기 자신의 머리는 치지 않는다는 것</li>
<li>자신의 숫자가 다른 사람 숫자의 <strong>배수</strong>일 때만 머리를 톡톡친다는 것</li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<h4 id="시간-초과-코드들">시간 초과 코드들</h4>
<pre><code class="language-python">N = int(input())
student_nums = []
for _ in range(N):
    student_nums.append(int(input()))
results = [0] * N
for i in range(N):
    for j in range(i+1, N):
        stu1 = student_nums[i]
        stu2 = student_nums[j]
        if (stu1 == stu2):
            results[i]+=1
            results[j]+=1
        elif (stu1 % stu2 == 0):
            results[i]+=1
        elif (stu2 % stu1 == 0):
            results[j]+=1
for result in results:
    print(result)</code></pre>
<ul>
<li>위 코드는 내가 쓰면서도 너무 오래걸리지 않을까 고민했던 코드이다.. </li>
<li>일단 이중 for문을 썼기 때문에 시간 복잡도가 거의 N^2에 가까워서 시간 초과가 발생한 듯 하다.</li>
<li>여기서는 일단 학생들의 숫자를 입력받고 (i+1)번째 학생의 숫자와 i+2, ..., N번째 학생의 숫자를 다음 3가지 경우로 비교해 최종 경우의 수를 구해주려고 했다.
  1) 숫자 같은 경우 : 두 학생 모두 서로의 배수이므로 i, j 인덱스에 해당하는 원소에 1을 더함
  2) i+1번째 학생의 숫자가 다른 학생의 숫자의 배수일 경우 : i 인덱스에 해당하는 원소에 1을 더함
  3) 2에서 반대의 경우 : j 인덱스에 해당하는 원소에 1을 더함</li>
</ul>
<p>👉🏻 시간 초과가 발생해서 일단 될까..? 하는 마음으로 작성한 코드가 아래에 있다. </p>
<pre><code class="language-python">import sys

N = int(sys.stdin.readline())
student_nums = [0]*N
results = [0]*N

for i in range(N):
    stu_num = int(sys.stdin.readline())
    student_nums[i] = stu_num
    for j in range(i):
        if (stu_num == student_nums[j]):
            results[i]+=1
            results[j]+=1
        elif (stu_num % student_nums[j] == 0):
            results[i]+=1
        elif (student_nums[j] % stu_num == 0):
            results[j]+=1
answer = &quot;&quot;
for result in results:
    answer += str(result)+&quot;\n&quot;
print(answer)</code></pre>
<ul>
<li>여기서는 파이썬에서 시간 초과 발생 시 할 수 있다는 대표적인? 방법들 중 다음 3가지를 적용해봤다. </li>
</ul>
<ol>
<li>input 대신 sys 모듈 import 후 sys.stdin.readline을 사용</li>
<li>append() 함수 대신 인덱스를 사용해 array에 값을 대입</li>
<li>print() 함수를 여러 번 호출하는 대신 문자열로 구성해 1번의 print() 함수 호출만으로 여러 줄바꿈을 수행</li>
</ol>
<p>👉🏻 역시나 골드 문제답게 이걸로 해결은 불가능했다.. 이럴 때 생각해야 하는 것은 <strong>다른 풀이를 찾아보는 것</strong>이다. 아마 문제에서 요구하는 풀이 방향이 있을 것이라 생각하고 어떤 것을 활용할지 생각해봐야 한다. </p>
<h4 id="시간-통과한-코드">시간 통과한 코드</h4>
<blockquote>
<p>시간 초과가 뜬 코드에서는 배수 개념을 그대로 사용했는데, 문제는 중복되게 구해야 하는 것들이 너무 많았다는 것이다. 그래서 이번에는 반대로 약수 개념을 사용해 중복되는 부분들은 최대한 이미 구했던 부분에서 활용할 수 있게 해보려고 했다. </p>
</blockquote>
<ul>
<li>배수 → 약수로 바꿔 생각하면, 결국 어떤 특정 숫자 A의 약수가 되는 숫자 개수를 찾는 문제가 된다. </li>
<li>단, 최종적으로 자기 자신은 카운팅하면 안된다. </li>
<li>아래 코드는 결국 숫자 4가 있을 때 약수인 숫자 1, 2, 4의 개수를 더하면 정답을 풀 수 있다는 점을 가지고 작성한 내용이다. </li>
</ul>
<pre><code class="language-python">import sys
N = int(sys.stdin.readline())

circle, result = [0]*N, [0]*N
for i in range(N):
    circle[i] = int(sys.stdin.readline())

matrix = [0 for _ in range(max(circle)+1)]
for c in circle:
    matrix[c]+=1

for n in range(N):
    k = 1
    while (k*k &lt;= circle[n]):
        if circle[n] % k == 0: # k가 circle[n]의 약수이면 다음 2가지 경우로 나눠 생각
            if k*k != circle[n]: # 1) circle[n]과 k**2이 같지 않을 때 : 약수 k와 circle[n]//k의 개수를 더한다. 
                result[n] += matrix[k] + matrix[circle[n]//k]
            else: # 2) circle[n]과 k**2이 같을 때 : k의 제곱과 같으면 약수는 k 하나이므로 matrix[k] 하나만 더한다. 
                result[n] += matrix[k]
        k += 1

answer = &quot;&quot;
for r in result:
    answer += str(r-1)+&quot;\n&quot; # -1은 while 문에서 자기 자신을 배수로 취급하여 센 것을 빼기 위해서이다. 
print(answer)</code></pre>
<p>코드를 주어진 예제로 이해하면 다음과 같다. 
<strong>circle</strong></p>
<table>
<thead>
<tr>
<th>2</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
</tr>
</thead>
</table>
<p><strong>matrix - 숫자 개수 나타내는 배열(범위는 0~circle 배열에서 최대 숫자)</strong> </p>
<table>
<thead>
<tr>
<th align="center">0</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
</tr>
</thead>
<tbody><tr>
<td align="center">0</td>
<td align="center">1</td>
<td align="center">2</td>
<td align="center">1</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">👉🏻 숫자 1이 1개, 숫자 2가 2개, 숫자 3이 1개, 숫자 4가 1개 등장한다는 의미</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<p><strong>result</strong></p>
<table>
<thead>
<tr>
<th align="center">0</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
</tr>
</thead>
<tbody><tr>
<td align="center">2</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">1</td>
<td align="center">3</td>
</tr>
</tbody></table>
<p><strong>예시) n = 0, k = 1일 때 - circle[0] = 2</strong>
: k*k(1)이 2보다 작은데, 같지는 않으므로 약수 1과 2//1=2에 대해 matrix[1]과 matrix[2//1]=matrix[2]를 더해 result[0]을 계산한다. </p>
<h4 id="시간-단축한-다른-풀이">시간 단축한 다른 풀이</h4>
<pre><code class="language-python">import sys

t = 1000000
N = int(sys.stdin.readline())
circle = [int(sys.stdin.readline()) for _ in range(N)]
list = [0]*(t+1) # circle 요소들 개수 세는 리스트 
cnt = [0]*(t+1) # 머리 툭툭 치는 횟수 저장하는 리스트 

for c in circle:
    list[c] += 1

for i in range(1,t+1):
    if list[i]: # list[i] != 0일 때 
        cnt[i] += list[i]-1 # 1을 뺀 것은 자기 자신을 제외하기 위함
        for j in range(i+i,t+1,i): # 2*i, 3*i, 4*i, ... 는 i의 배수이므로 j의 cnt에 i 개수를 더해준다. 
            cnt[j] += list[i]

answer = &quot;&quot;
for i in circle:
    answer += str(cnt[i]) + &quot;\n&quot;
print(answer)</code></pre>
<ul>
<li>이 코드는 문제에서 제공해준 N의 범위 중 최댓값을 t에 저장해 시간복잡도가 O(t)가 되도록 했다. </li>
<li>i라는 숫자가 입력에서 존재했더라면 if list[i]가 if True가 되어 if문 안 3줄의 코드가 수행된다. 먼저 첫 번째 덧셈 부분은 자기 자신을 제외하고 같은 숫자가 존재하는 개수를 더해준 것이고, for문은 숫자 i의 배수들의 cnt에 i의 개수를 더해주는 코드이다. </li>
</ul>
<h3 id="✨-결과">✨ 결과</h3>
<h4 id="시간-통과한-코드-1">시간 통과한 코드</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/e0ccd0a5-f4e5-4e9d-8133-44f2f629702e/image.png" alt=""></p>
<h4 id="시간-단축한-다른-풀이-1">시간 단축한 다른 풀이</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/924c9e27-e167-4903-9c44-4f5b1bbb5f50/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>시간 단축이 나타나면 문제 풀이 방향을 다르게 생각해봐야 하고 배수 문제 같은 경우는 약수 문제로도 바꿔 풀 수 있는지 확인해보는 게 좋다는 생각이 들었다. 또, 3번째 코드도 결과를 보면 시간이 꽤 오래 걸렸는데, 이것보다 더 시간을 단축한 아래 풀이는 다른 풀이들을 보고 정리한 거라 아직 많이 부족하다는 생각이 들었다. 다 풀고 나서 보니 시간을 단축한 풀이가 더 생각하기 쉬웠을 것 같다는 생각을 했다. 그래도 이번 기회에 상대적으로 다양한 풀이로 문제를 접근해봐서 좋았다. 다음 문제도 고고~~!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1038번 - 감소하는 수 by Python(파이썬)]]></title>
            <link>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1038</link>
            <guid>https://velog.io/@ddo_0/%EB%B0%B1%EC%A4%80-1038</guid>
            <pubDate>Thu, 13 Jul 2023 15:09:01 GMT</pubDate>
            <description><![CDATA[<h3 id="✨-문제">✨ 문제</h3>
<p>문제 링크 → <a href="https://www.acmicpc.net/problem/1038">백준 1038번 - 감소하는 수</a>
<img src="https://velog.velcdn.com/images/ddo_0/post/b267cd3e-7667-4ee1-98ce-5269bef68b35/image.png" alt=""></p>
<h3 id="✨-주의할-점">✨ 주의할 점</h3>
<ul>
<li>0~9의 한자리 수 또한 감소하는 수이다. </li>
<li>0번째 감소하는 수는 0이라는 점이다. (1번째 감소하는 수 != 0)</li>
<li>322에서 22와 같이 같은 숫자가 연속되어도 감소하는 수라 볼 수 없다. </li>
</ul>
<h3 id="✨-풀이">✨ 풀이</h3>
<h4 id="collection-모듈-combinations-이용">collection 모듈 combinations 이용</h4>
<blockquote>
<p>1부터 차례대로 1씩 늘려가며 해당 숫자가 감소하는 수인지 판단하기는 너무 시간이 오래 걸릴 것 같아 숫자 길이 단위로 나눠보려고 사용한 방식이다. 
ex) N = 10 → 길이가 1인 감소하는 수를 make_decreasing_num 함수가 리스트로 리턴한 결과 0,1,2,3,4,5,6,7,8,9 10개이므로 아직 답을 구하지 못하고 길이가 2인 감소하는 수를 찾아 나서는 과정으로 푸는 것이다. </p>
</blockquote>
<pre><code class="language-python">from itertools import combinations
def make_decreasing_num(length):
    re = []
    li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    for comb in combinations(li, length):
        comb = list(comb)
        comb.sort() # (2, 1, 3)과 같은 조합이 등장할 경우 감소하는 수를 만들기 위해 (1, 2, 3)으로 만들어주는 것과 같다. 
        num = 0
        for y, j in enumerate(comb):
            num += j * pow(10, y)
        re.append(num)
    re.sort() # N번째 감소하는 수를 알기 위해서는 감소하는 수 리스트가 오름차순으로 정렬되어 있어야 한다. 
    return re

if __name__ == &quot;__main__&quot;:
    N = int(input())
    num = []
    result = -1 # N번째 감소하는 수가 없을 때 출력할 값을 저장해두기
    for i in range(1, 11):
        num.extend(make_decreasing_num(i))
        if(len(num) &gt; N):
            result = num[N]
            break
    print(result)</code></pre>
<ul>
<li>main 부분에서는 N을 입력받고 길이가 i인 감소하는 수 리스트를 make_decreasing_num으로 구해 num 리스트에 추가한 후, 다음 길이로 넘어가기 전에 num 리스트의 길이와 N을 비교해 N번째 감소하는 수가 포함된 num 리스트가 만들어지면 break하여 나오고 그렇지 않으면 다음 반복으로 넘어가도록 했다. </li>
<li>make_decreasing_num 함수는 combinations를 이용해 li에서 length개의 원소를 골라 조합을 만든 후, 해당 조합을 오름차수 정렬하여 숫자로 변환한 뒤 리스트에 넣어주는 과정을 반복한다. 이후 감소하는 수가 모인 리스트를 정렬해 리턴한다. </li>
</ul>
<h4 id="dfs-이용">dfs 이용</h4>
<blockquote>
<p>dfs를 이용하는 방식은 위 방식으로 풀고 제출한 후, 다른 사람들의 풀이를 보다가 괜찮은 것 같아서 해당 방식으로 풀어본 코드이다. </p>
</blockquote>
<pre><code class="language-python">N = int(input())
num = []

def make_decreasing_dfs(number):
    num.append(number)
    units = int(str(number)[0])
    for i in range(units+1, 10):
        make_decreasing_dfs(int(str(i)+str(number)))

for i in range(10):
    make_decreasing_dfs(i)

if len(num) &gt; N:
    num.sort()
    print(num[N])
else:
    print(-1)</code></pre>
<ul>
<li>dfs 핵심 = 재귀 &amp; 종료 조건</li>
<li>여기서는 0~9까지의 i가 반복적으로 make_decreasing_dfs를 호출하고, 해당 함수는 재귀적으로 호출되며 계속해서 감소하는 수를 찾아 리스트 num에 append한다. 함수는 계속해서 반복하다 units가 9일 때, 즉 인자로 넘어온 수의 가장 맨 앞에 있는 숫자가 9일 때 리턴된다. </li>
</ul>
<h3 id="✨-결과">✨ 결과</h3>
<h4 id="combinations-이용한-코드">combinations 이용한 코드</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/d9cab22e-9cc3-4087-9d57-ad78bf5d222b/image.png" alt=""></p>
<h4 id="dfs-이용한-코드">dfs 이용한 코드</h4>
<p><img src="https://velog.velcdn.com/images/ddo_0/post/38b08abd-7401-4f59-8fe2-e7b66b698dd2/image.png" alt=""></p>
<h3 id="👩🏻💻-후기">👩🏻‍💻 후기</h3>
<p>문제를 보고 든 생각은 1부터 세기는 시간이 너무 오래 걸리겠다..와 자릿수를 기준으로 나눠서 구해볼까..였다. 후자의 생각이 combinations를 떠올리게 하는데까지 오래 걸려서 문제였지만,, 이 문제를 풀었으니 앞으로 combinations를 잘 활용해봐야겠다. 또, 문제를 풀고 다른 사람 코드를 봤을 때 dfs 방식도 쓸 수 있구나 생각이 들어서 작성해본 코드도 꽤 괜찮은 것 같다. 실제로 시간도 조금 더 빨랐기 때문이다. 대신 dfs는 자릿수가 아니라 0~9까지의 베이스 숫자를 가지고 감소하는 수를 만들어 확장해나가는 방식이다. 바로 저번 학기에 알고리즘 수업을 들었는데, 이때 배운 dfs를 떠올리며 코드를 작성해봤다. 마지막으로 이 문제는 2년 전에.. 그니까 신입생인 1학년 때 도전했다가 실패해서 남겨둔 문제인데 이번에 풀게 되어서 의미가 컸다! </p>
]]></description>
        </item>
    </channel>
</rss>