본문 바로가기

TIL

[TIL 2024. 04. 08] Django 기초세팅 | strip() | l로 만들기

Django 기초세팅

지금은 여러 프로젝트를 하는 것이 아니니, 사실 가상환경 없이 전역환경에서 pip install을 진행해도 상관은 없다.

하지만 이후에 여러 프로젝트를 진행하게 되는 경우를 생각한다면 지금부터 가상환경 내에서 연습을 해보는 것이 좋을 같아서 가상환경 생성부터 세팅을 시작했다.

 

 

1. 가상환경 생성

python -m venv .venv

 

강의에서는 venv라는 가상환경을 만들었다. 하지만 나는 .venv가 익숙하기도 하고, 해당 명령어를 제대로 이해하기도 편한 것 같아서 .venv라는 이름으로 폴더를 만들어서 가상환경을 생성해주었다.

 


2. 가상환경 활성화

source .venv/Scripts/activate

 

위의 명령어는 윈도우에서 가상환경 활성화를 사용한다. 윈도우에서는 .venv폴더(가상환경 폴더)의 Scripts폴더 안에 activate.bat파일이 있으므로 그 경로를 명시해줌으로써 가상환경을 활성화시키는 것이다.

(cf. 맥에는 bin폴더 내에 activate파일이 있다 -> source .venv/bin/actiavte)

 


3. 장고(django) 설치

pip install django==4.2

 

django뒤에 "==4.2"를 붙여준 것은 django의 LST(Long Term Support) 버전을 설치하기 위해서다. 안정적인 개발 환경을 위해서는 LST사용이 권장되므로, 해당 공식 사이트에서 안내하는 LST에 관한 일정들을 확인하는 것은 중요하다!

 


4. requirements.txt로 freeze하기 (의존성 파일 생성)

pip freeze > requirements.txt

 

기본적으로 pip freeze를 하기 전에는 가상환경 내에서 pip list로 모든 항목들이 제대로 설치되어 있는지 확인해줘야 한다.

이 명령어를 통해 현재 설치되어 있는 항목들을(pip) freeze해서 requirement.txt라는 파일을 생성할 수 있다.

 

우리가 이렇게 txt파일을 만드는 이유는 해당 장고의 '의존성' 때문이다. 즉, 장고라는 프레임워크를 구성하는 데 필요한 여타의 요소들도 버전이 동일하게 관리되어야 오류가 없을 것이므로, 이러한 버전을 사용해야 한다고 적어준 것이다.

 

 freeze한 requirements.txt를 활용하는 방법:  pip install -r requirements.txt
--> 이 명령어는 requirements.txt를 읽어내려가며 차례대로 install하게 함

 

 


5. 프로젝트 생성

django-admin startproject <프로젝트 이름> <생성 디렉토리>
# <생성 디렉토리> 위치에 <프로젝트 이름>의 디렉토리(폴더)를 생성하고 해당 디렉토리에 프로젝트를 생성함


django-admin startproject <프로젝트 이름> . 
#현재 폴더를 프로젝트 디렉토리(폴더)로 사용해서 프로젝트를 생성함

 

프로젝트 폴더 내에는 여러 .py파일들이 생성되어 있을 것인데, 그 중에서 우리에게 중요한 것은 "settings.py"와 "urls.py"이다.

-> settings.py: 프로젝트의 설정을 관리

-> urls.py: 어떤 요청을 처리할지 결정

 


( 6. 서버 실행 )

cd <프로젝트 디렉토리>
#먼저 해당 프로젝트 폴더로 이동해야함

python manage.py runserver
#서버 실행

 

 


7. django app 생성

 

기본적으로 app생성은 두 가지 단계로 이루어진다. 즉, "app을 생성"하라고 하면 (1) app을 생성하고, (2) app을 등록하는 과정까지를 포괄하는 것이다.

python manage.py startapp <앱 이름>

python manage.py startapp articles
#예시: articles라는 이름의 app을 생성_django은 '복수형'의 app이름을 사용하기를 권장함

 

이제 app을 '등록'해야 하는데, 구체적으로는 앱과 같은 선상에 있는 프로젝트명과 동일한 폴더 내의 settings.py의 INSTALLED_APPS에 "새로 생성한 앱 이름"과 "트레일링 콤마"를 적어주면 된다.

 

app폴더 내에도 프로젝트에서와 마찬가지로 여러 개의 .py파일이 생성된다. 이 중에서 우리에게 중요한 것은 "models.py"와 "views.py"파일이다.

-> models.py : DB관련 정의

-> views.py: 요청을 처리하고, 처리한 결과를 반환

 

프로젝트와 app의 관계를 정리하면, 기능단위로 묶은 모듈인 'app'이 모인 것이 '프로젝트'이다.

이때, app은 여러개로 분산해서 각 기능들을 개발하기도 하고, 하나의 app안에 기능들을 모두 넣어서 개발할 수도 있다.

하지만 기본적으로는 여러 개의 app에 각 기능들을 개발하는 형태가 권장된다.


strip()

strip()은 파이썬 내장 함수이며, 원래 문자열의 시작과 끝에서 주어진 문자를 제거한다.

 

기본적으로 strip() 함수는 문자열의 시작과 끝에서 공백을 제거한 후 반환하며, 괄호 안에 특정 값을 넣을 경우에는 해당하는 문자열을 제거한다.

 

strip 함수에는 rstrip, lstrip, strip으로 총 3가지가 있다. rstrip은 오른쪽에 있는 것만 제거하고, lstrip은 왼쪽에 있는 것만 제거하고, strip은 양쪽 다 제거한다. 이때 제거의 대상은 "공백"과 "특정 문자열"을 모두 포함한다.


(1) strip()

# 공백을 제거하는 경우
string = "     abcde     "
string.strip()
#'abcde'
 
 
# 특정 문자열을 제거하는 경우
string = "     abcde     "
string.strip('c')
#'abde'

 

 

(2) lstrip()

# 공백을 제거하는 경우
string = "     abcde     "
string.lstrip()
#'abcde     '
 
 
# 특정 문자열을 제거하는 경우
string = "     oooabcdeooo     "
string.lstrip('o')
# 'abcdeooo'

 

 

(3) rstrip()

# 공백을 제거하는 경우
string = "     abcde     "
string.rstrip()
# '     abcde'
 
 
# 특정 문자열을 제거하는 경우
string = "     oooabcdeooo     "
string.rstrip('o')
# 'oooabcde'

l로 만들기

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

알파벳을 기준으로 l 이전이면 모두 l로 변환하고, l이후면 해당 문자 그대로 붙여서 출력해야 하는 문제이다.

 

처음에는 알파벳 기준을 어떻게 코드화 해야하는지 감이 잡히지 않아서, 단순하게 딕셔너리 방식으로 키-값쌍을 모두 주는 방식으로 문제풀이를 시도했다. 키로는 알파벳을, 값으로는 1부터 순서를 차례로 부여해서 문제를 풀었다.

 

이때 주의해야 할점은 딕셔너리의 값에 키로 접근할 때 따옴표는 필요없다는 점이다.

딕셔너리의 키는 항상 문자열이며 고유해야 한다. 그래서 처음에는 별생각 없이 dict['i'] 작성했더니 계속 오류가 발생했다.

 

곰곰히 생각해보니 i는 반복문 내에서 변수로 쓰이고 있는데, dict['i']는 문자열 'i'를 키값으로 딕셔너리에 접근하는 것이므로 당연히 오류가 발생할 수 밖에 없다. 즉, 반복 변수인 i를 키로 사용하는 것이 당연하다.

def solution(myString):
    dict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7, 'h':8, 'i':9, 'j':10, 'k':11, 'l':12, 'm':13, 'n':14, 'o':15, 'p':16, 'q':17, 'r':18, 's':19, 't':20, 'u':21, 'v':22, 'w':23, 'x':24, 'y':25, 'z':26}
    answer = ''

    for i in myString:
        if dict[i] <= 11:
            i = 'l'
        answer += i
    return answer

 

 

그런데 뭔가 풀면서도 이것보다 더 효율적인 방법이 있을텐데 라는 생각이 들었다..ㅎ

그래서 다른 분들의 풀이도 살펴봤다

 

def solution(myString):
    answer = ''
    for i in myString:
        if i < "l":
            answer+='l'
        else:
            answer+=i
    return answer
#lllllvwxyz

def solution(myString):
    answer = [x if x > 'l' else 'l' for x in myString]  #l보다 크면 반복변수 x로 바꾸기
    return ''.join(answer)
#lllllvwxyz


def solution(myString):
    answer = ['x' if x > 'l' else 'l' for x in myString]    #l보다 크면 문자열 'x'로 바꾸기
    return ''.join(answer)
#lllllxxxxx

print(solution("abcdevwxyz"))

 

위 두 가지 풀이를 참고해볼 수 있다. 첫번째 풀이는 풀어서 쓴 버전이고, 두 번째 풀이는 리스트 컴프리핸션을 통해 간결하게 쓴 것일 뿐 사실상 큰 차이는 없다.

 

즉, myString이라는 문자열을 x로 돌면서 l보다 크면 x를, l보다 작으면 x를 l로 변환해서 출력하는 것이다.

 

이때, 세 번째 solution함수와 같은 실수는 하면 안된다. x를 'x'로 쓰면 x가 l보다 클 때 해당 변수인 x가 아니라 문자열 'x'를 출력하겠다는 의미가 되버린다.


다른 분들의 풀이를 보면서 반복문을 도는 x는 문자열인데, 어떻게 비교연산자(<,>)로 비교가 가능한건지 궁금했다.

그래서 찾아보니 '문자열 비교'시에는 아스키 코드를 사용하기 때문에 위와 같은 연산이 가능한 것이었다.

 

즉, '>'와 '<' 연산자는 문자열을 비교할 때 ASCII 값에 기반하여 비교를 수해하는 것이다. 문제에서 문자열 myString은 모두 소문자로 구성된다고 했으므로 97~122까지의 숫자로 비교연산이 가능하다.

 

아스키 코드표

 

 

 

참고자료

https://jimmy-ai.tistory.com/73

https://ye5ni.tistory.com/180#google_vignette