#include <iostream>
#include <algorithm>
using namespace std;

bool compare(string a, string b)
{
	if (a.length() == b.length())
		return a<b;
	else return a.length() < b.length();
}

int main()
{
	int n;
	cin >> n;
	string* alist = new string[n];

	for (int i = 0; i < n; i++)
	{
		cin >> alist[i];
	}
	sort(alist, alist+n, compare);

	for (int i = 0; i < n; i++)
	{
		if (i>0 && alist[i] == alist[i - 1])
			continue;
		cout << alist[i] << endl;
	}

	delete[] alist;
	return 0;
}

 

 

 

문제: https://www.acmicpc.net/problem/1181

 

1181번: 단어 정렬

첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

www.acmicpc.net

'Baekjoon > C++' 카테고리의 다른 글

[백준 1094번] 막대기  (0) 2023.10.08
[백준 28278번] 스택 2  (0) 2023.10.06
[백준 1018번] 체스판 다시 칠하기  (0) 2023.09.24
[백준 1009번] 분산처리  (0) 2023.07.25
[백준 1012번] 유기농 배추  (0) 2023.07.25
#include <iostream>

using namespace std;

int cut(int x) 
{
	int stick = 64;
	int shortStick = 64;
	int n = 1;
	while (x < stick) 
	{
		shortStick = shortStick/2;
		if (x <= (stick - shortStick))
		{
			stick -= shortStick;
			n--;
		}
		n++;
	}
	return n;
}

int main()
{
	int x;
	cin >> x;
	cout << cut(x);
}

 

 

 

문제: https://www.acmicpc.net/problem/1094

 

1094번: 막대기

지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대

www.acmicpc.net

'Baekjoon > C++' 카테고리의 다른 글

[백준 1181번] 단어 정렬  (0) 2024.01.08
[백준 28278번] 스택 2  (0) 2023.10.06
[백준 1018번] 체스판 다시 칠하기  (0) 2023.09.24
[백준 1009번] 분산처리  (0) 2023.07.25
[백준 1012번] 유기농 배추  (0) 2023.07.25
#include <iostream>
using namespace std;

class Stack
{
public:
	Stack(int k)
	{ 
		this->length = k;
		this->top = -1;
		this->arr = new int[length];
	}
	~Stack()
	{
		delete[] arr;
	}
	void insert(int n)
	{
		top++;
		arr[top] = n;
	}
	bool isEmpty()
	{
		if (top == -1)
			return 1;
		else
			return 0;
	}
	int size()
	{
		return top + 1;
	}
	int pop()
	{
		if (top == -1)
			return -1;
		else
		{
			top--;
			return arr[top + 1];
		}
	}
	int getTop()
	{
		if (top == -1)
			return -1;
		else
		{
			return arr[top];
		}
	}


private:
	int length;
	int top;
	int* arr;
};

int main()
{
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n, command, num;
	cin >> n;
	Stack Mystack = Stack(n - 1);
	for (int i = 0; i < n; i++)
	{
		cin >> command;
		switch (command)
		{
		case 1:
			cin >> num;
			Mystack.insert(num);
			break;
		case 2:
			cout << Mystack.pop() << '\n';
			break;
		case 3:
			cout << Mystack.size() << '\n';
			break;
		case 4:
			cout << Mystack.isEmpty() << '\n';
			break;
		case 5:
			if (Mystack.isEmpty())
				cout << -1 << '\n';
			else
			{
				cout << Mystack.getTop() << '\n';
			}
			break;
		}
	}
}

 

첫 시도 때 시간초과가 떠서 아래의 코드를 메인 함수에 넣어줬다. 두 줄로 바로 해결되었다.

 

ios_base::sync_with_stdio(false);
cin.tie(NULL);

 

문제에서의 입력의 양이 많기 때문에 빠른 입출력 방식을 사용해야 했다.

 

 

 

문제: https://www.acmicpc.net/problem/28278

 

28278번: 스택 2

첫째 줄에 명령의 수 N이 주어진다. (1 ≤ N ≤ 1,000,000) 둘째 줄부터 N개 줄에 명령이 하나씩 주어진다. 출력을 요구하는 명령은 하나 이상 주어진다.

www.acmicpc.net

'Baekjoon > C++' 카테고리의 다른 글

[백준 1181번] 단어 정렬  (0) 2024.01.08
[백준 1094번] 막대기  (0) 2023.10.08
[백준 1018번] 체스판 다시 칠하기  (0) 2023.09.24
[백준 1009번] 분산처리  (0) 2023.07.25
[백준 1012번] 유기농 배추  (0) 2023.07.25

1학년 1학기 여름방학 때 동기들과 함께 2022 메타버스 개발자 경진대회에 참가했다.

우리는 360헥사월드를 이용해 직접 랜드마크 건물들을 만들고 유니티로 미래의 서울을 만드는 과제를 맡았다.

 

아래의 영상들이 1학년 5명이 모여 열심히 작업한 결과물을 담은 영상이다.

 

아래의 영상은 우리 팀의 팀장 방모씨가 우리의 결과물을 직접 나레이션하여 제작한 영상이다.

 

 

결과는 1차합격 후 2차에서 떨어졌다. (ㅠㅠ)

1차 합격 당시 매우 기쁜 상태를 보여주는 인스타 스토리다..ㅎㅎ

2차에서 떨어져 무척이나 아쉬웠다. 1차 합격한 후 2차를 위해 더 많은 아이디어를 내고 준비하고 있었던 우리였기 때문이다. 상심이 컸지만 지금 생각하면 정말 좋은 경험이라 생각된다. 

'game > unity(C#)' 카테고리의 다른 글

나만의 리듬게임 만들기 - 3  (0) 2022.09.13
나만의 리듬게임 개발일지 - 2  (0) 2022.08.10
나만의 리듬게임 개발일지 - 1  (0) 2022.07.27
2D 기초 - 3 (Jump 구현)  (0) 2022.07.21
2D 기초 - 2 (Player 이동 구현)  (0) 2022.07.14

이 프로젝트는 동아리 KHUDA에서 진행하였습니다.

 

1. 연구 배경

 카카오톡을 이용하는 많은 사람들이 카카오톡 이모티콘을 사용한다. 이모티콘은 중요한 감정표현의 수단이다. 현재 수많은 이모티콘이 존재하지만 역설적으로 이모티콘 선택 과정에 어려움이 발생한다. 이에 우리 팀은 텍스트를 통해 감정을 분석하고 이미지 데이터 기반으로 이모티콘을 추천해주는 시스템을 개발하고자 했다.

이미 '카카오톡 이모티콘 플러스'라는 서비스가 존재한다. 채팅창에 단어만 입력해도 상황에 딱 맞는 이모티콘을 추천해준다. 이 서비스의 사용자들을 대상으로 설문하고 연구한 논문에 따르면 다음과 같다.

이 설문 결과를 통해 사용자의 취향상황에 맞는 이모티콘을 추천하는 것이 중요함을 느꼈다.

 

우리 팀은 컨텐츠 기반 필터링을 바탕으로 개발하고자 했다.

Content-based Filtering란?

사용자가 소비한 아이템에 대해 아이템의 내용(content)이 비슷하거나 특별한 관계가 있는 다른 아이템을 추천하는 방법을 말한다.

아이템이 유사한지 확인하려면 아이템의 비슷한 정도(유사도)를 수치로 계산할 수 있어야 한다. 유사도 계산을 위해서 일반적으로 아이템을 벡터 형태로 표현하고 이들 벡터간의 유사도 계산 방법을 많이 활용한다.

 

표현해야 하는 데이터 범주의 영역이 넓거나 이미지와 같이 복잡한 데이터인 경우는 데이터를 고정된 크기의 벡터로 표현하는 임베딩(Embedding) 방법을 많이 사용한다.

 

우리 팀이 개발하고자 하는 서비스 모델은 다음과 같다.

이모티콘을 쓰는 사람 중 대부분은 자신이 주로 사용하는 이모티콘이 하나씩은 있을 것이다. 사용자가 기존에 사용했던 이모티콘을 input에 넣어 그림체가 유사한 이모티콘을 선별하고자 한다.

조금 더 자세한 모델 구조는 다음과 같다.

 

 

 

2. 이미지 데이터

Style Transfer의 Gram Matrix

[이론]

스타일(style)은 서로 다른 특징(feature)간의 상관관계(correlation)을 의미한다. Gij는 특징 i와 특증 j의 상관관계이다.

 

Gram Matrix(구글에 검색하면 잘 나와있으니 설명은 생략한다.)

 

[코드]

Code를 조금 살펴 보겠다. (현재 코드 원본 파일이 날라가 ppt 자료를 참고 했습니다. ㅠㅠ)

pre-trained된 ResNet을 사용한다.

ResNet(Residual neural network)는 Skip connection 방식을 사용한다. 따라서 깊이(layer)가 깊어졌을 때 발생하는 문제를 해결할 수 있다.

그리고 shape 조절 후 list에 array를 저장했다.

그런 후 ResNet 모델을 가져와 feature 정보를 추출하고 feature 행렬을 고차원에서 2차원으로 차원 축소를 하였다. 차원 축소를 한 이유는 시각화를 위해서다.

가장 가까운 이웃 3개를 계산한 후 시각화했다. 그 결과는 아래와 같다.

 

참고로 이번 프로젝트에서 사용한 이모티콘은 총 50개로, 최대한 다양하게 인기 순위에서 임의로 선정하였다.

선정한 이모티콘들

 

[결과]

 

 

 

 

[RGB Scale]

 

  • 색깔을 더 중요하게 반영하는 경향이 있음.
  • 비슷한 그림체이지만 색깔이 다르면 잡아 내지 못함.
  • 직관적으로 납득이 가지 않는 부분이 존재함.

 

 

 

 

 

 

 

 

 

 

 

[Gray Scale]

 

  • 색깔을 더 중요하게 반영하는 문제를 해결함.
  • 하지만, 그림체의 특징을 추출하는 성능이 저하함.
  • 여전히 직관적으로 납득이 가지 않는 부분이 존재함.

 

 

 

 

 

 

 

[문제점]

Covariance이므로 상대적이다. 즉, 매번 계산을 할 때마다 테스트 데이터를 포함하여 covariance를 계산해야 한다. 이를 2차원으로 mapping하는 t-SNE 과정이 오래걸리고 번거롭다. 또한 오래된 방법이라 성능이 뛰어나지 못하다.(직관적으로 납득이 가지 않는 부분이 존재한다.)

 

CLIP(Contrastive Learning In Pretraining)

[이론]

 

CLIP은 4억개의 (이미지, 텍스트) 쌍으로 학습된 모델이다. (이미지, 물체 분류) 데이터를 사용하는 다른 모델과는 달리 (이미지, 텍스트) 데이터를 사용하는 것이 특징이다. 전자의 경우에는 label이 지니는 정보의 양이 너무 적다는 단점이 있다. 이미지에 포함된 다양한 정보들 중 물체의 '종류'라는 단일 정보만을 표현하기 때문에 이미지가 가진 다양한 특징을 활용하는 데에는 한계가 있다. 그래서 우리 팀은 CLIP을 사용하고자 했다. 

우리 팀은 이모티콘의 썸네일의 특징 추출을 할 것이기 때문에 이미지 인코더 부분만 사용했다.

N개의 (텍스트, 이미지) 쌍의 배치가 주어진다고 할 때, CLIP은 그림에서 보다시피 N*N의 가능한 (이미지, 텍스트) 쌍을 예측하도록 학습된다. 따라서 만약 대각선에 위치한 positive pair의 코사인 유사도를 최대화 하고, 나머지 쌍들(negative pair)은 코사인 유사도를 최소화 하는 방향으로 Cross Entropy loss를 사용해 학습한다.

 

VIT(Vision Transformer)란?

NLP 분야에서 사용하는 Transformer를 Image Classification 분야에 맞게 약간 변형한 것이다.

이미지를 Patch로 분할 후 Sequence로 입력다. 이는 NLP에서 단어가 입력되는 방식과 동일하다.

 

[코드]

 

[결과]

이미지 오른쪽 상단에 루피(결과: 파란색)와 사람 이미지(결과: 빨간색)를 입력으로 넣은 결과이다. 유사도가 가장 높은 5개를 체크 해두었다.

루피에 대한 결과를 보면 먼저 루피와 똑같은 시리즈인 이모티콘들은 모두 유사도가 가장 높게 나왔고 루피와 비슷한 포즈를 한 동물들이 그 다음으로 높게 나온 것을 확인할 수 있다.

사람 이미지에 대한 결과를 보면 똑같은 실제 사람 이모티콘의 유사도가 가장 높게 나온 것을 확인할 수 있고 실제 사람은 아니지만 사람 형태를 한 이모티콘이 그 다음으로 높게 나온 것을 확인할 수 있다.

 

이후 투표 시스템을 추가했다.

 

 

 

3. 텍스트 데이터

  • 감정에 맞게 이모티콘을 추천해주는 것이 주제이므로 다중 분류 모델로 학습을 진행했다.
  • 충분한 대화 데이터 셋 확보가 어려워 사전 훈련된 모델을 사용했다.
  • 사전 학습 모델 중 한국어로 학습한 koBERT 모델이 가장 성능이 좋다.

 

[데이터 수집]

아래를 참고해 총 84MB 가량의 데이터를 확보했다.

1. 한국어 감정 정보가 포함된 단발성 대화 데이터셋

2. 한국어 감정 정보가 포함된 연속적 대화 데이터셋

3. 감성대화 말뭉치

4. 온라인 구어체 말뭉치 데이터

 

[데이터 전처리]

  • 중복되는 감정을 통합함.
  • json 파일에서 필요한 내용만 추출하여 정리함.
  • 필요없는 column은 제거함.

 

[데이터 증강]

라벨링이 되지 않은 데이터를 ChatGPT API를 이용해 라벨링을 진행했다.

Data augmentation: I want you to classify this text to '불안, 당황, 분노, 슬픔, 중립, 행복, 혐오', the text is '%sentence_input

그 결과 1.1MB의 데이터를 추가적으로 확보할 수 있었다.

 

[코드]

pre-trained된 KoBERT 모델을 이용했다. 분류하려는 감정 개수, 클래스 수를 6으로 설정 했다.

KoBERT에 대한 내용은 다음의 링크를 참고해 주세요. (https://velog.io/@seolini43/KOBERT%EB%A1%9C-%EB%8B%A4%EC%A4%91-%EB%B6%84%EB%A5%98-%EB%AA%A8%EB%8D%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0-%ED%8C%8C%EC%9D%B4%EC%8D%ACColab)

 

[결과 - 1]

 

매 epoch마다 모델 학습 결과를 저장했고 Epoch 3 이후 test acc가 감소하여 학습을 중단 시켰다. 가장 test acc가 높게 나온 epoch3의 모델을 활용했다.

 

1차 결과

 

  • '혐오'의 경우가 잘 드러나지 않았다. '혐오'를 '분노'에 통합시켰다.
  • test acc가 0.7 정도로 train acc에 비해 낮았다.
  • 행복 데이터를 기준으로 데이터 비율 재수정 후 2차학습을 진행했다.

 

[결과 - 2]

이번에도 epoch 3 이후에 test acc가 감소했고 가장 높게 나온 epoch3의 모델을 활용했다. 모델에 텍스트를 입력한 결과는 다음과 같다.

 

[한계점]

  • 데이터 비율이 고르지 못했다.
  • ChatGPT로 데이터 증강을 시도했으나 과연 잘 된 것인지 검증을 하지 못했다.
  • 이모티콘 라벨링 과정에서 부정적인 감정이 별로 없었다.

 

 

4. 최종 결과

최종 결과는 가독성을 위해 ppt 자료를 이용 하겠다.

[Example 1]

가장 먼저 실사 인물 형태의 이모티콘을 이미지 input으로 줬을 때의 이미지 추천 결과이다. 

그리고 텍스트 input을 입력하고 난 뒤 최종적으로 선정된 이모티콘들은 다음과 같다.

 

 

[Example 2]

두번째 예시로는 실제 사람은 아니지만 인물 형태의 이모티콘을 input으로 넣었다. 텍스트를 입력한 뒤 나온 최종 결과는 아래와 같다.

 

 

[Example 3]

마지막으로는 동물 형태의 이모티콘을 주로 사용한다고 가정하였다. 결과는 다음과 같다.

 

5. Review

 생각보다 좋은 결과가 나온 것 같아 뿌듯했다. 나는 이미지 데이터를 주로 맡아 개발을 했다. 약 2주라는 정말 짧은 시간 안에 프로젝트를 진행해야 했던 터라 이론을 완벽하게 공부하지 못하고 진행한 면이 없지 않아 있다. 추후 다시 프로젝트를 리뷰하며 이론을 확실히 하는 시간을 가지면 좋을 것 같다. 팀원들이 다양한 분야를 희망하고 있었기 때문에 추천 시스템, 컴퓨터비전, 자연어 처리 분야를 모두 섞은 프로젝트가 된 것 같다. 세 분야에 대해 경험과 지식이 없었던 나로써는 정말 좋은 경험이 되지 않았나 싶다. 당장은 이 분야들을 공부할 계획은 없지만 나중에 공부하게 된다면 아마 이번 프로젝트가 도움이 되어 좀 더 수월하게 공부할 수 있을 것이라 생각한다.

#include <iostream>
#include <string>

using namespace std;

int count(int n, int m, char* board[]) {
	int num = 2500;
	int num1 = 0;
	int num2 = 0;
	int result=2500;

	for (int a = 0; a < n - 7; a++) {
		for (int b = 0; b < m - 7; b++) {
			num1 = 0;
			num2 = 0;
			for (int i = a; i < 8 + a; i++) {
				for (int j = b; j < 8 + b; j++) {
						if ((i + j - a - b) % 2 == 0) {
							if (board[i][j] == 'B') {
								num1++;
							}
							else
								num2++;
						}
						else {
							if (board[i][j] == 'W')
								num1++;
							else
								num2++;
						}
				}
			}
			num = num1 > num2 ? num2 : num1;
			if (result > num)
				result = num;
			//cout << num1 << " " << num2 << " " << result << endl;
		}
	}

	return result;
}

int main() {
	int n, m, result;
	cin >> n >> m;
	char** board = new char * [n];

	for (int i = 0; i < n; i++) {
		board[i] = new char[m];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> board[i][j];
		}
	}


	result = count(n, m, board);

	cout << result;


	for (int i = 0; i < n; i++)
		delete[] board[i];

	delete[] board;
}

 

체스판을 무조건 8x8로 잘라낸다는 조건과 W으로 시작할 지, B으로 시작할 지에 집중했다.

 

 

 

문제: https://www.acmicpc.net/problem/1018

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

'Baekjoon > C++' 카테고리의 다른 글

[백준 1094번] 막대기  (0) 2023.10.08
[백준 28278번] 스택 2  (0) 2023.10.06
[백준 1009번] 분산처리  (0) 2023.07.25
[백준 1012번] 유기농 배추  (0) 2023.07.25
[백준 1010번] 다리 놓기  (0) 2023.07.24

man-month: 한달에 투입되는 사람수(소프트웨어를 개발할 때 얼마나 많은 사람이 투입되어야 하는가), 정량적 수치

1 man-month: 한 사람이 한달동안 풀로 들어가는 것

12 M/Ms = 12명이 1달 = 1명이 12달?에 대한 문제 발생 -> 문제가 없는 논리이지만 소프트웨어에서는 안 통한다.

늦어진 소프트웨어 프로젝트에 사람을 추가하는 것은 더 늦게 끝나게 한다.

 

책(직접 겪었던 프로젝트 관리 실패담들을 모은 책)에서 강조한 것

man-month

Second system effect

prototyping

 

이전처럼 소프트웨어를 관리하는 것은 실패

-> man-month쓰기 부적절, 변수가 많음. 환상이다.

   길어지는 이유

   1.새로운 사람 뽑으면 교육하는데 오래 걸림

        (애자일로 training 시간이 더 오래 걸리게 됨. 문서 수가 적으므로)

Man-month의 문제점: SW개발에서 서로 다른 팀끼리의 소통이 필수적이지만 사람이 늘어나면 소통이 길어질 수밖에 없다.

 

케이스 바이 케이스(no silver bullet)

한가지 방법이 모든 문제에 적용되지는 않는다.

!!!!!!!경험이 레퍼런스가 될 수 있으나 다른 문제의 솔루션이 될 수 없음!!!!!!!!!!!!!

이렇게 해결 가능한 완전 재사용가능한 프로그램은 없음

 

Second-system Effect

첫번째 시스템에서 느꼈던 아쉬운 점, 못 만든 기능들을 다 넣을려고, 만들려고 한다. 따라서 반드시 필요한 개선점이 들어가야 하는 것이다. 오버하는 것은 지양해야 한다.

Over-engineering

개발자들의 문제를 관리자들이 이해해야함 그리하지 못함

!!!!!!!!!!!!! Second-system에는 반드시 필요한 것들만 추가 개선!!!!!!!!!!!!!

 

Irreducible number of errors

버그가 없는 프로그램은 존재하기 힘들다. 따라서 작은 버그는 두고 큰 버그들을 해결해야 한다. 정성, 정량적으로 버그의 level을 나눠서 사소한 버그들은 두고, 큰 버그들을 다뤄야 한다.

 

Progress tracking

수면 위에 드러나지 않은 문제들로 전체적인 시간 delay가 있을 수 있다.

소프트웨어 개발이 어떻게 1년이나 늦어지는 거지? 하루에 한 시간씩 늦어지면 그럴 수도 있지.

애자일: 데일리 스크럼등으로 자주 대화하는 이유가 이러한 문제들을 파악하고 해결함

즉 각자 알아서 하라고 내버려두는 것이 아니라 소통을 통해 문제들 파악하게 하는 것

 

Conceptual integrity

소프트웨어를 만들 때 소프트웨어가 가져야 할 철학, 일관성

Waterfall 방식인 것 같음.

시스템 아키텍쳐: 시스템을 설계(기술적인 부분)

프로젝트 매니저: 프로젝트를 관리, 행정을 한다.

하나의 시스템 설계팀이 철학, 일관성에 따라 결정한다. Ex) 스티브 잡스, 다이슨

하나의 설계팀에서

SW의 전체적인 구조 설계와 철학, 일관성을 고려한 결정을하고 계획함

추가적인 기능등도 일관성 측면에서 판단하고 추가 또는 배제함

 

The Manual(개발과 관련됨, 시스템 아키텍쳐가 쓰는 것)

설계자가 매뉴얼 정의 -> 맞춰서 개발

The pilot system(권장 사항) = Prototype(주요 기능을 구현해보고 확인하고 나서 버린다.)

첫번째로 만든 시스템은 대부분 시행착오를 겪고 잘못된 설계 하에 채워질 수 있으니 상용화 하지 말고 버려라.

프로그램에서 검증해야할 중요한 것들 중심으로 먼저 만들어보기

 

Formal documents(project manager)

Product Manager(PM): 관리쪽(개발X)

이들이 만드는 문서에는

프로젝트의 목적, 누가 만드는지, 언제 만들어질 건지, 비용 등

포함됨 (개발관련 X)

 

project estimation:

공식적인 개발과 관련된 일정을 누가 얼마에 하는지 등을 계산(행정)

어떤 SW를 파는 것은 만드는 것과 다른 얘기

상용화 하기 위한 준비기간이 매우 김

waterfall일때 전체 기간의 30퍼센트만 개발 기간이 주어짐

 

Communication

큰 문제 피하기위함

탑다운일 때, 내가 결정하는 것이 아닌 물어봐야함(전체철학에 맞는지)

업무의 경우 이메일로(주장 및 근거, 책임...)

통화, 대화로 하지 않는다

 

The surgical team

파일럿 팀: 유능한 사람들이 먼저 개발하고

그 뒤에 대체 인력 투입

개발자의 능력은 동일하지 않다.

 

Code freeze and system versioning: 코드를 얼린다=개발을 종료한다.

오류가 있어도 code freeze 했으면 손을 데지 않아야 한다. 완벽할 수는 없다.

요구 사항을 더이상 받지 않고 개발 종류 선언

완벽한 SW가 아닐 수 있으나 괜찮음 원래  그럼

 

Specialized tools

개발 도구를 직접 개발한다. 반복적인 일을 도구로 만든다. Ex) 업무 자동화.

Ex) projectlibre

 

Lower software development costs

소프트웨어 개발 비용을 낮추는 것이다. 어떤 조직에서는 개발하는 사람이 항상 필요하지는 않다.

코딩이 필요한 시간에만 개발자를 고용하라

요구사항을 만족하는 오픈소스나 상용 제품이 있다면 그것을 그냥 쓰는 것도 나쁘지 않다.

오픈소스 라이선스: 소프트웨어를 출시하고 사용할 때 신경 써야 할 중요한 부분

오픈소스의 정의

배포된 소스코드를 자유롭게 복사, 수정, 사용, 재배포 할 수 있는 소프트웨어를 뜻한다.

 

오픈소스 선택 시 고려사항

품질: 기능(우리가 원하는 기능이 있는가?), 성능, 호환성(얼마나 수정해야 하는가?) 등 오픈소스의 품질은 오픈소스를 선택하는 데 가장 중요한 요소다. 개발자 입맛에 따라 오픈 소스가 만들어지므로 오픈소스의 클래스, 메소드들이 다 다르다. github에서의 sta, fork수(정성적 정량 수치)로 오픈소스의 완성도를 가늠할 수 있다. 오픈소스를 사용하려는 기술 조직은 당연히 충분한 기능과 성능 검증을 수행한 후 제품/서비스에 도입해야 한다.

 

커뮤니티: 오픈소스가 얼마나 사용자를 보유하고 있는지, issue 관리는 이루어지고 있는지, 지속적으로 업데이트를 하는 지 등, 지속가능한 오픈소스를 선택해야 한다.

 

문서화: 문서화가 잘 되어있으면 기업이 도입하는 데 수월하다. 설명이 잘 되어 있는 것을 선택한다.

 

보안 취약점: 사용하려는 오픈소스의 버전이 보안 취약점이 있는지 확인 후 사용해야 한다. 보안은 OS 보안, 네트워크 보안, 웹 보안으로 나뉘는데 웹 보안이 가장 문제가 많다. CVE 사이트에서 사용하려는 오픈소스 보안 취약점을 체크해라.

 

라이선스: 오픈소스를 “재배포 시” 준수해야 할 의무사항을 요구한다. 가장 간단한 의무인 고지 의무부터 가장 복잡한 의무인 소스 코드 공개 의무까지.

GPL: 관련된 모든 소스코드를 공개(가장 강력한 라이센스)

 

 

오픈소스와 법적 책임

라이선스를 지키지 않으면 사용 권리가 박탈되고 제품을 판매할 수 없다. 또한 수익을 능가하는 돈을 내야 할 수도 있다. 기업 이미지에 큰 손실을 끼친다. 법적 소송에 연루될 수 있다.

 

 

오픈소스도 저작권 지식 재산권 존재

!!!!!!!!소스코드가 공개 되도 오픈소스 라이센스가 없으면 오픈소스가 아님!!!!!!!

 

 

오픈소스 라이선스의 주요 의무 사항

1. 저작권 표시 및 라이선스 고지: 가장 약한 라이선스, 소스 코드 파일 상단에 주석을 달거나 README 파일 안에 고지한다.

2. 소스코드 공개

3. 재배포시 동일 라이선스 적용: “Copyleft”

2,3을 동시에 요구하는 라이센스: GPL

오픈소스를 사내에서 테스트 용도로 사용한다면, 의무사항은 부과되지 않는다.

OSI: 오픈소스에 해당하는 라이선스의 최소한의 기준을 정의 해놓고 이 정의에 따라 오픈소스 라이선스를 인증함.

 

아무 조건 없이 사용 가능한 라이선스

Creative Commons Zero

The Unlicense: 아무런 제한을 걸지 않는 라이선스(아무런 제한을 걸지 않아도 라이선스를 등록 해야한다.)

수월하게 사용 가능한 라이선스(Permissive License)

오픈소스 라이선스의 고지 의무가 있는 라이선스

Ex) BSD, JSON License, MIT License, Microsoft Public License, Python Software Foundation License, Independent JPEG Group License

주의가 필요한 copyleft 라이선스

GPL은 재배포 시 소스코드 공개를 요구한다. +Create commons attribution.

이러한 오픈소스는 설계 단계에서부터 build 시 자사 소프트웨어와 통합되지 않고 runtime에도 독립된 프로세스로 동작되도록 해야한다.

GPL-3.0 같은 경우에는 제품을 배포하기 위해 소스 코드뿐만 아니라 설치 정보를 함께 제공해야 한다.

Weak Copyleft

LGPL: 메모리를 공유하는 방식인 Dynamic Linking 방식은 봐준다.

별도의 실행 파일을 통신으로 하면 GPL 라이선스를 겪지 않을 수 있다. LGPL Library 부분만 소스 코드를 공개하면 되고, 결합하는 코드는 공개를 하지 않아도 된다.

+apple, mozilla, eclipse

 

static linking: 코드가 링킹되어 하나의 실행 파일안에 링킹되어 있을때, 99개중 1개가 GPL 라이선스면 배포 시 100개가 모두 GPL이 걸리는 것이다.

dynamic linking: 별도 파일(dll)로 존재하여 필요할 때 메모리에 올려 사용

 

GPL: static,dynamic 둘다 소스코드 공개, 재배포시 동일 라이선스 적용

lGPL: dll은 봐주는 약화된 GPL

GPL우회법: 별도 프로그램 두개로 만들어서 '통신'으로 연결함

 

사용 제한 라이선스

네트워크에서는 gpl보다도 agpl이 더 강력하다. 서버에 agpl의 오픈소스가 있다면 배포하지 않아도 함께 링크되어 동작하는 다른 소프트웨어의 소스코드까지 agpl로 공개해야 한다. 회사의 핵심 서버 프로그램까지도 공개해야 하는 위험이 있다.

광고 조항 포함 라이선스도 있다.

 

소스코드 제공 의무 유형

GNU GPL, GNU AGPL: 모든 소스 코드를 공개해야함

GNU LGPL, NASA: static하게 연결된 모든 걸 열어라(파생 작업물)

Mozila, Sun public license: 코드가 아닌 파일 공개, 파일 단위로 열어라, 다는 아님.

이클립스: 모듈 단위(함수, 함수의 변형된 형태 공개), 다는 아님.

~ : 수정된 부분만 파일 단위로 공개

~ :모듈(함수의 수정된 부분만 모듈 단위로 공개)

 

Apache: 고지의무

GNU GPL

카피레프트, 자유 소프트웨어 재단에서 만든 라이선스, 배포하는 경우 무조건 GPL로 공개해야 한다. Dynamic Linking을 해도 GPL 라이선스.

별도의 실행 파일을 두개로 만들어서 통신으로 연결하면 GPL 라이선스를 겪지 않을 수 있다.

EX) 리눅스 커널, 워드프레스

GNU AGPL(server)

서버에 agpl의 오픈소스가 있다면 배포하지 않아도 함께 링크되어 동작하는 다른 소프트웨어의 소스코드까지 agpl로 공개해야 한다.

Ex) 몽고DB

 

GNU LGPL

좋은 자유 소프트웨어 제품이 더 많이 쓰이고 표준이 되도록 유도하기 위해 단순한 라이브러리, 모듈 링크를 허용한 라이선스.

EX) 모질라 파이어폭스

 

MIT License

MIT에서 소프트웨어 공학도들을 돕기 위해 개발한 라이선스. 가장 느슨한 조건을 가진 라이선스 중 하나이다. 고지의무를 가진다.

EX) 부트스트랩, Backbone.js, jQuery

 

BSD License

버클리의 캘리포니아 대학에서 배포하는 라이선스다. 공공의 몫으로 돌려주자는 의미가 강하다. 저작권 표시 조건 외에는 제약이 없다.

EX) Nginx

 

 

주의가 필요한 copyleft 라이센스

가장 강력함!

GPL이 여기 속함

 

Creative common 라이센스, 뒤에 붙는 레벨에 따라 다름!

지적 재산권을 명시하면서도 사용을 허용함

 

기능정의 후 개발 전 관련 라이센스 등을 다 확인

 

weak copyleft:

LGPL: DLL에 대해서 완화해준다.(약간 완화됨)

이클립스: lgpl에 속하는 오픈소스

소스코드 말고도 설치 정보등의 사용자 제품에대한 정보도 공개해야함

다이나믹 link에대해서 dll은 봐줌(PPT 참조)

대부분의 법적 절차는 '기간'이 치명적임

그 정도 기간이면 웬만한 스타트업은 못버티고 사라짐

 

사용 제한 라이선스

GNU affero : 옾소가 들어간 서버가 인터넷 서비스 -> 이건 재배포에 해당하니까 코드 공개

따라서 많은 기업들이 금지함

광고를 포함한 라이선스 : 요구사항 준수가 어려워 대부분 사용을 금지함

 

대표적인 오픈소스 라이선스

 

[GPL이 무서운 이유]

내가만든 실행파일에 GPL 라이선스 포함되면 전부 공개

 

static link,Dynamic linking: 동일한 메모리를 공유하면 전부 해당됨

 

몽고DB: Affero GPL(통신으로~ 소스코드 다운가능해야함)

 

LGPL: 분리되어 있는 경우, 봐줌(라이브러리,모듈 링크를 허용함)

정적링크는 소스코드와 앱의 오브젝트 코드도 공개해야함

 

Mozilla Public License(MPL)

개발자 편향적(GPL과 반대)

소스코드와 실행파일의 저작권을 분리함!

실행파일은 내꺼

 

MIT License

가장 느슨, 법적 고지문을 카피해서 포함하는 형태면 충분

bootstrap,angular.js

 

Berkeley Sw Distribution (BSD)

라이센스 및 저작권 표시하면 끝

0. Decorator Pattern이란?

 데코레이터 패턴은 객체의 추가적인 요건을 동적으로 추가하는 패턴이다. 중심이 되는 객체가 반환하는 값에 추가적으로 더해져서 결과값을 반환한다.

 

 

1. goal

 데코레이터 패턴은 특정 객체의 기능을 정적으로 확장(장식)하는 데 사용할 수 있다. 하나의 객체에 부가적인 기능을 덧붙여 많은 객체에게 다양한 부가기능을 쉽고 빠르게 적용하는 것이 목표이다. 다시 말해 객체가 동적으로 움직이고 있는 중에 특정 기능을 추가하고 뺄 수 있도록 하는 것이다.

 

 

2. Detail

 중심이 되는 객체를 놔두고 추가적인 사항을 첨가하는 방식이라 객체에 기능을 추가 또는 삭제할 때 중심이 되는 객체를 수정하지 않고 동적으로 추가 또는 삭제할 수 있다는 장점이 있다. 객체 지향의 원칙 중 확장에는 열려 있고 변경에는 닫혀 있어야 한다는 원칙인 OCP(Open-Close Principle)에 충실한 패턴이다. 데코레이터 패턴을 사용하게 되면 기존 객체는 변경하지 않고 자유로운 확장을 구현할 수 있으며 기존 객체 혹은 데코레이터가 수정되더라도 해당 클래스의 내용만 수정해주면 되기 때문에 변경에 대해서도 닫혀 있다. 또한 기본적인 데이터에 첨가하는 데이터가 일정하지 않고 다양할 때 데코레이터 패턴을 사용하면 효율적으로 사용할 수 있다. 반면에 데코레이터를 너무 많이 사용하게 되면 자잘한 객체가 많이 추가될 수 있고 오히려 코드가 복잡해질 수 있다는 단점이 있다.

 

[상속과의 차이점]

상속은 하위 클래스를 생성하는 방법으로 확장을 하며 데코레이터 패턴은 기본 객체에 추가하는 객체를 생성하는 방법으로 확장을 한다. 상속은 오버라이딩을 통해 기능을 전부 명시해 줘야 하지만 데코레이터 패턴은 기본 기능은 놔두고 추가되는 기능만 명시해 줄 수 있다는 차이가 있다.

 

[Composite 패턴과 차이점]

다양하고 일정하지 않은 여러 객체들을 하나의 객체로 묶는 것을 Composite 패턴이라고 한다. Composite 패턴은 목적이 생성되어 있는 객체들 간의 합성에 있고 데코레이터 패턴은 목적이 객체에 새로운 행동을 추가하는 데에 있다.

 

[Strategy 패턴과의 차이점]

Strategy 패턴은 유사한 행위를 캡슐화하는 인터페이스를 정의하여 객체들의 행위를 유연하게 확장하는 방법이다. Strategy 패턴은 객체의 내부를 변화시키며 데코레이터 패턴은 새로운 객체를 추가하여 객체를 변경시킨다는 점에서 차이가 있다.

 

 

3. UMLs

Component: 동적으로 추가할 객체들의 인터페이스 역할을 한다.

 

ConcreteComponent: 제공할 서비스의 베이스가 되는 컴포넌트를 정의한다.

 

Decorator: Component 객체에 대한 참조자를 관리(인스턴스 변수로 소유)하면서 Component에 정의된 인터페이스를 만족하도록 인터페이스를 정의한다.

 

ConcreteDecoreator: Component에 추가할 내용을 구체적으로 구현한다.

 

 

 

 

 

 

 

4.     Code Example

 위젯을 그리는 프로그램을 만든다고 가정하고 여러가지 위젯 중 캘린더 위젯을 만들고 위젯은 Scroller, Boarder로 구성할 수 있다.

[Component]

class WidgetComponent {

public:

    virtual void Draw() = 0;

};

 

[ConcreteComponent]

class CalendarWidget: public WidgetComponent {

public:

    virtual void Draw() {

        cout<<"Draw Window"<<endl;

    }

};

 

[Decorator]

class Decorator: public WidgetComponent {

public:

    Decorator(WidgetComponent* comp): component(comp){};

   

    virtual void Draw() {

        component->Draw();

    }

   

private:

    WidgetComponent* component;

};

 

[ConcreteDecorator]

class BorderDecorator: public Decorator {

public:

    BorderDecorator(WidgetComponent* comp)

    :Decorator(comp){}

   

    virtual void Draw() {

        Decorator::Draw();

        DrawBoarder();

    }

   

private:

    void DrawBoarder() {

        cout<<"Draw Boarder"<<endl;

    }

};

 

class ScrollDecorator: public Decorator {

public:

    ScrollDecorator(WidgetComponent* comp)

    :Decorator(comp){}

   

    virtual void Draw() {

        Decorator::Draw();

        DrawScroll();

    }

   

private:

    void DrawScroll() {

        cout<<"Draw Scroll"<<endl;

    }

};

 

[실행]

int main(int argc, const char * argv[]) {

    WidgetComponent* widget = new CalendarWidget();

    widget = new BorderDecorator(widget);

    widget = new ScrollDecorator(widget);

   

    widget->Draw();

   

    return 0;

}

 

[실행 결과]

Draw Window

Draw Boarder

Draw Scroll

'강의 정리 > 오픈소스sw개발방법및도구' 카테고리의 다른 글

Project Management  (0) 2023.08.31
Opensource License  (0) 2023.08.31
Design Pattern  (0) 2023.08.31
Online Co-work Education  (2) 2023.08.31
Try unittest & unittest.mock for your own SW  (0) 2023.08.31

Design Pattern의 효과
Design Pattern을 통해 내가 만들 소프트웨어에 어떤 class가 존재해야 하고 그들의 관계는 어떠해야 하는지를 빠르게 이해하고 접근할 수 있다.
최근 언어들은 Hello World!! 부터가 아닌
최소한의 구조가 갖춰진 프로젝트 형태에서 시작함
 
Design Pattern을 재사용하는 이유
재사용: 생산성(보다 빠른 시간안에 소프트웨어를 출시하기 위함)과 신뢰성(그 패턴이 오랫동안 사용되어 와서 대부분의 문제가 정리되었다고 봄) 증가, 개발 시간 감소
디자인 패턴도 재활용, 재사용한다.
 
Design Pattern
흔히 발생하는 문제에 대한 솔루션을 재사용한다. 특정 프로그래밍 언어의 특징을 반영하지 않는다. 코드와 밀결합된 것이 아니다. Class와 그들의 상관관계에 대한 것이다. 알고리즘의 상위개념이다.
객체지향 디자인 패턴: 전형적으로 클래스나 오브젝트 간의 상관관계를 보여준다.

 
Adapter Pattern
신입 사원이 주로 쓴다.
목표: 기존의 클래스, 코드를 수정하지 않으면서 서로를 연결하기 위해 만들어졌다. (건들면 안 되는 입력 파라미터 3개를 요구하는 adaptee와 입력 파라미터 1개를 요구하는 adaptee를 연결해주기 위해 중간에 adapter를 끼워 맞추는 것이다.) 양립 불가능한 인터페이스를 가진 클래스들을 작동하게 하기위한 코드이다.
Adapter 클래스가 adaptee를 호출한다.
c++에서는 adapter class가 어댑티 클래스를 상속했다.
C++은 다중 상속이 됨( istream, ostream을 상속받는 iostream)
다중 상속이 안되면, mixing class를 사용함.
Adaptee: 수정X
Adapter: 우리가 작성, 수정하는 코드
1대1의 관계
Adapter class가 adaptee를 부르고 클라이언트의 입력을 연결해주는 역할
adaptee, 클라이언트를 안 고쳐도 됨!
 
Façade Pattern
1대n의 관계
겉면만 모양을 유지하고 뒤는 좋게 바꾸는 것이다.
목적: 사용자의 interface는 바꾸지 않겠다.
Client가 Façade class를 호출하면 파사드는 필요에 따라 다른 클래스를 호출한다. 파사드 클래스의 메소드 안에서 클래스의 객체를 생성한다.
성능이 좋지 못하다는 단점이 있다.
사용자가 복잡한 서브 시스템에 직접 접근하지 못하도록 한다. 예쁜 인터페이스로 입구를 차단해버림
내부에 작동하는걸 외부에 보여줄 필요가 없다.
모든 프로그래밍 언어의 기본 철학
Information hiding, Encapsule 좋음
 
Decorator Pattern
객체가 동적으로 움직이고 있는 중에 특정 기능을 추가하고 뺄 수 있다. 게임에서는 아이템이나 무기를 추가할 수 있도록 하는 디자인 패턴이다. 즉 기능을 추가할 수 있다.
1대n의 관계

Component를 base로 하여 concreteComponent와 decorator class를 생성하고 decorator를 base로 하는 concreteDecorator class를 생성한다. Decorator는 component 클래스와 has relationship 관계이다. 이때 ConcreteComponent는 가장 기본적인 아무것도 없는 캐릭터이고, concreteDecorator는 갑옷, 칼, 총 등 추가되는 아이템들이다.
ConcreteComponent: 가장 기본적인 아무것도 없는 캐릭, 먼저 실행됨
ConcreteDecorator: 갑옷, 칼, 총 등 추가되는 아이템들
 
Singleton
반드시 하나의 객체만 존재해야 한다. 절대로 이 클래스에서 만들어진 객체가 두 개 이상이면 안 된다. Ex) 자원을 관리하거나 중요한 데이터를 관리하는 프로그램에서 사용됨, 하드웨어의 자원은 물리적으로 하나이다. 두개 이상의 제어가 발생할 경우 충돌한다.
 
최근에 나온 소프트웨어 디자인 관련 책: clean code, clean, architecture
디자인 패턴은
SW 설계에 있어 시행착오를 줄여 줌
Design Pattern은 매우매우매우 호불호가 갈릴 수 있음
클래스 다이어그램으로 시각화
언어마다 구조가 다를 수 있음 -> Dependency
 
디자인 패턴의 비판
1. poor language
언어가 별로 안 좋아서 기능적을 부족한 게 많아서 디자인 패턴을 고민하는 것 아니냐?
23개 중 16개 의미가 없었음
-> 그래도 7개는 의미 있네, 쓰기 싫으면 쓰지마 (호불호 갈림)
2. 불필요하게 복잡성만 높인다.

디지털 노마드의 정의

디지털 노마드: (직장이 아닌 다른 곳으로 떠나) 원하는 곳에서 개발하거나 일할 자유를 말한다. 유목민이라고 말하기도 한다.

어디에서 일하는 지를 정하는 대신 그 선택에 책임을 져야 한다.

 

디지털 노마드를 찬성하는 고용주의 입장

고용주들은 전세계적으로 최고의 인재를 모을 수 있다. 중견, 중소 기업에서 국내의 인재들을 데려오기 힘들 때 다른 나라에 있는, 예를 들어 비교적 인건비가 저렴한 인도에서 경쟁력 있는 인재를 고용할 수 있다.

 

디지털 노마드를 찬성하는 개인 개발자의 입장

편리하다는 장점이 있다. 이동시간이 감소된다는 점, 집을 새로 마련하지 않아도 된다는 점, 주거비. 식사. 교통 면에서 직장에 출근하여 직장에서 일하는 것보다 비용이 적게 든다. 즉 경제적 부담이 감소된다. 또한 근무 시간이 자유롭다는 장점이 있다.

 

Covid 이전과 이후의 디지털 노마드를 찬성하는 이유

Covid 이전에는 훌륭한 인재를 채용하기 위해 디지털 노마드를 했다면, Covid 이후에는 직원을 한 곳에 모아두지 않는다면 돈을 안써도 된다는 것을 깨닳았기 때문이다. 예를 들어 직원을 한 곳에 모아뒀을 때 들어가는 부동산 값, 커피 값, 식당 등 업무 환경을 위해 드는 잡다한 비용이 많다.

 

이전에는 직원의 움직임, 장소에 벗어나는 것 등에 압박

이후에는 거점 오피스 등이 많이 생기고 장소 압박이 적다 (문화적 변화)

 

어디서 디지털 노마드를 하는지, 그리고 그 기준은?

기준

1.인터넷이 빠른가?

2.물가가 싼가?

장소

일본, 캘리포니아: 집 가격이 비싸서 비대면을 좋아함

한국은 치안이 괜찮은편이다. 그래서 서울로 많이들 디지털 노마드 하러 온다.

제주도에서 가장 열심이다.

제주도에는 다음, 카카오 본사가 있다. 장소에 독립적인(회사가 어디 있든 문제없는) 개발사들을 위치시켜 지역 활성화를 유도한다. 제주도가 그 예시이다.

 

워케이션: work+vacation: 휴양지 등에 회사를 위치시킨다.

 

디지털 노마드 tools

Slack은 Collaboration을 위한 것이다. 업무용 채팅 소프트웨어이고 개발 도구와 연동이 된다. 과거의 기록을 찾아볼 수 있다.

구글 드라이브는 Team Work를 위한 것이다.

Zoom은 Communication을 위한 것이다.

Doist(Item Manager), TRELLO(Project Manager), Parabol(Agile Meeting)

 

보안 때문에 웹에서 IDE를 구현하는 경우도 있음

애초에 코드가 세어 나가지 않도록

애자일 스크럼, 깃허브 etc...

기업에도 채팅 시스템 존재:

채팅 로그, 트래픽 분석을 통해 직원의 영향력 등을 파악함

다 감시하고 인사과에서 유용하게 씀

실제로 네이버 비즈니스 플랫폼은 기업들한테 제공하는 서비스

 

기업들은 빠르게 서비스를 만드는 것이 중요함

-> 웹 서비스 구현을 전부 오픈소스로 해버림

    -> 서비스 사용화 시간 단축

 

미네르바 대학

크게 5개 학과로 나눠 여행하면서 온라인으로 수업 받음. 여러 나라로 여행을 다니면서 교육을 함. “비판적인 사고, 창의적인 사고, 효율적인 소통”

전 세계 7개의 도시를 순환하면서 학생들이 함께 생활하는 하이브리드 주거 모델을 제공함.

철학: 고등 교육의 위기, 꼭 대학에서 해야 할 필요가 없음, 대학에서는 실용적 지식을 가르쳐야 함, 글로벌 문화, 다 차원적인 교육, 우리 시대의 가장 복잡한 문제를 해결하는 데 필요한 광범위한 지식과 실용적인 기술

MIT는 서로 다른 전공의 사람들이 모여 협업하고 인프라 제공에 대학의 의미가 있다고 함.

인류 존속에 관한 문제 해결을 위한 학과 존재함.

과 5개: 예술&인문학, computational sciences(컴퓨터를 도구로 삼아 문제를 해결함, engineer 계열은 아님), 자연 과학, 사회 과학, 비즈니스

computational sciences: 컴퓨터로 사회 문제를 분석한다. Computer science가 아니다.

문제를 찾아서 해결하는 방식으로 가르침. Learn the critical skills you need to make evidence-based, data informed decisions.

Tokbox: Active Learning Platform

Uncertainty: 불확실성에 대한 대비로 개인의 능력을 기른다

불확실한 미래에 대해 개인 주도적 문제 정의 및 해결을 위함

여행은 이러한 문제정의에 대한 도움

 

프랑 에꼴 42: 교수가 없는 교육 기관 -> 한국에서도 모방해 42서울을 만듦.

1. unittest

 Unittest를 처음 경험해보기 때문에 먼저 매우 간단한 코드를 통해 unittest를 해보았다. myCalc.py 파일에 input 파라미터를 두 개를 받아 더한 값을 return 해주는 add함수와 input 파 라미터로 두 개를 받아 첫 번째 input에서 두 번째 input을 뺀 값을 return 해주는 substract 함수 를 정의했다.

 

 

그리고 나서 unittest를 위한 test.py 파일을 작성했다. unittest.TestCase로부터 파생된 MyCalcTest 클래스를 생성했다. 그리고 test_add와 test_substract 테스트 메서드를 작성했고, 그 안에서 self.assertEqual()를 사용하여 결과를 검사했다. 마지막 줄에서 unittest.main()이 실행되면, 테스트 메서드들이 실행되게 된다.

여기서 주의할 점은 테스트 메서드의 이름은 반드시 test로 시작해야 한다는 것이다. 그래야 테스트를 실행할 때 해당 메서드가 누락되지 않고 정확히 테스트 케이스로 인식이 된다.

 

 

unittest 모듈의 TestCase 클래스틑 assertEqual 말고도 assert로 시작하는 많은 메서드를 제공한다.

MyCalcTest 클래스는 TestCase 클래스를 상속하고 있기 때문에 부모 클래스인 TestCase가 제공하는 모든 메서드를 self를 통해 접근하여 호출할 수 있다.

IDLE에서 test.py를 실행한 결과는 다음과 같다. 두개의 메서드를 통과했기 때문에 점( . )이 2개가 찍히는 것을 볼 수 있다.

 

 

참고로 점( . )대신에 좀 더 자세한 피드백을 받고 싶다면 -v 옵션을 붙여서 테스트를 실행하면 된다.

test_add 메서드와 test_substract 메서드가 잘 실행된 것을 볼 수 있다.

test_add 메서드를 아래와 같이 수정하고 test.py 파일을 실행하면,

 

 

테스트가 실패했다고 알려주며 어떤 부분이 틀렸는지를 피드백 해준다.

 

 

2. unittest.mock

 mocking이란 단위 테스트를 작성할 때 외부에 의존하는 부분을 임의의 가짜로 대체하는 기법 이다. 즉, 외부 서비스에 의존하지 않고 독립적으로 실행이 가능한 단위 테스트를 작성하기 위해 서 사용되는 테스팅 기법이다. 다른 사람의 코드를 사용해 짠 코드를 테스트해야 하는데 아직 다 른 사람이 코드를 다 작성하지 못했을 때 사용한다.

test.py를 수정하여 unittest.mock를 사용해 코드를 작성하고 실행시켜 보았다. 결과는 아래와 같다.

 

 

20과 10을 더하면 30이지만 mock을 통해 실패하지 않고 정상이라 판단되었다.

 

 TDD 기법에 대해 공부한 후 직접 unittest를 해보니 더 잘 와닿는 것 같다. 평소에 소프트웨어 를 작성하는 방식과는 조금 달라 신기했지만 생각보다 괜찮은 기법이라고 여겨진다. 다음에 소프 트웨어를 개발할 대 TDD 기법을 이용해 해봐도 좋을 것 같다는 생각이 들었다.

+ Recent posts