생활코딩 git 04 - git branch (정보확인)

|

생활코딩-git 수업을 듣고 중요 내용을 정리합니다.

브랜치 간에 비교할 때

git log "비교할 브랜치 명 1".."비교할 브랜치 명 2"

브랜치 간의 코드를 비교 할 때

git diff "비교할 브랜치 명 1".."비교할 브랜치 명 2"

로그에 모든 브랜치를 표시하고, 그래프로 표현하고, 브랜치 명을 표시

❯ git log --branches --graph --decorate


* commit 2e6daddeda998647a6551617285a1d3b2799723c (HEAD -> master)
| Author: siwabada <siwabada@gmail.com>
| Date:   Tue Apr 4 10:33:01 2017 +0900
|
|     7
|
| * commit 7ba6cb1d4ca6e6e6b2f666875bf02a1503711619 (exp)
| | Author: siwabada <siwabada@gmail.com>
| | Date:   Tue Apr 4 10:15:34 2017 +0900
| |
| |     6
| |
| * commit 019d8ce8fd45225dce5bef97545d7c3438386191
| | Author: siwabada <siwabada@gmail.com>
| | Date:   Tue Apr 4 10:11:11 2017 +0900
| |
| |     5
| |
| * commit d239731ceded9102c7d32fec25862939e38ac31e
| | Author: siwabada <siwabada@gmail.com>
| | Date:   Tue Apr 4 10:05:40 2017 +0900
| |
| |     4
| |
| * commit 410316d2203b296ab96a5bc035cda60e89332c18
|/  Author: siwabada <siwabada@gmail.com>
|   Date:   Tue Apr 4 10:03:47 2017 +0900
|
|       3
|
* commit db667dd20e77f7896e01b45a8e5672f9308f3e9e
| Author: siwabada <siwabada@gmail.com>
| Date:   Tue Apr 4 09:51:35 2017 +0900
|
|     2
|
* commit 932645b6dc8e4e0d23543b2e94cbf1dd5a34ecb2
  Author: siwabada <siwabada@gmail.com>
  Date:   Tue Apr 4 09:51:09 2017 +0900

      1
  • --oneline 옵션을 통해 한줄로 표시
❯ git log --branches --graph --decorate --oneline

* 2e6dadd (HEAD -> master) 7
| * 7ba6cb1 (exp) 6
| * 019d8ce 5
| * d239731 4
| * 410316d 3
|/
* db667dd 2
* 932645b 1

zsh, bash 단축키

|

zsh에서 ipython 등을 실행하여 간단하게 코드를 작성하는 경우가 많다.
그때마다 줄 전체를 삭제 한다던지 줄의 맨 앞으로 이동 하는 등의 간단한 동작도 원하는 대로 잘 되지 않아서 불편했었다. 검색해보니 bash, zsh에도 편리하게 명령어를 편집할 수 있도록 shortcut이 존재한다는 것을 알았다.
Shortcuts to improve your bash & zsh productivity

자주 사용하는 명령어

shorcut Action
CTRL + A 라인 맨 앞으로 이동
CTRL + E (end-of-line) 라인 맨 끝으로 이동
CTRL + 좌우방향키 단어 단위로 이동
CTRL + U 라인 전체 삭제 (라인시작~커서위치)
CTRL + K ( kill-line) 라인 전체 삭제 (커서위치~라인 끝)
CTRL + W 커서 앞 단어 삭제
CTRL + R 이력 검색 (CTRL + G : 종료)
CTRL + _ 실행취소

모든 검색어 보기

  • zsh에서 bindkey 명령을 통해 사용할 수 있는 단축키 리스트를 확인할 수 있다.
❯ bindkey
"^@" set-mark-command
"^A" beginning-of-line
"^B" backward-char
"^D" delete-char-or-list
"^E" end-of-line
"^F" forward-char
"^G" send-break
"^H" backward-delete-char
"^I" fzf-completion
"^J" accept-line
"^K" kill-line
"^L" clear-screen
...
...
...

강의노트 04. 파이썬 pickle 모듈

|

패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 중요한 내용을 정리했습니다. 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.

pickle 모듈

  • 일반 텍스트를 파일로 저장할 때는 파일 입출력을 이용한다.
  • 하지만 리스트나 클래스같은 텍스트가 아닌 자료형은 일반적인 파일 입출력 방법으로는 데이터를 저장하거나 불러올 수 없다.
  • 파이썬에서는 이와 같은 텍스트 이외의 자료형을 파일로 저장하기 위하여 pickle이라는 모듈을 제공한다.

일반적인 방법으로 데이터 입력

# 파일에 텍스트 입력하기
>>>text = "hello world"

>>> with open('hello.txt', 'w') as f:
        f.write(text)

>>> cat hello.txt
hello world

# 파일에 리스트 입력하기  > TypeError 발생
>>> list = ['a', 'b', 'c']
>>> with open('list.txt', 'w') as f:
...     f.write(list)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: write() argument must be str, not list

pickle 모듈을 활용하여 데이터 입력 및 로드

  • import pickle 을 통하여 모듈 임포트가 필요하다.
  • pickle 모듈을 이용하면 원하는 데이터를 자료형의 변경없이 파일로 저장하여 그대로 로드할 수 있다.
    (open(‘text.txt’, ‘w’) 방식으로 데이터를 입력하면 string 자료형으로 저장된다.)
  • pickle로 데이터를 저장하거나 불러올때는 파일을 바이트형식으로 읽거나 써야한다. (wb, rb)
  • wb로 데이터를 입력하는 경우는 .bin 확장자를 사용하는게 좋다.
  • 모든 파이썬 데이터 객체를 저장하고 읽을 수 있다.

입력

  • pickle.dump(data, file)
>>> import pickle
>>> list = ['a', 'b', 'c']
>>> with open('list.txt', 'wb') as f:
...     pickle.dump(list, f)

로드

  • 변수 = pickle.load(file)
  • 한줄씩 파일을 읽어오고 더이상 로드할 데이터가 없으면 EOFError 발생
>>> with open('list.txt', 'rb') as f:
...     data = pickle.load(f) # 단 한줄씩 읽어옴

>>> data
['a', 'b', 'c']

참고

  • pickle.load(파일) 을 통해서 파일 내용을 읽어오려면, pickle.dump를 사용해서 데이터를 입력한 파일이어야한다.
# vim으로 작성한 abc.txt 파일
 cat abc.txt
{'greg': 95},
{'john': 25},
{'yang': 50},
{'timothy': 15},
{'melisa': 100},
{'thor': 10},
{'elen': 25},
{'mark': 80},
{'steve': 95},
{'anna': 20}%

# pickle.dump()를 사용하여 해당 내용을 abc2.bin 파일에 입력
# abc2.txt 와 같이 txt 파일에 wb 형식으로 데이터를 입력하면 다른 메타정보도 함께 입력

In [5]: with open('abc2.bin', 'wb') as file:
   ...:     for data in text_list:
   ...:         pickle.dump(data, file)

# pickle.load()를 사용하여 파일 로드
# 데이터를 한 줄 밖에 읽어오지 못함

In [6]: with open('abc2.bin', 'rb') as file:
   ...:     data = pickle.load(file)
   ...:

In [7]: data
Out[7]: "{'greg': 95},\n"

# pickle.load()를 사용하여 파일 전체 내용 로드
In [8]: with open('abc2.bin', 'rb') as file:
   ...:     data_list = []
   ...:     while True:
   ...:         try:
   ...:             data = pickle.load(file)
   ...:         except EOFError:
   ...:             break
   ...:         data_list.append(data)
   ...:

In [9]: data_list
Out[9]:
["{'greg': 95},\n",
 "{'john': 25},\n",
 "{'yang': 50},\n",
 "{'timothy': 15},\n",
 "{'melisa': 100},\n",
 "{'thor': 10},\n",
 "{'elen': 25},\n",
 "{'mark': 80},\n",
 "{'steve': 95},\n",
 "{'anna': 20}"]

170404_TIL

|

오늘 할 일 (계획)

  • 생활코딩 git branch 수업 듣기
  • 패스트캠퍼스 컴퓨터공학 입문 수업 듣기
  • AskDjango 수업 듣기
  • jekyll 블로그 pagination 방법 찾아보기 참고

오늘 한 일 (회고)

  • 생활코딩 git branch 수업을 들었다.
    • branch를 만들고 새로운 파일을 add commit 했더니 기존의 master branch 에서 해당 파일이 사라지는걸 finder에서 직접 할 수 있었다.
    • 나중에 팀으로 협업을 할 때 유용하게 쓰일 수 있으니 잘 배워둬야겠다.
  • 패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 강의노트를 정리했다.
    • pickle 모듈을 통해서 원하는 자료형으로 데이터를 입력하고 로드하는 방법에 대해서 배웠다.
    • 절차지향 프로그래밍 방식에 대해서 경험했다.
    • class의 개념에 대해서 배웠다. class의 멤버를 수정하려면 꼭 class의 메소드를 통해서 접근해야 한다는 점이 인상 깊었다. (참고로 다른 언어는 정보은닉을 통해서 직접 멤버에 직접 접근이 불가능하다는 점도 배웠다.)
  • AskDjango
    • static files
    • Media files
  • 공부한 내용을 정리하려고 만든 블로그인데 그래도 들어와서 봐주는 사람이 조금씩 늘어나고 있는게 신기하다.

내일 할 일

  • 컴퓨터공학 입문 강의노트 정리 마무리 하기
  • 생활코딩 git branch 수업 듣기
  • 패스트캠퍼스 컴퓨터공학 입문 수업 듣기
  • AskDjango 수업 듣기

강의노트 03. 파이썬 lambda, map, filter, reduce, dic

|

패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 중요한 내용을 정리했습니다. 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


lambda 함수

  • 익명함수 : 메모리를 아끼고 가독성을 향상시킨다. pythonic
  • 일반적인 함수는 객체를 만들고, 재사용을 위해 함수 이름(메모리)를 할당한다.
# lambda 인수1, 인수2, ... : 인수를 이용한 표현식
>>> sum = lambda a, b: a+b
>>> sum(3,4)
7

lambda는 왜 쓰는가?

  • 익명함수이기 때문에 한번 쓰이고 다음줄로 넘어가면 힙(heap) 메모리 영역에서 증발
  • (참고) 가비지 컬렉터 (참조하는 객체가 없으면 지워버린다)
    • 파이썬에서는 모든것이 객체로 관리 되고 각 객체들은 레퍼런스 카운터를 갖게 된다. 이 카운터가 0 즉, 그 누구도 참조하지 않게 된다면 메모리를 환원 하게 된다.

map 함수

  • 내장함수
  • 입력받은 자료형의 각 요소가 합수에 의해 수행된 결과를 묶어서 map iterator 객체로 리턴
# 문법
map(f, iterable)
# 함수(f)와 반복 가능한 (iterable) 자료형을 입력으로 받는다.

map 예시문제

  • map으로 짜면 게으른 연산을 진행해서 메모리를 크게 절약할 수 있다.
  • map의 연산 결과는 map iterator 객체로 리턴한다.
# Input : li = [1, 2, 3]
# Output : result = [1, 4, 9]

# 풀이
result = list(map(lambda i: i ** 2 , li))

(참고) 게으른 연산

  • 필요할 때 가져다 쓴다.(예: map함수의 결과 객체)
  • iterator 객체
    • next() 메소드로 데이터를 순차적으로 호출 가능한 object
    • 마지막 데이터까지 불러 오면 다음은 StopIteration exception 발생
    • iterable한 객체를 iterator 로 변환하고 싶다면, iter() 라는 built-in function 을 사용
    • for 문으로 looping 하는 동안, python 내부에서는 임시로 list를 iterator로 자동 변환
# ex1.
li = [1, 2, 3]
result = map(lambda i: i * i, li)
next(result) # 1
next(result) # 4
next(result) # 9
next(result) # StopIteration 발생

# ex2.
>>> x = [1,2,3]
>>> type(x)
<class 'list'>
>>> y = iter(x)
>>> type(y)
<class 'list_iterator'>

3항 연산자

# if else문
def func(a):
    if a > 10:
        return 'a가 10보다 크다'
    else:
        return 'a가 10보다 작다'

# 3항 연산자
def func2(a):
    return 'a가 10보다 크다' if a > 10 else 'a가 10보다 작다'

3항 연산자 예시문제

  • 조건이 3개일 경우에도 3항 연산자 사용이 가능하다.
#Input : li = [-3, -2, 0, 6, 8]
#Output : ['음수', '음수', 0, '양수', '양수']

#풀이 1
>>> ['양수' if i > 0 else ('음수' if i < 0 else 0)  for i in li]
>>> ['음수', '음수', 0, '양수', '양수']

#풀이 2
>>> list(map(lambda i: '양수' if i > 0 else ('음수' if i < 0 else 0), li))
>>> ['음수', '음수', 0, '양수', '양수']

filter 함수

  • filter(함수, literable)
  • 두번째 인수인 반복 가능한 자료형 요소들을 첫번째 인자 함수에 하나씩 입력하여 리턴값이 참인 것만 묶어서 돌려준다.
  • 함수의 리턴 값은 참이나 거짓이어야 한다.
li = [-2, -3, 5, 6]

# 양수만 반환하는 리스트
def ft(li):
    result = []
    for e in li:
        if e > 0:
            result.append(e)
        else:
            pass
    return result


# filter 함수 사용시
def positive(x):
  return x > 0

list(filter(positive, li))

# filter + lambda 함수 사용시
list(filter(lambda x: x > 0, li))

reduce 함수

  • python3 부터 내장함수에서 빠짐
  • reduce(function, iterable[, initializer])
  • 문서
from functools import reduce
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
# = ((((1+2)+3)+4)+5)

reduce 함수 예시문제 1

from functools import reduce

# 문제1. 전통적으로 최대값 구하기
def maximum(li):
    default = 0
    for e in li:
        if default < e:
            default = e
    return default
maximum(li)

# 문제1. reduce 활용하여 최대값 구하기
reduce(lambda a,b: a if a > b else b ,li)

(참고) 문자별 갯수 구하기 알고리즘

or, and

>>> [1,2,3] and []
>>> []

>>> [1,2,3] or []
>>> [1,2,3]

>>> bool([1,2,3] or [])
>>> True

dictionary 관련함수

  • dict : dictionary 만들기
  • .get() : key를 통하여 value 값 검색
  • .update() : dictinary 요소 업데이트
# dict
>>> dic = dict(one=1, two=2)
>>> print(dic)
>>> {'one': 1, 'two': 2}

# .get()
>>> dic['three'] # 해당 key 값이 없으면 KeyError
>>> dic.get('three') # 해당 key 값이 없으면 None
>>> dic.get('three', 3) # 해당 key 값이 없으면 & 디폴트 값이 있으면  디폴드 값 반환

# .update()
>>> dic.update({'three': 3}) # dictinary에 요소를 업데이트, 리턴 값은 None
>>> dic
>>> {'one': 1, 'three': 3, 'two': 2}

## update와 동시에 결과 값을 반환하고 싶을 때
>>> dic.update({'four': 4}) or dic
>>> {'four': 4, 'one': 1, 'three': 3, 'two': 2}

문제 (중요)

# Input : data = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c']
# Output : {'a': 3, 'b': 2, 'c': 3}

# 풀이 1
>>> reduce(lambda a, b: a.update({b: a.get(b, 0) + 1}) or a,
        data,
        {}
      )
# reduce(lambda a, b: a.update({b: a.get(b, 0) + 1}) or a, data,{})

# 풀이 2
# 풀이 1이 풀이 2보다 더 효율적이다 (변수, itorator 객체 생성 메모리 절약)
>>>result =  { i : 0 for i in data} # {'a': 0, 'b': 0, 'c': 0}
>>>for i in data:
       result[i] += 1
>>>result
>>>{'a': 3, 'b': 2, 'c': 3}