2016년 4월 27일 수요일

[GitHub] Hello World 가이드

회사에서는 GitLab에 SourceTree 사용하느라 Github는 사용해본지 오래 되었다.
오랜만에 사용하는거니 가이드를 읽어보자.

https://guides.github.com/activities/hello-world/
=========================================================





Step 1. Create a Repository

(리파지토리 생성)

개발자가 아니어도 이해하기 좋게 리파지토리 개념 설명이 적혀있다.

리파지토리를 생성하려면

1. 우상단 + 누르고 'New repository' 클릭
2. 이름은 hello-world
3. 설명은 적당히
4. 'Initialize this repository with a README' 체크
(Repository 초기화 + README 파일 생성)
> 생성 버튼 클릭
new-repo-form





Step 2. Create a Branch

(브랜치 생성)

브랜치 관련한 설명이 이어진다. git 공통 내용이라 개발자라면 익숙하다.

브랜치를 생성하려면

1. 생성한 hello-world 프로젝트로 이동
2. [branch: master] 써있는 부분을 클릭한다.
3. 브랜치 이름은 readme-edits 라고 쓰고
4. [Create branch] 를 클릭하거나 엔터키를 누른다.
branch gif

이제 master 와 readme-edits 두 개의 브랜치가 있다.





Step 3. Make and commit changes

(커밋)

변경사항을 만들고 커밋하려면

1. 'README.md' 파일 클릭
2. 우상단 연필 아이콘 클릭
3. 에디터에 적당히 기입
4. 커밋 메시지에 변경 사항을 설명
5. [Commit changes] 버튼 클릭
commit

readme-edits 브랜치에 변경사항이 생겨서 master 브랜치와 차이가 생겼다.





Step 4. Open a Pull Request


풀 리퀘스트를 오픈하면, 너의 수정사항을 제안하고, 누군가가 그걸 검토하고 그들의 브랜치에 머지하도록 요청하게 된다.
풀 리퀘스트는 추가사항 녹색, 제거사항 빨간색 으로 각 브랜치의 차이를 보여준다.

본인 소유의 리파지토리에도 풀 리퀘스트를 오픈할 수 있다. 큰 프로젝트에서 작업하기 전 GitHub 흐름을 익히는데 좋은 방법이다.


1. Pull Request 탭을 클릭하고 [New pull request] 버튼을 클릭
pr-tab

2. 베이스와 비교대상을 선택
branch

3. 비교 페이지에서 차이점을 볼 수 있다.
diff

4. 전송하려면 [Create Pull Request] 버튼을 클릭
create-pull

5. 풀 리퀘스트의 제목과 설명을 작성
pr-form

6. Create pull request 클릭




Step 5. Merge your Pull Request

(풀 리퀘스트 머지)

1. [Merge pull request] 버튼 클릭
2. [Confirm merge]을 클릭하면 머지가 완료된다.
3. [Delete branch] 버튼을 클릭하면 readme-edits 브랜치가 제거된다.
merge
delete




Hello World 완료!



2016년 4월 19일 화요일

[JSP EL] JSP 문자 비교시 예외 발생 / jsp test char exception

- jsp test char exception
- javax.servlet.jsp.el.ELException: An exception occurred trying to convert String "x" to type "java.lang.Long"




<c:when test="${value eq 'x'}">

JSP에서 위와 같은 단순한 비교문을 사용했는데, 아래와 같은 예외가 발생헀다


javax.servlet.jsp.el.ELException: An exception occurred trying to convert String "x" to type "java.lang.Long"


찾아보니 Expression Language Specification 2.2에 char를 Long으로 비교한다고 명시 되어있다.
(1.8.1 단락 / 13 페이지)

=================================================
1.8.1 A {<,>,<=,>=,lt,gt,le,ge} B
■ If A==B, if operator is <=, le, >=, or ge return true.
■ If A is null or B is null, return false
■ If A or B is BigDecimal, coerce both A and B to BigDecimal and use the return
value of A.compareTo(B).
■ If A or B is Float or Double coerce both A and B to Double apply operator
■ If A or B is BigInteger, coerce both A and B to BigInteger and use the return
value of A.compareTo(B).
Chapter 1 Language Syntax and Semantics 13
■ If A or B is Byte, Short, Character, Integer, or Long coerce both A and B to
Long and apply operator
■ If A or B is String coerce both A and B to String, compare lexically
■ If A is Comparable, then:
■ If A.compareTo(B) throws exception, error.
■ Otherwise use result of A.compareTo(B)
■ If B is Comparable, then:
■ If B.compareTo(A) throws exception, error.
■ Otherwise use result of B.compareTo(A)
■ Otherwise, error
=================================================




해결 방법은 아래와 같이 .charAt(0) 부분을 추가해주면 된다

<c:when test="${value eq 'x'.charAt(0)}">






참고 :
http://download.oracle.com/otn-pub/jcp/expression_language-2.2-mrel-eval-oth-JSpec/expression_language-2_2-mrel-spec.pdf
http://www.coderanch.com/t/569524/JSP/java/Issues-Character-comparison-JSTL

2016년 4월 6일 수요일

[Python] Openpyxl를 이용한 엑셀 읽기

Excel Data read



라이브러리 설치
0. pip가 설치되어있지 않다면 먼저 설치
$ sudo easy_install pip

1. pip를 이용해서 openpyxl 라이브러리 설치
$ sudo pip install openpyxl



2. 기본 활용
>>> from openpyxl import load_workbook
>>> wb = load_workbook(filename = 'empty_book.xlsx')
>>> sheet_ranges = wb['range names']
>>> print(sheet_ranges['D18'].value)
3




2016년 4월 5일 화요일

[Python] urllib2 Library MultiPartForm class

로컬에서 MultiPartForm 전송


import itertools
import mimetools
import mimetypes
from cStringIO import StringIO
import urllib
import urllib2

class MultiPartForm(object):
    """Accumulate the data to be used when posting a form."""

    def __init__(self):
        self.form_fields = []
        self.files = []
        self.boundary = mimetools.choose_boundary()
        return
    
    def get_content_type(self):
        return 'multipart/form-data; boundary=%s' % self.boundary

    def add_field(self, name, value):
        """Add a simple field to the form data."""
        self.form_fields.append((name, value))
        return

    def add_file(self, fieldname, filename, fileHandle, mimetype=None):
        """Add a file to be uploaded."""
        body = fileHandle.read()
        if mimetype is None:
            mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
        self.files.append((fieldname, filename, mimetype, body))
        return
    
    def __str__(self):
        """Return a string representing the form data, including attached files."""
        # Build a list of lists, each containing "lines" of the
        # request.  Each part is separated by a boundary string.
        # Once the list is built, return a string where each
        # line is separated by '\r\n'.  
        parts = []
        part_boundary = '--' + self.boundary
        
        # Add the form fields
        parts.extend(
            [ part_boundary,
              'Content-Disposition: form-data; name="%s"' % name,
              '',
              value,
            ]
            for name, value in self.form_fields
            )
        
        # Add the files to upload
        parts.extend(
            [ part_boundary,
              'Content-Disposition: file; name="%s"; filename="%s"' % \
                 (field_name, filename),
              'Content-Type: %s' % content_type,
              '',
              body,
            ]
            for field_name, filename, content_type, body in self.files
            )
        
        # Flatten the list and add closing boundary marker,
        # then return CR+LF separated data
        flattened = list(itertools.chain(*parts))
        flattened.append('--' + self.boundary + '--')
        flattened.append('')
        return '\r\n'.join(flattened)

if __name__ == '__main__':
    # Create the form with simple fields
    form = MultiPartForm()
    form.add_field('firstname', 'Doug')
    form.add_field('lastname', 'Hellmann')
    
    # Add a fake file
    form.add_file('biography', 'bio.txt', 
                  fileHandle=StringIO('Python developer and blogger.'))

    # Build the request
    request = urllib2.Request('http://localhost:8080/')
    request.add_header('User-agent', 'PyMOTW (http://www.doughellmann.com/PyMOTW/)')
    body = str(form)
    request.add_header('Content-type', form.get_content_type())
    request.add_header('Content-length', len(body))
    request.add_data(body)

    print
    print 'OUTGOING DATA:'
    print request.get_data()

    print
    print 'SERVER RESPONSE:'
    print urllib2.urlopen(request).read()


참고:
https://pymotw.com/2/urllib2/


[Python] 한글 처리중 에러 (UnicodeEncodeError: 'ascii' codec can't encode characters in position ....)

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)



문서 상단에 선언시 해결 가능

import sys
reload(sys)
sys.setdefaultencoding('utf-8')


사용하면 위험하다는 의견과 무방하다는 의견이 분분하긴 한데 테스트 결과 문제는 없었다.



참고 :
http://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script




[Python] utf-8 선언

SyntaxError: Non-ASCII character ......  but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details


최상단에 해당 문서의 인코딩을 선언하면 된다.
#-*- coding: utf-8 -*-