ALGORITHM in Alter Table

# ALGORITHM={ DEFAULT | INPLACE | COPY }
  • COPY : MySQL 5.5이하 버전에서 사용되던 방법으로 데이터를 임시 테이블로 모두 복사후, rename하는 방식
  • INPLACE : MySQL 5.6이상 버전에서 지원되는 방법으로, 데이터를 바로 변경하되, 변경 작업시 일어나는 DML작업들은 별도의 로그로 보관했다가 데이터 변경 마지막에 일괄 적용하는 방법
  • DEFAULT : ALGORITHM를 명시하지 않은 것과 같음

Install command-line tools on Mac

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

며칠전부터 제 Mac에 용량이 부족하다고 떠서 앱을 몇개 지웠는데 무심코 XCode를 지워버렸는데 생각해보니까 Mac은 XCode깔면 Command-line명령어도 다 같이 깔리고 했던거 같은데 아니나 다를까 command-line명령어가 안먹더라구요. 다시 XCode를 설치하자니 불필요하게 10GB를 써야하고 해서 구글을 좀 해봤더니, xcode-select라는 명령어를 사용해서 XCode설치 안하고 command-line명령어만 설치를 할수가 있더라구요.

xcode-select --install

위의 명령어를 통해서 command-line을 설치하신 이후에, Mac에서 무거운 XCode를 설치하지 않고도, command-line을 사용하실수 있습니다.

Pytest assert 종류

# 한번이상 호출되었는지
assert_called()

# 정확한게 한번 호출되었는지
assert_called_once()

# 주어진 인자를 가지고 호출되었는지
assert_called_with(*args, **kwargs)

# 주어진 인자를 가지고 정확하게 한번 호출되었는지
assert_called_once_with(*args, **kwargs)

# 한번이라도 주어진 인자를 가지고 호출이 되었는지
assert_any_call(*args, **kwargs)

# 단한번도 호출되지 않았는지
assert_not_called()

# 해당 mock함수가 호출된 횟수
assert mock_function.call_count == 2

Source: https://docs.python.org/3/library/unittest.mock.html

Linked List

아래는 링크드리스트의 append와 delete를 파이썬으로 구현한 코드입니다.

class Node:
	def __init__(self, data):
		self.data = data
		self.next = None

class LinkedList:
	def __init__(self):
		self.head = Node(None)

	def append(self, data):
		if self.head is None:
			self.head = Node(data)
			return
		
		node = self.head
		while node.next is not None:
			node = node.next

		node.next = Node(data)

	def delete(self, data):
		node = self.head
		while node.next is not None:
			if node.next.data == data:
				node.next = node.next.next
				break

			node = node.next

	def retrieve(self):
		node = self.head
		while node.next is not None:
			print(str(node.data), end=" ")
			node = node.next
		print(node.data)

ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
ll.append(4)
ll.retrieve()
ll.delete(2)
ll.delete(3)
ll.retrieve()

실행해보시면 결과는 아래와 같습니다.

$ python linkedlist.py
None 1 2 3 4
None 1 4

Yield in Python

파이썬 함수에서 return대신 yield를 하면 무슨일이 일어나는지 보여드릴게요. 아래 코드를 보시면요, a라는 함수가 10번 돌면서 yield를 하고 있죠? 그리고 yield를 하기 직전에 a:반환할숫자를 출력해보도록 할게요

def a():
  for i in range(10):
    print(f'a:{i}')
    yield i

자 그러면 과연 이 함수는 어떤 값을 반환할까요? a()함수에서 반환받은 값을 하나씩 돌면서 아래와 같이 출력을 해볼게요.

for i in a():
  print(i)

위의 코드를 실행하면 아래와 같이 0부터 9까지 출력을 하는데 함수안에서 출력한 것과 함수 바깥에서 출력한것이 하나씩 번갈아가면서 출력이 됩니다.

a:0
0
a:1
1
a:2
2
a:3
3
a:4
4
a:5
5
a:6
6
a:7
7
a:8
8
a:9
9

위의 결과에서 보시는 것과 같이 yield는 반환을 하고 다시 돌아와서 다음값을 또 반환하고 하는 식으로 바깥의 코드가 자기를 일을 다 마무리짓기를 않아도 되도록 처리가 되는 대로 하나씩 바깥에 던져줍니다. 이렇게 코드를 수행하면 함수 바깥쪽 코드가 결과를 한꺼번에 다 오기를 기다렸다가 한꺼번에 받아서 하는 것보다 받는대로 수행할수 있어서 일이 좀더 수월하겠죠.

다양한 For문 in Python

key를 가지고 vlaue를 찾고 싶을때는 다음과 같이 합니다.

for key, value in Features.items():
    if key is 'name'
        print(value)

key와 value를 반대로 key를 value로, value를 key로 바꾸는 방법입니다.

d = {
    'k1': 'v1',
    'k2': 'v2',
    'k3': 'v3'
}

r = {value: key for key, value in d.items()}

print(r)
----------------------------
# result
{
   'v1': 'k1',
   'v2': 'k2',
   'v3': 'k3'
}

아래는 For문을 간소화하여 표현하는 방법입니다.

# brute force code
result = set()
for item in array:
    result.add(item["key"])

# simplified version
result = {item["key"] for item in array}

초간단 Python 디버깅

그냥 아무데서나 아래 코드를 삽입하고 실행시키면 거기서 멈춤니다.

import pdb; pdb.set_trace()

h를 입력하고 엔터를 치면, 다음과 같이 사용가능한 명령어의 모음을 보여줍니다.

(Pdb) h

Documented commands (type help <topic>):
========================================
EOF    c          d        h         list      q        rv       undisplay
a      cl         debug    help      ll        quit     s        unt
alias  clear      disable  ignore    longlist  r        source   until
args   commands   display  interact  n         restart  step     up
b      condition  down     j         next      return   tbreak   w
break  cont       enable   jump      p         retval   u        whatis
bt     continue   exit     l         pp        run      unalias  where

Miscellaneous help topics:
==========================
exec  pdb

이 상태에서 확인하고자 하는 변수를 치면, 해당 변수가 어떤 값을 가지고 있는지 보여줍니다.

(Pdb) node.next.data
1

l은 현재 내가 어디있는지 위아래 코드를 보여줍니다. l명령어에 출력할 시작 라인넘버와 끝 라인넘버를 인자로 주면 원하는 부분의 코드를 출력합니다.

(Pdb) l
 19  			node.next = Node(data)
 20
 21  		def delete(self, data):
 22  			node = self.head
 23  			import pdb; pdb.set_trace()
 24  ->			while node.next is not None:
 25  				if node.next.data == data:
 26  					node.next = node.next.next
 27  					break
 28
 29  				node = node.next

n명령어로 다음라인을 실행할수 있습니다.

(Pdb) n
> /Users/slim/test/python/linkedlist.py(25)delete()
-> if node.next.data == data:

s명령어도 마찬가지로 하나의 라인을 실행하는데, 얘는 현재 라인을 실행합니다.

(Pdb) s
> /Users/slim/test/python/linkedlist.py(29)delete()
-> node = node.next

unt명령어를 이용하면 코드의 라인넘버를 지정하여 원하는 코드까지 실행을 할수 있습니다. 일단 l명령어를 이용해서 이동하고자 하는 라인넘버를 확인한후, unt명령어에 25라는 숫자를 인자로 넘기면, 해당 25번째 코드까지 실행을 합니다.

(Pdb) l
 19  			node.next = Node(data)
 20
 21  		def delete(self, data):
 22  			node = self.head
 23  			import pdb; pdb.set_trace()
 24  ->			while node.next is not None:
 25  				if node.next.data == data:
 26  					node.next = node.next.next
 27  					break
 28
 29  				node = node.next
(Pdb) unt 25
> /Users/slim/test/python/linkedlist.py(25)delete()
-> if node.next.data == data:
(Pdb) l
 20
 21  		def delete(self, data):
 22  			node = self.head
 23  			import pdb; pdb.set_trace()
 24  			while node.next is not None:
 25  ->				if node.next.data == data:
 26  					node.next = node.next.next
 27  					break
 28
 29  				node = node.next

b명령어를 이용해서 break point를 지정하실수 있습니다. l명령어를 이용해서 break point로 지정할 라인을 확인하고, b명령어에 라인넘버를 인자로 넘겨서 break point를 지정합니다.

(Pdb) l
 20
 21  		def delete(self, data):
 22  			node = self.head
 23  			import pdb; pdb.set_trace()
 24  			while node.next is not None:
 25  ->				if node.next.data == data:
 26  					node.next = node.next.next
 27  					break
 28
 29  				node = node.next
 30
(Pdb) b 29
Breakpoint 1 at /Users/slim/test/python/linkedlist.py:29

c명령어를 이용해서 지정된 break point까지 실행합니다. l을 통해 확인을 해보면 30번째 라인까지 실행하고 while문을 통해 다시 올라가서 while문 첫번째 라인에서 다음 실행을 대기하고 있습니다.

(Pdb) c
> /Users/slim/test/python/linkedlist.py(24)delete()
-> while node.next is not None:
(Pdb) l
 19  			node.next = Node(data)
 20
 21  		def delete(self, data):
 22  			node = self.head
 23  			import pdb; pdb.set_trace()
 24  ->			while node.next is not None:
 25  				if node.next.data == data:
 26  					node.next = node.next.next
 27  					break
 28
 29  				node = node.next

이때, r을 입력하면, 현재 function 에서 return하는 부분까지 실행합니다.

(Pdb) r
--Return--
> /Users/slim/test/python/linkedlist.py(27)delete()->None
-> break

a명령어는 현재 함수를 실행하면서 받은 모든 인자를 출력합니다.

(Pdb) a
self = <__main__.LinkedList object at 0x10a4eb470>
data = 3

q를 입력하면, 디버깅을 종료합니다.

(Pdb) q
Traceback (most recent call last):
  File "linkedlist.py", line 44, in <module>
    ll.delete(2)
  File "linkedlist.py", line 24, in delete
    while node.next is not None:
  File "linkedlist.py", line 24, in delete
    while node.next is not None:
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/bdb.py", line 88, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/bdb.py", line 113, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit

#pythondegugging #debug #debugging #파이썬디버깅

bash 폰트색상 및 스타일링

이번시간에는 bash 스크립트를 작성할때, 결과물을 칼라풀하게 보여주는 방법에 대해서 설명드릴게요. 맥북 사용자분들은 터미널의 bash이 옛날버전이라 색상기능을 지원하지 않을 수도 있어요. Homebrew 등을 이용해서 최신버전을 설치해주세요.

brew install bash

설치를 하고나서 bash의 버전을 확인해주세요

bash --version

버젼이 5.0.17이상이 아니라면 방금설치한 bash를 기본으로 사용하지 않는 경우에요. 아래 명령어를 실행해서 bash이 어디에 설치가 되어있는지를 찾아봅니다.

which -a bash

다른 곳에 설치되어 있는 bash의 버전을 보면서 최신 버전의 경로를 찾아주세요.

/usr/local/bin/bash --version

최신 버전의 bash을 찾았으면, PATH에 해당 경로를 추가해주세요.

PATH=$PATH:/usr/local/bin

bash의 버전을 확인해보면, 최신버전이 되어있을거에요. 혹시 아직도 옛날버전으로 나온다면 PATH관련한 도움글을 찾아서 해결한뒤에 계속 진행해주세요.

bash --version

자 이제, 색상테스트를 해봅니다

echo -e "\033[1;31m This is red text \033[0m"

위의 글씨가 빨강색으로 출력이 되면 설치가 잘된거에요.

bash에서 문자열을 꾸미는 예약어는 바로:

  • \e
  • \033
  • \x1B

이렇게 세가지 인데요, printf에서는 셋다 사용이 가능한데,

printf "\e[2mtest\n"
printf "\033[2mtest\n"
printf "\x1B[2mtest\n"

저만 그런건지 echo로 출력할때는 \033만 사용이 가능하더라구요, 원래 \e도 되야 하는데 제가 맥이라 그런지 echo로 출력할때는 \033으로만되서 예제에서는 \033으로 사용할건데요 \e가 되는 분은 \e로 바꿔서 실행하셔도됩니다. 그리고 echo로 출력할때는 -e옵션을 주어야 색상코드가 인식이 됩니다.

echo -e "\033[2mtest"

폰트스타일 예약어(이하 \033)는 폰트의 스타일을 지정할때 사용되고요, 옵션은 6가지가 있습니다. 사용방법은 문자열 안에서 \033로 시작하면 지금부터는 폰트 스타일이야 라고 bash한테 알려주는거에요. \033[1m이렇게 1번을 주면 지금부터 쓰는 문자는 두껍게 보여주라는 뜻이에요.

echo -e "기본\033[1m굵게"

2번은 색상이 살짝 바래보이는 것이에요. 스타일적용한걸 취소하려면, \033[0m을 만나면 거기서 스타일적용이 끝납니다.

echo -e "기본\033[2m흐리게\033[0m기본"

아래는 폰스타일 관련한 명령어들의 번호입니다.

\033[1m굵게
\033[2m희미하게
\033[4m밑줄
\033[7m배경색과 전환

모든 스타일을 취소할때는 \e[0m을 사용하면 되는데, 만약에 여러가지 적용된 스타일중에서 하나만 제외하고 다른 스타일은 계속 사용하고 싶다면 아래에 각 스타일별로 취소하는 명령어의 번호를 별도로 제공하고 있습니다.

\033[0m모든 스타일 적용 취소
\033[21m굵게한거 취소
\033[22m회색으로 만든거 취소
\033[24m밑줄 취소
\033[27m배경색이랑 전환했던거 취소

아래는 폰트의 색상을 바꾸는 명령어입니다.

\033[39m기본색
\033[30m검정
\033[31m빨강
\033[32m초록
\033[33m노랑
\033[34m파랑
\033[35m형광분홍
\033[36m아쿠아
\033[37m밝은회색
\033[90m어두운회색
\033[91m밝은 빨강
\033[92m밝은 초록
\033[93m밝은 노랑
\033[94m밝은 파랑
\033[95m밝은형광분홍
\033[96m밝은아쿠아
\033[97m흰색

이번엔 글씨의 배경색을 바꾸는 코드입니다.

\033[49m기본색
\033[40m검정
\033[41m빨강
\033[42m초록
\033[43m노랑
\033[44m파랑
\033[45m형광분홍
\033[46m아쿠아
\033[47m밝은회색
\033[100m어두운회색
\033[101m밝은 빨강
\033[102m밝은 초록
\033[103m밝은 노랑
\033[104m밝은 파랑
\033[105m밝은형광분홍
\033[106m밝은아쿠아
\033[107m흰색

색상은 총 256가지가 지원이 되고 있고요. 터미널에서 아래의 코드를 실행하면 사용할수 있는 모든 칼라와 해당하는 번호를 볼수있습니다.

for fgbg in 38 48 ; do
  for color in {0..255} ; do
    printf "\e[${fgbg};5;%sm  %3s  \e[0m" $color $color
    if [ $((($color + 1) % 6)) == 4 ] ; then
      echo # New line
    fi
  done
  echo
done

Source: https://misc.flogisoft.com/bash/tip_colors_and_formatting

CSS로 이미지 정가운데 보여주기

이번시간에는 오직 CSS만 이용해서 하나의 이미지를 화면의 정가운데 보여주는데, 윈도우의 사이즈를 바꿀때마다 자동으로 줄어들었다 커졌다 하면서, 가로든 세로든 이미지가 잘리지 않고 전체가 보이도록 가로나 세로중 더 작은 쪽은 기준으로 이미지 사이즈를 결정하여 정 가운데 위치하도록 하는 CSS팁을 알려드리도록 하겠습니다.

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .imgbox {
            display: grid;
            height: 100%;
        }
        .center-fit {
            max-width: 100%;
            max-height: 100vh;
            margin: auto;
        }
    </style>
</head>
<body>
<div class="imgbox">
    <img class="center-fit" src="logo.png" />
</div>
</body>
</html>

위의 코드를 테스트해보면 아래와 같이 가로든 세로든 화면을 어떻게 변경해도 로고가 절대 짤리지 않고 크기가 조정되면서 언제나 정가운데 위치합니다.

화면을 아주 크게 키워도,

화면을 아주 작게 줄여도,

화면을 가로로 길게 늘여도,

화면을 세로로 길게 늘여도,

이미지는 언제나 정가운데 짤림없이 보여집니다.

Archived: CSS