<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>mankiew_vol9.log</title>
        <link>https://velog.io/</link>
        <description>맨큐의 개발일지</description>
        <lastBuildDate>Thu, 30 Jan 2025 01:55:43 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>mankiew_vol9.log</title>
            <url>https://velog.velcdn.com/images/mankiew_vol9/profile/1dc49ced-fdb1-49fa-b78b-74540176880a/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. mankiew_vol9.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/mankiew_vol9" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Flutter]To Do List 후기]]></title>
            <link>https://velog.io/@mankiew_vol9/FlutterTo-Do-List-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@mankiew_vol9/FlutterTo-Do-List-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Thu, 30 Jan 2025 01:55:43 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-dart">import &#39;package:flutter/material.dart&#39;;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    const String appTitle = &#39;Flutter layout demo&#39;;
    return MaterialApp(
      title: appTitle,
      home: MyToDo(),
    );
  }
}

class MyToDo extends StatefulWidget {
  const MyToDo({super.key});

  @override
  State&lt;MyToDo&gt; createState() =&gt; _MyToDoState();
}

class _MyToDoState extends State&lt;MyToDo&gt; {
  final TextEditingController _controller = TextEditingController();
  var widgets = &lt;Widget&gt;[];
  @override //IDK
  initState(){
    widgets=[AddWidgets()];
    super.initState();

  }


  Widget AddWidgets(){
    return Padding(
        padding: const EdgeInsets.all(20.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          spacing: 50.0,
          children: [
            Icon(
              Icons.calendar_today,
              size: 30.0,
            ),
            SizedBox(
              width: 250,
              child: TextFormField(
                controller: _controller,
                decoration: const InputDecoration(
                  hintText: &#39;What is your Task?&#39;,
                  labelText: &#39;Enter your Task&#39;,
                ),
              ),
            ),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  widgets.add(
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
          children: [
            MyButton(),
            Padding(
              padding: const EdgeInsets.all(20.0),
              child: Text(_controller.text),
            )
          ],
        ));
                });
              },
              child: Text(&#39;Add Task&#39;),
            ),
          ],
        ));
  }

  Widget getbody(){
   return Column(children:
      widgets,
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(&quot;Woomin ToDO&quot;),
      ),
      body: Center(
        child: Column(
          children: [

            getbody()
          ],
        ),
      ),
    );
  }
}


class MyRow extends StatelessWidget {
  const MyRow({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    var children = &lt;Widget&gt;[];
    children.add(Text(&quot;&quot;));
    return Row(
      children: children,
    );
  }
}

class MyButton extends StatefulWidget {
  const MyButton({super.key});

  @override
  State&lt;MyButton&gt; createState() =&gt; _MyCounterState();
}

class _MyCounterState extends State&lt;MyButton&gt; {
  bool initValue = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Checkbox(
          value: initValue,
          onChanged: (bool? newValue) {
            setState(() {
              initValue = !initValue;
            });
          },
        ),
      ],
    );
  }
}</code></pre>
<p>만들어보고싶은게 많아서 플러터로 앱같은거 만들어 보고 싶어서 몇일째 공식문서만 보다가 마참내 플러터로 투두 리스트 만들어 보기로 했다.</p>
<p>가장 힘들었던건 동적으로 위젯을 생성하는것이 였는데 다행히도 컨트롤러의 개념과
<a href="https://stackoverflow.com/questions/68274886/adding-widgets-dynamically-with-flutter">https://stackoverflow.com/questions/68274886/adding-widgets-dynamically-with-flutter</a>
이 글 을 보고 해결되었다.
근데 문제는 어떻게 작동되는지 잘 모르겠다.</p>
<ol>
<li>class를 써야되는 경우랑 widget만 써도 되는경우</li>
</ol>
<blockquote>
<p>Flutter에서 클래스를 써야 하는 경우와 단순 위젯만 써도 되는 경우는 상황에 따라 다릅니다.</p>
</blockquote>
<ol>
<li>클래스를 써야 하는 경우
📌 재사용이 필요한 위젯
같은 UI 요소를 여러 곳에서 반복적으로 사용할 때
같은 스타일과 동작을 유지하면서, 일부 속성만 변경하고 싶을 때
예제: MyButton, MyRow
📌 상태(StatefulWidget)가 필요한 경우
내부적으로 상태를 변경해야 하는 경우 (예: 체크박스, 버튼 클릭 시 변화)
StatefulWidget을 사용하여 setState()를 통해 UI를 갱신할 필요가 있을 때
예제: MyButton (체크박스의 상태 변경을 위해 StatefulWidget 필요)
📌 규모가 커지는 위젯
코드가 길어지고 복잡해질 경우 유지보수를 위해 클래스로 분리하는 것이 좋음</li>
<li>단순한 위젯만 써도 되는 경우
📌 일회성으로 사용되는 위젯
특정 화면에서만 사용되며 재사용될 필요가 없을 때
예제: AddWidgets() 함수 (이건 단순히 위젯을 반환하는 역할이므로 함수로 충분함)
📌 상태 관리가 필요 없는 정적인 UI 요소
내부적으로 변경되지 않는 경우
단순히 레이아웃을 구성하는 경우
예제: MyRow는 사실 const Row()로도 충분함</li>
</ol>
<p>2.initstate()는 무슨 코드임</p>
<blockquote>
<p>initState()란?
initState()는 StatefulWidget에서 위젯이 처음 생성될 때 한 번만 실행되는 메서드입니다.
즉, 위젯이 화면에 나타나기 전에 초기화해야 할 작업을 수행하는 곳이에요.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot]UploadExample모르는거 정리]]></title>
            <link>https://velog.io/@mankiew_vol9/SpringBootUploadExample%EB%AA%A8%EB%A5%B4%EB%8A%94%EA%B1%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@mankiew_vol9/SpringBootUploadExample%EB%AA%A8%EB%A5%B4%EB%8A%94%EA%B1%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 21 Jan 2025 02:38:02 GMT</pubDate>
            <description><![CDATA[<p>Q1)</p>
<pre><code class="language-java">@Entity

public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name =&quot;id&quot;)
    private Long id;
    @Column(name = &quot;title&quot;)
    private String title;
    @Column(name = &quot;content&quot;)
    private String content;

    protected  Article(){  }

    @Builder
    public Article(String title, String content){
        this.title = title;
        this.content= content;
    }

}</code></pre>
<p>여기서 왜</p>
<pre><code class="language-java">protected  Article(){  }

    @Builder
    public Article(String title, String content){
        this.title = title;
        this.content= content;
    }</code></pre>
<p>이런 코드를 어떤생각으로 도출해내는건지 모르겠다.</p>
<p>A1)대충 결론부터 말하면 JPA프레임워크에서 요구하는 코드라고 한다. 조금더 자세히 말하면</p>
<blockquote>
<p>JPA는 엔티티 객체를 생성하고 관리하기 위해 리플렉션(Reflection) 이라는 기술을 사용합니다. 리플렉션을 통해 클래스의 정보를 가져오고 객체를 생성하는데, 이때 기본 생성자가 필요합니다. protected 접근 제어자는 외부에서 직접 객체를 생성하는 것을 막으면서도 JPA가 내부적으로 객체를 생성할 수 있도록 허용합니다.</p>
</blockquote>
<p>이런 이유 때문이라고 한다.</p>
<pre><code class="language-java">@Getter
@Setter
public class AddArticleRequest {
 private Long id;
 private String title;
 private String content;
 public Article toEntity(){
   return  Article.builder()
           .title(title)
           .content(content)
           .build();

 }
}</code></pre>
<p>여기(DTO)에서 toEntity()메서드 쓰는 이유도 물어봤다</p>
<blockquote>
<p>DTO(Data Transfer Object)는 계층 간 데이터 교환을 위해 사용되는 객체입니다. 즉, 레이어 간 데이터를 주고받을 때 사용하는 객체를 의미합니다. 예를 들어, 컨트롤러에서 서비스 계층으로 데이터를 전달하거나, 서비스 계층에서 데이터베이스에 데이터를 저장할 때 DTO를 사용할 수 있습니다.</p>
</blockquote>
<blockquote>
<p>toEntity() 메서드는 DTO (Data Transfer Object) 객체를 엔티티 객체로 변환하기 위해 만든 메서드입니다.
DTO는 계층 간 데이터 교환을 위한 객체이고, 엔티티는 데이터베이스에 저장되는 객체입니다. DTO와 엔티티는 역할과 구조가 다르기 때문에, DTO를 엔티티로 변환하는 작업이 필요합니다.
toEntity() 메서드는 DTO 객체의 데이터를 사용하여 새로운 Article 엔티티 객체를 생성하고 반환합니다. 이렇게 생성된 엔티티 객체는 JPA를 통해 데이터베이스에 저장될 수 있습니다.</p>
</blockquote>
<p>DTO사용안한 코드는 이렇다
Controller</p>
<pre><code class="language-java">package com.BlogExample;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@RequiredArgsConstructor
@Controller
public class BlogApiController {
    private final BlogService blogService;

    @PostMapping(&quot;/api/articles&quot;)
    public ResponseEntity&lt;Article&gt; add(@RequestBody Article request) { // DTO 대신 엔티티를 직접 사용
        Article savedArticle = blogService.save(request);
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(savedArticle);
    }
}</code></pre>
<p>Service</p>
<pre><code class="language-java">package com.BlogExample;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class BlogService {
    private final BlogRepository blogRepository;

    public Article save(Article article) { // DTO 대신 엔티티를 직접 사용
        return blogRepository.save(article);
    }
}
</code></pre>
<p>또 궁금했던건 controller는 json으로 응답을 받을텐데 이거를 어떻게 데이터베이스에 저장하는지 그 매커니즘이 궁금했다.
또 간단하게 설명하면 이렇다.</p>
<blockquote>
<p>Jackson 라이브러리는 기본적으로 JSON 데이터의 필드 이름과 객체의 필드 이름을 일치시켜 값을 저장합니다.</p>
</blockquote>
<pre><code class="language-json">
{
  &quot;title&quot;:&quot;첫글&quot;,
  &quot;content&quot;:&quot;첫글은 역시 똥글&quot;
}</code></pre>
<blockquote>
<p>이 JSON 데이터를 Article 객체로 변환하면, Jackson 라이브러리는 JSON 데이터의 &quot;title&quot; 필드 값을 Article 객체의 title 필드에 저장하고, &quot;content&quot; 필드 값을 content 필드에 저장합니다.</p>
</blockquote>
<pre><code>ResponseEntity&lt;Article&gt;</code></pre><blockquote>
<p>사용하는 이유는 HTTP 응답을 더욱 세밀하게 제어하고, RESTful API 디자인 원칙을 준수하기 위해서입니다.ResponseEntity의 장점
HTTP 상태 코드 제어: ResponseEntity를 사용하면 HTTP 상태 코드를 명시적으로 지정할 수 있습니다. 예를 들어, ResponseEntity.status(HttpStatus.CREATED)는 201 Created 상태 코드를 응답과 함께 전송합니다. 이를 통해 클라이언트에게 요청의 성공 여부, 생성된 리소스의 위치 등을 정확하게 알릴 수 있습니다.
응답 헤더 설정: ResponseEntity를 사용하면 응답 헤더를 자유롭게 설정할 수 있습니다. 예를 들어, Location 헤더를 사용하여 새로 생성된 리소스의 URI를 클라이언트에게 알려줄 수 있습니다.
응답 본문 설정: ResponseEntity를 사용하면 응답 본문에 Article 객체와 같은 자바 객체를 담아서 전송할 수 있습니다. Jackson 라이브러리를 사용하여 자바 객체를 JSON 형식으로 자동 변환하여 클라이언트에게 전달합니다.
RESTful API 디자인: ResponseEntity를 사용하면 RESTful API 디자인 원칙을 준수하는 데 도움이 됩니다. RESTful API는 HTTP 상태 코드, 헤더, 본문을 사용하여 리소스의 상태와 관련된 정보를 명확하게 전달해야 합니다.
ResponseEntity를 사용하지 않을 경우
ResponseEntity를 사용하지 않고 Article 객체만 반환하면, Spring은 기본적으로 200 OK 상태 코드와 함께 응답을 전송합니다. 이는 단순한 API에서는 문제가 되지 않지만, 복잡한 API에서는 클라이언트에게 충분한 정보를 제공하지 못할 수 있습니다.
결론
ResponseEntity를 사용하면 HTTP 응답을 세밀하게 제어하고, RESTful API 디자인 원칙을 준수하여 클라이언트에게 더욱 명확하고 유용한 정보를 제공할 수 있습니다. 따라서, RESTful API를 개발할 때는 ResponseEntity를 사용하는 것이 권장됩니다.</p>
</blockquote>
<p>Article로 반환받아도 되긴 한다는거다 ㅋㅎ</p>
<p>Article로 반환받으면 이렇게 된다고 한다</p>
<pre><code class="language-java">
public Article addArticle(@RequestBody AddArticleRequest request) {

    // AddArticleRequest를 Article 엔티티로 변환합니다.
    Article article = Article.builder()
            .title(request.getTitle())
            .content(request.getContent())
            // 필요한 다른 필드 설정
            .build();

    // blogService를 사용하여 Article을 저장합니다.
    return blogService.save(article);
}
</code></pre>
<p>모르는게 뭔지 알아도 다시 짜기는 무섭다.. ㄷㄷㄷ</p>
<p>p.s)추가로 더 알아봐야할것은 제네릭과 리스트에 대해서 자바책으로 조금더 공부해야겠다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot]UploadExample 만들기2
]]></title>
            <link>https://velog.io/@mankiew_vol9/SpringBootUploadExample-%EB%A7%8C%EB%93%A4%EA%B8%B02</link>
            <guid>https://velog.io/@mankiew_vol9/SpringBootUploadExample-%EB%A7%8C%EB%93%A4%EA%B8%B02</guid>
            <pubDate>Mon, 20 Jan 2025 23:31:21 GMT</pubDate>
            <description><![CDATA[<p>결국 또 막막해서 포기함...
가장 막막했던건 내가 뭘 모르는지도 모른다는거였다.</p>
<h3 id="내가-했던것">내가 했던것</h3>
<p>우선 클래스들을 만들었다. 
엔티티, 컨트롤러, 리포지토리,서비스 클래스를 만들었다.</p>
<p>근데 작성하는 방법을 까먹었다.
엔티티는 대충
@Id, @GeneratedValue, @Column쓰는것 까지는 기억이 났다. 물론 공식문서도 참고했다.
<a href="https://spring.io/guides/gs/uploading-files">https://spring.io/guides/gs/uploading-files</a>
자세하게 참고한건 아니고 각 계층별 형식같은것만 대충 참고했다.
리포지토리도 그냥 CrudRepository..대충 따라쳤다.</p>
<h3 id="모르겠는것들">모르겠는것들</h3>
<pre><code class="language-java">@Entity

public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name =&quot;id&quot;)
    private Long id;
    @Column(name = &quot;title&quot;)
    private String title;
    @Column(name = &quot;content&quot;)
    private String content;

    protected  Article(){  }

    @Builder
    public Article(String title, String content){
        this.title = title;
        this.content= content;
    }

}
</code></pre>
<p>여기서 왜 </p>
<pre><code class="language-java">protected  Article(){  }

    @Builder
    public Article(String title, String content){
        this.title = title;
        this.content= content;
    }</code></pre>
<p>이런 코드를 어떤생각으로 도출해내는건지 모르겠다.</p>
<p>그리고 Dto를 왜 만들었고 어떻게 쓰는지에 대한 이해가 더 필요할 것 같다.</p>
<pre><code class="language-java">@RequiredArgsConstructor
@Controller
public class BlogApiController {
    private final BlogService blogService;
    @PostMapping(&quot;/api/articles&quot;)
    public ResponseEntity&lt;Article&gt; add(@RequestBody AddArticleRequest request){
            Article savedArticle = blogService.save(request);
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(savedArticle);
        }

    }</code></pre>
<p>이 코드를 어떻게 생각해내야했을지 더 생각해봐야겠다.</p>
<p>다음포스트에서는 내가 모르는것들에 대한 정리를 해보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot]UploadExample 만들기]]></title>
            <link>https://velog.io/@mankiew_vol9/SpringBootUploadExample-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@mankiew_vol9/SpringBootUploadExample-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 20 Jan 2025 05:13:18 GMT</pubDate>
            <description><![CDATA[<p>구현해야할기능</p>
<ol>
<li>localhost:8080/add/articles로 post요청 json으로 <pre><code class="language-json">{
&quot;title&quot;:&quot;첫글&quot;,
&quot;content&quot;:&quot;첫글은 역시 똥글&quot;
}</code></pre>
이렇게 보내면 mySQl db에
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/0909cdff-0495-4f05-9c1a-77ec18ba3317/image.png" alt="">
이런식으로 저장되게</li>
</ol>
<p>구조
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/be0c67bb-94e5-4e87-8e39-2b940abc6942/image.png" alt=""></p>
<p>책에 나온데로 똑같이 해볼것이다.
맨날 막막해서 그냥 책 봐버렸는데 이제는 내힘으로 해볼꺼다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring boot] 작동방식  Dispatcher Sevlet,계층, MVC]]></title>
            <link>https://velog.io/@mankiew_vol9/Spring-Servlet-contianer-Spring-containerServletBean</link>
            <guid>https://velog.io/@mankiew_vol9/Spring-Servlet-contianer-Spring-containerServletBean</guid>
            <pubDate>Wed, 15 Jan 2025 23:22:18 GMT</pubDate>
            <description><![CDATA[<h3 id="스프링부트-작동방식">스프링부트 작동방식</h3>
<p>기본구조</p>
<p>1.MVC
모델: 데이터, 비즈니스 로직</p>
<p>뷰:
모델로부터 데이터를 받아 사용자에게 표시
사용자의 입력을 받아 컨트롤러에 전달</p>
<p>컨트롤러:
사용자의 입력처리, 모델과 뷰 사이에 상호작용 관리</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/43f15179-f89e-4555-9c3e-b34c6d47dd16/image.png" alt=""></p>
<p>내방식대로 대충 정리
Dispatcher Servlet이 브라우저로부터의 요청을 어떻게 잘 처리해서 컨트롤러에게 넘김
컨트롤러는 매핑된대로 서비스에게 넘김
서비스는 컨트롤러에게 가공된 요청을 받아서 비즈니스 로직 수행함
이 과정에서 repository에 데이터 엑세스할수도 있음
repository는 비즈니스로직한테 요청받으면 데이터베이스 읽고 씀
컨트롤러는 실행한 로직을 바탕으로 사용자에게 보여줌
(DispatcherServlet이 반환된 view객체 이용해 최종 응답 렌더링)</p>
<p>Dispatcher Servlet은 요청처음에 받을때 일하고 마지막에 내보낼때 일하는 약간 문지기 느낌?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring Boot]JPA, ORM, Hibernate,JDBC,Spring Data DAO, DTO, Entity, 계층]]></title>
            <link>https://velog.io/@mankiew_vol9/SpringJPA-ORM-HibernateJDBCDAO-DTO-Entity</link>
            <guid>https://velog.io/@mankiew_vol9/SpringJPA-ORM-HibernateJDBCDAO-DTO-Entity</guid>
            <pubDate>Wed, 15 Jan 2025 23:06:11 GMT</pubDate>
            <description><![CDATA[<p><strong>JPA</strong>란?
Java의 표준 <strong>ORM</strong></p>
<p><strong>ORM</strong>이란?
Java의 객체와 DB연결하는 프로그래밍 기법
<strong>RDBMS</strong>(관계형 DB 관리하기 위한 소프트웨어 ex)MySQL, Oracle)안써도 되니까 간편함</p>
<p>JPA는 인터페이스 이므로 실제사용을 위해서는 ORM 프레임워크를 써야함
대표적인것이 <strong>하이버네이트</strong></p>
<p>하이버네이트 내부적으로는 <strong>JDBC</strong> API사용</p>
<p> <strong>Spring Data</strong>는 
 엔티티 상태관리,트랜잭션 커밋을 클래스 레벨에서 추상화함</p>
<p> <strong>Spring Data JPA</strong>
 Spring Data+ JPA기능</p>
<p>** Entity**
 DB테이블과 매핑되는 객체(객체이지만 DB에 영향을 미치는 쿼리를 실행하는 객체)</p>
<p> JPA의 중요속성1
 <strong>Entity 매니저</strong>
 엔티티 관리: DB와 어플리케이션 사이에서 객체생성, 수정, 삭제
 엔티티 팩토리에서 만들어짐</p>
<p> JPA중요속성2
 영속성 컨텍스트
 엔티티 관리하는 가상공간
 -1차캐시
 -쓰기지연
 -변경감지
 -지연로딩</p>
<p> <strong>계층</strong>
 1.프레젠테이션 계층
 :컨트롤러, 요청과 매핑하여 비즈니스 계층으로 넘김</p>
<p> 2.비즈니스 계층
 :비즈니스 로직 처리</p>
<p> 3.퍼시스턴스 계층
 :모든 DB관련 로직처리
 이 과정에서  DB에 접근하는 DAO객체를 사용할수 있음</p>
<p><strong>DTO</strong>(data transfer object)는 계층끼리 데이터를 교환하기 위해 사용하는 객체입니다. </p>
<p><strong>DAO</strong>는 데이터베이스와 연결되고 데이터를 조회하고 수정하는데 사용하는 객체라 데이터 수정과 관련된 로직이 포함되지만  </p>
<p>DTO는 단순하게 데이터를 옮기기 위해 사용하는 전달자 역할을 하는 객체이기 때문에  별도의 비즈니스 로직을 포함하지 않습니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java]기간별 학습내용]]></title>
            <link>https://velog.io/@mankiew_vol9/Java%EA%B8%B0%EA%B0%84%EB%B3%84-%ED%95%99%EC%8A%B5%EB%82%B4%EC%9A%A9</link>
            <guid>https://velog.io/@mankiew_vol9/Java%EA%B8%B0%EA%B0%84%EB%B3%84-%ED%95%99%EC%8A%B5%EB%82%B4%EC%9A%A9</guid>
            <pubDate>Fri, 10 Jan 2025 05:08:43 GMT</pubDate>
            <description><![CDATA[<h2 id="110">1/10</h2>
<p>Chapter 06 클래스 
6.1 객체 지향 프로그래밍 
6.2 객체와 클래스 
6.3 클래스 선언 
6.4 객체 생성과 클래스 변수 
6.5 클래스의 구성 멤버 
6.6 필드 선언과 사용 
6.7 생성자 선언과 호출 
6.8 메소드 선언과 호출 
6.9 인스턴스 멤버 
6.10 정적 멤버 
6.11 final 필드와 상수 
6.12 패키지 
6.13 접근 제한자 
6.14 Getter와 Setter 
6.15 싱글톤 패턴</p>
<p>Chapter 07 상속<br>7.1 상속 개념 
7.2 클래스 상속 
7.3 부모 생성자 호출 
7.4 메소드 재정의 
7.5 final 클래스와 final 메소드 
7.6 protected 접근 제한자 
7.7 타입 변환 
7.8 다형성 
7.9 객체 타입 확인 
7.10 추상 클래스 
7.11 봉인된 클래스 </p>
<p>Chapter 08 인터페이스 
8.1 인터페이스 역할 
8.2 인터페이스와 구현 클래스 선언 
8.3 상수 필드 
8.4 추상 메소드 
8.5 디폴트 메소드 
8.6 정적 메소드 
8.7 private 메소드 
8.8 다중 인터페이스 구현 
8.9 인터페이스 상속 
8.10 타입 변환 
8.11 다형성 
8.12 객체 타입 확인 
8.13 봉인된 인터페이스 </p>
<p>Chapter 12 java base 모듈
12.11 리플렉션 
12.12 어노테이션 </p>
<p>Chapter 13 제네릭 
13.1 제네릭이란? 
13.2 제네릭 타입 
13.3 제네릭 메소드 
13.4 제한된 타입 파라미터 
13.5 와일드카드 타입 파라미터 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java]자바입문 시작]]></title>
            <link>https://velog.io/@mankiew_vol9/Java%EC%9E%90%EB%B0%94%EC%9E%85%EB%AC%B8-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@mankiew_vol9/Java%EC%9E%90%EB%B0%94%EC%9E%85%EB%AC%B8-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Thu, 09 Jan 2025 01:41:11 GMT</pubDate>
            <description><![CDATA[<p>1/3~
학습매체</p>
<p>&quot;이것이 자바다&quot; 책 
+udemy &quot;초보자를 위한 자바 프로그래밍 과정부터 자바 객체 지향 프로그래밍까지. 보너스: Spring Boot를 활용한 REST API 설계</p>
<p>학습예상기간
(1~3개월)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] static에 대해 알아보자]]></title>
            <link>https://velog.io/@mankiew_vol9/Java-static%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@mankiew_vol9/Java-static%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sun, 05 Jan 2025 11:22:19 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">class Foo{
    public static String classVar = &quot;I class var&quot;;
    public String instanceVar = &quot;I instance var&quot;;
    public static void classMethod() {
        System.out.println(classVar); // Ok
//        System.out.println(instanceVar); // Error
    }
    public void instanceMethod() {
        System.out.println(classVar); // Ok
        System.out.println(instanceVar); // Ok
    }
}
public class StaticApp {

    public static void main(String[] args) {
        System.out.println(Foo.classVar); // OK
//        System.out.println(Foo.instanceVar); // Error
        Foo.classMethod();
//        Foo.instanceMethod();

        Foo f1 = new Foo();
        Foo f2 = new Foo();
//        
        System.out.println(f1.classVar); // I class var
        System.out.println(f1.instanceVar); // I instance var
//        
        f1.classVar = &quot;changed by f1&quot;;
        System.out.println(Foo.classVar); // changed by f1
        System.out.println(f2.classVar);  // changed by f1
//        
        f1.instanceVar = &quot;changed by f1&quot;;
        System.out.println(f1.instanceVar); // changed by f1
        System.out.println(f2.instanceVar); // I instance var
    }

}</code></pre>
<p>static은 &#39;정적&#39;이라는 뜻으로 static이 붙는것과 아닌것의 메모리 할당시점이 다르다</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/6fb2bc41-f87a-45d3-b091-6e5b5b17b741/image.png" alt=""></p>
<p>Error라고 쓰여진 주석코드를 각각 e1,e2라 하겠다</p>
<p>e1이 발생한 이유는 instanceVar는 인스턴스 변수이기 때문에 객체가 생성이되어야 메모리에 할당이 되기 때문에 객체가 생성이 안된 시점에서는 호출할수 없기 때문이다.</p>
<p>반면  instanceMethod 속 instanceVar를 불러올수 있느 이유는 instanceMethod또한 인스턴스 메소드 이기 때문에 instanceVar가 호출된 시점에는 이미 인스턴스 객체가 생성되고 난 후이기 때문이다.</p>
<p>e2가 발생한 이유는 e1과 같다. </p>
<p>그 밑에 Foo.instanceMethod()가 안되는 이유는 instanceMethod()는 인스턴스 메소드이기 때문에 인스턴스 객체가 생성되어야 호출할수 있기 때문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[사이드 프로젝트] Subreddit 후기]]></title>
            <link>https://velog.io/@mankiew_vol9/%EC%82%AC%EC%9D%B4%EB%93%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-Subreddit-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@mankiew_vol9/%EC%82%AC%EC%9D%B4%EB%93%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-Subreddit-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Thu, 02 Jan 2025 03:01:34 GMT</pubDate>
            <description><![CDATA[<p>유데미에서 듣고있는 web developer bootcamp2024의 섹션34(358강)에서 더 복잡한 subreddit프로젝트를 만드는게 있길래 모범답안을 보기전에 먼저 만들기로 했다. 물론 엉망이긴 했다</p>
<p><a href="https://github.com/woominKO/subreddit2">https://github.com/woominKO/subreddit2</a></p>
<p>우선 데이터베이스를 연결하는 법은 알려주시지 않았기때문에 json형식으로 데이터를 주셨는데 이것때문에도 꽤나 힘들었다. json을 js에서 어떻게 파싱하는지도 몰랐기 때문이다. </p>
<p>gpt는 최대한 쓰지 않기로 했다. gpt는 정답이 하나인것처럼 말해주는데 그렇게 계속하다보면 생각하는 능력이 떨어지고 다양한 방법을 생각하고 그속에서 의사결정 하는 능력이 떨어질것 같다.
(그렇지만 마지막에는 써버렸다...)</p>
<p>아무튼 json파일은 이렇다</p>
<pre><code class="language-json">{
    &quot;soccer&quot;: {
        &quot;name&quot;: &quot;Soccer&quot;,
        &quot;subscribers&quot;: 800000,
        &quot;description&quot;: &quot;The football subreddit. News, results and discussion about the beautiful game.&quot;,
        &quot;posts&quot;: [
            {
                &quot;title&quot;: &quot;Marten de Roon to make pizza for more than 1,000 people in Bergamo if Atalanta win the Champions league.&quot;,
                &quot;author&quot;: &quot;joeextreme&quot;
            },
            {
                &quot;title&quot;: &quot;Stephan Lichtsteiner has retired from professional football&quot;,
                &quot;author&quot;: &quot;odd person&quot;
            },
            {
                &quot;title&quot;: &quot;OFFICIAL: Dani Parejo signs for Villareal.&quot;,
                &quot;author&quot;: &quot;joeextreme&quot;
            }
        ]
    },
    &quot;chickens&quot;: {
        &quot;name&quot;: &quot;Chickens&quot;,
        &quot;subscribers&quot;: 23956,
        &quot;description&quot;: &quot;A place to post your photos, video and questions about chickens!&quot;,
        &quot;posts&quot;: [
            {
                &quot;title&quot;: &quot;Naughty chicken hid under a shed for 3 weeks and came home with 25 chicks today!&quot;,
                &quot;author&quot;: &quot;joeextreme&quot;,
                &quot;img&quot;: &quot;https://preview.redd.it/pcn8u4j7c9z61.jpg?width=960&amp;crop=smart&amp;auto=webp&amp;s=e114976dde1108b9556555d2db36a3cb6211798d&quot;
            },
            {
                &quot;title&quot;: &quot;Had to kill my first chicken today. Does it get any easier?&quot;,
                &quot;author&quot;: &quot;sad boi&quot;
            },
            {
                &quot;title&quot;: &quot;My five year old chicken set and hatched one baby. I guess she wanted to be a mama one more time.&quot;,
                &quot;author&quot;: &quot;tammythetiger&quot;,
                &quot;img&quot;: &quot;https://preview.redd.it/lervkuis3me51.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=6a18ab3c4daa80eccf3449217589b922fa443946&quot;
            }
        ]
    },
    &quot;mightyharvest&quot;: {
        &quot;name&quot;: &quot;Mighty Harvest&quot;,
        &quot;subscribers&quot;: 44002,
        &quot;description&quot;: &quot;Feeding many villages and village idiots for 10s of days.&quot;,
        &quot;posts&quot;: [
            {
                &quot;title&quot;: &quot;My first meyer lemon ripened today. Im so proud of the little guy. Banana for scale&quot;,
                &quot;author&quot;: &quot;proudmamma&quot;,
                &quot;img&quot;: &quot;https://preview.redd.it/1bz6we4j54941.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=a036ea99299f7737efde9f6c3bfa43893f5eaa00&quot;
            },
            {
                &quot;title&quot;: &quot;I think I overestimated the harvest basket size I needed.&quot;,
                &quot;author&quot;: &quot;grower123&quot;,
                &quot;img&quot;: &quot;https://preview.redd.it/4h99osd25i351.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=d651250a345bbceeba7a66632e8c52a02d71bc73&quot;
            }
        ]
    }
}
</code></pre>
<p>구현하고 싶었던 것은 
서버파일을 실행하고 url창에
localhost:3000/r/[subreddit주제]
를 입력하면 ejs가 주제에 맞춰서 페이지를 띄워줘야하는데
이때, ejs반복문을 사용해서 title,author를 출력하고 페이지의 이름과 description도 출력해야했다. css는 뒤로 미뤄두고 간단하게 글자들만 출력하기로 했다.</p>
<h3 id="구현할때-생각해보아야-할것들은-다음과-같았다"><strong>구현할때 생각해보아야 할것들은 다음과 같았다.</strong></h3>
<p>0.기본적인 express.js구조 
1.라우팅(/r/서브레딧주제)
2.ejs 반복문을 어떻게 짤것인가</p>
<h3 id="프로젝트를-만들면서-몰랐던것들은-다음과-같다"><strong>프로젝트를 만들면서 몰랐던것들은 다음과 같다</strong></h3>
<p><del>0.기본적인 express.js서버파일구조</del>
0.1 express()해야하는 이유
0.2 app.listen반드시 써야함
1.프로젝트 경로에 있는 파일을 서버파일과 연결하는법
2.json파일을 js에 이식하는법
3.fs.readFile - (강사분은 이걸 안썼다..)
4.반복문기초
5.js 객체 접근문법
6. app.set이란?
7. res.render문법
8.path.join을 왜써야하고 어떻게 쓰는지
9.구조분해할당--&gt; ex){...data}
10.res.params(이건 알았는데 자세히 공부해야할듯)
11.함수속 메소드 (express()와 express.static이 되는 이유)</p>
<p>나는 반복문을 어디까지 써야할지 고민이였다. 레딧 서브페이지는 따로 만들어야할지 그것조차 반복문(?)을 써야할지..</p>
<p>나는 subreddit마다 페이지를 따로따로 만들었지만
강사분은</p>
<pre><code class="language-js">const redditData = require(&#39;./data.json&#39;);
app.get(&#39;/r/:subreddit&#39;, (req, res) =&gt; {
    const { subreddit } = req.params;
    const data = redditData[subreddit];
    if (data) {
        res.render(&#39;subreddit&#39;, { ...data });
    } else {
        res.render(&#39;notfound&#39;, { subreddit })
    }
})
</code></pre>
<p>이런식으로  :subreddit요청이 오면 json에서 아예 해당 subreddit만 추출해서 ejs에 보내고</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;&lt;%= name %&gt; &lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;/app.css&quot;&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;h1&gt;Browsing The &lt;%= name %&gt; subreddit&lt;/h1&gt;
    &lt;h2&gt;&lt;%= description %&gt;&lt;/h2&gt;
    &lt;p&gt;&lt;%=subscribers %&gt; Total Subscribers&lt;/p&gt;
    &lt;hr&gt;

    &lt;% for(let post of posts) { %&gt;
    &lt;article&gt;
        &lt;p&gt;&lt;%= post.title %&gt; - &lt;b&gt;&lt;%=post.author %&gt;&lt;/b&gt;&lt;/p&gt;
        &lt;% if(post.img) { %&gt;
        &lt;img src=&quot;&lt;%= post.img %&gt;&quot; alt=&quot;&quot;&gt;
        &lt;% } %&gt;
    &lt;/article&gt;
    &lt;% } %&gt;
&lt;/body&gt;

&lt;/html&gt;</code></pre>
<p>이런식으로 만들었는데 놀라웠다.. 이생각을 왜못했지..</p>
<h2 id="배운점들-정리">[배운점들 정리]</h2>
<p>0.1 익스프레스를 사용할때 </p>
<pre><code class="language-js">const express = require(&#39;express&#39;);
const app = express();</code></pre>
<p>왜 이렇게 하는지 몰라서 index.js파일 만들고 어떤 코드부터 넣어야할지 머릿속에서 아무생각이 없이 멍~했다.</p>
<p>첫번째 줄에서 require로 모듈시스템을 이용하여 라이브러리를 불러오는것은 알게되었는데
두번째줄 관련 코드를 검색해보니 인스턴스를 생성하는코드라는데 인스턴스는 뭘까..</p>
<blockquote>
<p>자바스크립트에서 인스턴스는 특정 클래스 또는 생성자함수로부터 생성된 객체를 의미합니다</p>
</blockquote>
<pre><code class="language-js">function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function () {
    console.log(`Hello, my name is ${this.name}`);
  };
}
// 인스턴스 생성
const person1 = new Person(&#39;Alice&#39;, 25);
const person2 = new Person(&#39;Bob&#39;, 30);
person1.greet(); // Hello, my name is Alice
person2.greet(); // Hello, my name is Bob</code></pre>
<p>위 예제에서 Person은 생성자 함수이고, person1과 person2는 Person의 인스턴스입니다.</p>
<pre><code class="language-js">class Animal {
  constructor(type, sound) {
    this.type = type;
    this.sound = sound;
  }
  makeSound() {
    console.log(`${this.type} says ${this.sound}`);
  }
}
// 인스턴스 생성
const dog = new Animal(&#39;Dog&#39;, &#39;Woof&#39;);
const cat = new Animal(&#39;Cat&#39;, &#39;Meow&#39;);
dog.makeSound(); // Dog says Woof
cat.makeSound(); // Cat says Meow</code></pre>
<p>여기서 Animal은 클래스이고, dog와 cat은 해당 클래스의 인스턴스입니다.</p>
<p>this.name = name은 생성한 인스턴스 괄호속에 있는 인자를 인스턴스의 메소드로 집어넣는다는 뜻인것 같다. 정확히 말하자면 생성한 인스턴스의 property에 괄호 속에 인자를 할당한다는 뜻이라고 한다.</p>
<p>그래서 익스프레스의 인스턴스를 만드는건 뭘까 
내생각에는 app.get같은걸 쓰기 위해서 쓰는것 같긴하다.</p>
<blockquote>
<p>require(&#39;express&#39;):
Node.js의 모듈 시스템을 사용하여 Express 라이브러리를 불러옵니다.
이때 반환되는 값은 함수(function) 또는 객체(object)입니다.
express 변수:
이 변수는 Express 프레임워크 자체를 의미하며, 서버 인스턴스를 생성할 수 있는 함수를 포함합니다.</p>
</blockquote>
<p>어렴풋이 알것같은데.. 정확히는 이해는 안가는 느낌...</p>
<blockquote>
<p>좋은 질문이에요! 😊 <strong>Express</strong>에서 <code>express()</code>는 왜 함수처럼 호출되는지 설명드리겠습니다.  </p>
</blockquote>
<h2 id="1-핵심-차이점-express는-함수function이고-avante는-객체object"><strong>1. 핵심 차이점: Express는 함수(Function)이고, avante는 객체(Object)</strong></h2>
<h3 id="객체object">객체(Object)</h3>
<pre><code class="language-javascript">class Car {
  constructor(brand, name, color) {
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
}
const avante = new Car(&#39;hyundai&#39;, &#39;avante&#39;, &#39;blue&#39;);</code></pre>
<ul>
<li><code>avante</code>는 <strong>클래스(Car)</strong>의 <strong>인스턴스(객체)</strong>입니다.  </li>
<li><strong>객체는 함수처럼 호출할 수 없습니다.</strong> → <code>avante()</code>는 <strong>오류</strong> 발생!  <h3 id="express의-경우-함수function"><strong>Express의 경우: 함수(Function)</strong></h3>
```js
const express = require(&#39;express&#39;); // express는 함수!
const app = express(); // 함수 호출</li>
<li>require(&#39;express&#39;)  //모듈 자체가 함수(Function)를 반환합니다.<br>express() 호출: <ul>
<li>이 함수는 새로운 <strong>애플리케이션 인스턴스(객체)</strong>를 생성하고 반환합니다.  </li>
<li>반환된 객체(<code>app</code>)는 서버를 설정하는 데 사용됩니다.<br>즉, Express 모듈 자체가 함수이기 때문에 <strong><code>express()</code></strong>처럼 호출할 수 있습니다.<pre><code>## **2. Express는 함수지만 객체처럼 동작**  
### 내부 동작:
```javascript
function express() {
const app = Object.create(null); // 새로운 객체 생성
app.use = function () { /* 미들웨어 추가 */ };
app.get = function () { /* GET 라우트 설정 */ };
app.listen = function () { /* 서버 실행 */ };
return app; // 최종 객체 반환
}</code></pre></li>
</ul>
</li>
<li><strong><code>express()</code> 함수</strong>는 내부적으로 <strong>객체(app)</strong>를 생성하고 반환합니다.  </li>
<li>이 객체에는 <strong>메서드</strong>(<code>use</code>, <code>get</code>, <code>listen</code>)가 정의되어 있습니다.  </li>
<li>결과적으로 <strong><code>express()</code>는 함수처럼 호출되지만 반환값은 객체</strong>이므로, 아래와 같은 사용이 가능해집니다.  <pre><code class="language-javascript">const app = express(); // 새로운 객체(app) 반환
app.get(&#39;/&#39;, (req, res) =&gt; res.send(&#39;Hello World!&#39;)); // 객체 메서드 사용</code></pre>
<h2 id="3-일반-객체도-함수처럼-만들-수-있음-팩토리-패턴"><strong>3. 일반 객체도 함수처럼 만들 수 있음! (팩토리 패턴)</strong></h2>
Express의 구조는 <strong>팩토리 패턴(Factory Pattern)</strong>을 사용한 예제입니다.  <strong>팩토리 패턴</strong>을 활용하면 일반 객체도 함수처럼 동작할 수 있습니다.<pre><code class="language-javascript">function createCar(brand, name, color) {
return {
  brand: brand,
  name: name,
  color: color,
  drive() {
    console.log(`${this.name} is driving`);
  }
};
}
const avante = createCar(&#39;hyundai&#39;, &#39;avante&#39;, &#39;blue&#39;); // 함수 호출
avante.drive(); // &#39;avante is driving&#39;</code></pre>
</li>
<li>이 예제에서 <strong><code>createCar()</code></strong>는 <strong>함수이면서 객체를 반환</strong>합니다.  </li>
<li>Express도 이와 유사하게 동작합니다.  <h2 id="4-결론"><strong>4. 결론</strong></h2>
</li>
<li><strong><code>express()</code></strong>는 <strong>함수(Function)</strong>로 정의되어 있기 때문에 직접 호출할 수 있습니다.  </li>
<li><strong><code>avante</code></strong>는 <strong>객체(Object)</strong>이기 때문에 직접 호출할 수 없습니다.  - Express는 <strong>팩토리 패턴</strong>을 이용해 함수 호출 시 객체를 반환하는 방식으로 동작합니다.  </li>
<li>필요에 따라 일반 객체도 <strong>팩토리 패턴</strong>을 사용하여 함수처럼 동작하게 만들 수 있습니다.  </li>
<li>이해가 안 되는 부분이나 추가 궁금한 점이 있으면 언제든 물어봐 주세요! 😊</li>
</ul>
<p>0.2 app.listen이란?
서버를 어느포트에서 실행한껀지를 정하는데 문법은
app.listen(포트번호,콜백함수) 로 되는데 보통 콜백함수에는 console.log(&quot;you&#39;re listening to 포트번호&quot;)이렇게 많이 쓰는듯 하다</p>
<p>1.우선 익스프레스 모듈을 js파일로 불러와야 하는데 이때 require를 쓴다.</p>
<p>NodeJS에서는 require 메서드를 통해 외부 모듈을 가져올수 있다.
require메서드는 node가 local object에 추가한 메서드로서 다음 과 같이 파라미터로 추가할 모듈의 파일 경로값을 받는다</p>
<pre><code class="language-js">require(&#39;파일경로&#39;);</code></pre>
<p>만약 연결하는 모듈파일이 같은 파일안에 있다는 경로값의 시작은 ./이 됩니다.
npm으로 설치하거나 기본내장모듈은 파일경로에 이름만 단순히 입력해도 불러와진다.</p>
<p>깟땜gpt한테 물어본 결과</p>
<blockquote>
</blockquote>
<p><code>require(&#39;express&#39;)</code>만 입력해도 되는 이유는 <strong>Express.js</strong>가 Node.js의 <strong>npm(Node Package Manager)</strong> 패키지로 설치되기 때문입니다.  </p>
<h3 id="1-npm-패키지-구조"><strong>1. npm 패키지 구조</strong></h3>
<p>Express.js는 npm을 통해 설치되며, <code>node_modules</code> 폴더에 저장됩니다.<br>예를 들어, 다음 명령어로 설치할 수 있습니다.  </p>
<pre><code class="language-bash">npm install express</code></pre>
<h3 id="2-패키지-이름과-모듈-경로-매칭"><strong>2. 패키지 이름과 모듈 경로 매칭</strong></h3>
<ul>
<li>설치된 Express.js는 <code>node_modules/express</code> 폴더에 위치합니다.  </li>
<li><code>require()</code> 함수는 기본적으로 <code>node_modules</code> 폴더를 검색합니다.  </li>
<li>따라서 <code>require(&#39;express&#39;)</code>는 <code>node_modules/express/index.js</code> 파일을 로드합니다.  <h3 id="3-packagejson의-main-필드-활용"><strong>3. package.json의 &quot;main&quot; 필드 활용</strong></h3>
<code>node_modules/express</code> 폴더 안의 <strong><code>package.json</code></strong> 파일에는 다음과 같은 내용이 있습니다.<pre><code class="language-json">{
&quot;name&quot;: &quot;express&quot;,
&quot;main&quot;: &quot;index.js&quot;
}</code></pre>
</li>
<li>여기서 <code>&quot;main&quot;: &quot;index.js&quot;</code>는 기본 진입점(entry point)을 정의합니다.  </li>
<li>따라서 <code>require(&#39;express&#39;)</code>는 자동으로 <code>index.js</code>를 불러옵니다.  <h3 id="4-파일-경로를-명시하지-않아도-되는-이유"><strong>4. 파일 경로를 명시하지 않아도 되는 이유</strong></h3>
직접 파일 경로(예: <code>require(&#39;./express&#39;)</code>) 대신 <code>require(&#39;express&#39;)</code>를 사용해도 되는 이유는:</li>
<li>npm 패키지는 전역 모듈 검색 경로에 등록됩니다.</li>
<li>Node.js는 자동으로 <code>node_modules</code> 폴더를 찾습니다.</li>
<li><code>express</code> 패키지는 등록된 이름으로 직접 호출됩니다.<h3 id="정리"><strong>정리</strong></h3>
Express.js를 npm을 통해 설치하면, Node.js는 자동으로 모듈을 찾고 로드합니다.<br>따라서 파일 경로 대신 패키지 이름만 입력하면 쉽게 사용할 수 있습니다.</li>
<li>참고로 module.exports를 해야 해당모듈을 다른파일에서도 불러올 수 있다. </li>
</ul>
<p>라고한다..</p>
<p><a href="https://velog.io/@kakasoo/Node%EC%9D%98%EB%AA%A8%EB%93%88%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BCrequire">https://velog.io/@kakasoo/Node%EC%9D%98%EB%AA%A8%EB%93%88%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BCrequire</a>
참고링크</p>
<p>2&amp;3 json파일을 js에 이식하는법
내가쓴 방법은 fs.readFile을 씀으로써 js가 json을 받아들이도록 했다.
fs는 file system의 약자로 nodejs 내장모듈이다
<a href="https://nodejs.org/api/fs.html#fsreadfilepath-options-callback">https://nodejs.org/api/fs.html#fsreadfilepath-options-callback</a></p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/6ff854d7-8a73-4cfe-bb31-f1dcf6ec883e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/0cd746a1-a244-4860-908c-82f511b3aaa5/image.png" alt=""></p>
<p>그렇다고 합니다</p>
<ol start="4">
<li><p>object array반복문</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/d378afaf-b27f-4d1e-b208-30096aac04e1/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/8b3ef95d-9250-4f17-b093-713ebe2e65f3/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/845fc0ce-56df-4b41-b844-2f07090b2c22/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/2ef6c0e2-6903-4329-9986-2871ac22c4fe/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/f20bb220-2203-4280-b379-b3195a367f96/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/da1d0555-9ac9-4173-ba56-2ee1662901b8/image.png" alt=""></p>
<p>foreach는 반복문이 아니라 메소드였다는 사실!!</p>
</li>
<li><p>js 객체접근문법</p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/2a0d1530-2f49-49d2-b8ae-20e3829b2b9d/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/51ba529b-9100-4284-9bb6-ff54e621c8f3/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/4b2f6deb-8d28-4df0-a1ac-5b002f9ea88d/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/4c1103bf-4655-4006-a9f4-6217c0884180/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/7a1d6ef6-9de4-4c2f-bb62-a5d8e59ca283/image.png" alt=""></p>
<p>참고* 
key값에 접근하는법
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/53e7bc80-1023-47c3-9ffd-62d164df3d68/image.png" alt=""></p>
<ol start="6">
<li>app.set이란?
<a href="https://expressjs.com/en/5x/api.html#app.set">https://expressjs.com/en/5x/api.html#app.set</a>
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/9f9d8dac-72cb-419b-9173-e51cf91af7f9/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/763e496b-fbbe-42e4-a54b-45211e7f76ee/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/25b0e937-9290-426e-8b01-ad3dd46000eb/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/95483557-84b1-4ee2-8fac-9ad813dcd990/image.png" alt=""></li>
</ol>
<p>*참고 app.use
<a href="https://expressjs.com/en/guide/using-middleware.html">https://expressjs.com/en/guide/using-middleware.html</a>
<a href="https://backend.turing.edu/module2/lessons/how_the_web_works_http">https://backend.turing.edu/module2/lessons/how_the_web_works_http</a>
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/ec8e0514-61dc-4534-94c0-a866d7671420/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/ca8cf034-0385-4f11-a409-25ba1a04a032/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/fd03247b-9133-4191-98f8-2690687a8fa9/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/31fcac3e-4d3e-495a-8769-0439a06af7de/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/71d5b8dc-54b2-441c-b698-ac11366abdfe/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/d79f173c-cfca-4488-b6fe-5e668e99009b/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/f42c86ce-5901-4d1a-b97b-ea01f1e308d3/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/bfb54b52-dcee-4f06-9a93-b36edffe783f/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/e6fbe9ae-5066-4ff2-af8a-fb5819f2bab6/image.png" alt=""></p>
<p>Router-lever middleware도 있다는데 다음에 알아보자</p>
<ol start="7">
<li>res.render문
<a href="https://expressjs.com/en/api.html#res.render">https://expressjs.com/en/api.html#res.render</a>
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/c555c87a-1e18-4bb9-996e-502c902ad0e9/image.png" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/73de455c-b9c9-4032-82b2-e0dbe4e256b9/image.png" alt=""></li>
</ol>
<ol start="8">
<li>path.join()<pre><code class="language-js">const express= require(&#39;express&#39;)
const path= require(&#39;path&#39;)
const app = express()
</code></pre>
</li>
</ol>
<p>app.set(&quot;view engine&quot;, &quot;ejs&quot;);
app.set(&quot;views&quot;, path.join(__dirname, &#39;views&#39;))</p>
<p>app.get(&#39;/r/:subreddit&#39;,(req,res)=&gt;{
    const subreddit = req.params.subreddit;
    console.log(subreddit)
    res.render(&#39;index&#39;, {subreddit:subreddit})
})</p>
<p>app.listen(3000);</p>
<pre><code>위 코드를 보면서 path.join에 대해 알아보자


path.join은 view engine과 관련해서 쓰였다.
그래서 view, view engine 부터 알아보자 

view와 view engine은
app.set의 name칸에 들어가는 property다
app.set은 아까봤듯이 말그대로 어플리케이션의 세팅을해주는 메소드인데 
위에있는 사진에서 있던view에 대한 설명을 가져오자면
A directory or an array of directories for the application&#39;s views
라고한다.

그리고 view engine에 대한 설명은
The default engine extension to use when omitted. 
라고 한다.

공식문서에는 
![](https://velog.velcdn.com/images/mankiew_vol9/post/4d49eae4-fec4-4458-bee3-8deb6ad5c697/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/b3b1f3dc-90b0-4b24-84a4-8517d2ebb292/image.png)
라고 나와있다.
&gt; To render template files, set the following application setting properties, in the default app.js created by the generator:
views, the directory where the template files are located. Eg: app.set(&#39;views&#39;, &#39;./views&#39;). This defaults to the views directory in the application root directory. 
view engine, the template engine to use. For example, to use the Pug template engine: app.set(&#39;view engine&#39;, &#39;pug&#39;).

세팅을 해야한다는거 보니 app.set으로 view, view engine을 설정해야하는것 같다.

위에 설명한 app.set(&#39;views&#39;, &#39;./views&#39;) 을 보면 뒤에 인자에 파일경로를 써야되는것 같은데 위에 js코드를 보면 여기에 path.join이 쓰였다.

https://expressjs.com/en/guide/using-template-engines.html
![](https://velog.velcdn.com/images/mankiew_vol9/post/de4421de-8051-4d3f-a576-400d87b70f83/image.png)

9.구조분해할당
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
![](https://velog.velcdn.com/images/mankiew_vol9/post/56744981-dd46-48c9-af03-a048f831ff1c/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/8185e55e-5d89-4ce3-be51-1d241f1e9aeb/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/06cf6b45-3ad7-4e34-ae09-a0ee0903274d/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/413b9ef3-a1ca-4453-b7c4-4afe703eaf0e/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/68666408-3849-4b32-8f1b-fee8a99cbc05/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/3d11e6f9-4dbd-47b6-8144-38c2e0103961/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/d36b3575-3b72-4e0d-9847-8f6ac8569575/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/64575748-2b22-4cf7-bf83-46a372b6c14b/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/3d29920e-706f-4681-83bd-06f0a575e145/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/0b9db425-49f6-410e-87bc-b0eeb58cdb5b/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/59cbe750-f1fb-4577-9e42-2f7ba74c9794/image.png)
![](https://velog.velcdn.com/images/mankiew_vol9/post/708f092c-54ca-46de-82ea-0418627ec867/image.png)

10.res.params
![](https://velog.velcdn.com/images/mankiew_vol9/post/7c51b5ed-b041-4e49-881e-d0d80d16e8ea/image.png)

11.prototype
https://developer.mozilla.org/ko/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
```js
const express= require(&#39;express&#39;)
const app = express()
express.XXX</code></pre><p>뭔가 이상하다</p>
<p>express는 함수라 호출도 되는데 
express.xxx처럼 메소드도 있다.</p>
<p>아마 prototype때문에 가능한것 같다.
<img src="blob:https://velog.io/2f96bac6-6351-402d-8a0c-42d7bd6b93cc" alt="업로드중.."></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQLD  시험본 후기]]></title>
            <link>https://velog.io/@mankiew_vol9/SQLD-%EC%8B%9C%ED%97%98%EB%B3%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@mankiew_vol9/SQLD-%EC%8B%9C%ED%97%98%EB%B3%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sat, 10 Jun 2023 04:23:40 GMT</pubDate>
            <description><![CDATA[<p>공부기간: 한달이지만 띄엄띄엄 설렁설렁 공부함</p>
<p>공부방법</p>
<p><a href="https://www.youtube.com/watch?v=llk__mId4yQ&amp;t=256s&amp;pp=ygUPc3FsZCDqs7XrtoDrspUg">https://www.youtube.com/watch?v=llk__mId4yQ&amp;t=256s&amp;pp=ygUPc3FsZCDqs7XrtoDrspUg</a></p>
<p>저 위 동영상대로 data onair랑 요약본 개념보다가 너무 어려워서 때려침... 근데 처음보면 진짜 1과목은 경악스러운데 자주보고 인터넷에 검색하면서 최대한 쉬운말로 풀어써져 있는 말로 되어있는걸로보면 나중에는 별것도 아닌데 왜이렇게 어렵게 써놨을까 라는 생각이 든다</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/b46eb7a7-4755-43ee-bed5-e0f24b5766dd/image.jpeg" alt="">
밀리의서재에 있는 민트책을 여러번 읽었다</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/93ddd265-b6cc-477f-8be0-c7a95035fb71/image.png" alt="">
그리고 노랑이 풀었는데 2과목 너어어무 어려워서 울면서 풀었는데 막상 시험은 그렇게 어렵게 나오진 않았다.( 쉬웠다는 뜻이 아니다. 그에 준하는 복잡한 문제들도 있었다) 참고로 어쩌다DBA님의 해설강의를 보면 그나마 낫다. 개념설명도 해주셔서(특히 계층형 쿼리 설명이 좋았음)보면 좋다.</p>
<p>기출을 봐야한다고 했는데 볼껄 후회중이다...왜냐하면 문제의 수준과 빈출유형을 알 수 있기 때문이다.</p>
<p>막판에 3개 동영상을 봤는데 이 세 동영상에 있는 내용을 완벽하게 숙지한다면 진짜 합격했을것 같다. 진짜 이대로 나옴..</p>
<p><a href="https://www.youtube.com/watch?v=PC3ypt_VGWI&amp;pp=ygUEc3FsZA%3D%3D">https://www.youtube.com/watch?v=PC3ypt_VGWI&amp;pp=ygUEc3FsZA%3D%3D</a></p>
<p><a href="https://www.youtube.com/watch?v=PjCSvexo3Ow&amp;t=327s&amp;pp=ygUEc3FsZA%3D%3D">https://www.youtube.com/watch?v=PjCSvexo3Ow&amp;t=327s&amp;pp=ygUEc3FsZA%3D%3D</a></p>
<p><a href="https://www.youtube.com/watch?v=BQxAxMnHByU&amp;t=5s&amp;pp=ygUEc3FsZA%3D%3D">https://www.youtube.com/watch?v=BQxAxMnHByU&amp;t=5s&amp;pp=ygUEc3FsZA%3D%3D</a>
쪽집게 강의는 강의 자료도 줬는데 여기 필기하면서 보고 시험보기 전에 계속 보고 있었더니 도움이 되었다.</p>
<p>9월에.. 재도전??</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[피로그래밍코딩테스트]]></title>
            <link>https://velog.io/@mankiew_vol9/%ED%94%BC%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@mankiew_vol9/%ED%94%BC%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Mon, 05 Jun 2023 06:19:26 GMT</pubDate>
            <description><![CDATA[<p>깃헙 레포지토리=<a href="https://github.com/woominKO/Pirograming">https://github.com/woominKO/Pirograming</a></p>
<h4 id="문제">[문제]</h4>
<h1 id="19기-코딩-테스트-문제">19기 코딩 테스트 문제</h1>
<h3 id="컴퓨터가-되어버린-운영진을-이겨라">컴퓨터가 되어버린 운영진을 이겨라!</h3>
<p> <strong>피로그래밍 운영진 카드 게임</strong> </p>
<p>2개월 간의 혹독하지만 보람찬 세션과 과제들을 완수하며 <code>**코딩 지옥🔥**</code>에 빠져버린 피로그래밍 운영진들…</p>
<p>운영진과의 카드 게임에서 1등을 해야 코딩 지옥에서 벗어날 수 있다는데..😨</p>
<p>제시된 출력 형태를 참고하여 아래의 조건들을 만족하는 프로그램을 구현해 운영진을 구해주세요🥺✨</p>
<p> 출력 형태를 바탕으로 아래의 조건들에 맞게 프로그램을 구현하시오.</p>
<p><strong>문제설명</strong></p>
<p>[ 게임 시작 전 ] </p>
<ul>
<li>캐릭터가 총 4명 존재한다.</li>
</ul>
<table>
<thead>
<tr>
<th>캐릭터 표</th>
<th>박신빈</th>
<th>윤정원</th>
<th>임담희</th>
<th>김용현</th>
</tr>
</thead>
<tbody><tr>
<td>- 사용자는 4개의 캐릭터 중 하나를 자신의 캐릭터로 선택한다. - 선택방식은 자유</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 이때 선택된 캐릭터는 게임이 끝날 때까지 바뀌지 않는다.</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 컴퓨터가 1부터 13 사이의 숫자 카드를 랜덤으로 30장 생성한다. (중복 가능)</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 내 캐릭터 포함 네 명의 플레이어들은 돌아가며 덱의 맨 뒤부터 카드를 뽑는다.</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- <strong>1라운드</strong>는 이름 순 <strong>2,3,4 라운드</strong>는 점수가 낮은 순서대로 카드를 뽑는다.</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 문서 마지막의 입출력 케이스를 참고하시면 이해가 쉽습니다.</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>[ 게임 진행 ] </p>
<ul>
<li>게임은 4 라운드 동안 진행된다.</li>
<li>매 라운드의 시작마다 카드 덱을 섞는다.</li>
<li>내 캐릭터 포함 네 명의 플레이어들은 돌아가며 덱의 맨 뒤부터 카드를 뽑는다.</li>
<li>모든 사람이 카드를 뽑은 후 해당 라운드에서 가장 숫자가 큰 카드를 뽑은 플레이어가 승리하며, 승리한 플레이어는 가장 낮은 숫자의 카드를 뽑은 플레이어의 카드 숫자와의 차이만큼 점수를 얻는다.<ul>
<li>가장 숫자가 큰 카드를 뽑은 사람이 여러 명일 경우 해당되는 모든 플레이어가 점수를 얻는다.</li>
<li>이때 모든 사람이 카드가 동일한 경우 결론적으로 모든 0점을 얻게 된다.</li>
</ul>
</li>
<li>플레이어가(내 캐릭터, 컴퓨터 공통) 카드를 선택할 때마다 어떤 카드를 뽑았는지 출력한다.
카드를 모두 뽑은 후 승리한 플레이어가 얻을 점수를 구해서 출력한다.</li>
</ul>
<ul>
<li>각 라운드가 종료되었을 때 업데이트된 플레이어의 점수를 표시.</li>
</ul>
<p>[ 게임 종료 후 ]</p>
<ul>
<li>4라운드 동안 진행되며, 4라운드 종료 후 게임 결과를 출력한다.<ul>
<li>먼저 라운드에서 승리한 횟수 순서, 점수 순서 두가지 형태로 각각 출력한다.<br>단, 승리한 횟수나 점수가 같을 경우 이름 순으로 출력한다.</li>
<li>결과 출력 상에서 내가 <strong>선택한 캐릭터는 이름 앞뒤에 <code>*</code> 를 출력해준다.</strong></li>
</ul>
</li>
</ul>
<p><strong>HINT</strong></p>
<ul>
<li><p>카드를 무작위로 뽑거나 섞을 때는 random 함수를 사용해보세요.</p>
</li>
<li><p>정렬할 때에는 sort, lambda 함수를 사용해보세요.</p>
</li>
<li><p><strong>어디서부터 공부해야할지 모르겠다면, 아래 링크에 들어가보세요!</strong></p>
<ul>
<li><a href="https://wikidocs.net/book/1">https://wikidocs.net/book/1</a> (점프 투 파이썬)</li>
<li>점프 투 파이썬 1, 2, 3, 4, 5장을 참고하세요.</li>
</ul>
<p><strong>스켈레톤 코드</strong> </p>
</li>
<li><p>스켈레톤 코드는 참고사항일 뿐입니다.</p>
</li>
<li><p>스켈레톤 코드를 사용하지 않아도 좋습니다.</p>
</li>
<li><p>사용하실 분들은 TODO 로 표시 되어있는 부분을 참고해주세요.</p>
</li>
<li><p>자유롭게 조건에 맞는 프로그램을 구현해주세요.</p>
</li>
</ul>
<pre><code class="language-python">import random

class Player:
    def __init__(self, name):
        self.name = name
        self.score = 0
        self.round_wins = 0

    def __str__(self) -&gt; str:
        return f&quot;{self.name}&quot;

class Game:
    def __init__(self):
        self.players = [] # 유저들의 목록
        self.deck = [] # 카드 무작위 생성
        self.my_player = &quot;&quot;

    def start_game(self):
        &quot;&quot;&quot;
        - [ 게임 시작 전 ] 부분을 담당하는 함수 입니다.
        - 캐릭터들을 초기화 하고, 사용자가 플레이할 캐릭터를 선택합니다.
        - 1부터 13사이의 숫자의 무작위 숫자를 골라서 30개의 카드로 이루어진 덱을 만듭니다.
        - 동일 클래스의 game()에서 호출됩니다.
        &quot;&quot;&quot;

        self.players.append(Player(&quot;박신빈&quot;))
        self.players.append(Player(&quot;윤정원&quot;))
        self.players.append(Player(&quot;임담희&quot;))
        self.players.append(Player(&quot;김용현&quot;))

        print(&quot;당신의 캐릭터 번호를 선택해주세요 (1,2,3,4) :&quot;, end = &quot;&quot;)
        # TODO 1-(1): 사용자로부터 캐릭터를 입력받아 my_player에 저장해주세요.
        # Write code here..
        ##### END OF TODO 1-(1)(문제와 본 라인 사이에 코드를 작성하세요.) #####

        # TODO 1-(2) : 랜덤으로 1부터 13 사이의 카드 30장을 deck에 저장해주세요
        # random에 대한 함수를 공부해봅시다.
        # Write code here..
        ##### END OF TODO 1-(2)(문제와 본 라인 사이에 코드를 작성하세요.) #####

    def set_play_order(self, round_num):
        &quot;&quot;&quot; 
        - [ 게임 진행 ] 부분에서 게임진행 순서를 정하는 함수 입니다.
        - 동일 클래스의 play_game()에서 호출됩니다.
        &quot;&quot;&quot;
        # TODO 2 : 게임진행을 위한 플레이어를 재정렬해주세요.(ROUND 1 : 사전 순서로 이름을 오름차순으로 정렬, ROUND 2,3,4 : 점수를 기준으로 오름차순 정렬)
        # sort 와 lambda 함수에 대해 공부해보세요. 사용하지 않아도 좋습니다.
        # Write code here..
        ##### END OF TODO 2 (문제와 본 라인 사이에 코드를 작성하세요.) #####

    def play_round(self):
        &quot;&quot;&quot;
        - [ 게임 진행 ] 라운드 진행을 담당하는 함수 입니다.
        - 동일 클래스의 play_game()에서 호출됩니다.
        &quot;&quot;&quot;

        play_order = &quot;,&quot;.join(map(str, self.players))

        print(f&quot;게임은 {play_order} 순으로 진행됩니다.\n&quot;)

        # TODO 3-(1) : 카드를 뽑기 전에 self.deck을 랜덤으로 섞어주셔요.
        # Write code here..
        ##### END OF TODO 3-(1) (문제와 본 라인 사이에 코드를 작성하세요.) #####

        print(&quot;===========플레이어가 뽑은 카드============&quot;)
        # TODO 3-(2) : 플레이어들이 카드를 뽑는 부분입니다. 플레이어들이 뽑은 카드를 players_cards에 저장해주시고, 뽑을 때마다 어떠한 카드를 뽑았는지 출력하는 코드를 작성해주세요. 
        # Write code here..
        ##### END OF TODO 3-(2) (문제와 본 라인 사이에 코드를 작성하세요.) ##### 

        # TODO 3-(3) : 가장 큰 숫자를 뽑은 플레이어가 점수를 얻는 코드를 작성해주세요.
        # 점수 계산 방식 : 본인의 카드에 적힌 숫자 - 플레이어들이 뽑은 카드 중 가장 숫자가 작은 카드에 적힌 숫자
        # Write code here..
        ##### END OF TODO 3-(3) (문제와 본 라인 사이에 코드를 작성하세요.) ##### 

    def play_game(self):

        &quot;&quot;&quot;
        - [ 게임 진행 ] 부분을 담당하는 함수 입니다.
        - 동일 클래스의 game()에서 호출됩니다.
        &quot;&quot;&quot;
        for round_num in range(1, 5):

          self.set_play_order(round_num)

          print(&quot;===========================&quot;)
          print(f&quot;     ROUND {round_num} - START&quot;)
          print(&quot;===========================&quot;)
          self.play_round()


          print(&quot;===========================&quot;)
          print(f&quot;     ROUND {round_num} - END&quot;)
          print(&quot;===========================&quot;)
          # 라운드 종료 후 각 플레이어들의 현재 점수
          for order, player in enumerate(self.players, 1): 
            print(f&quot;{order}. {player} : {player.score}점&quot;)
          print()

    def game_result(self):

        # TODO 4-(1) : 점수 순으로 결과값을 출력해주세요.
        # 내가 선택한 캐릭터 이름 앞뒤에는 *을 붙여주세요.
        # sort 와 lambda 함수에 대해 공부해보세요. 사용하지 않아도 좋습니다.
        print(&quot;=============================&quot;)
        print(&quot;     게임 순위 - 점수&quot;)
        print(&quot;=============================&quot;)
        # Write code here..
        ##### END OF TODO 4-(1)(문제와 본 라인 사이에 코드를 작성하세요.) #####


        # TODO 4-(2) : 승리 횟수 순으로 결과값을 출력해주세요.
        # 내가 선택한 캐릭터 이름 앞뒤에는 *을 붙여주세요.
        # sort 와 lambda 함수에 대해 공부해보세요. 사용하지 않아도 좋습니다.
        print(&quot;=============================&quot;)
        print(&quot;     게임 순위 - 승리 횟수&quot;)
        print(&quot;=============================&quot;)
        # Write code here..
        ##### END OF TODO 4-(2)(문제와 본 라인 사이에 코드를 작성하세요.) #####


    def game(self):

        &quot;&quot;&quot;
        - 게임 운영을 위한 함수입니다. 
        - 별도의 코드 작성이 필요 없습니다. 
        &quot;&quot;&quot;

        self.start_game()
        self.play_game()
        self.game_result()

if __name__ == &quot;__main__&quot;:  
    &quot;&quot;&quot;
    - 코드를 실행하는 부분입니다. 
    - 역시 별도의 코드 작성이 필요 없습니다. 
    &quot;&quot;&quot;
    game = Game()

    game.game()</code></pre>
<p><strong>TODO list</strong></p>
<ul>
<li><p>TODO List</p>
<p>  1-1. 번호 입력 받아 해당 캐릭터 my_player에 저장하기</p>
<p>  1-2. 1부터 13 사이의 숫자 카드를 랜덤으로 30장 생성해서 deck에 저장하기</p>
<ol start="2">
<li><p>플레이어 순서 정렬 (1R: 이름 순, 2R ~: 점수 낮은 순)</p>
<p>3-1. 카드를 뽑기 전에 deck을 랜덤으로 섞기</p>
<p>3-2. 플레이어별로 카드를 deck의 뒤에서부터 뽑고 출력하기</p>
<p>3-3. 라운드 종료 후 플레이어별로 점수 계산해서 업데이트 후 출력하기</p>
<p>4-1. 점수 순으로 결과값 출력하기</p>
<p>⇒ 점수가 같다면 이름순 출력</p>
<p>4-2. 게임 종료 후 승리 횟수 순으로 결과값 출력하기</p>
<p>⇒ 승리 횟수가 같다면 이름순 출력</p>
</li>
</ol>
</li>
</ul>
<p><strong>입출력케이스</strong></p>
<ul>
<li><p>이해에 도움을 드리기 위한 다양한 입출력케이스입니다.</p>
</li>
<li><p>입출력 예시 1</p>
<p>  <strong>입력형태 1</strong></p>
<p>  당신의 캐릭터 번호를 선택해주세요 (1,2,3,4) : 4</p>
<p>  <strong>출력형태 1</strong></p>
<pre><code class="language-python">  ===========================
       ROUND 1 - START
  ===========================
  게임은 김용현,박신빈,윤정원,임담희 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 5

  &gt;&gt; 박신빈 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 11

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 6

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 2

  &gt;&gt;&gt;&gt; 박신빈님이 9 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 1 - END
  ===========================
  1. 김용현 : 0점
  2. 박신빈 : 9점
  3. 윤정원 : 0점
  4. 임담희 : 0점

  ===========================
       ROUND 2 - START
  ===========================
  게임은 김용현,윤정원,임담희,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 9

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 10

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 8

  &gt;&gt; 박신빈 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 4

  &gt;&gt;&gt;&gt; 윤정원님이 6 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 2 - END
  ===========================
  1. 김용현 : 0점
  2. 윤정원 : 6점
  3. 임담희 : 0점
  4. 박신빈 : 9점

  ===========================
       ROUND 3 - START
  ===========================
  게임은 김용현,임담희,윤정원,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 12

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 5

  &gt;&gt; 윤정원 (현재 점수: 6)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt; 박신빈 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 3

  &gt;&gt;&gt;&gt; 김용현님이 9 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 3 - END
  ===========================
  1. 김용현 : 9점
  2. 임담희 : 0점
  3. 윤정원 : 6점
  4. 박신빈 : 9점

  ===========================
       ROUND 4 - START
  ===========================
  게임은 임담희,윤정원,김용현,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 12

  &gt;&gt; 윤정원 (현재 점수: 6)
  &gt;&gt; 뽑은 카드: 3

  &gt;&gt; 김용현 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 11

  &gt;&gt; 박신빈 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt;&gt;&gt; 임담희님이 9 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 4 - END
  ===========================
  1. 임담희 : 9점
  2. 윤정원 : 6점
  3. 김용현 : 9점
  4. 박신빈 : 9점

  =============================
       게임 순위 - 점수
  =============================
  1등 - *김용현* : 9점
  2등 - 박신빈 : 9점
  3등 - 임담희 : 9점
  4등 - 윤정원 : 6점
  =============================
       게임 순위 - 승리 횟수
  =============================
  1등 - *김용현* : 1번
  2등 - 박신빈 : 1번
  3등 - 윤정원 : 1번
  4등 - 임담희 : 1번</code></pre>
</li>
<li><p>입출력 예시 2</p>
<p>  <strong>입력형태 2</strong></p>
<p>  당신의 캐릭터 번호를 선택해주세요 (1,2,3,4) : 3</p>
<p>  <strong>출력형태 2</strong></p>
<pre><code class="language-python">  ===========================
       ROUND 1 - START
  ===========================
  게임은 김용현,박신빈,윤정원,임담희 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 3

  &gt;&gt; 박신빈 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 10

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 8

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 3

  &gt;&gt;&gt;&gt; 박신빈님이 7 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 1 - END
  ===========================
  1. 김용현 : 0점
  2. 박신빈 : 7점
  3. 윤정원 : 0점
  4. 임담희 : 0점

  ===========================
       ROUND 2 - START
  ===========================
  게임은 김용현,윤정원,임담희,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 11

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 2

  &gt;&gt; 박신빈 (현재 점수: 7)
  &gt;&gt; 뽑은 카드: 4

  &gt;&gt;&gt;&gt; 김용현님이 9 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 2 - END
  ===========================
  1. 김용현 : 9점
  2. 윤정원 : 0점
  3. 임담희 : 0점
  4. 박신빈 : 7점

  ===========================
       ROUND 3 - START
  ===========================
  게임은 윤정원,임담희,박신빈,김용현 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 1

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 11

  &gt;&gt; 박신빈 (현재 점수: 7)
  &gt;&gt; 뽑은 카드: 10

  &gt;&gt; 김용현 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt;&gt;&gt; 임담희님이 10 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 3 - END
  ===========================
  1. 윤정원 : 0점
  2. 임담희 : 10점
  3. 박신빈 : 7점
  4. 김용현 : 9점

  ===========================
       ROUND 4 - START
  ===========================
  게임은 윤정원,박신빈,김용현,임담희 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 8

  &gt;&gt; 박신빈 (현재 점수: 7)
  &gt;&gt; 뽑은 카드: 2

  &gt;&gt; 김용현 (현재 점수: 9)
  &gt;&gt; 뽑은 카드: 9

  &gt;&gt; 임담희 (현재 점수: 10)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt;&gt;&gt; 김용현님이 7 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 4 - END
  ===========================
  1. 윤정원 : 0점
  2. 박신빈 : 7점
  3. 김용현 : 16점
  4. 임담희 : 10점

  =============================
       게임 순위 - 점수
  =============================
  1등 - 김용현 : 16점
  2등 - *임담희* : 10점
  3등 - 박신빈 : 7점
  4등 - 윤정원 : 0점
  =============================
       게임 순위 - 승리 횟수
  =============================
  1등 - 김용현 : 2번
  2등 - 박신빈 : 1번
  3등 - *임담희* : 1번
  4등 - 윤정원 : 0번</code></pre>
</li>
<li><p>입출력 예시 3</p>
<p>  <strong>입력형태 3</strong></p>
<p>  당신의 캐릭터 번호를 선택해주세요 (1,2,3,4) : <strong>4</strong></p>
<p>  <strong>출력형태 3</strong></p>
<pre><code class="language-python">  ===========================
       ROUND 1 - START
  ===========================
  게임은 김용현,박신빈,윤정원,임담희 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 김용현 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 13

  &gt;&gt; 박신빈 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 7

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 8

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 8

  &gt;&gt;&gt;&gt; 김용현님이 6 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 1 - END
  ===========================
  1. 김용현 : 6점
  2. 박신빈 : 0점
  3. 윤정원 : 0점
  4. 임담희 : 0점

  ===========================
       ROUND 2 - START
  ===========================
  게임은 박신빈,윤정원,임담희,김용현 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 박신빈 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 13

  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 10

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 4

  &gt;&gt; 김용현 (현재 점수: 6)
  &gt;&gt; 뽑은 카드: 2

  &gt;&gt;&gt;&gt; 박신빈님이 11 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 2 - END
  ===========================
  1. 박신빈 : 11점
  2. 윤정원 : 0점
  3. 임담희 : 0점
  4. 김용현 : 6점

  ===========================
       ROUND 3 - START
  ===========================
  게임은 윤정원,임담희,김용현,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 2

  &gt;&gt; 임담희 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 9

  &gt;&gt; 김용현 (현재 점수: 6)
  &gt;&gt; 뽑은 카드: 5

  &gt;&gt; 박신빈 (현재 점수: 11)
  &gt;&gt; 뽑은 카드: 6

  &gt;&gt;&gt;&gt; 임담희님이 7 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 3 - END
  ===========================
  1. 윤정원 : 0점
  2. 임담희 : 7점
  3. 김용현 : 6점
  4. 박신빈 : 11점

  ===========================
       ROUND 4 - START
  ===========================
  게임은 윤정원,김용현,임담희,박신빈 순으로 진행됩니다.

  ===========플레이어가 뽑은 카드============
  &gt;&gt; 윤정원 (현재 점수: 0)
  &gt;&gt; 뽑은 카드: 1

  &gt;&gt; 김용현 (현재 점수: 6)
  &gt;&gt; 뽑은 카드: 6

  &gt;&gt; 임담희 (현재 점수: 7)
  &gt;&gt; 뽑은 카드: 5

  &gt;&gt; 박신빈 (현재 점수: 11)
  &gt;&gt; 뽑은 카드: 11

  &gt;&gt;&gt;&gt; 박신빈님이 10 점을 얻었습니다 \^_^/ &lt;&lt;&lt;&lt;

  ===========================
       ROUND 4 - END
  ===========================
  1. 윤정원 : 0점
  2. 김용현 : 6점
  3. 임담희 : 7점
  4. 박신빈 : 21점

  =============================
       게임 순위 - 점수
  =============================
  1등 - 박신빈 : 21점
  2등 - 임담희 : 7점
  3등 - *김용현* : 6점
  4등 - 윤정원 : 0점
  =============================
       게임 순위 - 승리 횟수
  =============================
  1등 - 박신빈 : 2번
  2등 - *김용현* : 1번
  3등 - 임담희 : 1번
  4등 - 윤정원 : 0번</code></pre>
</li>
</ul>
<p>코드 로직</p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/44177fb6-0476-4d0a-a11f-1cc973c313a7/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/29b9abcd-5ff2-4b03-93a4-8000ada86931/image.jpg" alt=""></p>
<p>파이썬 잘 못하는데 재미있었다.</p>
<p>추가로 공부해야할 부분들</p>
<p>1)람다 함수,sorted: 인터넷에 올라온데로 막 썼는데 정확한 동작원리를 모르겠다.</p>
<pre><code class="language-python">
        if round_num == 1:
            self.players = sorted(self.players, key=lambda x: x.name)
        elif round_num &gt; 1:
            self.players = sorted(self.players, key=lambda x: x.score)</code></pre>
<p>2) for문 enumerate가 뭔지</p>
<pre><code class="language-python"> for i, player in enumerate(self.players):
            if self.deck[-(i+1)] == MaxCard:
                MaxPlayer = player
                MaxPlayer.score += MaxCard - MinCard
                MaxPlayer.round_wins += 1</code></pre>
<p>3)</p>
<pre><code class="language-python">def __str__(self) -&gt; str:
        return f&quot;{self.name}&quot;

def __repr__(self):
        return f&quot;{self.name}&quot;</code></pre>
<p>4)</p>
<pre><code class="language-python">if __name__ == &quot;__main__&quot;:
    &quot;&quot;&quot;
    - 코드를 실행하는 부분입니다. 
    - 역시 별도의 코드 작성이 필요 없습니다. 
    &quot;&quot;&quot;
    game = Game()

    game.game()
</code></pre>
<p>5)</p>
<pre><code class="language-python">play_order = &quot;,&quot;.join(map(str, self.players))
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQLD 12일전]]></title>
            <link>https://velog.io/@mankiew_vol9/SQLD-12%EC%9D%BC%EC%A0%84</link>
            <guid>https://velog.io/@mankiew_vol9/SQLD-12%EC%9D%BC%EC%A0%84</guid>
            <pubDate>Sun, 28 May 2023 19:25:03 GMT</pubDate>
            <description><![CDATA[<p>아직 노랭이 1회독도 못한거 실화냐 가슴이 옹졸해진다..이 속도면 3수는 해야한다.. 힘내자..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQLD 도전!]]></title>
            <link>https://velog.io/@mankiew_vol9/SQLD-%EB%8F%84%EC%A0%84</link>
            <guid>https://velog.io/@mankiew_vol9/SQLD-%EB%8F%84%EC%A0%84</guid>
            <pubDate>Sun, 14 May 2023 05:15:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/50cec2bb-c2d3-4ad6-9f65-fa8416e49212/image.jpeg" alt=""></p>
<p>스터디원의 권유로 인해 막차타고 5/12일에 신청했다. 다행이 고사장 자리는 있었다.</p>
<p>sqld 공부하느라 당분간 커밋은 못할것같기도 하지만 스터디에서 프로젝트같은거 할꺼니까 활동을 꾸준히 할 수 있을 것 같기도 하다. 벨로그는 공부 일지적는용으로 쓸것 같다.</p>
<p>공부법은 아래 링크대로 공부할 예정이다. 
<a href="https://www.youtube.com/watch?v=llk__mId4yQ&amp;t=133s&amp;pp=ygUJc3FsZCAz7KO8">https://www.youtube.com/watch?v=llk__mId4yQ&amp;t=133s&amp;pp=ygUJc3FsZCAz7KO8</a></p>
<p>아니 근데 그나저나 응시료 5만원 실화냐</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘의 뻘짓-ECMAScript 2015 Language Specification 읽어보기]]></title>
            <link>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98%EC%9D%98-%EB%BB%98%EC%A7%93-ECMAScript-2015-Language-Specification-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98%EC%9D%98-%EB%BB%98%EC%A7%93-ECMAScript-2015-Language-Specification-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Thu, 11 May 2023 06:47:14 GMT</pubDate>
            <description><![CDATA[<p>사이트:<a href="https://262.ecma-international.org/6.0/">https://262.ecma-international.org/6.0/</a></p>
<p>나는 프론트엔드의 깊은 이해가 필요하다고 생각했다. 그래서 자바스크립트 deepdive책도 찾아봤다. 그러던중 커뮤니티에서 위 사이트를 추천해주었는데 페이지를 열자마자 엄청나게 어려운 기술용어와 영어울렁증이 시너지를 이루어 나를 숨막히게 했다. 그래도 드림코딩의 ECMAScript의 변천사에 관한 영상을 본적이 있기에 익숙한 내용이 몇몇개 있기는 했다.</p>
<p>내가 읽은 몇개의 문단들을 소개하겠다.</p>
<ul>
<li>주의 
필자는 영어에 잼병이므로 필자의 해석을 믿지 마시오</li>
</ul>
<p>Introduction의 일부분</p>
<p><strong><em>This Ecma standard defines the ECMAScript 2015 language, which is the sixth edition of the ECMAScript language specification. Since the first edition was published in 1997, ECMAScript has become one of the most widely used general-purpose programming languages in the world. It is best known as the language embedded in web browsers, but it is also widely used for server and embedded applications. The sixth edition is the most comprehensive update to ECMAScript since the first edition was published in 1997...</em></strong></p>
<p>초간단 해석: 
ECMAscipt 2015는 6판(가장 포괄적), 가장 널리 쓰이는 프로그램됨, 서버와 임베디드 app에도 쓰임 -대충 자랑</p>
<p><em>*<em>Goals for ECMAScript 2015 include providing better support for large applications, library creation, and for use of ECMAScript as a compilation target for other languages. Some of its major enhancements include modules, class declarations, lexical block scoping, iterators and generators, promises for asynchronous programming, destructuring patterns, and proper tail calls. The ECMAScript library of built-ins has been expanded to support additional data abstractions including maps, sets, and arrays of binary numeric values as well as additional support for Unicode supplemental characters in strings and regular expressions. The built-ins are now extensible via subclassing.
*</em></em>
초간단해석:
ES6는 더 많은 기능을 지원함(include modules, class,비동기적 프로그래밍을 위한 promise 등등 겁나 많음)</p>
<p><em><strong>ECMAScript is based on several originating technologies, the most well-known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company’s Navigator 2.0 browser. It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0.</strong></em></p>
<p>초간단해석:ECMAScript는 js와 Jscript기반임</p>
<p>The development of the ECMAScript Language Specification started in November 1996. The first edition of this Ecma Standard was adopted by the Ecma General Assembly of June 1997.</p>
<p>초간단 해석: ECMAScript 스펙은 1996부터 작성됨</p>
<p><em><strong>That Ecma Standard was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.</strong></em></p>
<p>초간단해석: 
Ecma Standard는 ISO/IEC에 fast-trak(거의 절차 없이 개빨리) 승인됨 international standard ISO/IEC 16262으로 1판과 2판은 거의차이 없는 편집상의 수정사항
(1판은 ISO/IEC JTC 1  가 채택한것 같은데 2판부터는 Ecma General Assembly가 채택하는듯)</p>
<p><em><strong>The third edition of the Standard introduced powerful regular expressions, better string handling, new control statements, try/catch exception handling, tighter definition of errors, formatting for numeric output and minor changes in anticipation future language growth. The third edition of the ECMAScript standard was adopted by the Ecma General Assembly of December 1999 and published as ISO/IEC 16262:2002 in June 2002.</strong></em></p>
<p>초간단 해석:3판도 겁나 기능 추가됨 3판은 Ecma General Assembly에 의해 채택되었고  ISO/IEC 16262:2002 로 공개됨</p>
<p>After publication of the third edition, ECMAScript achieved massive adoption in conjunction with the World Wide Web where it has become the programming language that is supported by essentially all web browsers. Significant work was done to develop a fourth edition of ECMAScript. However, that work was not completed and not published as the fourth edition of ECMAScript but some of it was incorporated into the development of the sixth edition.</p>
<p>초간단해석: 
3판 공개 이후 월드 와이드 웹과의 연결에 채택됨-모든 브라우저에서 지원됨</p>
<p>4판에는 중요한 것들이 있었지만 4판이라는 이름으로 출간되지 않고 6판에 끼워서 출간됨</p>
<p>The fifth edition of ECMAScript (published as ECMA-262 5th edition) codified de facto interpretations of the language specification that have become common among browser implementations and added support for new features that had emerged since the publication of the third edition. Such features include accessor properties, reflective creation and inspection of objects, program control of property attributes, additional array manipulation functions, support for the JSON object encoding format, and a strict mode that provides enhanced error checking and program security. The Fifth Edition was adopted by the Ecma General Assembly of December 2009.</p>
<p>초간단해석:
5판... 아 귀찮아.. 안할래 comformance부터 보세요 ㅎ</p>
<p>The fifth Edition was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262:2011. Edition 5.1 of the ECMAScript Standard incorporated minor corrections and is the same text as ISO/IEC 16262:2011. The 5.1 Edition was adopted by the Ecma General Assembly of June 2011.</p>
<p>초간단해석:</p>
<p>[Conformance]의 일부분
-&gt; 약간 준수해야 하는 메뉴얼 같은 느낌?
comformance: 적합성</p>
<p><em><strong>A conforming implementation of ECMAScript must provide and support all the types, values, objects, properties, functions, and program syntax and semantics described in this specification.</strong></em></p>
<p>ECMAScipt 준수하면서 구현하려면 타입, 변수 ,객체, 프로퍼티 함수 그리고 프로그램 문법등이 스펙에 제공되어야함</p>
<p><em><strong>A conforming implementation of ECMAScript must interpret source text input in conformance with the Unicode Standard, Version 5.1.0 or later and ISO/IEC 10646. If the adopted ISO/IEC 10646-1 subset is not otherwise specified, it is presumed to be the Unicode set, collection 10646.</strong></em></p>
<p>ES준수하면서 구현하려면 텍스트 입력을 유니코드 기준에 맞춰야 한다.</p>
<p>A conforming implementation of ECMAScript that provides an application programming interface that supports programs that need to adapt to the linguistic and cultural conventions used by different human languages and countries must implement the interface defined by the most recent edition of ECMA-402 that is compatible with this specification. </p>
<p> 언어적 문화적 관습에 적응될 필요가 있는 프로그램을 도와주는 api를 제공하는  ES 준수하면서 구현하는것은 반드시 구현해야 한다 인터페이스를 ECMA-402에 의해 정의된</p>
<p>근데 여기서 말하는 api가 정확히 무엇을 의미하는지는 모르겠음..
서버 통신하는 api는 아닌것 같은데..</p>
<p>이 문단이 너어어어ㅓㅇ무 해석하기 어려워서 이 문단이 쓰인 의미와 정 반대 의미로 해석했을 수 있다</p>
<p>A conforming implementation of ECMAScript may provide additional types, values, objects, properties, and functions beyond those described in this specification. In particular, a conforming implementation of ECMAScript may provide properties not described in this specification, and values for those properties, for objects that are described in this specification.</p>
<p>(앞에서 말했던 지원 내용) 변수 타입 객체 프로퍼티등을 준수하면서 구현해야함</p>
<p><strong>후기</strong>
이걸 왜읽었을까?.. 너무 앞부분만 읽어서 구체적인 작동원리는 잘 모르겠다. 뒷부분을 읽어야할것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[up_down_game]]></title>
            <link>https://velog.io/@mankiew_vol9/updowngame</link>
            <guid>https://velog.io/@mankiew_vol9/updowngame</guid>
            <pubDate>Thu, 11 May 2023 05:56:42 GMT</pubDate>
            <description><![CDATA[<p>site:<a href="https://woomin-up-down-game.netlify.app/">https://woomin-up-down-game.netlify.app/</a>
github repository:<a href="https://github.com/woominKO/updown_game">https://github.com/woominKO/updown_game</a></p>
<p>컴퓨터가 랜덤으로 1-20까지 숫자를 고르면 내가 맞추면 되는 게임이다
내가 입력한 숫자가 더 크면 up 이 출력되고 더 낮으면 down이 출력된다.</p>
<p>여기서 내가 조금 어려웠던 것은 이 부분이다.</p>
<pre><code class="language-js">function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //최댓값은 제외, 최솟값은 포함
}</code></pre>
<p>math.random 메소드를 사용한 것인데...로직을 설명해 보자면 우선 Math.ceil과 Math.floor는 변수와 가장 근처에 있는 정수 하나를 반환한다. 요약하자면 올림/내림이다 .그런데 어짜피 정수를 입력받을 것이기 때문에 딱히 필요없는 코드이긴 한 것 같다. 하지만 Math.floor의 기능을 그냥 지나쳐도 되냐는 질문에는 아니요 라고 대답할 것같다. 왜냐하면 return값에 Math.floor메소드를 사용했기 때문이다. Math.random() 은 0 이상 1 미만의 부동소숫점 의사 난수를 반환한다. 여기서 한가지 궁금했던 점은 왜 max-min을 곱하냐는 것이다. </p>
<p>예시를 들어 그림을 그려보면 조금더 쉽게 이해가 된다.<img src="https://velog.velcdn.com/images/mankiew_vol9/post/ae706ed1-8d2b-4806-ac28-b0e00a677d2d/image.jpg" alt="">
이렇게 보면 math.random()이 어떤 0과 1사이의 부동소수점을 생성하는지와 관계없이 max값과 min사이의 정수값들을 모두 출력한다.참으로 신기한 로직이다</p>
<p>한가지 수정사항이 필요한데 
html이 다 로드된 후에 while문이 실행되도록 하고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘 한 개발공부6]]></title>
            <link>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%806</link>
            <guid>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%806</guid>
            <pubDate>Wed, 10 May 2023 15:47:16 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/e87305f6-69f5-422e-b9c8-98002cd23822/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[todo list4]]></title>
            <link>https://velog.io/@mankiew_vol9/todo-list4</link>
            <guid>https://velog.io/@mankiew_vol9/todo-list4</guid>
            <pubDate>Wed, 10 May 2023 08:21:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/64ced310-302e-4f8a-811f-df338bedcdf9/image.png" alt=""></p>
<p>깃헙 리포지토리:<a href="https://github.com/woominKO/ToDoList">https://github.com/woominKO/ToDoList</a>
넷틀리파이:<a href="https://woomin-todo-list.netlify.app/">https://woomin-todo-list.netlify.app/</a></p>
<p>*<em>삭제버튼 작동하게 만듬
*</em></p>
<p>조금 힘들었다.ㅎㅎ
가장 많이 마주쳤던 오류는 
<code>Uncaught TypeError: Cannot read property &#39;addEventListener&#39; of null</code>이다.
그 이유인 즉슨 나는 처음에 동적으로 생성되는 html위에 
해당 생성되는 html의 요소를 queryselector로 선택했고 addeventlistenr를 추가했기 때문에 오류가 발생했다.
<img src="https://velog.velcdn.com/images/mankiew_vol9/post/59cc9f33-32e1-45a6-b46f-93adb2e90b0c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/527f2e68-0df1-4d77-a129-98728599c93a/image.png" alt=""></p>
<p>전자 처럼 코드를 짰더니 newdiv를 인식하지 못해서 혹시..? 하는 마음에 후자처럼 코드를 옮겼더니 오류가 해결되었다. 사실 delfunc의 removechild 메소드가 document.만 선택해서 오류가 떴긴 했지만 금방 해결했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘 한 개발공부5]]></title>
            <link>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%805</link>
            <guid>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%805</guid>
            <pubDate>Tue, 09 May 2023 13:35:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/cfbf16e3-a939-4147-aa5b-e14640e07dcc/image.jpg" alt=""></p>
<p>조금더 할일이 있었지만 피곤해서 내일로 미뤘다. 중요한건 코딩할 여력을 남겨놓는것이다. 다 소진해버리는 것이 아닌</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘 한 개발공부4]]></title>
            <link>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%804</link>
            <guid>https://velog.io/@mankiew_vol9/%EC%98%A4%EB%8A%98-%ED%95%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%804</guid>
            <pubDate>Mon, 08 May 2023 14:13:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mankiew_vol9/post/bc440097-619f-432f-a543-9e49438a6428/image.jpg" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>