알고리즘 [탐색] - 순차탐색(linear search) 알고리즘

|

순차검색(Sequential Search), 선형검색 알고리즘(linear search algorithm)

  • 리스트에서 찾고자 하는 값을 맨 앞에서부터 끝까지 차례대로 찾아 나가는 것
  • 시간복잡도 O(n)

구현코드

def sequential_search(s, key):
    i = 0
    while i < len(s):
        if s[i] == key:
            return i
        i += 1
    return -1


def sequential_search2(s, key):
	for idx, val in enumerate(s):
		if val == key:
			return idx
	return -1

순차탐색 vs 이진탐색

  • 시간복잡도를 비교하면 순차탐색 O(n), 이진탐색(O(log n)으로 이진 탐색이 훨씬 빠르다.
  • 단, 이진탐색은 데이터가 정렬되어 있어야 한다는 전제 조건이 있다.
  • 일반적인 정렬 알고리즘은 O(n log n)의 시간 복잡도를 가지기에 이진탐색이 반드시 좋다고 할 수 없다.
  • 따라서 상황에 맞는 알고리즘을 선택하는 것이 중요하다.

reference

lambda함수 를 활용한 구구단 생성

|

문제

람다함수와 리스트 컴프리헨션을 사용해 한 줄로 구구단의 결과를 갖는 리스트를 생성해본다.

풀이코드

[(lambda x,y : '{}x{}={}'.format(x, y, x*y))(x, y) for x in range(2,10) for y in range(1,10)]
  • (람다함수)(인자)처럼 람다함수 뒤에 인자를 바로 할당 할 수 있다.
# 쉬운 예시
>>> (lambda x,y: x*y)(2,3) # 6

기본 셸을 zsh로 변경, .zshrc 백업을 위한 심볼릭 링크파일 생성

|

기본 셸 변경

zsh

http://theyearlyprophet.com/love-your-terminal.html
bash와 비슷하게 동작하는 셸로, 사용성이 좋다.

리눅스

sudo apt-get install zsh
curl -L http://install.ohmyz.sh | sh
chsh -s `which zsh`

brew install zsh zsh-completions
curl -L http://install.ohmyz.sh | sh
chsh -s `which zsh`
  • chsh: /usr/local/bin/zsh: non-standard shell 오류 발생할 경우
sudo vim /etc/shells
맨 아래에 `which zsh`했을때의 결과를 추가 후 저장
  • 현재 shell 확인법 : echo $SHELL

백업을 위한 심볼릭 링크파일 생성

  • root 폴더내의 원본 설정 파일을 드롭박스 settings 폴더 안으로 옮긴다
  • 해당 원본파일에 대한 심볼릭 링크 파일을 root 폴더내에 만든다. (바로가기 같은 것)
  • -s 옵션 : 심볼릭 링크파일을 생성
  • 링크파일 생성
❯ mv .zshrc ~/Dropbox/settings # 원본을 Dropbox/settings/ 폴더로 이동
❯ ln -s ~/Dropbox/settings/.zshrc ~/ # 심볼릭 링크파일 생성
  • root 폴더의 .zshrc는 Dropbox 원본을 가르키고 있으며, 수정시 Dropbox 내의 파일이 함께 수정된다.

사용자 인증 (django.contrib.auth)

|

AskDjango 수업을 듣고 중요한 내용을 정리하였습니다.

django.contrib.auth 앱을 통한 회원가입/로그인/로그아웃

인증 관련 기본설정

  • global settings에 정의된 인증관련 기본 설정
  • 위치 : django/django/conf/global_settings.py
from django.conf import settings # << 해당 위치의 global settings 내용
# local settings.py에서 오버라이딩 가능

# 기본 로그인 페이지 URL 지정
# login_required 장식자 등에 의해서 사용
LOGIN_URL = '/accounts/login/'

# 로그인 완료 후 next 인자가 지정되면 해당 URL 페이지로 이동
# next 인자가 없으면 아래 URL로 이동
LOGIN_REDIRECT_URL = '/accounts/profile/'

# 로그아웃 후에 next 인자기 지정되면 해당 URL 페이지로 이동
# next 인자가 없으면 LOGOUT_REDIRECT_URL로 이동
# LOGOUT_REDIRECT_URL이 None(디폴트)이면, 'registration/logged_out.html' 템플릿 렌더링
LOGOUT_REDIRECT_URL = None

# 인증에 사용할 커스텀 User 모델 지정 : '앱이름.모델명'
AUTH_USER_MODEL = 'auth.User'

인증 관련 주요 모델필드

  • 위치 : django/django/contrib/auth/models.py
class AbstractBaseUser(models.Model):
    password = models.CharField(max_length=128)
	last_login = models.DateTimeField(blank=True, null=True)
	...

class PermissionsMixin(models.Model):
    is_superuser = models.BooleanField(default=False)
	...

class AbstractUser(AbstractBaseUser, PermissionsMixin):
	username = models.CharField(max_length=150, unique=True)
	first_name = models.CharField(max_length=30, blank=True)  
	last_name = models.CharField(max_length=30, blank=True)
	email = models.EmailField(blank=True)
	is_staff = models.BooleanField(default=False)
	is_active = models.BooleanField(default=False) # 로그인 허용 여부
	date_joined = models.DateTimeField(default=timezone.now)

class User(AbstractUser): # 우리가 사용하는 User 모델
	...

class AnonymousUser: # 로그아웃 유저를 표현하는 클래스 (모델아님)
	...

AbstractUser 클래스 주요 속성, 멤버함수

  • .is_authenticated : 로그인여부 (속성)
  • .is_anonymous : 로그아웃 여부 (속성)
  • .set_password(raw_password) : 지정 암호를 암호화해서 password 필드에 저장 (save함수 호출 안함)
  • .check_password(raw_password) : 암호비교
  • .set_unusable_password() : 로그인 불가 암호로 세팅 (암호를 통한 로그인X, 외부인증 OAuth에 의한 유저일 경우)
  • .has_unusable_password() : 로그인 불가 암호 설정여부

User 모델 클래스 획득 방법 (중요)

직접 User 모델 import (비추)

  • global settings 오버라이딩을 통해서 인증 User 모델을 다른 모델로 변경할 수 있음
from django.contrib.auth.models import User

User.objects.all()

get_user_model helper 함수를 통해 모델 클래스 참고 (추천)

from django.contrib.auth import get_user_model

User = get_user_model()
User.objects.all()

settings.AUTH_USER_MODEL 을 통한 모델클래스 참조 (추천)

from django.conf import settings # 추천!
from django.conf.auth.models import User # 비추
from django.db import models

class Post(models.Model):
	author = models.ForeignKey(User) 		# 비추
	author = models.ForeignKey('auth.User') # 비추
	author = models.ForeignKey(settings.AUTH_USER_MODEL) # 추천!

뷰 에서 현재 로그인 유저 획득하는 방법

  1. FBV : request.user
  2. CBV : self.request.user
    • 로그인 상태 :settings.AUTH_USER_MODEL 클래스 인스턴스
    • 로그아웃 상태 :django.contrib.auth.models.AnonymousUser 클래스 (모델 인스턴스가 아님, 다른 모델과 관계 불가능)
    • context_processor를 통해서 user가 모든 view에 context로 기본 제공 됨

git 도구 - 커밋 수정, 삭제 rebase

|

Pro Git Book 을 읽고 주요 내용을 정리합니다.

마지막(가장 최근) 커밋 수정하기

  • 커밋 메시지를 수정하려면 아래 명령을 사용한다.
$ git commit --amend
  • 커밋 파일을 추가하거나 삭제하려면 git add 명령으로 Staging Area에 넣거나 git rm 명령으로 추적하는 파일 삭제한다. 그리고 git commit --amend 명령으로 커밋하면 된다. 이 명령은 현 Staging Area의 내용을 이용해서 수정한다.

과거 커밋 메시지 여러개 수정하기

  • git rebase 를통해서 어느 시점부터 HEAD 까지의 커밋을 한번에 Rebase 한다.
  • 이미 중앙서버에 Push 한 커밋은 절대 고치지 말아야 한다. Push 한 커밋을 Rebase 하면 결국 같은 내용을 두 번 Push 하는 것이기 때문이다.
$ git rebase -i HEAD~3 # HEAD에서 부터 최근 3개의 커밋 표시한다
  • 특정 커밋에서 실행을 멈추게 하려면 스크립트를 수정해야 한다. pick이라는 단어를 ‘edit’로 수정하면 그 커밋에서 멈춘다.
  • git commit --amend 를 통해서 멈춘 커밋의 이전 커밋 메시지를 수정할 수 있다.
  • 커밋 메시지를 수정하고 텍스트 편집기를 종료하고 나서 git rebase --continue 명령을 실행한다.
  • 다른 것도 pick을 edit로 수정해서 이 작업을 몇 번이든 반복할 수 있다

커밋 삭제, 순서 바꾸기, 합치기

  • 대화형 Rebase 도구로 커밋 전체를 삭제하거나 순서를 조정하거나, 합칠 수 있다.
  • 커밋 리스트에서 삭제하고 싶은 커밋을 삭제하고, 순서를 변경하면 그대로 적용된다.
# 대화형 Rebase 실행
$ git rebase -i HEAD~3 # HEAD에서 부터 최근 3개의 커밋 표시한다
  • squash를 입력하면 Git은 해당 커밋과 바로 이전 커밋을 합칠 것이고 커밋 메시지도 Merge 한다.
  • 저장하고 나서 편집기를 종료하면 Git은 3개의 커밋 메시지를 Merge 할 수 있도록 에디터를 바로 실행해준다.

모든 커밋에서 특정 파일 제거하기

  • git filter-branch --tree-filter명령을 통해서 passwords.txt 같은 파일을 히스토리에서 삭제할 수 있다.
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD