[TIL]20210727

도커

docker ps를 통해 동작중인 컨테이너를 확인할 수 있다.
pull을 통해 같은 이미지를 다운받으면 레파지토리 tag는 다르나 image IDsms 같다. 즉, 동일한 이미지라는 것.

Dockerfile

FROM node:12 || 작동시킬 베이스 이미지와 버전 제공
COPY hello.js \ || hello.js(내부에 코드 있음)를 컨테이너 최상위 디렉토리로 이동.
CMD ["node", "/hello.js"] || node라는 명령어를 통해 최상위 dr에 있는 hello.js를 실행시킴

컨테이너 보관창고(레지스트리)

역할과 종류

registry: 여러 형태의 컨테이너 이미지를 보관하는 창고
Private registry: Hub에 공개하지 않고 프라이빗하게 사용하기 위함

터미널에서 docker search "키워드" 를 통해 이미지를 검색가능.

터미널에서 hub.docker.com에 업로드 및 다운로드 해보기

docker search httpd 를 통해 찾기.
docker pull httpd 를 통해 다운받기.
docker tag httpd [hub id]/httpd로 이름을 변경해야함.
docker push [hub id]/httpd 를 통해 업로드.

프라이빗 레지스트리 제작해보기

registry 라는 컨테이너를 다운받아 이용하면 나만의 레지스트리를 만드는 것이 가능하다.
docker run -d -p 5000:5000 --restart always --name registry registry:2 를 입력하면 컨테이너를 다운받고 바로 run 함.

도커 제대로 사용하기.

docker inspect [option] <이미지명:태그명(또는 컨테이너명)> 다운받은 이미지(컨테이너) 상세보기.
docker rmi [option] <이미지명> 이미지 삭제.

컨테이너 실행 라이프 사이클

docker create --name webserver nginx 가지고있는 nginx컨테이너를 이용해서 webserver라는 이름을 가진 컨테이너를 만듬.
docker start [옵션] webeserver 컨테이너를 실행시킴 --> 서비스가 실행됬다.
docker run --name webserver [옵션, (-d)] nginx 컨테이너 생성/실행 --> 서비스가 실행됬다.
docker ps 를 통해 컨테이너의 상태를 확인.
docker inspect webserver 를 통해 상세히 확인.
docker stop webserver 를 통해 정지.
docekr rm webserver 를 통해 컨테이너 제거. (사용됬던 이미지가 지워지는 것은 아님.)
docker top webserver 컨테이너에서 작동하는 프로세스 확인.
docker logs webserver 컨테이너가 생성한 로그 확인.
docker exec -it webserver /bin/bash exec 명령을 통해 컨테이너에 접근에 /bin/bash 를 현재의 터미널에서 실행.
docker attach webserver 포그라운드로 실행중인 컨테이너에 연결.

알고리즘

임의 정밀도

임의 정밀도 정수형이란 무제한 자릿수를 제공하는 정수형이다.
이는 정수를 숫자의 배열로 간주하였기에 가능하다. 대신 계산속도가 매우 저하되지만, 숫자를 단일형으로 처리하고 오버플로를 고민할 필요가 없다는 점이 강점이다.

매핑

매팽 타입은 키와 자료형으로 구성된 복합 자료형, 파이썬에 내장된 것은 딕셔너리뿐.

집합(set)

a=set()를 통해 빈 집합을 선언할 수 있다. 이때 입력순서가 유지되지 않고, 중복된 값이 있을 경우 하나의 값만을 유지한다.

시퀀스

수열. 순서있는 나열. str은 문자열을 이루는 자료형, list는 다양한 값들이 배열 형태로 이뤄져있는 자료형. 시퀀스는 불변(ex. str, tuple,bytes)과 가변(ex. list)으로 구분.

객체

파이썬은 모든 것이 객체이다.
불변 객체: bool, int, float, tuple, str
가변 객체: list, set, dict
파이썬에서 변수를 할당하는 작업은 해당 객체에 대해 참조를 한다는 의미.
여기에는 예외가 없다. 문자와 숫자 모두 객체.

>>>a=10
>>>b=a
>>>id(10), id(a), id(b)
(4523465792, 4523465792, 4523465792)

c언어처럼 원시 타입이엇다면 각각의 값들은 각 메모리의 다른영역에 위치하겠지만, 파이썬은 모든것이 객체임으로 메모리상에 위치한 객체의 주소를 얻어오는 id()를 실행한 결과는 모두 같다.
여기서 c++의 참조와 다른 점이 있다.

int a=10;
int &b=a;
b=7;
std::cout << a << std::endl;

a를 출력하게되면 7이 나온다.

a=10
b=a
id(a), id(b)
-->(4313201728, 4313201728)
b=7
-->a, id(a), id(b)
(10, 4313201728, 4313201632)

a를 출력하면 10이 나온다. b=a를 통해 동일한 메모리 주소를 할당했지만, b=7이라는 새로운 값을 할당하게 되면 더이상 b는 a를 참조하지 않는다는 것이 c++의 참조와 차이점이다. 할당 방식이 다름으로 주의가 필요함.

is 연산자

is는 id()값을 비교하는 함수이다. None는 (Null)로 값 자체가 정의되어 있지 않아 == 연산자를 통해서는 비교가 불가능하고, is로만 비교가 가능하다.

a=[1,2,3]
a==list(a) --> True
a is list(a) --> False

값은 동일하지만 list()로 한번더 묶어주면, 별도의 객체로 복사가 되어 다른 id를 가지게된다.

list \ dic

파이썬의 리스트는 객체로 되어있는 모든자료형을 포인터로 연결한다.
그렇기에 정수형 배열이면 정수로만 이뤄진 값을 연속된 메모리 공간에 저장하고, 정수가 아닌 값을 저장할 수 없는 일반적인 경우와는 다르게 다양한 타입을 동시에 단일 리스트에서 관리할 수 있다. 자료형의 크기는 저마다 다르기 때문에 연속된 메모리 공간에 할당하는 것이 불가능해 각가그이 객체에 대한 참조로 구현하면서 리스트를 강력하게 만드는 대신 속도를 희생함.

파이썬에서 딕셔너리는 순서를 포함한다.
for k,v in a.items():
print(k, v)

를 이용하면 키와 값을 불러와 출력하게 만든다.

defaultdict 객체

존재하지 않는 키를 조회할 경우 오류를 출력하는 대신 디폴트 값을 기준으로 딕셔너리를 만듬.

a={'key1':'value1', 'key2':'value2'}
a[key3]='value3'
--> 키와 값을 리스트에 추가함.
a[key4]
--> 없는 키라면서 오류 발생.

import collections

a=collections.defaultdict(int)
a['3']=4
a['4']=5
a['5']
a['6']+=1
print(a)
--->defaultdict(<class 'int'>, {'3': 4, '4': 5, '5': 0, '6': 1})

디폴트인 0을 기준으로 생성된다.

counter 객체

아래처럼 아이템의 값이 키에. 해당 아이템의 개수가 값에 들어가는 딕셔너리를 생성한다.

import collections

a=[1,2,3,4,5,5,5,6,6]
b=collections.Counter(a)
print(b)
--->Counter({5: 3, 6: 2, 1: 1, 2: 1, 3: 1, 4: 1})
most_common(n)

빈도 수가 높은 요소를 차례대로 n개 만큼 출력해준다.

print(b.most_common(2))
---->[(5, 3), (6, 2)]

단, counter 를 사용해야지만 가능.

125. Valid Palindrome [leetcode]


1.
class Solution:
   def isPalindrome(self, s: str) -> bool:
       strs = [ ]
       for char in s:
           if char.isalnum():
               strs.append(char.lower())
       while len(strs) > 1:
           if strs.pop(0) != strs.pop():
               return False
       return True

코드 설명:
isalnum()은 숫자/영문자이면 0이아닌 다른값, 아니면 0을 리턴함.
lower()은 모두 소문자로 변환.
pop()은 기본적으로 맨 뒤의 값을 가져온 후 불러온 곳에서는 삭제한다.
pop(0)처럼 0을 붙이면 맨 앞(0번째) 값을 가져오고 삭제한다.
숫자/문자들만 strs에 담고 while문을 통해 앞 뒤를 비교한다.

오류: IndentationError: expected an indented block
들여쓰기 제대로 안하면 이런 오류가 발생한다.

  1. 데크 자료형을 이용하면 훨씬 빠르게 풀 수 있다지만 뒤에서 배운다길래 배운후에 다시보는걸로..
  2. 슬라이싱 이용
    1번의 isalnum()과 다르게 정규식을 이용해 숫자/영문자를 걸러낸다.
    또한, 리스트를 [::-1] 를 통해서 뒤집을 수 있다!
s=s.lower()
s=re.sub('[^a-z0-9]', '', s)

return s==s[::-1]

코드설명:
re.sub()는 re.sub('패턴', '바꿀문자열', '문자열', 바꿀횟수)
로 구성된다.
패턴에서 (영문자와 숫자가 아닌것들)을 지정했고, 바꿀문자열은 null(?)임으로 s의 문자열안에서 패턴에 해당하는 것들을 null로 바꾼다.
그러면 영문자와 숫자만이 남게되고 return 을 통해 문자열s와 뒤집힌 문자열s[::-1]을 통째로 비교하여 결과값을 리턴한다.
이는 어느정도 c로 구성되어 있어 훨씬 속도가 빠르다.

문자열 슬라이싱: 문자열을 조작할때 슬라이싱하는 것이 대부분의 경우에서 매우 빠르기에 애용하는 것이 좋다.
간단한 사례로 reverse()함수를 쓰는 것이 s[::-1]하는것보다 5배가 느리다.

344. Reverse String [leetcode]

1.

   def reverseString(self, s: List[str]) -> None:
       left,right=0,len(s)-1
       while left<right:
           s[left], s[right] = s[right], s[left]
           left+=1
           right-=1

가장 전통적인 방법인 투 포인터를 이용한 스왑 이라고 한다.
내가 이 문제를 직접풀었더라도 이렇게 비효율적으로 풀었을거라 예상한다.

2.
파이썬다운 방식.

	def reverseString(self, s: List[str]) -> None:
	    s.reverse() 

3.
슬라이싱.

	def reverseString(self, s: List[str]) -> None:
	    s[:]=s[::-1]

이 문제에 답을 제출할때는 s=s[::-1]이 공간복잡도 문제때문에 위의 코드처럼 수정해야한다고 함.

box model

 <style>
   div {
     margin: 50px;
     padding: 50px;
     border: 10px solid #000;
   }
 </style>

이런식으로 구성.

border

요소의 안쪽 여백.

  • border-width
    기본 값 : medium, 선의 굵기를 지정하는 속성입니다. border-top-width, border-bottom-width, border-right-width, border-left-width를 이용하여 상하좌우 선의 굵기를 다르게 표현할 수 있습니다.
    border-width: [top] [right] [bottom] [left];
    < 속성 값 >
    키워드
    thin, medium, thick
    단위
    px, em, rem ... ( % , 정수 단위 사용불가 )

  • border-style 기본 값 : none, 선의 모양을 지정하는 속성입니다. border-top-style, border-bottom-style, border-right-style, border-left-style을 이용하여 상하좌우 선의 모양을 다르게 표현할 수 있습니다.
    border-style: [top][right] [bottom][left];
    또한, 위처럼 축약하여 공백을 이용해 각 방향에 대한 스타일을 지정할 수도 있습니다.
    < 속성 값 >
    none
    border를 표시 하지 않습니다.
    solid
    border를 실선 모양으로 나타냅니다.
    double
    border를 이중 실선 모양으로 나타냅니다.
    dotted
    border를 점선 모양으로 나타냅니다.
    그 밖에도 dashed, double, groove, ridge, inset, outset 등의 다양한 스타일이 있습니다.

  • border- color 기본 값 : currentColor 선의 색상을 지정하는 속성입니다. border-top-color, border-bottom-color, border-right-color, border-left-color를 이용하여 상하좌우 선의 색상을 다르게 표현할 수 있습니다.
    border-color: [top][right] [bottom][left];
    또한, 위처럼 축약하여 공백을 이용해 각 방향의 색상을 지정할 수도 있습니다. 색상은 일반적인 CSS 색상 값 사용 방식과 같습니다.

  • border 축약
    border: [-width][-style] [-color];
    위와 같이 공백으로 구분해 축약하여 사용할 수 있고, 정의되지 않은 속성값에 대해서는 기본값이 적용됩니다.

    border-width: 6px; 보더 두께
    border-width: 6px 3px; 보더 상하, 좌우 두께
    border-width: 6px 3px 4px; 보더 상, 좌우, 하 두께
    border-width: 6px 3px 4px 1px; 보더 상, 우, 하, 좌 두께 (시계방향 순서!)

padding

요소의 안쪽 여백.

padding: [-top] [-right] [-bottom] [-left];
                   0      10px     20px      30px   /* 상, 우, 하, 좌 다름 */
                   0      10px     20px             /* 좌, 우 같음 */
                   0      10px                      /* 상, 하 같음 & 좌, 우 같음 */
                   0                                /* 상, 우, 하, 좌 모두 같음 */

margin

요소의 바깥 여백

margin: auto --> 브라우저가 자동으로 여백을 계산해 적용해주는 기능.
width값과 함께 이용하면 정렬을 할 수 있다.
width는 컨텐츠의 너비(가로 값)를 결정한다.
width의 기본 값은 auto로 웹페이지 양 끝에 맞춰지도록 설정되어있는데, 이를 300px로 정한다면 컨텐츠 영역의 너비가 고정된다.

width값을 준 상태에서 margin을 auto로 준다면 가로 정렬이 된다. 이는 실제로도 자주 사용된다고 한다.
margin-left: auto 를 한다면 오른쪽 정렬을 하게되고,
margin-right: auto 를 한다면 왼쪽 정렬을 한다.

margin collapse

margin값의 top과 bottom이 겹치면 더 큰값을 적용시키고 겹치게 만드는 margin의 특징이다.

margin 과 padding

각 속성의 특징을 확실히 이해해보기.

+ - auto 단위
margin O O O px, %
padding O X X px, %

단, 단위의 %는 가로축을 기준으로 하기때문에 top과 bottom에 넣을 때도 동일하게 가로축을 기준으로 잡힘. 그렇기에 웹페이지를 양옆으로 늘려도 top이나 bottom의 %비율이 변하여 표시되는 위아래 폭이 달라짐. margin에서 좌우를 음수로 설정하면 페이지의 기본크기를 벗어나서 좌우스크롤을 해야한다. 또한, 위아래에 음수로 설정하면 박스모델끼리 겹쳐서 출력된다. padding에 음수를 입력하면 invalid하여 제대로 표시되지 않는다.

width

요소의 가로값을 결정. 기본값은 auto.
box 요소 전체 사이즈를 계산할 때는 box값(width total) = width(contents영역, 입력값) + padding + border.

만약

<div class="parent">
  <div class="child">
    child
  </div>
</div>
 
.parent {
  width: 300px;
  border: 20px solid red;
}
.child {
  width: 50%;
  padding: 20px;
  border: 10px solid black;
}

이렇게 구상한다면
child에서 width 50%는 parent의 width(contents)의 50% 즉, 150px을 가져온다. box값(width total) = 150 + 20 2 + 10 2 = 210(px) 이 된다.
참고로, parent는 가장 가까운 블록 레벨의 조상으로 설정되고, 만약 최상단까지 블록 레벨 요소가 없다면 body를 기준으로 계산한다. 또한, 부모의 값이 auto여도 상관이 없다.

height

height도 width 거의 동일하다.
단, %를 이용하여 값을 지정할 때 width와는 다르게 parent값이 명시되어야 한다.

좋은 웹페이지 즐겨찾기