티스토리 뷰

반응형

flask는 라우팅 기능을 한다.

사용자가 어떠한 액션을 요청했을 때, 규칙을 이용해서 해당 기능을 띄워주는 기능이다.

 

라우팅 기능이 핵심이다.

 

127.0.0.1의 5000번 포트가 기본이다.

 

그래서 인터넷 망 밖으로 나가기 위해서 nginx라는 녀석을 설정해준다.

nginx같은 경우에는 file도 nginx로 외부 인터넷 망을 통해서 서비스 할 수 있다.

 

추가로 시간이 있다면 WAS에 model을 넣어볼 것이다.

문장을 입력하면은 분류해주는 모델

 

다른 어플리케이션인 슬랙을 클라이언트쪽으로 설정해서 msg를 쓰면 인터넷 망을 타고 들어가서, 모델의 결과 데이터를 답변으로 보내주는 것

 

incoming web hook, outgoing web hook을 설정해서 구현해볼 것이다.

 

nginx 실험해보기

지난번에 만들었던 html, css, js 파일을 web이라는 디렉토리에 넣어서 넣어보자.

해당 파일을 서버 쪽으로 파일 전달을 해야 한다.

 

scp를 써야 한다.

scp -ri <pem file path> <source file path> <user name>@<public ip>:<destination
file path>
destination은 ~/으로 하면 계정의 최상위 디렉토리에 들어간다.

일단 web 디렉토리가 있는 곳으로 가고, ls web으로 파일들을 확인한다.

 

그런 후에 위의 양식과 똑같이 넣어주면 된다.

 

파일 전송이 완료되었고, 서버로 접속한다.

 

그러면 경로는 /home/ubuntu/web에 있을 것이다.

sudo vi /etc/nginx/sites-available/default

server {
listen 8080;
location / {
root /home/ubuntu/web;
	}
}
————————————————————————————————————————

 

이제 여기서 내용을 수정하면 된다.

i 누르고 :wq하고, 리부트하면 된다.

sudo systemctl restart nginx

 

여기까지 하면 커버 페이지가 나온다.

 

본인의 포트폴리오를 웹 페이지로 만들어서 소개를 하면 인상을 줄 수 있다.

인상적인 포트폴리오 = 웹페이지에서 마리오 게임과 이력서를 결합

 

자기를 많이 포장해서 회사에 들어가면 포장한 만큼 크다.

그러면 회사에서 맨날 야근하고 못한다면 짤린다.

 

결국에는 자기 실력을 높이는 게 중요하다.

 

실무자가 개발자 뽑을 때는 인성과 실력이 둘다 좋다하면 무조건 뽑는다.

그러면 하나가 하자인 녀석들은? 인성이 좋은 사람들 뽑는다.

인성이 안좋은데 실력이 좋으면 폭탄을 키우는 것이다. 오히려 리스크이다.

 

자기가 한 프로젝트가 있다면 조리 있게 설명하는 하에 좋은 점수를 줬다.

 

AI 넣은 포트폴리오로 준비해 가면 도움이 될 것이다.

 

쥬피터 노트북에서

쥬피터 노트북을 실행해본다.

일단 세션을 만든다.

 

tmux new -s ai
cd ~/
mkdir notebooks
cd notebooks
jupyter lab
혹은
jupyter notebooks

를 해서 브라우저에 띄운다.

 

그리고 ctrl+b,c를 해서 2번째를 띄운다.

이제 데코레이터를 실습해볼 것이다.

 

데코레이터

함수에서 코드를 변경하지 않고, 기능을 추가, 수정하는 문법

함수 안에 중복 코드를 데코레이터 함수로 작성할 수 있다.

 

def fuc1():
    print('code1')
    print('code2')
    print('code3')

def func2():
    print('code1')
    print('code4')
    print('code3')

여기서 code 1과 code3은 중복된다.

 

그러므로 해당 함수들을 묶어서 관리할 수 있다면 가장 좋다.

 

def deco(func):
    def wrapper(*args, **kwargs): #local function, 모든 파라미터들을 받아준다.
        print('code1')
        func(*args, **kwargs) #코드가 다른 것들을 포함하기 위해 받아준다.
        print('code3')
    return wrapper
    
def func1():
    print('code2')

def func2():
    print('code4')
func1()
func2()

이렇게 되었을 때, 코드를 바꾸지 않고 그냥 @deco에 func1()과 func2()를 넣어주면 된다.

이는 deco(func1)과 같은 효과이다.

@deco
def func1():
    print('code2')

@deco
def func2():
    print('code4')

func1()
func2()

 

time 함수로 wrapper 해보기

def show_time(func):
    def wrapper():
        import time
        start = time.time()
        func() #코드가 있는 부분
        end = time.time()
        print(end -start)
    return wrapper

이렇게 func을 블록으로 감싸준다.

 

그러면

@show_time
def func1():
    print('code2')

@show_time
def func2():
    print('code4')
func1()
func2()

>code2
0.001016378402709961
code4
1.5735626220703125e-05

한마디로, func1이 위에 있는 wrapper 코드로 바뀌는 것이다.

즉, show_time(func1)이다.

 

이게 데코레이터 문법이다.

그래서 @을 붙여서 기능을 추가한다.

 

데코레이터로 로그인 기능 추가하기

def login(func):
    def wrapper():
        pw = input('pw : ')
        if pw == '1234': #상속받는 arg먼트중에 1234가 있다면
            func()
        else:
            print('wrong password')
    return wrapper
    
@login
def func1():
    print('code2')

func1()

 

arg랑 kwarg는 있어야지 전달할 수 있다.

이렇게 wrapper로 감싸주면, 

참고로 데코레이터는 @login 아래에 @show_time 처럼 여러개를 추가할 수 있다.

 

argment를 추가하고 싶다고 하면,

def login(func):
    def wrapper(*arg,**kwargs):
        pw = input('pw : ')
        if pw == '1234': #상속받는 arg먼트중에 1234가 있다면
            func(*arg,**kwargs)
        else:
            print('wrong password')
    return wrapper
    
@login
def func1(kt):
    print('code2',kt)

func1('aivle')

만약 show time도 쓰고 싶다고 하면, show time에도 arg를 쓰면 된다.

def show_time(func):
    def wrapper(*arg,**kwargs):
        import time
        start = time.time()
        func(*arg,**kwargs) #코드가 있는 부분
        end = time.time()
        print(end -start)
    return wrapper

 

*args, **kwargs

#parameter에서 사용하는 경우 : 여러개의 argument를 하나의 parameter(tuple,dict)로 받는 방법 

#argument에서 사용하는 경우 : 하나의 parameter(list,tuple,dict)를 여러개의 argument로 사용하는 방법

여러 개의 데이터를 하나로 받아주려면,

식별자 1개, 데이터 n 개 = collection 데이터 타입 - dict, tuple

그래서 tuple과 dict로 받아준다.

 

def plus(n1,n2=2,n3=3):
print(n1+n2+n3)
print(1,n3=10)

 

이렇게 되어 있으면 디폴트 파라미터가 있다.

만약 4개를 하려면

그런데 print()에서, 괄호 안에 넣는 argument (n1,n2,n3) 개수에 상관 없이)

실행하게 하려면

def plus(*args):
	print(type(args),args)

plus(1,2,3)

>class 'tuple > (1,2,3,4,5)

따라서 argument 개수의 제한을 풀어준다.

몇개가 들어가도 된다.

 

그런데 일정 n4=10,n5=20과 같이 키워드가 지정된 녀석들은 **kwargs에서 받는다.

def plus(*args,**kwargs):
	print(type(args),args)
    print(type(kwargs),kwargs)
    print(type(args),args)

plus(1,2,3,n4=10,n5=20)

>class 'tuple > (1,2,3,4,5)
>class 'dict' > {'n4':10, 'n5':20}

그렇게 tuple과 dict를 이용해서 연산할 수 있다.

 

만약에 *를 데이터 입력에서 써주면 어떻게 될까?

def echo(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs),kwargs)
    
data = [1,2,3]
echo(data) # echo([1,2,3])
echo(*data) # echo(1,2,3)

<class 'tuple'> ([1, 2, 3],)
<class 'dict'> {}
<class 'tuple'> (1, 2, 3)
<class 'dict'> {}

리스트가 넘어가느냐, 각자가 풀어서 넘어가느냐가 다르다.

 

마찬가지로 **도 똑같다. 여기는 dict를 넘겨준다.

data2 = {'n4':10, 'n5':20}
echo(data2) # echo([1,2,3])
echo(**data2) # echo(1,2,3)

><class 'tuple'> ({'n4': 10, 'n5': 20},)
<class 'dict'> {}
<class 'tuple'> ()
<class 'dict'> {'n4': 10, 'n5': 20}

 

 

따라서 함수 안의 파라미터에서 쪽에서 쓸 때는 여러개를 1개로 받아줄 때 쓰는 거고,

입력할 때는 argument에서는 1개를 n개로 바꿔주는 것이다.

 

그래서 쓰임이 반대이다.

 

데이터 베이스에 접속한다고 해보자

def connect(host,user,pw):
    print(host,user,pw)

connect('1.2.3.4', 'kt', '1234')
connect('1.2.3.4', 'kt', '1234')
connect('1.2.3.4', 'kt', '1234')
만약에 ip 주소가 바뀌었다면 위의 코드들 전체를 바꿔줘야 한다.
그걸 간결하게 할 수 있는 게 dict 형태로 써주는 것이다.

data = {'host':'1,2,3,4', 'user':'kt', 'pw':'1234'}
connect(data['host'],user=data['user'], pw=data['pw'])
이러면 data만 바꾸면 된다.
그런데 이건 dict 이므로,
connect(**data) 로 하면 잘 들어간다.

 

 

반응형