반응형

출처: https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html

 

누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog

누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!

backlog.com

이미 출처에서 잘 설명해주고 있지만, 나 스스로도 공부할 겸 포스팅을 진행한다.

개발을 팀단위로 할 때 다른 개발자들과 하나의 소프트웨어를 개발한다. 누군가는 버그픽스, 누군가는 새로운 기능 추가를 한다.

이렇듯 서로 다른 목적의 개발을 한 프로젝트에서 진행하기 때문에 각각 서로 다른 버전의 코드가 만들어 진다.

이럴때 여러 개발자들이 동시에 다양한 작업을 할 수 있게 만들어주는 기능이 브랜치다. 각자 독립된 로컬 레포지토리에서 소스코드를 변경하고 이후에 원래의 버전과 비교해서 하나의 새로운 버전으로 만들어낼 수 있다.

아래 그림을 보자. 여러 명이서 동시에 작업을 할 때의 흐름을 알 수 있다. 각자 맡은 작업의 브랜치를 생성해서 해당 작업을 마친 후 master 브랜치에 머지함으로서 소프트웨어의 완성도를 높일 수 있다. 또한, 브랜치 기록은 남으므로 어떤 시점이 문제인지, 복원도 가능하다.

 

작업에 따라 자유롭게 브랜치 생성이 가능하지만, 더욱 효과적으로 관리하려면 같이 일하는 작업자와 어떠한 방식으로 브랜치를 만들고 통합할 것인지 정해두는 것이 좋다.

우리가 만들 수 있는 브랜치의 종류는 다음과 같다.

통합 브랜치(Integration Branch)

언제든지 배포할 수 있는 버전을 만들 수 있어야하는 브랜치이다. 안정적인 상태를 유지하는 것이 중요하다. 일반적으로 master 브랜치가 통합 브랜치이다.

토픽 브랜치(Topic Branch)

기능 추가나 버그 수정과 같은 단위 작업을 위한 브랜치이다. 여러 개의 작업을 동시에 진행할 때 그 수만큼 토픽 브랜치를 생성할 수 있다.

토픽 브랜치는 통합 브랜치로부터 만들어지며 작업이 완료되면 통합 브랜치에 병합하는 방식으로 진행된다. 피처 브랜치(feature branch)라고도 불린다.

반응형

'Git' 카테고리의 다른 글

Git branch 심화  (0) 2022.04.10
Git merge  (0) 2022.04.09
.gitignore 설정  (0) 2022.03.31
Github 간단 설명  (0) 2022.03.17
반응형

내가 pull 한 뒤 다른 사람이 동일 저장소에 push할 경우 그 이후의 나의 push는 거절된다. 버전의 분기점이 되기 때문이다.

이때 2가지 경우가 있다.

  1. 내가 건드린 파일이 다른 사람이 수정한 파일과 의존성이 없는 경우
  2. 내가 건드린 파일이 다른 사람이 수정한 파일과 의존성이 있는 경우

1번의 상황에선 자동 merge가 가능하다. merge를 할 경우 내 로컬 레포지토리에 다른 사람의 수정 작업이 병합된다.

2번의 경우가 문제가 된다. 충돌이라하는 부분이다.

깃에서 충돌 부분을 표시해주는데 

위와 같이 표시해주며 ===== 윗부분이 로컬저장소, 아랫 부분이 원격 저장소의 변경 내용이다.

표시된 부분을 원하는 버전으로 고쳐주고 다시 커밋을 수행하면 된다.

 

출처: https://backlog.com/git-tutorial/kr/intro/intro5_2.html

반응형

'Git' 카테고리의 다른 글

Git branch 심화  (0) 2022.04.10
Git branch  (0) 2022.04.10
.gitignore 설정  (0) 2022.03.31
Github 간단 설명  (0) 2022.03.17
반응형

OOP가 무엇일까?

Object-Oriented Programming의 약자로 객체지향 프로그래밍이란 뜻이다.

프로그래밍의 종류에는 절차지향, 객체지향, 함수지향이 있다. (더 있을 수 있는데 여기까지..)

절차지향은 말그대로 위에서부터 주우욱 읽어가는 코드로 C언어 등이 있다.(요즘은 구조체로 객체의 느낌이 나지만 자세히는 모름)

객체지향으론 유명하게 파이썬과 java가 있다. 객체를 구성해서 프로그래밍하는 것인데 class를 만드는 것이다.

함수지향은 자료처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임이라한다. 자바스크립트 등이 있다.(잘 모르겠다...)

일반적으로는 객체지향을 잘 하면된다.- 제일 많이 쓰이니까!

객체지향이란 것은 객체를 생성해서 프로그래밍한다는 뜻인데 여기에는 룰이 존재한다. 그것이 5대 원칙이다. 지켰으면 좋겠다...라는 뜻

서론은 여기까지 하고, 5대원칙에 대해 설명해보자.

5대 원칙은 약자로 SOLID라고 하는데 각각 SRP(단일 책임 원칙), OCP(개방-폐쇄 원칙), LSP(리스코프 치환 원칙), DIP(의존 역전 원칙), ISP(인터페이스 분리 원칙)의 앞글자를 따서 만들어졌다. 

각각에 대해 알아보자.

단일 책임의 원칙(Single Responsibility Principle, SRP)

하나의 모듈은 한 가지 책임을 가져야한다는 것이다. 다른말로 작성된 Class는 하나의 기능만 가지며, 그 Class가 제공하는 모든 서비스는 하나의 책임을 수행하는 데 집중되어야한다는 것이다. 

예를 들어보자. 회원가입의 기능을 하는 SignUp class가 존재한다고 하자. SignUp 클래스 안에는 회원 가입을 담당하는 기능만 존재해야 한다. (로그인이나, 유저 삭제 등의 기능이 들어가면 안된다.) SignUp 클래스를 고쳤을 때 회원가입 기능만 문제가 발생하여야한다. 

만약 단일 책임 원칙을 지키지 않았을 경우에는 하나의 class에 다양한 기능이 들어가 있다는 뜻인데, 해당 클래스를 수정했을 때 다른 모듈에 어떠한 영향을 미치는지 그 범위를 추측하기 힘들 수 있다.

아래의 예를 보면 유저를 입력하는 메소드에 비밀번호를 암호화하는 코드가 SignUp 클래스 안에 혼재해 있다. 비밀번호 암호화 코드를 다른 클래스로 빼자. 

class SignUp:
    def insertUser(self, userId, userPw):
        ...
        #something insert user to DB code
        ...
        #something password encrypt code
		...
class SignUp:
	SimplePasswordEncoder simple_password_encoder
    
	def insertUser(self, userId, userPw):
        ...
        #something insert user to DB code
        ...
        
 class SimplePasswordEncoder:
 	def encryptPassword(pw):
    	...

위와 같이 클래스단위로 구분했는데, 그럼 왜 SingIn 클래스에 암호화 메소드를 추가하지 않느냐? 라는 의문이 든다. 나도 그렇게 생각했는데 이것이 바로 단일 책임이라는 것이다. 클래스(객체)가 단일 책임만 갖는 것이다.

단일 책임의 장점은 변경이 필요할 때 수정할 대상이 명확하다는 것이다.

개방 폐쇄 원칙 (Open-Closed Principle, OCP)

확장에 대해 열려있고 수정에 대해서는 닫혀있어야 한다는 원칙으로, 각각이 갖는 의미는 다음과 같다.

  • 확장에 대해 열려있다: 요구사항이 변경될 때 새로운 동작을 추가하여 애플리케이션의 기능을 확장할 수 있다.
  • 수정에 대해 닫혀있다: 기존의 코드를 수정하지 않고 애플리케이션의 동작을 추가하거나 변경할 수 있다.

내 상사가 나한테 암호화 알고리즘의 고도화가 필요하다고 요청을 한다. 그럼 한 번 위의 코드에서 바꿔보자.

class SignUp:
	ComplexPasswordEncoder complex_password_encoder
    
	def insertUser(self, userId, userPw):
        ...
        #something insert user to DB code
        ...
        
 class ComplexPasswordEncoder:
 	def encryptPassword(pw):
    	...
        #something powerful encrypt code
        ...

SimplePasswordEncoder를 ComplexPasswordEncoder로 수정했다. 그런데, 기존의 코드였던, 그리고 암호화 정책과 무관한 SignIn 코드도 고쳐야만 했다.

이 부분은 수정에 대해 닫혀있다라는 원칙에 위배된다. 이 부분을 해결하려면 추상화를 이용해야한다.

추상화 관련 내용은 이 링크를 따라가자

내가 이해한 내용을 바탕으로 예제를 보자.

from abc import *

class SignUp:
	PasswordEncoder password_encoder
    
	def insertUser(self, userId, userPw):
        ...
        #something insert user to DB code
        ...
        
class PowerPWEncoder(metaclass=ABCMeta):
	@abstractmethod
    def encryptPassword(self, pw):
    	...
        #something powerful encrypt code
        ...

class PasswordEncoder(PowerPWEncoder):
	def encryptPassword(self, pw):
	   	return super().encryptPassword()

위와 같은 방식을 이용하면 상속 클래스만 바꿔도 패스워드 암호화 방식을 변경할 수 있다. 파이썬에서 인터페이스가 따로 존재하지 않으므로 위 코드에서 PasswordEncoder 클래스를 인터페이스 클래스로 사용하였다. 

 

인터페이스 분리 원칙(Interface Segregation Principle, ISP)

객체가 충분히 높은 응집도의 작은 단위로 설계됐더라도, 목적과 관심이 각기 다른 클라이언트가 있다면 인터페이스를 통해 적절하게 분리해야한다. 즉, 인터페이스 분리원칙이란 클라이언트의 목적과 용도에 적합한 인터페이스만을 제공하는 것이다.

인터페이스 분리 원칙을 준수하면 모든 클라이언트가 자신의 관심에 맞는 퍼블릭 인터페이스만을 접근하여 불필요한 간섭을 최소화할 수 있다. 

위 코드에서 사용자가 비밀번호를 변경할 때 입력한 비밀번호가 기존의 비밀번호와 동일한지 여부를 판단해야하는 클라이언트가 있다고 생각해보자. 이때 PowerPWEncoder 클래스에서 encryptPassword를 동일하게 사용해줘야한다. 이유는 이미 기존의 비밀번호들은 강화된 암호화를 이용해 저장되어 있기 때문에 rawPW를 입력받아 강화된 암호화를 적용해서 기존의 암호와 비교해야하기 때문이다.

 

from abc import *

class SignUp:
	PasswordEncoder password_encoder
    
	def insertUser(self, userId, userPw):
        ...
        #something insert user to DB code
        ...
     
        
class PowerPWEncoder(metaclass=ABCMeta):
	@abstractmethod
    def encryptPassword(self, pw):
    	...
        #something powerful encrypt code
        ...
  
class PowerPWChecker(metaclass=ABCMeta):
	@abstractmethod
    def encryptPassword(self, pw):
    	...
        #something powerful encrypt code
        ...
    
    @abstractmethod
    def isCorrectPassword(self, rawPW, pw):
    	pass

class PasswordEncoder(PowerPWEncoder):
	def encryptPassword(self, pw):
	   	return super().encryptPassword()
        

        
class PasswordChecker(PowerPWChecker):
	def encryptPassword(self, pw):
	   	return super().encryptPassword()
    
    def isCorrectPassword(self, rawPW, pw):
    	encryptPW = encryptPassword(rawPW)
        return encryptPW.equals(pw).

이렇듯 클라이언트가 원하는 대로 인터페이스를 분리하여 불필요한 접근을 최소화해줄 수 있다.

 

리스코프 치환 원칙(Liskov Substitution Principle, LSP)

1988년 바바라 리스코프가 올바른 상속관계의 특징을 정의하기 위해 발표한 것이다. 하위 타입은 상위 타입을 대체할 수 있어야 한다는 것이다. 즉, 해당 객체를 사용하는 클라이언트는 상위 타입이 하위 타입으로 변경되어도, 차이점을 인식하지 못한 채 상위 타입의 퍼블릭 인터페이스를 통해 서브 클래스를 사용할 수 있어야 한다는 것이다.

두 가지를 지키면 된다고 한다.

  1. 하위 클래스는 상위 클래스에 정의된 것보다 사전조건을 엄격하게 만들면 안된다.
  2. 하위 클래스는 상위 클래스에 정의된 것 보다 약한 사후조건을 만들면 안된다.

하위 클래스의 메소드에 특정 변수가 필요한데, 상위 클래스의 메소드에 그 변수가 없을 경우 에러가 남.

상위 클래스의 메소드를 하위 클래스가 오버라이딩 할 경우 메소드의 기능은 동일해야함.

리스코프 치환 원칙을 준수하려면 상위 클래스의 메소드를 그대로 상속 받고 하위 클래스에서 필요한 기능을 추가하는 방향으로 가는 것이 좋다.

 

의존 역전 원칙 (Dependency Inversion Principle, DIP)

고수준 모듈은 저수준 모듈의 구현에 의존해서는 안되며, 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다는 것이다.

고수준 모듈: 변경이 없는 추상화된 클래스(또는 인터페이스)

저수준 모듈: 변하기 쉬운 구체 클래스

다시 말하자면 메인 스트림이 고수준의 모듈인 인터페이스에 의존되고 인터페이스는 구현체에 의존되어야 한다는 것이다.

개방폐쇄원칙과 밀접한 관련이 있으며 의존 역전 원칙이 위배되면 개방 폐쇄 원칙 역시 위배되게 될 가능성이 높다.

 

위의 SOLID는 추상화의 중요성을 말하고 있는 듯하다. 추상 클래스를 잘 활용하여 확장, 수정이 용이한 객체 지향적인 코드를 프로그래밍해보자.


반응형

'Python' 카테고리의 다른 글

"파이썬으로 데이터 분석하기: 주식 시장 예측 모델링"  (0) 2023.04.19
디자인 패턴  (0) 2022.04.14
추상클래스(abstract class)  (0) 2022.04.09
덕 타이핑이란?  (0) 2022.04.09
opencv cv2.imshow 에러 해결방법  (0) 2022.03.31
반응형
  • 추상클래스란 미구현 추상메소드를 한개 이상 가지며, 자식클래스에서 해당 추상 메소드를 반드시 구현하도록 강제합니다.
  • 상속받은 클래스는 추상메소드를 구현하지 않아도, import할 때까지 에러는 발생하지 않으나 객체를 생성할 시 에러가 발생합니다.
  • 추상메소드는 생략하면 기본적인 클래스 기능은 동작합니다만, 추상메소드를 추가한 후에는 객체를 생성하면 에러가 발생합니다.
  • abc 모듈을 import해야 합니다. abc는 Abstract Base Class의 약자입니다.
  • 추상 메소드 위에 @abstractmethod 데코레이터를 달아줍니다.
  • 추상클래스의 매개변수에 metaclass=ABCMeta를 입력해줍니다.

예제를 한 번 봅시다.

from abc import *

class AbstractPerson(metaclass=ABCMeta):
	
    @abstractmethod
    def sleep(self):
		pass
    
    @abstractmethod
    def eat(self):
		pass
        
class Walter(AbstractPerson):

    def sleep(self):
		print('zzZ')

    def eat(self):
		print('냠냠')

위의 코드에서 추상 메소드를 구현하지 않으면 에러가 난다.

추상클래스를 공부하며 어려운 부분이 왜 사용하냐 인데 이는 상위 클래스인 추상클래스를 이용하여 코드를 재사용하면서 시간을 절약할 수 있고, 수정을 할 경우 다른 코드의 영향도를 적게하기 위하여 사용한다. 그리고 추상 클래스는 하위 클래스에게 추상메소드를 구현하라고 강요하는 역할을 한다.

반응형

'Python' 카테고리의 다른 글

디자인 패턴  (0) 2022.04.14
OOP 5대 원칙(python 예제 포함)  (0) 2022.04.09
덕 타이핑이란?  (0) 2022.04.09
opencv cv2.imshow 에러 해결방법  (0) 2022.03.31
pix2pix augmentation  (0) 2022.03.31
반응형

동적 타이핑의 한 종류로 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말한다.

여기서 동적 타이핑이란, 자료형 검사가 컴파일이 아닌 런타임에 수행될 경우를 말한다. 파이썬과 같은 언어는 인터프리터 언어로 런타임때 자료형 검사가 진행된다.

클래스 상속이나 인터페이스 구현으로 타입을 구분하는 대신, 덕 타이핑은 객체가 어떤 타입에 걸맞은 변수와 메소드를 지니면 객체를 해당 타입에 속하는 것으로 간주한다. 비유를 하자면 아래와 같다.

만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다.

즉, 객체의 타입을 구분할 때 이건 어떤 객체이기 때문에 무슨무슨 특징을 갖는다. 라고 하는 것 보다. 이 객체는 어떤 어떤 특징을 가졌기 때문에 어떤 객체이다. 라고 표현하는 것이 내 이해의 상한선이다...

농담을 섞자면 난 ESTJ이기 때문에 꼰대다 보다는 꼰대이니까 ESTJ랄까?

예제를 한 번 보자.

def calculate(a, b, c):
    return (a+b)*c

a = calculate(1, 2, 3)
b = calculate([1,2,3],[4,5,6],2)
c = calculate("a","b",3)

print(a)
print(b)
print(c)
9
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
ababab

이것이 바로 런타임에 자료형이 결정되는 덕타이핑이라는 것이다.

반응형
반응형

gitignore란 무엇이냐하면

git add를 할 때 제외하고 싶은 파일 명 패턴을 입력하는 것이다.

만약 딥러닝 프로젝트를 한다 치면 데이터 셋들이 있는데 이를 전부 레포지토리로 옮길 순 없다. 파일 용량 제한 때문에...

그러니까 .git이 있는 곳에서 뭐... 대충

*.png
*.jpg
*.h5

등을 적으면 원하는 파일들만 업로드가 가능하다.

반응형

'Git' 카테고리의 다른 글

Git branch 심화  (0) 2022.04.10
Git branch  (0) 2022.04.10
Git merge  (0) 2022.04.09
Github 간단 설명  (0) 2022.03.17
반응형

정말 개같은 에러가 계속 났다. 아래와 같은 에러인데 검색해서 모든 방법을 다 해봤다.

conda에서 지우고 다시 깔고 opencv-contrib-python 깔고 다해봤는데 다 다다다다다안됐다.

cv2.error: OpenCV(4.5.5) /io/opencv/modules/highgui/src/window.cpp:1268: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

 

그럼 어떻게 해결했느냐?

pip list를 입력해서 opencv-python-headless가 있으면 지우자

pip uninstall opencv-python-headless

그럼 드디어 웹캠이 된다.....

반응형

'Python' 카테고리의 다른 글

추상클래스(abstract class)  (0) 2022.04.09
덕 타이핑이란?  (0) 2022.04.09
pix2pix augmentation  (0) 2022.03.31
기본적인 베이스 코딩 구조(Class 개념 - 붕어빵 비유)  (0) 2022.02.03
exception print하기  (0) 2022.01.26
반응형

도커가 완전히 망가졌다.

완전 삭제 후 재설치만이 답인 듯  하다. 망가진 이유는 모르겠다. 내가 안했다.

일단 도커 엔진을 삭제하자

sudo apt-get purge -y docker-engine docker docker.io docker-ce docker-ce-cli
sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce

그 다음 사용자가 만든 도커 관련 데이터를 다 삭제해주자.

sudo rm -rf /var/lib/docker /etc/docker 
sudo rm /etc/apparmor.d/docker 
sudo groupdel docker 
sudo rm -rf /var/run/docker.sock

사실 한번에 도커관련 모든 내용을 지우려면 아래와 같은 명령어를 입력하면 되는데 아무래도 루트부터 파인드해서 삭제하는건 리스크가 있어서 난 시도 안한다.

sudo find / -name "*docker*" -exec `rm -rf` {} +

그리고 도커 설치

sudo apt-get install docker-ce docker-ce-cli containerd.io

도커 설치가 한 줄로 되다니 신기방기스

 

반응형

+ Recent posts