명쾌한 코드 파이썬으로 어둠의 마법을 부릴 수 있다면, 가장 명쾌하고 간단한 방법을 추천합니다. 나쁜 예 def make_complex ( * args ): x , y = args return dict ( ** locals ()) 좋은 예 def make_complex ( x , y ): return { 'x' : x , 'y' : y } 위의 좋은 코드 예시에서 x와 y는 호출자로부터 직접 값을 받아와 곧바로 딕셔너리로 반환합니다. 이 함수를 쓰는 개발자들은 첫 줄과 마지막 줄을 읽는 것만으로 무엇을 하는 함수인지 정확히 알 수...
파이썬 코딩 스타일 PEP 8 파이썬 코딩 스타일 Python Enhancement Proposal 8 (PEP 8)은 파이썬 코딩 스타일에 대한 가이드를 제시하고 있다. PEP 8은 2001년 귀도 반 로썸에 의해 처음 제안되었으며, python.org 의 PEP 링크에 자세히 소개되어 있다. 파이썬 프로그래머들은 일반적으로 이러한 PEP 8 코딩 스타일에 따라 프로그래밍을 하고 있는데, 이러한 일관된 코딩 스타일을 적용하는 것은 자신의 코드를 명료하게 할 뿐만 아니라 특히 다른 개발자 혹은 커뮤니...
도메인 주도 설계에서 도메인이란 우리가소프트웨어로 “해결하고자 하는 문제 영역”을 의미합니다.
.
일반적으로 UML(Unified Modeling Language)에서 자주 사용하는 “클래스 다이어그램(Class Diagram)”부터, 필요에 따라 “상태 다이어그램(State Diagram)”이나 “시퀀스 다이어그램(Sequence Diagram)”을 사용할 수도 있고, 아니면 UML이 아닌 다른 방식으로 표현해도 무방합니다.
다만 도메인 모델을 표현할 때 최대한 표현력을 가질 수 있게 단순히 속성만 나열하는 것이 아니라 행위를 통해 도메인 기능을 나타내도록, 그리고 실제로 사용하는 도메인 용어를 사용하도록 해야 합니다.
도메인 객체는 기본적으로 “엔티티(Entity)”와 “밸류(Value)”로 구분할 수 있습니다.
엔티티는 식별성과 연속성을 가지는 객체인데, 좀 더 풀어서 얘기하자면 고유한 식별자로 식별할 수 있으며 자신의 상태와 라이프사이클(Life cycle)을 가지는 도메인 객체입니다.
밸류는 개념적으로 묶을 수 있는 데이터 집합을 표현합니다. 도메인 주도 설계를 몰랐더라도 자주 들었던 “값 객체(Value Object)”라고 부르는 것이 바로 이것입니다. 밸류를 사용하면 각각의 데이터를 단일로 취급할 때보다 표현력을 향상시킬 수 있습니다.
더불어 엔티티와 밸류의 메서드(행위)로 기능과 제약을 표현하고, 습관적으로 사용하는 setter/getter 메서드는 지양하라고 최범균님이 언급하셨는데,
// case 1
if (order.getStatus() == OrderStatus.DELIVERY_IN_PROGRESS)
저는 case 2가 case 1보다 무엇을 하고자 하는지 그 의도가 비교적 분명하게 느껴지고,
case 2처럼 만든 객체가 도메인 기능을 잘 표현하고 있는 도메인 객체라고 생각합니다.
애그리거트(Aggregate)
도메인 모델은 점차 복잡해지기 마련입니다. 서비스가 자랄수록 도메인 역시 함께 자라기 때문입니다. 이렇게 도메인 모델의 복잡도는 점차 증가하기 마련인데, 이러한 복잡도를 관리하기 위해 도메인 객체들의 묶음이자 집합체인 “애그리거트(Aggregate)”가 필요합니다. 애그리거트를 사용하면 우리가 다루는 도메인 객체를 좀 더 상위 수준으로 추상화할 수 있습니다.
이러한 애그리거트에는 포함된 객체들의 대표가 되는 “애그리거트 루트(Aggregate root)”가 필요합니다. 애그리거트에는 다수의 객체들이 포함되어 있고 이들은 함께 움직이면서 일관성을 유지해야 하는데, 만약 바깥에서 애그리거트 내부의 객체들에게 직접 접근해서 상태나 속성을 변경해버리면 일관성이 깨져버립니다.
따라서 애그리거트 바깥에서 애그리거트에 직접 접근할 수 있는 곳은 오직 애그리거트 루트 뿐이어야 합니다. 애그리거트 루트가 이러한 창구 역할을 하면서 애그리거트에 포함된 객체들의 일관성을 유지할 수 있습니다.
계층형 아키텍처(Layered Architecture)
계층형 아키텍처
계층형 아키텍처에서는 일반적으로 상위 계층이 하위 계층에 의존합니다. 표현 계층은 응용 계층에 의존하고, 응용 계층은 도메인 계층에 의존하는 방식입니다.
DIP(Dependency Inversion Principle)
예를 들어 “배송 알림” 기능은 고수준 모듈의 기능이고, “RDBMS에서 주문의 배송 정보를 조회하고, 주문자에게 메일로 배송 알림 메일을 전송한다”는 저수준 모듈의 기능이라고 할 수 있죠.
흔히 고수준 모듈이 저수준 모듈에 의존하도록 구현하는데, 이 경우 저수준 모듈의 변경이 곧 고수준 모듈의 변경으로 이뤄지곤 합니다.
고수준에서의 “배송 알림” 자체에 변경이 없어도, 저수준인 “메일로 배송 알림 메일을 전송한다”라는 저수준의 기능이 “SMS로 배송 알림 메시지를 전송한다”로 바뀐다면 고수준 모듈에서도 변경이 발생하는 것이죠.
이러한 단점을 극복하기 위해 의존 관계를 역전시켜서 저수준 모듈이 고수준 모듈에 의존하도록 구현하는 것을 DIP(Dependency Inversion Principle)라고 합니다.
저수준 모듈이 고수준 모듈을 의존
“배송 알림” 기능을 정의한 “배송 알리미” 인터페이스를 만들고, 저수준 모듈에서 “배송 알리미” 인터페이스를 구현한 저수준 모듈인 “메일 배송 알리미”나 “SMS 배송 알리미”를 만드는 것이죠.
이렇게 저수준 모듈이 고수준 모듈에 의존하도록 바꾸면 저수준 기능인 “메일로 배송 알림 메일을 전송”하던 것이 “SMS로 배송 알림 메시지를 전송”하는 것으로 바뀌더라도 고수준 모듈에서의 변경은 최소화할 수 있습니다.
이때 한 가지 주의사항이 있는데, DIP를 적용하는 목적은 고수준 모듈이 저수준 모듈에 의존하지 않고 반대로 저수준 모듈이 고수준 모듈에 의존하게 하려는 것이기에, 인터페이스를 도출할 때 저수준 모듈의 관점에서 도출하면 안 된다는 것입니다.
응용 서비스(Application service)
“응용 서비스(Application service)”는 도메인 객체를 이용하여 사용자의 요청에 알맞는 기능을 처리하고 결과를 반환하는 역할을 합니다. 표현 계층과 도메인 계층을 연결해주는 일종의 창구 역할이라고 볼 수 있습니다.
응용 서비스는 응용 계층에 속하기 때문에 도메인과 관련된 로직이 직접적으로 포함되지 않아야 합니다. 대신 도메인 계층에 포함된 도메인 객체들을 사용하여 도메인 기능을 처리하면서 흐름을 제어합니다. 이렇게 처리 흐름을 제어하는 역할을 하다보니 응용 서비스의 기능은 종종 트랜잭션의 단위가 되기도 합니다.
또한 응용 서비스는 표현 계층에 의존하지 않아야 합니다. 예를 들면 표현 계층의 기술인 HTTP 프로토콜에 대한 것(HttpSession, MultipartFile 등)은 응용 서비스에서 사용되지 않도록 해야 합니다.
응용 서비스의 전형적인 구현을 보자면,
1. 리포지터리로 사용할 도메인의 애그리거트 루트를 구하고,
2. 애그리거트 루트의 도메인 기능을 실행하고 처리 흐름을 제어하면서,
3. 처리 결과를 반환합니다.
응용 서비스에 대해서 최범균님이 언급하신 내용 중 하나는 “응용 서비스의 메서드 파라미터로 필요한 값들을 넘기는 대신 도메인 객체 자체를 넘기는 것은 최대한 지양하자”, 였습니다. 응용 서비스의 메서드 파라미터로 도메인 객체를 사용하다보면 도메인 객체에 원래는 필요하지 않던 속성들을 추가하기 마련이고, 이러한 속성들을 영속화에서 제외하는 경우 이를 위해 별도의 설정을 하는 등의 문제를 야기할 수 있기 때문입니다. 따라서 메서드 파라미터로 도메인 객체가 딱 들어맞는 경우에만 사용할 것을 권장하셨습니다.
또 하나 고민해볼 수 있는 내용으로는 “응용 서비스의 결과로 도메인 객체를 반환하는 것과 조회 전용 객체를 반환하는 것 중 어떤 것이 좋을까”, 입니다. 물론 각자 팀의 표준이나 구현 편의성, 성능 등 여러가지 상황을 고려하면 절대적인 답은 없겠지만 별도의 조회 전용 객체를 만들어 반환하는 편을 추천해주셨습니다.
리포지터리(Repository)
“리포지터리(Repository)”는 애그리거트의 영속성을 처리하기 위해 사용합니다.
리포지터리는 애그리거트 루트 단위로 존재해야 합니다. 애그리거트는 그 자체로 하나의 완전한 집합체이기 때문입니다. 따라서 영속화할 때 애그리거트 루트인 객체뿐만 아니라 애그리거트에 포함된 모든 객체를 함께 영속화해야 합니다. 물론 애그리거트를 저장소에서 조회하는 경우에도 애그리거트 루트와 애그리거트에 포함된 객체들을 전부 가져와야 하며, 삭제하는 경우도 마찬가지입니다.
따라서 “주문 애그리거트”가 있고 애그리거트 루트가 주문 객체라면, 주문 객체에 대한 리포지터리를 만들면 됩니다. 주문 애그리거트에 포함된 다른 객체인 “배송”이나 “주문 상품”, “주문자” 각각에 대해서 리포지터리를 만들 필요는 없습니다. 주문 리포지터리가 주문 애그리거트 전체의 영속성을 관리해주니까요.
최범균님은 JPA의 리포지터리를 사용하여 엔티티 객체를 로딩할 때 연관된 객체들을 기본적으로 EAGER 로딩하고, 필요한 경우에만 LAZY 로딩을 사용하기를 언급하셨습니다.
- 애플리케이션의 기능 요구 사항을 이해하기 위한 비즈니스 도메인 분석부터 시작합니다. 이 단계의 결과는 비공식적인 도메인 설명으로, 보다 공식적인 도메인 모델 세트로 구체화할 수 있습니다.
- 다음으로 도메인의 경계가 있는 컨텍스트 를 정의합니다. 각각의 제한된 컨텍스트에는 큰 애플리케이션의 특정 하위 도메인을 나타내는 도메인 모델이 포함됩니다.
- 제한된 컨텍스트 내에서 전술적 DDD 패턴을 적용하여 엔터티, 집계 및 도메인 서비스를 정의합니다.
- 이전 단계의 결과를 사용하여 애플리케이션에서 마이크로 서비스를 식별합니다.
제한된 컨텍스트 정의
도메인 모델은 현실 세계에 존재하는 항목 — 사용자, 드론, 패키지 등의 표현을 포함합니다. 그렇다고 해서 시스템의 모든 부분에서 동일한 항목에 대해 동일한 표현을 사용해야 한다는 것은 아닙니다.
예를 들어 드 론 복구 및 예측 분석을 처리 하는 하위 시스템은 유지 관리 기록, 진행 중, 연령, 모델 번호, 성능 특성 등 드 론의 여러 물리적 특성을 나타내야 합니다. 그러나 배달 예약에서는 그러한 특징을 고려하지 않습니다. 예약 하위 시스템은 드론의 가용 여부와, 수거 및 배달의 ETA를 알기만 하면 됩니다.
이 두 하위 시스템 모두에 대해 하나의 모델을 만들려고 하면 불필요하게 복잡해질 것입니다. 시간이 흘러 이 모델을 확장하게 되면 변경 사항이 개별 하위 시스템을 담당하는 여러 팀을 만족시켜야 하기 때문에 더 어려워집니다. 따라서 동일한 현실 세계 엔터티(이 경우 드론)을 두 가지 다른 컨텍스트에 표현하는 별도의 모델을 설계하는 것이 더 나은 경우가 종종 있습니다. 각 모델은 특정 컨텍스트 내에서 관련된 기능 및 특성만 포함합니다.
이 경우 바인딩된 컨텍스트의 DDD 개념이 재생 됩니다. 제한된 컨텍스트는 단순히 특정 도메인 모델이 적용되는 도메인 내의 경계입니다. 이전 다이어그램을 살펴보면 다양한 기능이 단일 도메인 모델을 공유하는지의 여부에 따라 기능을 그룹화할 수 있습니다.
경계가 있는 컨텍스트가 반드시 서로 격리될 필요는 없습니다. 이 다이어그램에서 경계가 있는 컨텍스트를 연결하는 실선은 경계가 있는 두 컨텍스트가 상호 작용하는 지점을 나타냅니다. 예를 들어 배송은 고객 정보를 가져오기 위해 사용자 계정을, 선단에서 드론을 예약하기 위해 드론 관리를 사용합니다.
Domain Driven Design 책에서 Eric Evans는 다른 경계가 있는 컨텍스트와 상호 작용할 때 도메인 모델의 무결성을 유지 관리하기 위한 여러 가지 패턴을 설명합니다. 마이크로 서비스의 기본 원칙 중 하나는 서비스가 잘 정의된 API를 통해 통신하는 것입니다. 이 방법은 Evans가 개방형 호스트 서비스와 게시된 언어라고 칭한 두 패턴에 해당합니다. 개방형 호스트 서비스란 하위 시스템이 다른 하위 시스템과의 통신을 위한 공식 프로토콜(API)를 정의하는 것입니다. 게시된 언어는 다른 팀이 클라이언트를 작성하는 데 사용할 수 있는 양식으로 API를 게시하여 이러한 개념을 확장합니다. 마이크로 서비스용 Api 디자인문서에서 openapi 사양 (이전의 Swagger)을 사용 하 여 JSON 또는 yaml 형식으로 표현 된 REST api에 대 한 언어에 관계 없는 인터페이스 설명을 정의 하는 방법을 설명 합니다.
이 섹션에서는 전술적 DDD 패턴에 대한 간략한 개요를 제공하므로 이미 DDD에 익숙하다면 이 섹션을 건너뛸 수 있습니다. 패턴은 Eric Evans의 책 5 – 6장과, Vaughn Vernon의 Implementing Domain-Driven Design(DDD 구현) 에서 더 상세히 설명합니다.
엔터티. 엔터티는 시간이 지나도 지속되는 고유의 ID가 있는 개체입니다. 예를 들어 뱅킹 애플리케이션에서 는 고객과 계좌가 엔터티입니다.
엔터티에는 엔터티를 조회하거나 검색하는 데 사용할 수 있는 고유의 식별자가 있습니다. 식별자가 항상 사용자에게 직접 노출되는 것은 아닙니다. 데이터베이스의 GUID 또는 기본 키가 될 수 있습니다.
ID는 여러 경계가 있는 컨텍스트를 포괄할 수 있고 애플리케이션의 수명을 넘어설 수 있습니다. 예를 들어 은행 계좌번호나 정부 발급 ID는 특정 애플리케이션의 수명 주기에 종속되지 않습니다.
엔터티의 특성은 시간이 지나면서 변화할 수 있습니다. 예를 들어 사용자 이름 또는 주소는 변경될 수 있지만 여전히 같은 사람입니다.
엔터티는 다른 엔터티에 대한 참조를 포함할 수 있습니다.
값 개체. 값 개체에는 ID가 없습니다. 해당 특성의 값으로만 정의됩니다. 값 개체도 변경할 수 없습니다. 값 개체를 업데이트하려면 항상 새 인스턴스를 만들어 기존 인스턴스를 대체합니다. 값 개체는 도메인 논리를 캡슐화하는 메서드를 갖을 수 있으나 이러한 메서드는 개체의 상태에 부작용을 주지 않아야 합니다. 값 개체의 대표적인 예로 색, 날짜 및 시간, 통화 값 등이 있습니다.
집계. 집계는 하나 이상의 엔터티에 대한 일관성 경계를 정의합니다. 한 집계에서 정확히 한 엔터티가 루트입니다. 조회는 루트 엔터티의 식별자를 사용하여 수행됩니다. 집계의 다른 엔터티는 루트의 자식 요소로, 루트의 다음 포인터에서 참조합니다.
집계의 목적은 트랜잭션 고정 항목을 모델링하는 것입니다. 현실은 매우 복잡한 관계로 얽혀있습니다. 고객이 주문을 접수하고, 주문에는 제품이 포함되어 있으며, 제품을 제공하는 공급자가 있는 등 이와 같은 관계가 계속 이어집니다. 애플리케이션이 몇 가지 관련 개체를 수정하는 경우 일관성을 어떻게 유지하나요? 고정 항목을 어떻게 추적하고 적용할까요?
전통적 애플리케이션에서는 데이터베이스 트랜잭션을 사용하여 일관성을 적용하는 경우가 종종 있었습니다. 그러나 분산형 애플리케이션의 경우 현실성이 떨어지는 경우가 많았습니다. 단일 비즈니스 트랜잭션이 여러 데이터 저장소에 걸쳐 있거나, 오래 실행되거나, 타사 서비스와 관련될 수 있습니다. 궁극적으로 이것은 데이터 계층이 아니라 도메인에 필요한 불변 항목을 시행하는 애플리케이션에 달려 있습니다. 이것이 집계가 모델링에서 갖는 의미입니다.
참고 집계는 자식 엔터티 없이 단일 엔터티로 구성될 수 있습니다. 집계를 만드는 것은 트랜잭션 경계입니다.
도메인 및 애플리케이션 서비스. DDD 용어에서 서비스란 상태를 유지하지 않고 일부 논리를 구현하는 개체입니다. Evans는 도메인 논리를 캡슐화 하는 도메인 서비스 와 사용자 인증 또는 SMS 메시지 전송과 같은 기술 기능을 제공 하는 응용 프로그램 서비스 를 구분 합니다. 도메인 서비스는 종종 여러 엔터티를 포괄하는 동작을 모델링하는 데 사용됩니다.
참고 서비스 라는 용어는 소프트웨어 개발에서 범위가 넓습니다. 여기에서는 그 정의가 마이크로 서비스와 직접적인 연관이 없습니다.
도메인 이벤트. 도메인 이벤트는 변경이 있을 때 시스템의 다른 부분에 이를 알리는 데 사용됩니다. 이름에서 알 수 있듯이 도메인 이벤트는 도메인 내의 이벤트를 나타내야 합니다. 예를 들어 "테이블에 레코드가 삽입"되는 것은 도메인 이벤트가 아닙니다. "배달 취소"는 도메인 이벤트입니다. 도메인 이벤트는 마이크로 서비스 아키텍처에서 특히 관련이 있습니다. 마이크로 서비스는 분산되고 데이터 저장소를 공유하지 않으므로, 도메인 이벤트를 통해 마이크로 서비스에서 서로 조정할 수 있습니다. 서비스 간 통신 문서에서는 비동기 메시징에 대해 자세히 설명 합니다.
필자는 도메인 주도 설계Domain-Driven Design(이하 DDD) 빌딩 블록Building blocks[1]으로 애플리케이션을 구현하면서 엔티티ENTITY[2] 마다 리파지토리REPOSITORY를 만드는 것을 자주 보았는데 자세히 살펴보면…
medium.com
필자는 도메인 주도 설계Domain-Driven Design(이하 DDD) 빌딩 블록Building blocks[1]으로 애플리케이션을 구현하면서 엔티티ENTITY[2] 마다 리파지토리REPOSITORY를 만드는 것을 자주 보았는데 자세히 살펴보면 여러 엔티티를 묶어서 하나처럼 사용하는 경우가 대부분이었다. DDD에서는 이러한 연관 객체의 묶음을 애그리게잇AGGREGATE이라고 정의하고 애그리게잇에 포함된 특정 엔티티를 루트Root 엔티티라고 부른다. 그리고 리파지토리를 만들 때 애그리게잇 루트 엔티티에 대해서만 리파지토리를 제공하라고 한다.
이 글은 주문 도메인 예시를 통해 애그리게잇이 무엇인지 알아보고 왜 애그리게잇 루트에 대해서만 리파지토리를 제공해야 하는지에 대해 설명한다.
OrderService에 비즈니스 규칙을 구현함에 따라 OrderService는 Order 뿐만 아니라 연관된 LineItem, OrderPayment, ShippingAddress을 함께 참조하고 있다. 이런 경우 Order를 사용할 때 늘 비즈니스 규칙을 머릿속에 넣어두고 코딩해야 한다. 이 글에서는 이해를 위해 Order를 단순화했지만 실무에서는 Order는 훨씬 더 복잡한 연관 관계와 속성을 가진다. 복잡한 연관 관계를 가지는 Order를 모두 파악하고 사용하는 것은 쉬운 일이 아니다.
DDD의 저자 에릭 에반스Eric Evans는 “모델 내에서 복잡한 연관 관계를 맺는 객체를 대상으로 변경의 일관성을 보장하기란 쉽지 않다. 그 까닭은 단지 개별 객체만이 아닌 서로 밀접한 관계에 있는 객체 집합에도 불변식이 적용돼야 하기 때문이다.” 라고 말했다. 여기서 불변식Invariants은 데이터가 변경될 때마다 유지돼야 하는 일관성 규칙(비즈니스 규칙)을 뜻한다.
Order, LineItem, ShippingAddress, OrderPayment는 각각이 아닌 하나의 집합으로 다루어야 한다. 에릭 에반스는 이를 애그리게잇AGGREGATE으로 정의한다.
모델 내의 참조에 대한 캡슐화를 추상화할 필요가 있다. AGGREGATE는 우리가 데이터 변경의 단위로 다루는 연관 객체의 묶음을 말한다.
각 AGGREGATE에는 루트(root)와 경계(boundary)가 있다.
경계는 AGGREGATE에 무엇이 포함되고 포함되지 않는지를 정의한다.
루트는 단 하나만 존재하며, AGGREGATE에 포함된 특정 ENTITIY를 가르킨다.
경계 안의 객체는 서로 참조할 수 있지만, 경계 바깥의 객체는 해당 AGGREGATE의 구성요소 가운데 루트만 참조할 수 있다.
— 도메인 주도 설계, 131쪽
애그리게잇에 포함된 특정 엔티티를 루트 엔티티라고 한다고 했다. Order, LineItem, ShippingAddress, OrderPayment 중 어떤 것이 루트 엔티티일까?
DDD에서는 루트 엔티티는 전역 식별성Global identity을 지닌 엔티티라고 말한다. 필자는 전자 상거래 사이트에서 주문 파트 개발자로 일한 적이 있다. 콜 센터나 상품 파트, 회원 파트와 협업할 일이 매우 많았는데 대부분 사람들이 주문 번호를 말하며 의사소통했다. 필자가 보기에는 이것이 바로 전역 식별성이다.
App Inventor Tutorials and Examples: Sortable | Pura Vida Apps
A Sortable List using Drag-and-Drop with App Inventor and jQuery UI The example displays an App Inventor list in a jQuery UI Sortable . Thank you furf , together with your jQuery UI Touch Punch library we can use drag and drop on the mobile device to order the list items manually.
기본기능
1. 드래그로 목록 순서를 변경
2. 목록 순서를 휴대폰에 저장
앱 제작
1. 화면 디자인
- 필요한 파일들을 올려주세요.
jquery-ui.css
ui-lightness-jquery-ui.css
ui-icons_ef8c08_256x240.png
jquery-1.7.2.min.js
jquery-ui.min.js
jquery.ui.touch-punch.min.js
2. 블록 코딩
- WebViewer에 띄울 html file을 셋팅하는 루틴
- 로컬 DB를 읽어오기, 자료가 없으면 목록을 초기값으로 설정
- 순서바꾸기를 터치하면 webviewer를 띄우고 html에 전달할 목록을 셋팅 후 web page javascript 실행
- 저장버튼을 터치하면 webviewer를 감추면서 webviewer의 CurrentPageTitle을 통해 결과값 가져오고 로컬DB에 저장
휴대폰 화면보다 큰 이미지를 배경으로 드래그 스크롤 하면서 동작하는 앱을 만들 때 사용하면 좋겠습니다.
- 기본 원리는 canvas 위쪽과 왼쪽에 크기 조절용 component (VerticalArrangement, HorizontalArrangement, Image, 등) 을 두고 이것의 크기를 조절하면 canvas 중에서 휴대폰 화면에 보이는 부분이 정해지는 원리입니다.
python 을 처음 접할 때 설치, 등 여러 가지 문제를 줄이면서 간편하게 빨리 python을 실행해볼 수 있는 것이 google colaboratory입니다.(사용법 : https://ndb796.tistory.com/312 )(제약은 있지만 GPU, TPU 실습도 가능...)
대부분 웹에서 정보를 가져오려고 할 때 beatifulsoup를 이용해서 각 사이트에 맞게 잘라서 가져오는 방법을 주로 사용합니다.
뉴스 형식의 데이터를 가져오는 python newspaper라는 library를 이용하면 어떻게 작업을 쉽게 할 수 있는지 살펴보고자 합니다.