블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2015. 7. 14. 22:54 Angular/Concept

Meteor는 Modern Application Platform이기도 하면서 Reactive Manifesto에서 이야기하는 User Responsive를 위한 Resilient와 Scalable을 갖추고 있다. 그래서 Meteor를 Realtime Modern Application을 위한 Reactive Platform이라 이야기를 해도 좋을 것 같다. 하지만 정작 Reactive라고 이야기를 해놓고 Reactive의 개념이 와닿지 않는 것은 거시적, 미시적 이해가 없기 때문이다. 최근에 각광 받고 있는 AngularJS는 Reactive Templating을 지원한다. Reactive라 붙일 수 있는 이유는 Reactive Programming에 대해 위키에서 찾아보면 액셀 예를 통해 어떤것을 의미하는지 이해를 할 수 있다. 다수의 b가 a를 의존할 때 a의 변화에 b가 종속이 되고, 옵저버 패턴(Observer Pattern)으로 보면 다수의 의존하는 Observer(소비자)가 데이터를 제공하는 Observerable(생산자)에 의존하는 것으로 a에 상태변경(이벤트 발생)에 대해 b에도 상태값을 알려주는 구조이다. Reactive Programming(RP)의 관건은 Asynchronous Data Flow관점에서 프로래밍을 하고 Functional Reactive Programming으로 오면 filter, map, reduce와 같은 블럭을 통해 Reactive Programming을 한다. 



리액티브 프로그래밍(RP)은 비동기와 이벤트 기반의 데이터 스트리밍(Asynchronous and Event-based Data Streaming)을 Observable Sequences로 변환해 개발하는 프로그래밍 방식이다.







Reactive 거시적, 미시적 이해


  Reactive Manifesto 의 내용을 이해할 필요가 있다. 왜 Reactive 해야 하는지 이유는 본 글에 잘 설명되어 있다. 현재는 인터넷 보급과 모바일 기기의 보급으로 365일 24시간 무정지의 끊김없는 빠른 서비스를 제공해야 한다. 이를 위해서는 장애(Failure)에 빨리 복구(Resilient)되고, 서비스의 수평적 확장이(Scalable) 용이해야 하며, Resilient와 Scalable 바탕에는 느슨한 결합(loose coupling)의 메세지 기반(Message Driven) 아키텍처가 기반이 되어야 한다. 


  - Responsive를 위한 Resilient와 Scalable 및 Message Driven에 대한 이야기

  - NDC에서 김종욱님이 발표한 RX와 Functional Reactive Programming 이야기 (원문)

    + 엔시소프트 리니지 서버의 Rx 적용 경험 공유

    + 2009년 MS 에서 Reactive eXtension 소개

    + 2011년 RxJS, 2012년 RxJava등이 나오고 현재는 RxSwift도 존재함 

    

   

  - 2013년 Infoq에 발표한 Reactive programming의 동향

    + 코세라에서 Scala 기반 오픈 강의 개설(Scala 창시자와 Rx 개발자가 직접 강의함) : Principles of Reactive Programming

    + Netflix에서는 RxJava 기반으로 광범위하게 개발을 하고 있다. 

    + Facebook은 ReactJS를 오픈소스화하고 페이스북 웹과 인스타그램 웹에 사용하고 있다.

    + Javascript 기반의 Bacon.js, Kefir.jsRxJS, Reactive.js 라이브러리를 타 프레임워크와 접목해서 사용할 수도 있다. 

  - Microsoft에서 이야기하는 Reactive eXtension 정의

  - 다양한 언어의 구현체는 ReactiveX(http://reactivex.io)에서 볼 수 있다.

  - 확장가능하고 병행처리 가능한 웹 아키텍쳐 구축하기


  - Observable에 대한 이해

    + 2분만에 이해하는 Observable : Rx is the underscore.js for events

    + FRP 연산자들에 대한 Sync와 Async에 대해 시뮬레이션 예제를 통해 보여준다. (슬라이드DevNation)

    + ReactiveX.io의 설명

       Observer는 Observable에 subscribe하고 onNext, onError, onCompleted를 Observer에 구현하면 이를 Observable이 호출

       onNext에는 emit 한다고 말하고, onError, onCompleted는 notification한다고 말함.

    + MS의 Reactive eXtension의 워크샵 (동영상)


  - Observable에 대한 기본 개념 

    

  

  - ReaciveX를 위한 Operators 종류

    + 언어별로 동일 연산자를 가진다. 

    + Create Observable, Transform Observable, Filtering Observable, Combining Observable, Error Handling, Utility, Conditional & Boolean ...

    + Operator사용을 위해서 Decision Tree의 내용을 숙지해 보자. 





Reactive Programming for JavaScript


  먼저 RxJS를 이용한 Reactive Programming에 대한 이해를 선행한 후에 FRP(Functional Reactive Programming)에 대한 이해를 위해 learnrx의 FRP 개념 이해를 위한 실습을 전부 따라해 본다. 


  - Javascript의 Sync처리와 Asynch 처리에 대한 이해를 뭔저 해본다. 동영사의 21분에서 forEach가 Sync, Async 처리 되는 과정을 이해.

   + Event-Loop 와 Call Stack, Task Queue 관계 시뮬레이션 (21분경에 나옴)

    


  - 예제들이 ES6 기준으로 되어 있는 경우가 많아 ES6 문법을 공부하자

    + Depth in ES6 이해 요약정리

  - Functional Reactive Programming (FRP) 에 대한 개념을 이해하자. 

    + Functional Programming 과 Reactive Programming의 결합 === Functional + Async Data Stream (Data Flow) 

    



  - Frontend Developer 입장에서 본 RxJS에 대한 기본 개념 이해 

    + Array에서 제공하는 map, filter, reduce는 할 때마다 다시 배열을 할당한다.(learnrx를 따라해보고 이해하자) 따라서 GC에 대한 이슈존재

    + RxJS의 Observable을 사용할 경우 배열 재할당이 없으므로 GC에 대한 이슈도 없다. 

    


  - RxJS의 깃헙 Readme를 읽자

  - RxJS 학습하기 

    + egghead.io의 RxJS 강좌와 Asynchronous 강좌를 본다.

    + RxMarbles : Rx를 다이어그램으로 보여주어서 시각적 이해를 돕는다

    + RxJSKoans 학습

    + RxJS GitBook 책을 읽자 (그외 RxJS 레퍼런스)


  - RxJS를 이용한 FRP API 소개 : 맨뒤의 참조 목록을 방문하자 

    


  - ng-conf 2015에서 Nexflix UI 개발자가 발표하는 Obserable을 보자 (슬라이드

    + RxJS 개념은 Angular 2.0 core 에서 사용한다!!!

    

  - Bacon.js  : Functional Reactive Programming(FRP) Library for Javascript
    + 강좌-1 : Hacking with jQuery
    + 강좌-2 : Bacon.js started
    + 강좌-3 : AJAX and stuffs



Reactive Programming for Another Stuffs

Reactive 프로그래밍은 다양한 언어를 지원하고 http://reactivex.io 에서 언어별로 확인이 가능하다. 
  - Java를 위한 Reactive 프로그래밍으로 RxJava를 제공하고, 안드로이드 v2.3 이상부터도 사용을 할 수 있다. 
  - 김대성님의 FRP에 대한 이야기 : RxJava를 소개하고 있다. 유튜브 동영상을 시청하면 보자.   
    

  - 안드로이드 개발을 위한 Rx기반의 아키텍쳐링 방법도 제공을 하고, RxAndroid 라이브러리도 제공을 한다
    

    + cycle.js를 React 스타일로 재구성한 cycle-react
    + Flux Pattern을 Rx-Flux 구현

  - Angular에 RX 적용하기 
    + BangJS : Reactive AngularJS 로서 Bacon.js를 사용한다.

  - D3.js와 붙여보자 




<참조>

  - React & Bacon 예

  - Neflix API를 사용해 Reactive Programming하기

  - Reactive Programming using RxJS

  - Observable 과 Promise의 차이점

  - Reactive Extension in MS

  - Rx 관련한 대부분의 자료 모음

  - RP and MVC 예제

posted by 윤영식
2015. 7. 11. 19:45 Meteor

2013년 이맘때 미티어를 처음 접하고 클라이언트와 서버 사이에 데이터베이스가 있다는 것이 이해되지 않았다. 그 의문이 이번주 스마트링크의 스터디를 하며 조금씩 해소되는 느낌이다. 이제는 Modern Application Platform의 큰 흐름에서 Runtime이라는 주제를 놓고 볼 때 미티어는 단연 앞선 플랫폼이고 한 분야를 리딩할만한 플랫폼이라 여겨진다. 그속에 많은 사상과 기술이 녹아있다. 미티어를 한주 안에 파악해 보기 위해 다음의 과정을 밟아보길 권한다. 






Meteor 넌 뭐니?


  - 스터디에서 발표한 내용의 동영상이다. 

    + Realtime을 근간으로 Collaboration과 Share를 위해 잘 갖추어진 Modern Application Platform 이다. 

    + Reactive 영역을 프론트엔드에서 백앤드로 확장해 기술셋을 잘 구비해 놓았다.

    + 프론트앤드 리액트 템플릿엔진 : Blaze, AngularJS, ReactJS를 사용할 수 있다. 

    + 백앤드 리액트 기술 : Full Stack DB Driver = DDP + Client mini DataBase + LiveQuery 를 갖추었다. 

    
    + 동영상의 발표자료
    


  - 위의 내용을 이해하기 위하여 다음과 같은 자료를 보았다. 

    + DiscoverMeteor 강좌 : 반드시 전과장을 직접 따라서 코딩해 보면 좋다. 물론 한글로 번역이 되어 있다. 

       이번에 출간한 "실전 프로젝트로 배우는 AngularJS"의 상당 부분이 이와 유사하게 전개한다. 놀란 것은 Node.js에서 MongoDB 제어와 권한 체크를 위한 코드 작성이 너무나도 쉽게 해결된다는 것이다. 정말 말 그대로 서버는 날로 먹는 것이다. Isomorphic Programming의 정수이다. 

    + 박승현님 Meteor Dev Study : 페북 미티어 코리아 그룹을 이끄시는 박승현님의 미티어 강좌를 보고 친숙하게 이해할 수 있을 것이다. 





Meteor Environment


미티어는 Ionic과 같은 CLI 제공을 통해 실행과 빌드를 통합하고 있다. 따라서 의존성관리를 위한 npm, bower 또는 빌드를 위한 grunt, gulp 명령등을 알 필요가 없다. 단순히 meteor <command> <option> 을 통해 완료된다. 


  - Meteor Command Line Tool 명령들

  - 미티어의 패키지 저장소 : Atomsphere

  - 많이 사용하는 패키지 검색 : Fastosphere





Meteor가 AngularJS 또는 ReactJS를 만났을 때

  

                    



  Blaze를 사용하지 않고 AngularJS를 사용할 때의 방식은 확연히 차이가 보인다. 만일 JQuery 개발 방식에 익숙하다면 Blaze를 사용한다. AngularJS를 사용해 보았다면 당장 AngularJS+Meteor를 사용하길 권한다. 공식적으로 지원을 하고 예제 문서까지 친절하게 나와있다. ReactJS는 아직 Preview단계로 보여지지만 긱하게 새로운 것을 도전해 보고 싶다면 권한다. ReactJS의 Virtual DOM 개념도 관심의 대상이지만 Flux라는 개념이 참 맘에 든다. 따라서 MVC 패턴이 아닌 좀 더 견고한(페북이 말하는) 패턴이라는 Flux 패턴을 적용하고 싶다면 ReactJS를 사용해 보자. 나의 선택은 물론 ReactJS + Flux 패턴이다. 


  - Blaze, AngularJS, ReactJS 비교하며 따라하기 예제

  - AngularJS + Meteor 홈페이지 : 물론 미티어 홈페이지에 AngularJS 공식 문서도 있다.'

  - ng vegas에서 발표한 angular-meteor 개발자인 유리 골드스테인의 Angular/Angular2와 Meteor에 대한 소개

    


  - ReactJS + Meteor Preview 예제 페이지

  - 페북과 유사한 ReactJS + Meteor 샘플 예제 : 데모 사이트를 이동해 직접 사용해 보자. 

    + Data Fetching Component는 Flux의 Controller View 이다.

    + Mini-Mongo Store는 Flux의 Store 이다.

    + Action은 Flux의 Action Creator 이다.

    



Meteor는 Modern Application Platform 이면서 클라이언트의 리액트를 백앤드로 확장해 주는 Reactive Platform이라 말할 수 있다. 다시 들여다 본지 1주일밖에 되지 않기에 오류를 잡고 파보아야할 곳이 많이 존재한다. 앞으로 두달간 진행하는 파일럿 프로젝트에서 ReactJS + Meteor를 사용하면서 내공을 쌓아야 할 상황이다. 




Modern Application Platform 으로서 Meteor 

  

  "Realtime 애플리케이션을 위해 프론트/백앤드 개발을 동질로 리액트하게 할 수 있는 플랫폼을 제공해 보자" 이게 그들의 머릿속을 스친 생각이 아니었을까? 리액티브 프로그래밍을 이소모픽하게 제공한다면 View 와 Data에 대하 부분을 리액티브하게 처리할 수 있다면... 아마 미티어 개발자들은 신이 나지 않았을까 싶다. 그래서 그와 관련된 회사들을 M&A하고 개발자를 영입해서 오늘의 1.* 미티어라는 리액티브 플랫폼을 완성해 가고 있다고 본다. 미티어를 리얼타임 플랫폼을 하는 마이크로 서비스로 보고 외부 시스템과 연계는 몽고디비를 통해 한다면 다양한 연동이 가능할 것이라 생각한다. 


  이중 DDP를 통한 React Native로 DDP Client를 사용하는 방법이 있는가 하면 

  

  일라스틱서치(Elastic Search)와 연동하기도 하고 

  

  

 미티어를 통해 상상하던 모던 애플리케이션 서비스를 일관되고 쉽게 만들어 갈 수 있다라는게 나의 결론이다. 




<참조> 


  - JavaScript.isSexy에서 이야기하는 Meteor 배우는 방법

posted by 윤영식
2015. 7. 4. 22:41 React

Flux는 페이스북이 ReactJS를 보다 더 큰 애플리케이션에 적용하기 위해 만든 아키텍처이다. 그러기 때문에 페이스북 웹 서비스와 인스타그램에도 적용되어 사용되고 있다. 하지만 처음 접하는 개발자에게는 생소한 패턴이고 새로운 용어들이 난무한다. Flux를 제대로 이해하기 위해서는 먼저 ReactJS의 데이터 흐름을 이해한 후 Flux를 보면 도움이 된다.  





Flux 넌 뭐니?


스터디에서 발표한 Flux 패턴에 대한 설명 동영상을 보자. 1시간 가량의 발표 및 토론 내용이다. 1주일동안 짬을 내어 Flux 예제 소스를 분석해 보았고, Flux 내의 Action, Dispatcher, Store, View 간의 데이터 흐름과 각각의 역할에 대해 살펴보고 있다. Flux를 이해하고 싶다면 본 예제를 돌려보고 설명하는 흐름에 따라 개념을 잡아보자. 

  - CartApp 예제에 대한 원본 글

  - CartApp 데모


   


발표한 내용의 PPT 자료도 동영상을 보며 살펴보자 

   - Flux 아키텍처에 대한 원본 글 


    




AngularJS에서 Flux 아키텍처 적용하기 


Flux는 아키텍처이고 사상일 뿐이다. 따라서 AngularJS에서도 당연히 적용해 볼 수 있다. 

  - AngularJS에서 Flux 적용하기 예제




참조 

  - Cart 소스 

  - ReactJS 개념 및 에코 시스템 이해하기 (스마트 링크 팀블로깅)

  - AngularJS vs ReatJS 이해하기

  - Flux 패턴 구현체들 (Fluxxor)

  - Flux pattern 설명

  - Flux를 이용한 Note App 예제

  - SlideShare: ReactJS와 Flux에서 데이터 흐름 설명 

'React' 카테고리의 다른 글

[React] 다시 시작하기  (0) 2018.09.14
[React] Semantic-UI를 React 컴포넌트로 만들기 - 1  (0) 2015.08.23
[React] CSS Framework 선정하기  (0) 2015.08.15
[React] AngularJS와 ReactJS 비교  (0) 2015.07.01
[React] 배우는 방법  (0) 2015.05.15
posted by 윤영식
2015. 7. 1. 09:17 React
AngularJS로 여러번의 프로젝트를 했었다. 그럴때 마다는 느끼는 보다낳은 컨트롤러의 구조는 무엇일까? 그리고 $scope를 어떻게 하면 잘 사용할 수 있을까이다. 어쩌면 $scope에 대해 고민하기 보다 다른 접근법을 시도해 보는 것은 어떨까? 그래서 ReactJS를 공부하기 시작했다. 1주일밖에 안된 입장에서 어떻게 접근하는 것이 좋을지 간략히 정리하고 스마트링커들과 토론한 내용을 올린다. 



AngularJS와 ReactJS 비교

  - AngularJS와 ReactJS간의 개발 방법론에 대한 스터디 자료 

    



  - MVC 패턴과 ReactJS의 차이점을 이야기한다. 

   + 해당 발표를 보면 위에서 내가 설명한 내용을 좀 더 이해하기 쉽지 않을까 싶다.

   


'React' 카테고리의 다른 글

[React] 다시 시작하기  (0) 2018.09.14
[React] Semantic-UI를 React 컴포넌트로 만들기 - 1  (0) 2015.08.23
[React] CSS Framework 선정하기  (0) 2015.08.15
[Flux] Flux 배우는 방법  (0) 2015.07.04
[React] 배우는 방법  (0) 2015.05.15
posted by 윤영식
2015. 6. 22. 23:20 Angular/Concept

  ECMAScript는 자바스크립트의 토대를 구성하는 스크립트 언어 명세이다. ECMA는 "Europen Computer Manufacturers Association"의 약어로 국제 표준화 기구이며, ECMAScript는 ECMA-262, ECMA-402 스펙안에서 표준화되었다. ECMAScript 3.0이 1999년 발표된 이래로 ECMAScript 5.0 이 2009년 발표되고 5.1이 2011년 그리고 마침내 ECMAScript 6.0이 2015년 6월 공표되었다. 모던 브라우저가 대부분 ECMAScript 5.0  을 지원하 있고, 현재 브라우저가 5,6,7 버전들에 대해 어느 범위까지 지원하는지 테스트 해볼 수 있다. 


  Angular 2는 TypeScript를 기반으로 개발되고 있고, TypeScript는 ES6를 포함해 별도의 추가 기능을 포함한다. ES6 기반으로 애플리케이션을 개발할 경우 BabelJS를 통해 ES5로 컴파일할 수 있다. 따라서 ES6에 대해 알아보고 필요한 문법을 사용한 후 애플리케이션 배포시에 ES5로 적용로 한다. Babel 사용을 자동화 하기위해 Browserify또는 Webpack을 사용하거나 Grunt/Gulp를 사용할 수도 있다.  




기초 문법 익히기


  - 문법을 보기전에 드미트리 소스니코드의 설명을 잠시 훑어보자

    


  - ECMAScript 6에 새롭게 추가된 기능 알아보기

  - ECMAScript 6를 5와 비교해서 실습하기 

  - Exploring JS ES6 무료 서적





ECMAScript 5 전환 자동화하기


  - Babel을 Browserify와 연동하기, Babel을 Browserify+Gulp 연동하기

  - Babel을 Webpack과 연동하기

  - Babel을 Gulp와 연동하기

  - Babel을 Grunt와 연동하기




참조 

  - ECMAScript 6.0 스펙  (PDF)

  - ECMAScript 버전별 자료

posted by 윤영식
2015. 5. 15. 11:38 React

ReactJS(리액트)는 자바스크립트로 UI 컴포넌트를 만드는 프레임워크이다. 만들어진 컴포넌트를 사용할 수도 있고, 수정할 수 있고, 조합할 수 있으며 자신만의 UI 컴포넌트를 직접 만들 수 있다. 즉 프론트앤드 UI의 화면을 컴포넌트 조합으로 만들고, 화면의 데이터를 앵귤러처럼 자동 업데이트 해주지만 앵귤러와 틀리게 단방향 데이터 바인딩이다. 리액트는 앵귤러(AngularJS)의 지시자(Directive)와 비교되지만 훨씬 간단하고 성능 또한 월등하다. 이제 배우고 익혀 사용할 때가 되었다. 







개념잡기 


  - 쿼라(Quora)에서 이야기하는 장/단점을 살펴보자. 

     장점

       + Virtual DOM 을 JS로 구현해서 UI 컴포넌트의 속도가 엄청 빠르다. 

       + Component의 재사용과 복잡한 UI 컴포넌트 조합이 가능하다.

       + Uni-direction(단방향) 방식하에 데이터가 변경되면 관련된 모든 UI 컴포넌트가 변경된다.

       + commonJS / AMD 패턴과 잘 조합되고, 크롬 익스텐션을 통해 디버깅할 수 있다. 

     단점

       + 초보자들에겐 역시 러닝 커브가 존재한다.

       + 다른 프레임워크가 동작하기 위해선 부가적인 작업들이 필요하다. 

       + 앵귤러처럼 router, model등 Frontend Full Framework을 제공하지 않아서 꼭 다른 프레임워크와의 조합이 필요하다. 


  - 처음에는 무조건 공식 홈페이지의 가이드를 보자. 

      + Quick Start

      + Advanced Guides

      + Reference


  - 프리젠테이션으로 정리해 보자. 재미있게 진행되니 WTF는 날리지 말자.

     

  - egghead.io 에서 리액트에 관련하여 ReactJS, React Native, Flux Architecture를 동강으로 제공한다. 물론 무료가 있다. 
    * 유료강좌를 듣길 추천한다. 앵귤러와 리액트에 대한 좋은 강좌가 많다. 한달 대략 15달러
    + Render MethodProperties, State 사용하기

  - 제이쿼리를 리액트로 바꾸는 과정을 잘 설명해 주고 있다. 글을 읽고 다시 egghead.io 를 보면 이해가 될 것이다. 

    + jQuery to React 가이드

       내용중에 앵귤러를 사용하고 있는 개발자라면 앵귤러의 지사자에서 scope: { createXXX: '&' } 방식으로 자식의 부모의 함수를 호출 할 수 있다

       그리고 자식, 부모간에 scope 객체의 상속을 통해 scope 속성을 접근할 수 있다는 것도 알 수 있다. 

    + Flux 소개 아래 영상을 보면 react가 Virtual DOM을 통해 더 낳은 성능과 단순성을 통한 버그 가능성 제거를 이룰 수 있는지 가늠할 수 있다

       * Flux 사이트

      


  - 이제 다시 설치부터 기초 개념을 문서를 통해 쭉 살펴보자. 

  - ng-conf 말고 react-conf도 있다. 동영상을 통해 향후 방향을 점쳐보자. 
    

  - 리액트 컴포넌트를 찾고 싶을 경우 


  - 리액트 자료 

    + Awesome 자료 목록들

    + 앵귤러와 결합해서 사용하기 : NGREACT 


  - 리액트 컴포넌트 프레임워크 : 트위터 부트스트랩같은 조합

   + reapp.io


  - 새 술은 새 푸대에 넣자. 리액트가 UI 컴포넌트라면 Webpack 또는 Browserify 를 이용해 모듈화 하자
    + 리액트를 위한 웹팩의 starter kit

  - 디버깅은 Chrome Extention 설치하고 시작
  - 필요에 맞는 툴과 환경을 선택한다.

 


Immutable Data에 대한 이해 

불변 데이터에 대해 알아 두어야 한다. 예로 리스트를 생성하고 거기에 새로운 값을 넣으면 리스트를 가르키는 레퍼런스는 같을까 틀릴까? 기존 방식이라면 동일한 레퍼런스이겠지만 Immutable의 세계에 오면 값이 변경 되면 새로운 객체가 된다. 리액트에서는 성능향상을 위해 Immutable.js를 사용토록 권장하고 있다. 이것에 대해 발표한 영상을 보고 영상을 요약한 블로그 글을 보도록 한다. 
  - 영상 설명 블로그 [1], [2], [3]
  - 발표 영상

  - 최근 보고 있는 Clojure는 기본적으로 Immutable Data이다. 클로져 관련 블로그를 읽어보자.



자바스크립트 개념 장착

리액트를 하다 보면 this와 bind(this)를 자주 사용할 때가 있고, ES6로 전환하다보면 좀 더 빈번히 보게 된다. 제대로 이해하고 React 코드를 보자 
  - bind를 해주는 이유 Callback 때문 그렇다면 Callback을 이해하자
  - Callback은 자바스크립트가 Funtional Programming이 가능하게 해주고 Closure이다. 클로저를 이해하자
  - React에서 Object만드는 것이 많이 나오니 자바스크립트의 Object에 대해 알아보자
  - http://javascriptissexy.com/ 에서 다른 글도 참조하시라


'React' 카테고리의 다른 글

[React] 다시 시작하기  (0) 2018.09.14
[React] Semantic-UI를 React 컴포넌트로 만들기 - 1  (0) 2015.08.23
[React] CSS Framework 선정하기  (0) 2015.08.15
[Flux] Flux 배우는 방법  (0) 2015.07.04
[React] AngularJS와 ReactJS 비교  (0) 2015.07.01
posted by 윤영식
2015. 4. 16. 17:50 My Services/Smart Analytics

AngularJS SPA 형태 개발을 진행할 때 AMD(Asychronous Module Definition)에 대한 고려를 하지 않고 있다. 계속해서 확장 되어야 하는 애플리케이션을 개발한다면 AMD를 염두에 두자. 하지만 AMD가 아니라 앵귤러 스러운 모듈단위의 동적 로딩을 하고 싶을 경우 어떻게 하는지 Smart Analytics 관점에서 컨셉을 테스트해 보자. 



개념 


  - CommonJS : exports, require, module을 통한 서버사이드 자바스크립트 모듈화 스팩이고 Node.js에서 많이 사용함

  - AMD : 브라우져에서 모듈화에 대한 스팩. 가장 많이 쓰는 구현체 require.js  를 통한 자세한 사용예(NHN)

    + 특징 : 동적 로딩, 의존성 관리, 모듈화 

    + define을 통한 모듈 패턴을 적용하여 모듈을 만든다

    + require를 통해 의존관계 모듈들을 주입받아 사용한다. 

  - AngularJS는 모듈화와 DI 즉, 의존성 주입을 가능하게 하고, RequireJS는 JS 파일의 의존성을 관리하고 동적 로딩을 통한 성능 최적화를 얻는다. (참조)





Smart Analytics에서 바로 보는 동적 로딩 시나리오

  

  ElasticSearch의 Kibana는 엘라스틱서치의 데이터를 자유롭게 표현할 수 있는 대시보드 소프트웨어이다. AngularJS + Require.js를 사용하고 있다. 하지만 좀 더 AngularJS 스러운 방식으로 앵귤러 모듈을 필요한 시점에 동적으로 할 수는 없을까? 화면이 라우팅될 때 또는 필요한 시점에 필요한 모듈만 로딩할 수 있도록 지원하는 앵귤러 컴포넌트로 ocLazyLoad 모듈이 있고 이를 이용하여 대시보드 화면에 국한하여 시나리오를 써보자


  - 사용자가 로그인을 하면 사용자마다 할당 된 대시보드 목록을 가져오고 첫번째 대시보드를 브라우저 영역 전체화면으로 보여준다.

  - 대시보드에는 사용자가 직접 제작한 차트가 보이고 해당 차트는 별도의 파일로 존재하고 앵귤러의 독립 모듈로 존재한다. 따라서 대시보드안에 들어가는 차트들은 플로그인 방식으로 동적으로 로딩되어 대시보드 일부분에 포함되어 들어가야 한다. 

  - 그러나 사용자가 직접 제작하지 않고  저작도구를 통해 제작한 차트는 별도의 파일로 존재하지 않고 환경값을 서버로 부터 받아 차트 컨테이너에 자동으로 해석되어 표현된다. 


  여기서 동적으로 로딩되어 표현할 것은 직접 별도로 제작된 차트를 대상으로 하고, 별도의 파일로 존재한다. 해당 파일은 로컬 또는 네트워크를 통해 로딩 될 수 있어서 다양한 차트 화면을 대시보드로 수용할 수 있다. 마치 플러그인 방식으로 대시보드 운영 서버의 재기동 없이도 플러그인을 설치하기만 하면 자동으로 대시보드의 특정위치에 차트가 표현되는 것이다. 

  

   - chart-config.json + chart-container를 통해 차트를 자동으로 표현하거나

   - 로컬에서 사용자가 직접 제작한 bizChart01.js 파일을 동적으로 로딩해서 표현하거나, bizGrid01.js를 원격에서 동적 로딩하는 개념이다. 







ocLazyLoad 기반 앵귤러 모듈의 동적 로딩


  ocLazyLoad 모듈을 이용해 파일 로딩하는 예를 보자. 설치하고 모듈 의존성 설정

// survey-gorilla 설문조사 오픈소스를 위해 만들어 놓은 제너레이터로서 generator-angular-fullstack을 기반으로 수정한 것이다. 

$ npm install generator-sg --save

$ mkdir prototyping & cd prototyping


// 애플리케이션 생성 : mongodb는 선택안하고, ui-bootstrap과 sass를 선택함

$ yo sg SAProto 

// oclazyload를 설치함 

$ bower install oclazyload --save

bower install       oclazyload#0.6.3


  ocLazyLoad 모듈을 위한 별도의 서비스를 /app/components/base/pluginer 폴더에 만들어 보자. pluginer 앵귤러 서비스를 base 모듈에 포함시키기 위해 먼저 base.module.js를 만든다. 

// base.module.js 를 만들고, oc.lazyLoad 모듈에 대한 의존관계를 설정한다. 

$ cd client/components

$ mkdir base & cd base

$ vi base.module.js 


(function() {

  'use strict';


angular 

    .module('sa.base', ['oc.lazyLoad']);


})();



// pluginer 서비스를 만들어 보자 

$ mkdir pluginer & cd pluginer

$ vi pluginer.service.js 


(function() {

  'use strict';


  angular

    .module('sa.base')

    .service('pluginer', pluginer);


  /* @ngInject */

  function pluginer($q, $ocLazyLoad) {

    this.load = load;


    function load(moduleName, filePath) {

      var deferred = $q.defer();


      $ocLazyLoad

        .load({

          name: moduleName,

          files: [ filePath ]

        })

        .then(function() {

          console.log('loaded plugin: ' + moduleName + ' successfully.');

          deferred.resolve('ok');

        }, function() {

          console.log('failed plugin: ' + moduleName + ' successfully.');

          deferred.reject('fail');

        });


      return deferred.promise;

    }

  }


})();


// 최종 폴더 구조 


  pluginer.service.js는 $ocLazyLoad를 통해 지정한 파일의 모듈을 로딩해서 사용할 수 있고 promise 패턴을 통해 비동기적인 상황에 대응한다. 다음으로 플러그인을 하나 만들어 보자. 우선 client 밑에 plugins 폴더를 만들고 index.html에 포함되지 않는 *.js / *.css / *.jpg(png) 등을 놓는다. plugin.bizchart01이라는 별도의 모듈을 만들고 bizchart01 서비스를 만든다. 

// client 밑에 plugins 폴더를 생성한다.

$ mkdir plugins & cd plugins

$ mkdir bizchart01 & cd bizchart01

$ vi bizchart01.js 


(function() {

  'use strict';


  angular

    .module('plugin.bizchart01', [])

    .service('bizchart01', bizchart01);


  function bizchart01() {

    this.draw = draw;


    function draw() {

      return 'drawing....';

    }

  }


})();


// plugins 폴더 

 

  이제 pluginer 서비스를 통해 plugin.bizchart01 모듈을 필요한 시점에 로딩을 하고 bizchart01 서비스의 draw() 를 호출해서 출력해 보자. sa.base 모듈을 app.js에 의존관계를 설정하고 app/main/main.html 를 바꿔보자. 

// /client/app/app.js 의 sa.base 모듈 의존 설정 

  angular

    .module('saprotoApp', [

 'ngCookies',

 'ngResource',

 'ngSanitize',

 'ui.router',

 'ui.bootstrap',

                  'sa.base'

])

    .config(config)

    .factory('authInterceptor', authInterceptor)

    .run(run);


// main.html 과 main.controller.js를 수정하여 테스트 코드 작성

// main.html 

 <li><a href="#" ng-click="lazyloading()">Load Module</a>: {{lazyloadingMsg}}</li>


// main.controller.js 

(function () {

  'use strict';


  angular

    .module('saprotoApp')

    .controller('MainCtrl', MainCtrl);


  /* @ngInject */

  function MainCtrl($scope, $injector, pluginer) {

    $scope.lazyloading = lazyloading;


    function lazyloading() {

      pluginer

        .load('plugin.bizchart01', 'plugins/bizchart01/bizchart01.js')

        .then(function() {

          var bizchart01 = $injector.get('bizchart01');

          $scope.lazyloadingMsg = 'lazyloading message: ' + bizchart01.draw();

          console.log($scope.lazyloadingMsg);

        });

    }    

  }


})();


  pluginer를 통해 "plugins/bizchart01/bizchart01.js" 에 있는 "plugin.bizchart01" 모듈을 로딩하고, $injector를 통해 "bizchart01" 서비스를 얻어와 draw()를 호출했다. 이를 확인할 수 있는 것은 크롬의 개발자 도구에서 브라우저에서 로딩 링크를 클릭했을 때 실제로 bizchart01.js 파일을 호출하는지 보면 된다. 


1) "Load Module"를 클릭한다. 



2) 크롬 개발자 도구의 Nework에서 "Load Module" 링크를 클릭시 bizchart01.js을 요청하는지 확인한다. 



이제 별도의 차트를 앵귤러 모듈로 만들어서 필요한 시점에 로딩할 수가 있다. 이외에도 ui-router를 통해 partial view가 변경될 때도 가능하고 다양한 예제는 ocLazyLoad를 참조한다. 


테스트 소스 : https://github.com/Smart-Analytics/prototyping/tree/feature/lazyloading




<참조>


  - CommonJS와 AMD 개념 비교 (NHN)

  - AMD : require.js 사용예

  - Node.js와 브라우져 사용예 (Mobicon)

  - ocLazyLoad GitHub

posted by 윤영식
2015. 3. 7. 21:19 AI Deep Learning

NMF(non-negative matrix factorization) 기법을 소개한다. 이 기법은 데이터내에 독립된 특성을 찾는데 사용한다. 많은 데이터 세트 내의 항목들은 미리 알기 어려운 다른 특성들과의 조합으로 생성되고 이러한 특성을 찾아 본다. 






이전 분류 방식

  

  - 베이지안 분류기 (Classification)

  - 의사결정트리

  - 지지벡터머신(SVM)

  - 군집 (Clustering)




비음수 행렬 인수분해 (NMF)


  - 행렬 준비 

    + 특성 행렬(feature matrix) : 가로줄에 각각의 특성을 가졌고 세로줄에 단어, 값들은 단어 특성의 중요도

     


    + 가중치 행렬(weights matrix) : 가로줄 타이틀, 세로줄 특성

      


    + 행렬 만들기 = 특성 행렬 * 가중치 행렬


  - 비음수 행렬 인수분해라 불리는 이유는 음수가 아닌 특성과 가중치를 리턴하기 때문이다. 모든 특성은 양수 값을 가져야 함을 의미한다.

  - 단어 출현 횟수와 같은 명사류 데이터뿐만 아니라 주식시장 데이터와 같은 숫자 데이터 문제에도 잘 어울린다.

  - 진행 : 행렬 준비 -> NMF 실행 -> 결과 출력    

     * 특성을 나누는 행렬을 만들고 필요없는 특성을 제거하면서 원하는 차원을 줄여서 원하는 것을 종합적인 결과를 출력함




<참조> 

 

 - 얼굴 인식

 - PCA, NMF



<참조>

- 파이썬 가상환경 만들기

posted by 윤영식
2015. 2. 28. 11:56 AI Deep Learning

선형 분류기 개념과 지지벡터머신(SVM, support-vector machines)에 대해 알아본다. 데이트 매칭에 데이터를 기본으로 알아봄. 



데이터 세트 


  - 데이터 분할에서 의사결정트리는 세로, 가로 직선으로 고지식함

  - 산포도(scatter plot chart)를 통해 도움받음 

 



기본 선형 분류


  - 산포도에서 각 범주(class) 내 모든 데이터들의 평균을 찾고 그 범주의 중앙을 나타내는 점을 만듦 (그림. 9-4)

  - 일치분류를 위해 백터의 각도를 계산해서 작으면 일치, 크면 불일치 (그림. 9-6)

  - 백터내적(dot-product) : 벡터와 벡터의 방향/크기 비교 






분류 데이터의 특성


  - 데이터 정규화 (Data Normalization)

  - 숫자로 변형 -> 예/아니오(1/-1), 관심/비관심(0/1) : 사람 쌍을 다룰 때 유용 

  - 공통 관심의 수, 모든 관심을 포용할 새로운 변수를 만듦

  - 거리 데이터 구함

  - 각 변수에 대한 축적(scale)을 조정함 : 최대/최소값 




커널 기법 이해

  

  - 커널 트릭 : 차원을 높이지 않고 차원을 올리는 효과를 거둠. 

  - 펑션을 통해 원하는 값을 구함 : 방사 펑션 (RBF: radial basis function)




지지 벡터 머신 (SVM)


  - 각 범주에서 가능한 멀리 떨어진 선을 찾아 해결하려고 시도한다. 비선형을 극복 (non-linear)

  - 먼저 범주를 나눈다 이때 커널 트릭을 사용해서 구하고 이것이 차원이 된다. 각 차원 즉 범주의 사이의 초평면(hyperplane)을 만든다. 

  - 해당 초평면에 근접한 것들이 매칭하는 것이다.  (그림. 9-10)





<참조> 


  - 내적 공간

  - 서포트 벡터 머신(한글), 서포트 벡터 머신 공식(영어)

  - 초평면

  - LIBSVM 라이브러리 

  - 정규화

'AI Deep Learning' 카테고리의 다른 글

[인공지능] 공부 여정  (0) 2018.07.31
[ML] 11주차 - 독립 특성 발견  (0) 2015.03.07
[ML] 9주차 - 가격 모델링  (0) 2015.02.21
[ML] 8주차 - 7장 의사결정트리  (0) 2015.02.14
[ML] 7주차 - 6장 문서 필터링  (0) 2015.02.07
posted by 윤영식
2015. 2. 21. 13:23 AI Deep Learning

가격 결정을 위한 모델링은 이질적인 속성을 기반을 둔 숫자 데이터를 예측하는데 최적의 알고리즘이다.




kNN


  - K-nearnest neighbors : k는 마지막 결과를 얻기 위해 평균을 낼 물품의 개수를 말한다. 데이터가 완벽하다면 k=1을 사용한다. 

  - 인접개수의 평균을 낼 때 너무 작거나 크면 안되고 적정개수를 찾아야 한다. 




물품 가중치


  - 거리에 따라 가중치를 둔다. 물품들이 비슷할 수록 그들 간의 거리가 더 가까워진다. 

  - 물품들을 군집화하기 위한 방법 - 적정한 인접 개수를 구하는 것이 필요하다. 

  - 역함수(inverse function), 빼기 함수(substraction function), 가우스 함수(gaussian function)

  - 가중 kNN (Weighted kNN) : 가우시안을 구하고 평균을 구한다 




교차검증


  - 데이터를 학습 세트와 테스트 세트로 나누는 기법들을 총칭한다. (cross validation set) : 표본값을 잘 뽑는 방법

  - training set -> test set 




이질 변수


  - 가격 결정에 너무 큰 영향을 미치는 이질적 요소

  - 변수의 단위가 틀릴때 스케일(Scale)을 조정하여 대입한다. 




실습 


  - $ pip install virtualenvwrapper

 - $ source /usr/local/bin/virtualenvwrapper.sh

 - mkvirtualenv env1

 - vi requirements.txt

// requirements.txt 내역 

beautifulsoup4==4.3.2

html5lib==0.999

lxml==3.4.2

numpy==1.9.1

pandas==0.15.2

python-dateutil==2.4.0

pytz==2014.10

six==1.9.0

wsgiref==0.1.2


  - pip install ipython  (module 없을 경우 계속 pip install <moduleName>)

  - ipython notebook 을 통해서 실습 시작

  - chapter7의 treepredict 데이터 생성 : data.txt

Referrer,Location,Read FAQ,Pages viewed,Service chosen

Slashdot,USA,Yes,18,None

Google,France,Yes,23,Premium

Digg,USA,Yes,24,Basic

Kiwitobes,France,Yes,23,Basic

Google,UK,No,21,Premium

(direct),New Zealand,No,12,None

(direct),UK,No,21,Basic

Google,USA,No,24,Premium

Slashdot,France,Yes,19,None

Digg,USA,No,18,None

Google,UK,No,18,None

Kiwitobes,UK,No,19,None

Digg,New Zealand,Yes,12,Basic

Google,UK,Yes,18,Basic

Kiwitobes,France,Yes,19,Basic


  - treepredict.py 작성 : pandas 통해서 데이터 만듦

import pandas as pd 


def main():

  data = pd.read_csv("./data.txt", sep=",")

  print data

  values = data.values

  print values


if __name__ == '__main__':

  main()


  - pandas로 하면 데이터 유형이 틀려지므로 그냥 책에 있는 내용 copy&paste

  - 실행 내역을 html로 출력

$ ipython nbconvert treepredict.ipynb

[NbConvertApp] Using existing profile dir: u'/Users/nulpulum/.ipython/profile_default'

[NbConvertApp] Converting notebook treepredict.ipynb to html

[NbConvertApp] Support files will be in treepredict_files/

[NbConvertApp] Loaded template full.tpl

[NbConvertApp] Writing 202262 bytes to treepredict.html

(env1)




<참조> 


  - https://virtualenvwrapper.readthedocs.org/en/latest/ : python 가상 환경 

  - https://pypi.python.org/pypi/virtualenv

  - iPython notebook 사용하기 

posted by 윤영식
2015. 2. 14. 11:29 AI Deep Learning

의사결정 과정 모델링에 대해 알아본다. 의사결정트리는 고객 프로파일링, 재무 위험 분석, 보조 진단, 트래픽 예측과 같은 넓은 응용분야에서 사용한다. 예로 사용자가 유료 고객이 될 가망성을 예측하여 사용자가 고객이 될 것임을 시사하는 요소를 알았다면 이 정보를 이용해서 광고 전략을 짜거나 사이트의 특정 측면에 쉽게 접근할 수 있게 만들거나 유료 고객의 숫자를 늘리는 데 도움이 되는 다른 전략들을 사용할 수 있다.




가입 유형 추정 


  - 유료 고객이 될 가망성을 예측하기 : 베이지안 분류기, 신경망을 이용

  - 관찰 결과를 분류하는 방법 : 의사 결정 트리를 if~then으로 만들고 경로를 따라 내려가면 해답에 이르게 됨 




트리 학습 


  - CART(Classification and Regression Tree) : 데이터를 분리하는 최적의 변수 찾기 true or false로 분기해야 하기 때문 

  - 최적 단편 선정

    + 최상위 부모로 있을 노드를 선정하고 그 하위로 나뉘어 내려감  

    + 지니 불순도(Gini imprity) : 집합 내의 항목 중 하나에 무작위로 적용될 기대 오류율 - 확률이 0이면 모든 것이 올바른 집합안에 있음

    + 엔트로피 : 데이터를 두개의 그룹으로 나누어 엔트로피를 줄여야 한다.

       p(i) = frequency(outcome) = count(outcome) / count(total rows) Entropy = sum of p(i) x log(p(i))  

       p(i) = 빈도(출력) = 횟수(출력)/횟수(가로줄 개수)

       엔트로피 = 모든 출력에 대해 p(i) * log(p(i))의 합 




재귀적으로 트리 만들기


  - 전체 그룹에 먼저 엔트로피를 구함 

  - 어떤 속성이 가장 잘 나누는지 결정하기 위해 정보이득(information gain)을 계산 -> 모든 속성마다 정보이득을 계산해 가장 높은 정보이득을 가진 것을 선택한다. 

  - 관측 값에서 더 분할 할지를 결정 : 새로운 노드마다 최적을 속성을 계산하면서 트리를 생성한다. 




트리 가지치기 


  - 트리를 학습시키면 학습 데이터를 과대하게 반영하는 과잉적합(overfitted) 문제에 직면한다. 

  - 노드 쌍을 병합해서 경계값 이하로 엔트로피를 늘 수 있는지 본다. 그렇다면 한개 노드로 병합한다. -> 과잉적합을 회피 

  - 최소 이득이 높아지면 상위 부모 노드로 병합.

 



손상된 데이터 다루기


  - 데이터 조각이 없을(손상된) 경우 : 각 가지의 결과를 계산하고 개별 가중치로 결합한다.




<참조> 


  - 의사결정트리

  - slideshare 의사결정트리

'AI Deep Learning' 카테고리의 다른 글

[ML] 10주차 - 고급 분류 기법  (0) 2015.02.28
[ML] 9주차 - 가격 모델링  (0) 2015.02.21
[ML] 7주차 - 6장 문서 필터링  (0) 2015.02.07
[ML] 6주차 - 5장 최적화  (0) 2015.01.31
[ML] 4주차 - 군집하기  (0) 2015.01.03
posted by 윤영식
2015. 2. 7. 11:59 AI Deep Learning

문서 필터링의 예를 알아본다. 이메일을 문서로 보고 학습된 정보를 통해 좋고 나쁨을 확률적인 값을 구한다. supervised learning의 예이다  




스팸 필터링 

  

  - 분류된 문서를 통해 판단

  - 문서를 bad, good으로 분류 : word === feature 

  - 분류된 것(특성==단어)의 출현횟수를 0과 1사이 값 확률로 변환한다.

  - 스팸필터를 계속 학습 시킨다.




기본 분류기 


  - 나이브 베이지안 분류기 (Naive Bayesian classifier) : A확률과 B확률은 독립적이다. 

    + Pr(A | B)

    + A == feature, B == Category이다. 

    + Category는 문장이 good(0), bad(1) 인지 정의한 정보 

    + 즉, 카테고리별로 피쳐를 분류해서 독립적으로 본다. 

  - 스팸필터의 경우 bad로 필터링되는 경계값을 보통 3으로 설정해서 bad가 될 확률이 good으로 분류될 확률에 비해 3배 높게 설정한다.

  - 피셔 방식(Fisher method) : 특성별 분류 확률 (개별특성) -> 개별특성들에 대한 확률 결합

    + 여기서는 카테고리별로 보지 않고 먼저 피쳐를 보고 카테고리전체를 본다. 

    + Pr(B | A) x Pr(A)/Pr(B)


    Pr(A | B) = Pr(B | A) x Pr(A)/Pr(B)



<참조>


  - 나이브 베이지안 수행하기

'AI Deep Learning' 카테고리의 다른 글

[ML] 9주차 - 가격 모델링  (0) 2015.02.21
[ML] 8주차 - 7장 의사결정트리  (0) 2015.02.14
[ML] 6주차 - 5장 최적화  (0) 2015.01.31
[ML] 4주차 - 군집하기  (0) 2015.01.03
[ML] 3주차 - 추천하기  (0) 2014.12.13
posted by 윤영식
2015. 1. 31. 12:01 AI Deep Learning

최적의 방법을 찾는 행위 



최적화

  

  - Optimization은 무엇일까요?

    + 최고가 아닌 최적을 찾는 것.

  - Optimization 을 왜 하는가?

    + 기회 비용을 최소화해 최적화 값을 얻기 위해 통계적 최적화를 사용할 수 있다. 

  - Optimization 을 하면 최고인가?

    + 최적을 하는 것이다. 




해답 표현하기


  - 예) 비행편 출발 시간, 도착 시간을 하루 중 가장 먼저 출발하는 것을 0부터 시작해서 1씩 증가, 각 인원에 대한 수치를 1차원 배열로 나열하는 행위를 모델링이라 한다. 

    예) [1,4,5,2,3,7,4,2]

  - 첫값 : 0, 그리고 1식 증가 

  - 비행편 API 제공 : 카약 http://www.kayak.com/labs/api/search (개발자 키를 발급 받아야 함)

  - 랜덤 값을 사용한다. 얼마나 제대로 된 랜덤 값을 만들어 내느냐가 중요하다. 만약 랜덤 값을 사용하면 stochastic optimization 즉, 통계적인 최적화이다. 

  - 랜덤 값에 대한 부분은 도메인 지식을 필요로 한다?




비용 함수 (Cost Function)


  - 비용이 될 만한 것을 도출

  - 비용 함수에 적용하여 비용이 많이 들수록 큰값을 반환 




언덕등반 (hill climbing)


  - 무작위 해답으로 시작해서 더 좋은 해답을 찾아 이웃 해답들ㅇ르 살펴보는 기법

  - 내리막에서 오르막이 시작될 즈음에서 찾음. 좌우 비교를 통함. 

  - 결점 : 오르락 내리락할 때 작은 내리막이 최적이라고 판단할 수 있은 오류




시뮬레이티드 어닐링 (Simulated Annealing)


  - 물리학에서 영감을 받음

  - 언덕 등반의 결점을 보안

  - 나쁜 선택이 현재 선택이 될 수 있지만 계속 진행할 수록 낳아진다. 

  - 시장에서 많이 사용. 




유전자 알고리즘 (Genetic Algorithm)


  - 개체군(population)이란 무작위 해답들을 생성하면서 시작

  - elitism, 돌연변이(mutation), 교배(crossover), 번식(breeding)

  - 존 홀랜드 1975년 발생 "Adaptation in Natural and Artificial Systems"




선호도 최적화  


  - 최적화 기법의 필요 조건 : 문제가 정의된 비용 함수 + 유사한 해답이 유사한 결과를 낼 것




네트워크 시각화 

  

  - SNS에서 사용 



<참조> 


  - 시뮬레이티드 어닐링

  - 두번째

'AI Deep Learning' 카테고리의 다른 글

[ML] 8주차 - 7장 의사결정트리  (0) 2015.02.14
[ML] 7주차 - 6장 문서 필터링  (0) 2015.02.07
[ML] 4주차 - 군집하기  (0) 2015.01.03
[ML] 3주차 - 추천하기  (0) 2014.12.13
[ML] 2주차 - 추천하기  (0) 2014.12.06
posted by 윤영식
2015. 1. 21. 16:15 My Projects/Jandi

2주차 진행을 하며 기존 웹 저장소를 별도로 구성해 완전히 별도의 애플리케이션을 구축할 예정이었으나 프러덕션 저장소의 업무로직의 복잡도와 지속적인 개발로 인한 신규 저장소 소스의 불일치 문제가 발생하였다. 따라서 완전히 새로운 저장소로 별도 애플리케이션을 개발하기 보다 Lagacy 코드를 리팩토링 하고 테스트 코드를 신규로 넣고 동시에 연속적인 빌드 환경을 구축하기로 한다. 



1. 모듈 리팩토링


  - AngularJS에서 하나로 묶여 있는 모듈을 여러개로 쪼개는 작업을 진행한다. 

    + 다행히 기존 애플리케이션이 generator-angular-fullstack 으로 되어 있기 때문에 별도로 작업했던 내용을 적용한다. 

    + jandiApp 모듈만 존재한다면 애플리케이션을 위한 추상화 모듈과 공통 모듈로 두가지를 생성한다. 

  - web_client 폴더는 jandi의 웹 애플리케이션 저장소 이름이다. 

    + web_client/client 폴더 밑으로 components 폴더를 만들고 그 밑으로 app와 base 폴더를 만든다. 

    + components/app는 애플리케이션과 연관이 있는 대표 모듈 폴더이다. 

    + components/base는 jandi외에도 어디서나 사용 가능한 그리고 웹에서 bower로 다운로드한 모듈의 폴더이다. 

$ cd web_client/client/

$ mkdir components && cd components

$ mkdir app

$ mkdir base


  - app와 base에 대한 대표 모듈을 만든다.

    + components/app/app.framework.js 파일 생성

    + components/base/base.farmework.js 파일 생성

    + app.framework 모듈은 base.framework 모듈을 의존한다. 

// app.framework.js 내역 

(function() {

  'use strict';


  angular

    .module('app.framework', ['base.framework']);

    

})();


// base.framework.js 내역 

(function() {

  'use strict';


  angular

    .module('base.framework', []);

    

})();


  - 자바스크립트 로딩 우선순위를 지정한다. 

    + index.html 파일의 app.js 보다 먼저 로딩 될 수 있도록 app.framework.js와 base.framework.js를 지정한다. 

    + grunt serve 명령 수행시 app.framework.js와 base.framework.js 파일이 자동 inject 되지 않도록 ingore 설정을 한다. 

    + watch와 inject에 경로를 설정하고 설정앞에 ! 주면 exclude하겠다는 의미이다. 

// index.html 일부 내역 

<!-- build:js({.tmp,client}) app/app.js -->

<script src="components/base/base.framework.js"></script>

<script src="components/app/app.framework.js"></script>

<script src="app/app.js"></script>

<!-- injector:js -->

<script src="assets/javascripts/angulartics-ga-custom.js"></script>



// Gruntfile.js 일부 내역

 watch: {

            injectJS: {

                files: [

                    '<%= yeoman.client %>/{app,components}/**/*.js',

                    '!<%= yeoman.client %>/{app,components}/**/*.spec.js',

                    '!<%= yeoman.client %>/{app,components}/**/*.mock.js',

                    '!<%= yeoman.client %>/components/base/base.framework.js',

                    '!<%= yeoman.client %>/components/app/app.framework.js',

                    '!<%= yeoman.client %>/app/app.js'],

                tasks: ['injector:scripts']

            }, 

... 중략 ....

injector: {

            options: {},

            // Inject application script files into index.html (doesn't include bower)

            scripts: {

                options: {

                    transform: function(filePath) {

                        filePath = filePath.replace('/client/', '');

                        filePath = filePath.replace('/.tmp/', '');

                        return '<script src="' + filePath + '"></script>';

                    },

                    starttag: '<!-- injector:js -->',

                    endtag: '<!-- endinjector -->'

                },

                files: {

                    '<%= yeoman.client %>/index.html': [

                        [

                            '{.tmp,<%= yeoman.client %>}/assets/javascripts/*.js',

                            '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',

                            '!{.tmp,<%= yeoman.client %>}/components/base/base.framework.js',

                            '!{.tmp,<%= yeoman.client %>}/components/app/app.framework.js',

                            '!{.tmp,<%= yeoman.client %>}/app/app.js',

                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js',

                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js']

                    ]

                }

            },


  모듈 리팩토링 준비가 되었다. 리팩토링할 대상을 선정한다. generator-angular-fullstack으로 애플리케이션을 생성하면 client/app/app.js 파일이 메인 파일이 된다. 먼저 app.js안에 애플리케이션 모듈 set과 config, run에 다양한 설정이 되어 있다면 이들을 base.framework 또는 app.framework으로 분리할 수 있는지 점검한다. 일반적으로 다음과 같은 상태로 app.js를 설정하고 한다. 





  위와 같이 app.js 한 곳에 다양한 설정들이 있는 것을 리팩토링을 통해 모듈단위로 나눌것이다. 이렇게 할 수 있는 것은 메인 모듈이 의존하는 모듈을 설정하면서 의존모듈을 로딩하면서 의존모듈의 config, run을 수행해 주고 그리고 자신의 모듈을 로딩하기 때문이다. app.js안에 app.framework과 base.framework 모듈의 의존관계를 설정하고 로그를 찍어보자. 먼저 의존관계의 모듈 config와 최종 애플리케이션 모듈인 jandiApp config를 로딩한 후 run을 다시 의존 모듈부터 수행시킨다. 즉, 애플리케이션을 최초 호출할 때 config, run 은 최초 한번 수행됨을 이용해서 각 기능의 초기화를 모듈단위로 나누는 것이다. 

// app.js 의존관계 설정 

angular.module('jandiApp', [

    'base.framework',

    'app.framework',

    ... 중략 ...]);


// config, run의 수행 순서 로그 

=========> Base framework Module config

=========> App framework Module config

=========> jandiApp Module config

=========> Base framework Module run

=========> App framework Module run

=========> jandiApp Module run




2. Config 모듈 생성 


 최초 환경 설정 부분을 모듈로 만들어서 app.framework 모듈에 의존성을 설정해 보자. app.js의 run 메소드에는 api 버전과 서버주소에 대한 기본 환경 설정이 있다. 이것을 config.js라는 별도의 모듈로 빼서 환경설정에 대한 부분을 독립시킨다. 

  - config.js 모듈 파일 생성 : 최초 환경 셋업이 필요한 부분은 config 모듈의 run 메소드에 설정한다. 즉, app.js 있던것을 옮겨옴 

  - config.service.js 서비스 생성 : 해당 서비스를 통해 어디서나 주입을 받아 사용토록 한다. 

$ cd web_client/components/app

$ mkdir config && cd config


// app.js 일부내역 

app.run(function() {

$rootScope.server_address   = configuration.api_address + "inner-api/";

      $rootScope.server_uploaded  = configuration.api_address;

$rootScope.api_version      = configuration.api_version;

$rootScope.configuration    = configuration;  

});


// components/app/config/config.js 내역 

(function() {

  'use strict';


  angular

    .module('app.config', [])

    .constant('configuration', {

      name                : 'local',

      api_address         : 'http://www.jandi.com/',

      api_version         : '2',

      ga_token            : 'UA-222222-1',

      ga_token_global     : 'UA-1111111-1',

      mp_token            : 'abcdefghijklmn',

      base_url            : '.jandi.io',

      base_protocol       : 'http://',

      main_address        : 'http://www.jandi.com/main/#/',

      app_store_address   : 'xxxx',

      play_store_address  : 'yyyy'

    })

    .run(run);


  /* @ngInject */

  function run($rootScope, config) {

    // server address, server api version 

    config.init($rootScope);

  }


})();


// components/app/config/config.service.js 내역 

(function() {

  'use strict';


  angular

    .module('app.config')

    .service('config', config);

    

  /* @ngInject */

  function config(configuration) {

    var self = this;

    this.init = init; 


    function init($rootScope) {

      // TODO : maybe remove next factoring

      // compatibility for current version

      $rootScope.server_address   = configuration.api_address + "api/";

      $rootScope.server_uploaded  = configuration.api_address;

      $rootScope.api_version      = configuration.api_version;

      

      // configuration constant service       

      configuration.server_address  = configuration.api_address + "api/";

      configuration.server_uploaded = configuration.api_address;

      configuration.api_version     = configuration.api_version;


      // config service

      self.server_address  = configuration.api_address + "inner-api/";

      self.server_uploaded = configuration.api_address;

      self.api_version     = configuration.api_version; 

    }

  }

})();


  config.js 에서 app.config 모듈을 run 하면서 config.service.js 를 주입받아 최초에 init()을 하고 있다. 파라미터로 $rootScope를 전달하는데 이는 초기 app.js에서 환경값을 $rootScope에 설정해서 사용하기 때문이다. 향후에는 $rootScope를 통해 접근하는 것을 없애고 config 서비스 통해 필요한 정보를 접근토록 할 예정으로 1차로 기존 버전의 애플리케이션 수정없이 환경설정으로 뺄 수 있는 상태로 리팩토링한다. AngularJS에서 초기 설정 정보를 접근하기 위한 원칙을 다음과 같이 세우면 좋다. 


  - AngularJS의 서비스는 singleton object 이므로 초기 값을 변수로 가지고 있고 접근자 API를 노출한다. 

  - AngularJS 서비스에 $scope, $rootScope를 절대로 주입하지 않는다. 오직 controller와 module.run 에서만 주입을 받아 사용한다. 

  - 따라서 서비스는 서비스를 주입받아 공통정보에 접근해야 한다. 


원칙에 따라 하나씩 모듈로 쪼개고 app.js에는 업무적인 로직에만 집중할 수 있도록 만든다. 향후 components/app/* 모듈은 사용자가 사용하는 웹화면과 관리자가 사용하는 웹화면에 동시에 적용되는 애플리케이션과 관련된 공통 모듈이 들어갈 것이다. 현재까지 모듈의 의존관계 모습은 다음과 같이 app.js의 jandiApp 의존관계는 app.framework 밖에 없다. 하지만 서로 의존관계가 설정되어 있기 때문에 jandiApp 모듈의 AngularJS 모든 컴포넌트는 base.framework과 app.framework의 의존관계 설정 모듈의 컴포넌트를 주입받아 사용할 수 있게 된다. 

// app.js 의존관계 

angular

  .module('jandiApp', [

    'app.framework'

  ]);


// app.framework.js 의존관계

 angular

    .module('app.framework', [

        'base.framework',

        'app.config'

      ])

    .run(run)

    .config(config);


// base.framework.js 의존관계

  angular

    .module('base.framework', [

      'ui.router',

      'ui.bootstrap',

      'gettext'

      'ngCookies',

      'ngResource',

      'ngSanitize',

      'ngAnimate'

    ])


  좀 더 구조적인 관계의 모듈 설정을 통해 구조적인 애플리케이션을 개발하는 첫단추를 꽤었다. 


'My Projects > Jandi' 카테고리의 다른 글

[Jandi] 팀 커뮤니케이션 서비스  (0) 2015.01.07
posted by 윤영식
2015. 1. 7. 11:29 My Projects/Jandi

Tosslab의 잔디는 팀 그룹간에 원활한 커뮤니케이션을 위한 도구이다. 채팅 및 파일공유를 할 수 있어서 업무 커뮤케이션 툴로 사용하기에 적당하고 모바일, 웹에서 접근할 수 있다. 



잔디의 기술


  잔디는 MEAN Stack 기술을 사용하고 모바일은 네이티브로 개발한다. 업무적인 커뮤니케이션 도구는 사무실에서 웹을 통해 사용할 경우가 많아서 특히 웹에 대한 사용성이 좋아야 한다. 블로그에서는 프론트앤드 영역만을 다루도록 한다. 기존에는 AngularJS v1.2.* 기반으로 되어 있고 개발을 진행함에 따라 웹 애플리케이션의 복잡도가 증가하여서 애플리케이션을 재구성할 필요가 발생하였다. 




모듈단위 애플리케이션 구성


 애플리케이션 복잡도를 단순화 시키고 애플리케이션을 구조화하는 방안이 필요하다. 애플리케이션을 구조화 한다는 것은 거시적인 부분과 미시적인 부분의 조합으로 이루어진다. 먼저 거시적인 부분은 아키텍쳐레벨로 AngularJS의 모듈을 구성하는 것이다. 


 

  AngularJS 모듈은 컴포넌트의 그룹이다. 모듈안에는 다양한 컴포넌트를 가지고 있고 컴포넌트 성격별로 구분해 놓을 필요가 있다. 위의 예에서 가장 기본으로 있어야할 AngularJS에서 제공하는 모듈 묶음과 어느 프로젝트에서나 쓰일만한 모듈을 묶어놓은 공통 모듈이 있을 것이다. 그리고 업무적으로 추상화할 필요가 있는 업무 공통 모듈이 존재하고 업무를 처리하는 업무 모듈식으로 나눌 수 있다. 하위 모듈은 상위 모듈을 참조할 수 없고 상위 모듈만이 하위모듈안의 컴포넌트를 DI(Dependency Injection) 방식으로 사용을 할 수 있다. 




제너레이터를 통한 애플리케이션 구성


 기존의 애플리케이션을 보기하면서 다시 재구성하기 위해 무엇부터 시작을 해야할까? 


  - Yeoman Generator를 선정한다. generator-angular-fullstack을 사용할 예정이다. 

  - 자바스크립트 코딩 스타일은 구글의 자바스크립트 스타일 가이드를 따른다. 

  - AngularJS의 코딩 스타일은 존파파의 AngularJS 스타일 가이드를 따른다.


  generator-angular-fullstack의 템플릿을 존파파의 가이드에 따라 변경한 프로젝트를 만들어 본다. 불필요한 예제는 제거하고 몇가지 영역의 템플릿만을 취할 것이다. 먼저 generator-angular-fullstackgenerator-ng-component를 각각 git clone 하고 명칭을 generator-jdi, generator-jdi-component라고 바꾸고 내부의 .git폴더를 제거한 후 각 템플릿의 내용을 파파죤스 가이드에 따라서 수정을 한다. 

$ git clone https://github.com/DaftMonk/generator-angular-fullstack.git

$ git clone https://github.com/DaftMonk/generator-ng-component.git


$ mv generator-angular-fullstack generator-jdi

$ mv generator-ng-component generator-jdi-component


$ cd generator-jdi && rm -rf .git

$ cd generator-jdi-component && rm -rf .git


 파파죤스 가이드에 따라 generator-jdi-component/templates 폴더 밑의 모든 앵규러 컴포넌트를 다음과 같은 형식으로 수정한다. 

   + IIFE : Immediately Invoke Function Expression

   + 앵귤러 모듈 변수를 만들지 않음 

   + 컴포넌트의 펑션을 밖으로 뺌

   + DI 하는 부분은 ng-annotation을 이용함으로 주입받는 펑션위에 /* @ngInject */ 를 둚

(function() { 

  'use strict';


  angular

    .module('<%= scriptAppName %>')

    .controller('<%= classedName %>Ctrl', <%= classedName %>Ctrl);


  /* @ngInject */

  function <%= classedName %>Ctrl($scope) {

         

  }

})();


 수정한 내역에 대해 테스트는 다음과 같이 진행을 하면 된다.  먼저 테스트용 test 폴더를 하나 만든다. 테스트 폴더 밑에 node_modules 폴더를 만들고 밑으로 generator-jdi와 generator-jdi-component 에 대해 심볼릭 링크를 건다. 각 generator-* 폴더로 들어가 npm install을 해준다. 이제는 test밑에서 "yo jdi Jandi" 명령을 치면 애플리케이션 생성 프롬프트를 묻게 된다. 애플리케이션 템플릿은 generator-jdi/app/templates 밑에 존재하고 여기에 있는 파일도 파파죤스 스타일 가이드에 따라 수정을 해준다. 

$ mkdir test && cd test

$ mkdir node_modules && cd node_modules 


$ ln -s <fullPath>/generator-jdi  generator-jdi

$ ln -s <fullPath>/generator-jdi-component generator-jdi-component


// 둘은 같은 디렉토리에 있어야 함 

$ cd <fullPath>/generator-jdi-component && npm install

$ cd <fullPath>/generator-jdi && npm install 


$ cd test 

$ yo jdi Jandi


  각 수정한 generator-jdi, generator-jdi-component는 링크를 참조한다. 이제는 누구나 사용할 수 있도록 npm repository에 등록을 한다. npm publish 로 package.json 파일에 등록된 내역을 기반으로 배포가 된다. 따라서 clone한 generator의 버전을 따르지 않고 최초 0.0.1 버전으로 수정해 배포한다. 

$ cd generator-jdi-component 

$ npm publish

+ generator-jdi-component@0.0.1


$ cd generator-jdi

$ npm publish

+ generator-jdi@0.0.1


 이제 글로벌로 generator-jdi만을 설치해서 어디서나 "yo jdi <App명칭>" 명령을 수행해 최초 애플리케이션 골격을 만들 수 있다. 

$ npm install -g generator-jdi

$ mkdir web_tiger && cd web_tiger

$ yo jdi Jandi



'My Projects > Jandi' 카테고리의 다른 글

[Jandi] 애플리케이션 모듈 리팩토링  (0) 2015.01.21
posted by 윤영식
2015. 1. 5. 20:25 AngularJS/Concept

AngularJS v1.3에서 많은 기능들이 새롭게 추가되었지만 우선 성능에 영향을 미쳤던 부분을 해결하는 방법을 알아보자. 



양방향 데이터 바인딩 이해


  AngularJS의 특징중 양방향 데이터 바인딩은 reactive programming의 구현체라고 할 수 있다. Meteor의 Blaze, Facebook의 React도 같은 기능을 제공한다. 이들은 HTML과 JS사이에 특별한 코드의 등록없시도 HTML->JS / HTML <- JS 양방향으로 데이터 갱신이 가능하다. AngularJS에서 양뱡향 데이터 바인딩의 중요 매개체는 $scope이고 해당 객체 내부에는 데이터의 변경을 감시하는 $watch가 있는데, 모든 개별 데이터마다 $watch가 등록된다. 하기와 같이 $scope.name에 대한 expression도 watcher(감시자, 즉 $watch)가 등록된다. (예제)

<span> Hi {{name}}</span>


  name이 $scope에 속성으로 선언되어 HTML에서 사용을 하면(사용하지 않는 속성은 등록되지 않음) AngularJS는 $watch를 모두 등록하고 $scope 속성 하나라도 변경이 되면 Duty-Checking방식으로 AngluarJS Context안의 $digest 루프를 돌면서 매칭되는 $scope의 속성을 사용하는 DOM 내역을 동적으로 변경한다. 여기서 생각해 볼것은 만일 화면에 뿌려지는 $scope의 속성값이 100개이고(테이블이나 리스트 같은 경우 ng-repeat을 사용한다면) 최초 화면이 뿌려진 후 단 1개만이 사용자의 액션이나 실시간 Push를 통해 변경되는 것이어도 100의 $watch를 $digest루프를 돌며 변경을 체크하게 된다. 100개가 아니라 10만개라면 어떻게 될까? 분명 성능상에 영향을 미칠것이다. $watch, $digest에 대한 사항은 블로그를 읽어보자




Watch Expressions 성능 개선


  one-time expression은 최초 digest 루프를 한번 타고 값이 설정되면 그 다음에 다시 digest 루프를 타지 않게 해주는 것이다. 따라서 최초 동적 바인딩이 이루어진 후에는 $watch에서 제거되어 digest 루프를 타지 않도록 함으로 성능상의 이점을 누릴 수 있다. 사용방법은 간단히 $scope의 속성앞에 :: 를 하기와 같이 표기한다. (예제)

<span> Hi {{::name}}</span>


  이제 최초에 한번 데이터를 바인딩한 후에 동적 변경이 필요없는 HTML안의 AngularJS Expression들에 One-Time-Binding을 사용하자.




<참조> 


  - Explorering Angular v1.3 - One-Time-Binding

  - $watch, $digest는 무엇인가?

posted by 윤영식
2015. 1. 5. 12:32 My Projects/Bagle

베이글은 그룹 컨텐츠 공유 서비스이다. 그룹 관리자는 멀티미디어 컨텐츠 및 설문 조사를 위한 다양한 내용을 개제할 수 있고 멤버는 이에 대한 답변을 하거나 댓글은 단다. 페이스북과 유사한 UI이지만 퍼블릭 SNS가 아닌 버티컬 SNS를 지향한다. 





베이글의 탄생


  이전 StudyGPS의 서비스 v1.5를 v2.0으로 개편하면서 서비스이름을 새로 공모했고 최종적으로 베이글을 선택했다. 미국에서 프로젝트를 하면서 금요일 아침마다 먹었던 베이글이 생각나서 개발팀 이름도 MondayBread로 한 마당에 베이글이 어떠냐는 의견을 내놓았는데 잘 매칭되어 채택이 되었다. 베이글은 교육을 타케팅하는 서비스이다. 주로 선생님이 그룹을 만들고 학생이 답변을 다는 형태이다. 선생님은 학생들에게 학업과 관련한 컨텐츠를 제공하면서 이에대한 설문 조사를 수행할 수 있다. 컨텐츠는 파일 첨부, 이미지, 동영상등을 게재할 수 있고 설문형식은 주관식, 객관식등의 조사와 댓글을 통해 의견을 들을 수 있다. 


  보수적인 교육시스템에서는 자유로운 퍼블릭 SNS로 쌍방향 소통 보다는 단방향의 문제를 내는 사람과 문제를 푸는 사람을 구분하여 관심분야의 그룹을 운영할 수 있도록 하는데 목적이 있다. 




베이글의 기술


  스타트업에서 인기를 누리고 있는 MEAN (MongoDB ExpressJS AngularJS Node.js) 스택을 사용한다. 모바일은 하이브리드 앱방식으로 개발을 진행하고 이를 위한 프레임워크로 Ionic을 사용한다. 그외 Sass트위터 부트스트랩도 함께 사용한다. 하이브리드 앱 개발에서 중요한 체크 포인트는 다음과 같다. 


  1) 네이티브 UX에 근접한 경험을 줄 수 있는가?

  2) 네이티브 UI 컴포넌트와 같이 잘 정의된 레이아웃이나 컴포넌트가 있는가?

  3) HTML과 Javascript의 분리해서 네이티브처럼 개발을 진행할 수 있는가?


  1)번을 위한 약간 2주간 AppGyver를 사용해 보았으나 제약 사항이 많고 특히 MPA(Multi-Page Application)으로 WebView를 정말 Multi개만큼 생성해서 운영해야 제대로된 네이티브 기능을 사용할 수 있다. 이것의 단점은 모든 뷰가 하나의 AngularJS SPA가 되버린다는 것이다.  즉, 화면별로 WebView가 개별적으로 운영되면서 나타나는 현상이다. 하지만 steroids와 scanner 앱을 통해 편한 개발환경을 제공하고 있다. 따라서 아주 간단한 App을 만든다면 AppGyver도 쓸만한 프레임워크이자 플랫폼라 생각한다. AppGyver의 supersonic 하이브리드 프레임워크도 결국 Ionic을 내부적으로 사용하고 있고 SPA 방식으로 개발하면서 네이티브 수준의 UI와 UX를 선사하는 Ionic 프레임워크를 최종 선택하게 되었다. 올해(2015)초에는 정식 v1.0이 릴리즈 될 예정이고 ionic 내부에 angular, angular-sanitize, angular-animation, ui-router를 의존관계로 가지고 있고 AngluarJS v1.3.6 최신버전을 사용하고 있다. 


 2)번은 Sass로 일정부분 디자인을 하고 트위터 부트스트랩과 같은 UI 프레임워크를 사용하면 되고 3)번은 reactive programming을 할 수 있는 AngularJS의 양방향 데이터 바인딩을 사용하면 HTML과 JS파일을 분리해 개발을 할 수 있다.  


앞으로 개발하면서 느꼈던 점과 기술적인 이슈등을 회고식으로 적어볼 예정이다. 


  

posted by 윤영식
2015. 1. 3. 19:25 Angular/Prototyping

구글 폴리머기반으로 자신만의 Web Components 를 만들어 보자. 아주 초간단 웹 컴포넌트이지만 기반 컴포넌트를 설치하고 어떻게 구동되는지 손으로 익혀본다. 




설치하기 


  - 폴러머를 시작하기 위해 zip파일을 받을 수 있지만 클라이언트 컴포넌트 의존관리 툴이 바우어(Bower)를 사용한다. 

     바우어는 노드(Node.js)기반위에 돌ㄹ아가기 때문에 노드를 설치하고 바우어도 설치한다. 

  - 바우어를 통해 프로젝트를 초기화 해보자. bower init 후에 그냥 끝날 때가지 엔터를 친다. bower.json 환경파일이 생성된다. 

$ mkdir tutorial && cd tutorial

$ bower init 


  - 폴리머를 설치한다. polymer.js 는 Web Components를 지원하기 위한 polyfill 파일인 webcomponents.js 파일도 포함한다. 

    + polyfill은 Web Components 스팩을 지원하지 않는 브라우져에서도 Web Components를 사용할 수 있도록 해주는 파일이다. 

       따라서 과거 브라우져는 webcomponents.js (과거는 platform.js였음) 파일을 추가해야 한다. 

     + Chrome 36+ 이상 버전은 Web Components 스팩이 구현되어 있기 때문에 polyfill 파일이 필요없다. 

$ bower install --save Polymer/polymer




처음 만들어 보는 웹 컴포넌트 


  - 웹컴포넌트를 만든 후 html안에서 사용한다. 

  - 먼저 폴리머 웹 컴포넌트를 정의한다. 

    + 폴리머 엘러먼트를 사용하기 위해 polymer.html을 추가한다. 

    + 사용자 정의 웹컴포넌트 이름은 hi-dowon이다. 구분은 "-" 을 꼭 사용한다. 

    + html에서 사용할 때 public으로 노출 시킬 attribute로 name을 지정한다. 

    + <template>와 <script>에서 상호 작용한다. 스크립트 태그에 지정한 값이 template 쪽으로 {{}} 사용해 양방향 바인딩 된다. 

tutorial> mkdir elements && cd elements

tutorial/elements> vi hi-dowon.html 


// hi-dowon.html 내용 

<link rel="import" href="../bower_components/polymer/polymer.html">


<polymer-element name="hi-dowon" attributes="name">

  <template>

    <span> This is <b>hi-<span style="color: {{color}}">{{owner}}</span></b> tag <br>

    <span> And hi {{name}}</span><br>

    <input id="message" value="{{name}}">

    <button on-click="{{setFocus}}">Set Focus in name input</button>

  </template>

  <script>

    Polymer({

      owner: 'Dowon',

      color: 'red',

      name: 'youngsik',

      setFocus: function() {

        this.$.message.focus();

      }

    })

  </script>

</polymer-element>


  - 이제 elements/hi-dowon.html 파일을 사용하는 index.html 파일을 작성한다. 

    + 웹 컴포넌트는 HTML imported를 통해 사용하고자 하는 웹컴포넌트를 조합(Composition)해 확장(Scale-out)하는 방식이다. 

    + 모던 브라우져가 아닌 구버전의 브라우져에서 웹컴포넌트 스펙지원을 위해 polyfill파일인 webcomponents.js 파일추가한다. 

       Chrome 36+ 이상 버전은 polyfill 설정이 필요없다. 

<!DOCTYPE html>

<html>

    <head>

        <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>

        <link rel="import" href="./elements/hi-dowon.html">

    </head>

    <body>

        <hi-dowon name="ok"></hi-dowon>

    </body>

</html>


  - 결과 수행

    + 파이썬의 심플 서버를 뛰어서 호출해 본다. 

tutorial> python -m SimpleHTTPServer 8000


// 결과 화면 : 버튼을 클릭하면 포커스이동 


  - 폴리머의 레이어는 3계층으로 나뉜다 

    1) Web Components : Web Components 스팩을 지원하지 않는 브라우져를 위한 web components polyfill 레이어 

    2) Polymer 라이브러리 : 사용자 정의 엘러먼트(Custom element)를 위한 선언적 신택스를 제공

    3) Elements :Core 와 Paper element와 같이 기정의된 웹 컴포넌트 제공. 




1. Polymer에서 Custom Elements


  - Custom Element is True Element. 사용자 정의 엘러먼트를 사용하는 이유를 보자.

  • Reduce the amount of code you have to write. : 누군가 만들어 놓은 엘러먼트가 있다면 Don't invent한다. 
  • Express the function of the code. : 
  • Encapsulate internal details. : 코드 내부를 캡슐화 할 수 있다 
  • Implement APIs per element type. : 엘러먼트별 API가 있고 애트리뷰트로 접근한다. 
  • Increase productivity by letting you reuse elements. : 엘러먼트를 조합해서 생산성을 높일 수 있다. 
  • Use inheritance to create element tags based on other tags. : extends 키워들 통해 custom element를 확장할 수 잇다


  - 웹 컴포넌트의 Custom Element는 다음과 같이 작성을 해야하지만 폴리머를 쓰면 단순히 <polymer-element> 태그를 사용하면 끝!

    + Customer Element 명칭을 지을 땐 반드시 "-"이 있어야 한다. (polymer element 선언 참조)

// 코딩 

var myTag = document.registerElement('my-tag');


// 선언적 태깅 

<polymer-element name="my-tag">

  <template> 

    <div> hello dowon </div> 

  </template>

  <script>

     Polmer();

  </script>

</polymer-element>


  - extends 키워드를 통해 기존 엘러먼트를 확장할수 있고, 부모의 메소드와 속성을 자식 엘러먼트가 상속받는다. 

    또한 오버라이딩도 가능한다. 

  - 엘러먼트 종류로 UI 렌더링되는 엘러먼트와 No-UI 엘러먼트를 만들 수 있다. 예로 <core-ajax>은 XHR 요청을 마크업으로 할 수 있게 한다. 

<core-ajax url="http://gdata.youtube.com/feeds/api/videos/" auto params='{"alt":"json", "q":"chrome"}' handleAs="json"></core-ajax>

<script>

  var ajax = document.querySelector('core-ajax');

  ajax.addEventListener('core-response', function(e) {

    console.log(this.response);

  });

</script>




2. Polymer에서 Shadow DOM


  - 프로그램적으로 Shadow DOM을 하려면 createShadowRoot를 넣어야 하지만 Polymer에서는 <template> 태그를 사용한다. 

    + <span> <content> <footer>는 다른 커스텀 엘러먼트안에 있을 때 완전 캡슐화되어 숨겨진다는 것을 명심하자. 

<polymer-element name="my-custom-element" noscript>

  <template>

    <span>People say: </span>

      <content select="qq"></content> 

    <footer>sometimes</footer>

  </template>

</polymer-element>

  

  - DOM은 3가지가 있다. Light DOM, Shadow DOM, Composed DOM

     + Light DOM : 하기와 같이 my-custom-element 안에 <qq> Hi dowon </qq>로 포함된 DOM 이다. innerHTML로 접근이 가능하다.  

<my-custom-element>

  <qq> Hi dowon </qq>

</my-custom-element>


    + Shadow DOM : <polymer-element> 태그 안에 <template> ... </template> 태그안에 정의된 DOM 이다. 

       DevTools에서는 #docuement-fragment로 표기되고 사용자에게 숨겨져있고, <my-custom-element> 자식노드로 접근이 안된다. 


    + Composed (rendered) DOM : 실제 브라우져에 렌더링되는 DOM 이다. 

       light DOM이 shadow DOM에 포함되어 조합된 DOM이 보여진다. (이것은 마치 AngluarJS의 Directive에서 transclude와 유사하다)

<my-custom-element>

  <span>People say: <qq>Hi dowon</qq></span>

  <footer>sometimes</footer>

</my-custom-element>




3. Polymer에서 HTML imports 


  - <link> 태그를 사용해 HTML 도큐먼트를 재사용하면 된다. 

<link rel="import" href="my-custom-element.html">




4. Polymer에서 Web Animations


  - Web Animation 관련한 CSS Transitions, CSS Animations, SVG Animations /SMIL 스팩이 있다. 

    + 구현체

    + 아직은 복잡한 것을 표현하기에 부족함이 존재

  - 애니메이션 cost를 줄이고, animation 스팩끼리 상호작용할 수 있고, 스팩 작성자나 브라우져 벤더가 한 곳에서 사용할 수 있게하자.

  - Web Animations 모델은 웹에 애니메이션 컨텐트를 엔진에 묘사하는 것이다. 

     엔진은 CSS Transitions, CSS Animations, SVG Animations 를 지원한다. 

    + 자바스크립트 API를 통해 애니메이션을 정의 

    + Animation 오브젝트를 사용 그외 AnimationEffect, AnimationGroup, AnimationSequence 오브젝트를 사용한다. 




5. Polyfill로서 Web Components


  - web components 기술이 모든 브라우져에 구현되어 있지 않기 때문에 webcomponents.js polyfill 파일이 필요함 

  - webcomponents.js 는 다음의 라이브러리를 포함하고 있다. 

  • Web Components:

  • Dependencies required by the Web Components polyfills:


  - 설치는 바우어로 하고 웹 컴포넌트를 사용하려는 HTML에 <script> 태그로 포함시킨다. 

$ bower install --save webcomponentsjs


// html

<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>




<참조> 

  

  - Polymer 10 minutes

  - Understanding web components

  - 구글 폴리머 튜토리얼


posted by 윤영식
2015. 1. 3. 11:04 AI Deep Learning

그룹(그룹핑)에서 데이터 클러스터링(군집화)에 대해 알아본다. 



01. 군집발견 (Discover Clustering)


  - supervised learning : 신경망, 결정트리, svm, 베이지안 필터링

  - unsupervised learning : 군집은 올바른 답을 찾는 것이 아니라 데이터 집합 내에서 구조를 발견하는 것이다. 

    + NMF : non-nagative matrix factorization (ch10.)

    + SOM : self-organization maps

  - Clustering & Classification 차이? 

  


02. 단어 벡터 


  - 군집용 데이터를 준비하는 일반적인 방법은 항목 비교에 사용될 숫자 특성들의 공통집합을 결정하는 것이다. 

  - 블로거 군집화 : 피드안에 출현한 특정 단어들의 횟수 (피드 다운로드 -> 글에서 텍스트 추출 -> 빈도수를 표로 만든다)

    + universal feed parser를 통해 제목, 링크, 게시글을 추출가능 -> 빈도수 최대~최소 사이 단어추출 -> 데이터 세트 파일로 저장

  


03. 계층적 군집화 


  - 유사한 두 그룹을 계속 병합한다 (병합의 조건은?)

    + 노드들을 계층별로 배치한 계통도(dendrogram:덴드로그램)를 얻는다.

    + 덴드그램을 통해 어떤 항목들이 군집의 끝단에 있는지 확인가능 및 항목간의 떨어진 거리도 알수 있음 

 - 거리는 피어슨 계수를 통해 1.0이면 두항목은 완전 일치이고 0.0에 가까우면 전혀 관계가 없음

 - 새로운 군집용 데이터는 앞의 두 군집들에 대한 데이터의 평균값이다. 단 한개의 군집만 남을 때까지 반복 수행함



04. 계통도 출력 


  - 군집들을 계통도 형태로 그려보면 해석이 훨씬 편리하다. 

 



<참조>


  - unsupervised learning  위키 

  - Clustering in R

  - Decision Tree (결정 트리)

  - K means : 러닝커브를 통해 k 개까지의 군집화를 수행하는 방법. 이전은 1또는0, yes또는no로만 해서 K 개까지 돌림

'AI Deep Learning' 카테고리의 다른 글

[ML] 7주차 - 6장 문서 필터링  (0) 2015.02.07
[ML] 6주차 - 5장 최적화  (0) 2015.01.31
[ML] 3주차 - 추천하기  (0) 2014.12.13
[ML] 2주차 - 추천하기  (0) 2014.12.06
[ML] 1주차 - 시작하기  (0) 2014.11.22
posted by 윤영식

구글은 테스트를 어떻게 하는가라는 책에서 SET(Software Engineer in Test)가 프로토콜 버퍼를 기반으로 개발하는 서비스가 외부의 서비스와 연계를 위한 투명성을 확보하고 프로토콜 버퍼의 데이터 스팩에 기반해 통합 테스트를 위해 Mock, Fake를 작성한다는 이야기가 나온다. xUnitPattern 사이트를 보면 Test Double에 대한 내용이 나온다. 이것은 테스트하려는 시스템(SUT) 즉 개발하는 서비스에서 단위 테스트를 하려 할 때 실제 의존하는 컴포넌트 (Depended-on Component, DOC)를 사용할 수 없으면 Test Double로 교체해서 테스트를 할 수 있다. Mock, Fake, Stub등이 하기 그림과 같이 Test Double 박스에 위치한다. 그래서 Mock, Fake, Stub등은 Test Double에 속한다. 







Mock Object 


  - 위키피디아에서 Mock Object에 대한 정의

    + 목 오브젝트는 실제 오브젝트의 행위를 흉내낸(simulated) 오브젝트이다. 

    + 주로 어떤 오브젝트의 행위를 테스트하기위해 만든다

    + 실제 오브젝트의 인터페이스를 사용한다. 

    + 예외(exception)나 행(hang)을 일으켜 외부시스템과 연계시 일어날 수 있는 오류를 테스트 할 수 있다. 

    + TDD(Test-Driven Developmen)에서 목 오브젝트를 사용해 단위 테스트(Unit Test)를 수행해 개발자가 SUT(System Under Test)

       하에서 다른 의존관계 라이브러리없이 기대되는 행위 테스트에 집중토록 한다. 

    + 외부연계로 데이터베이스, 웹서비스, 다른 서비스 연계등에 대해 SoC(Separation of Concerns)을 통해 해결토록 도와준다. 

       앵귤러는 module 개념으로 복잡한 웹 개발환경을 확장가능하게 만들어 주고있다. 

       이런 외부 연계에 관여하는 오브젝트를 목 오브젝트로 만들어 테스트에 집중토록 한다. 

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts.


 - xUnit Pattern 의 Mock Object 

   + 목 오브젝트는 행위를 검증하는데 좋다 (Behavior Verification)

   + 그림에서 DOC (Depended-on Component)를 대신해서 Mock Object를 사용


    


  - 스택오버플로우

    + Stub : 미리 정의된 답을 제공하는 메소드를 가진 오브젝트 

    + Mock : 받기를 기대하는 호출스팩을 미리 프로그램한 오브젝트  

    + Fake : 제한된 능력을 가진 오브젝트 

    + Martin Fowler 이야기 : Mocks Aren't Stubs

Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production


Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.


Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.





Fake Object 


  - 스택오버플로우 

    + 고정된 데이터와 로직도 없는 인터페이스를 구현한 클래스 

Fake: a class that implements an interface but contains fixed data and no logic. Simply returns "good" or "bad" data depending on the implementation.


Mock: a class that implements an interface and allows the ability to dynamically set the values to return/exceptions to throw from particular methods and provides the ability to check if particular methods have been called/not called.


Stub: Like a mock class, except that it doesn't provide the ability to verify that methods have been called/not called.


  - xUnitPattern의 Fake Object


    


   * stub, spy에 대해서는 xUnitPattern 사이트 참조하자. 실제 예제를 앵귤러로 넣어 보면 좋겠다. 




<참조> 


  - Test Double 위키피이다

  - Test Double Pattern




'Computer Engineering > Want to Know Terms' 카테고리의 다른 글

[Terms] Syntactic sugar  (0) 2015.01.01
posted by 윤영식