함수의 정의


함수는 여러개의 문장을 하나로 묶어 주는 역할을 하며, 직접 구현을 하거나, 이미 정의되어 있는 함수를 사용 할 수 있다.

반복적으로 사용 할 수있고, 함수 내부에 다른 함수를 호출 할 수도 있다.


함수를 선언하는 방법은 다음과 같다.


def <함수명>(매개변수1, 2, ... N ):

     <구문>

     return <반환값>


예제 )

def test (a, b ):

c = a + b

return c


위와 같이 test라는 함수를 내가 정의를 한다면, 이제 test라는 함수가 생성되고, 다른 함수 내에서 test를 사용 할 수 있게 된다.

test(20,10)을 입력하면 30이 반환된다. 





스코핑룰


먼저 코드를 통해서 예를 들어 보자.


value = 1000  --- ( 1 )


def example():

   value = 200  --- ( 2 )


다음 (2)와 같이 example이라는 함수 내에서 value라는 값에 200을 대입하면 (1)의 값이 200으로 바뀔까? 

아니면 example이라는 함수 내에서 200이라는 값으로 초기화된 value가 생길까??? 


파이썬에서는 스코핑룰에 대해 모르고 변수에 대해 접근을 한다면 생각치 못한 결과를 가져 올 수 있다.


위의 예제에서는 전역함수에서의 value와 함수 내의 지역변수 value 2가지의 value가 생성되었다고 생각하면 된다. 파이썬 내에서는

변수를 지역, 전역, 내장의 순서로 검색을 한다. 그렇다면 만약 example 함수 내의 지역에서 value라는 값을 접근하고 싶다면 어떻게 하면 될까?


value = 1000

def example():
global value
value = 200

example()
c = value
print(c)

위와 같이 global 키워드를 통해 value를 선언하여 주면 전역변수 value를 사용하겠다고 선언하는 것과 같다. 위의 예제를 실행하면

value의 값은 200이 출력이 된다.





람다함수


람다함수는 이름이 없는 함수이다. 즉 다른 함수들 처럼 이름을 통해 호출 하는 것이 아닌 필요로 하는 위치에서 몸체만 정의하여 사용 하는 것이다.


lambda 인자 : < 구문 >


- 람다함수 내에서는 return 구문을 따로 적지 않지만, 하나의 반환 값을 돌려준다. 

- 여러 개의 인자를 일반함수와 동일하게 전달 받을 수 있다.


예제 ) 

x = 3
y = 3

value = (lambda _x, _y : _x * _y) (x,y)
print(value)
출력결과 = 9



pass


함수 지역 내에 아무런 동작도 취하지 않고 넘어 가겠다고 선언하는 키워드


예제)

def test():
pass

test()

출력결과 = 




이터레이터


리스트, 튜플 등 순회 가능한 객체의 각 요소를 순서대로 접근 할 수 있도록 해주는 객체


예제)


l = [1, 2, 3, 4, 5, 6]

for ele in l:
print(ele)


출력결과 :  1

               2 

               3

               4

               5

               6


원리는 다음과 같다. for문 내에서 이터레이터 객체를 가져오고, 이터레이터 내의 __next__() 함수를 실행한다. 그 다음 for문은 StopIteration 예외를 만날때까지 __next__() 함수를 수행한다. 이렇게하여 첫번째 요소부터 마지막 요소까지 순회를 할 수 있다.

__next__()는 내장함수인 next()를 통해서도 사용가능하다.


name = "jaehoon"

it = iter(name)

s = next(it)
print(s)

s = next(it)
print(s)

s = next(it)
print(s)
print ( it.__next__())
print ( it.__next__())


출력결과 :

첫번째 print :  j

두번째 print : a

세번째 print : e

네번째 print : h

다섯번쨰 print : o

   




제너레이터


이터레이터를 만들어주는 도구로서 함수의 반환을 return 대신 yield를 사용한다.


예제)


#1
def returnName():
name = "jaehoon"
for c in name:
yield c

result = iter( returnName() )

print( result.__next__() )
print( result.__next__() )
print( result.__next__() )
print( result.__next__() )
print( result.__next__() )

#2
for c in returnName():
print(c)



#1의 경우 yield가 아닌 return 이였을 경우 j만 반환되고 Stopoperation 예외가 반환이 된다. return을 통해서 해당 함수를 종료하였기 때문이다.

하지만 yield이기 때문에 함수가 최근 호출되었던 정보 상태로 유지가 되기 때문에 

#1의 출력결과는 


첫번째 print :  j

두번째 print : a

세번째 print : e

네번째 print : h

다섯번쨰 print : o 




#2번의 경우 


첫번째 print :  j

두번째 print : a

세번째 print : e

네번째 print : h

다섯번쨰 print : o 

여섯번쨰 print : o 

일곱번쨰 print : n


로 앞서 배웠던 이터레이터 객체를 사용하는 것과 같은 결과가 나온다.



#include <iostream>
#include <cstring>
using namespace std;
struct Node
{
char m_cName[20];
int m_iHp;
int m_iMp;
int m_iSpeed;
int m_iRange;
char m_cPosition[20];
Node* next;
};
//////////////////
// 함수 //
//////////////////
int Menu();
void InputData();
void Insert( char* name, int hp, int mp, int speed, int range, char* position );
void PrintAll();
void Search();
void Delete();
void PositionDeleteAll();
void FindMaxHp();
void SortByHp();
//////////////////
// 변수 //
//////////////////
Node *head = NULL;
char inputName[20];
int inputHp;
int inputMp;
int inputSpeed;
int inputRange;
char inputPosition[20];
int maxHp;
int sortFlag;
//////////////////
// 메인 //
//////////////////
int main()
{
Insert("럭스", 477, 334, 330, 550, "mid");
Insert("베이가", 492, 342, 340, 525, "mid");
Insert("벨코즈", 507, 325, 340, 525, "bottom");
Insert("징크스", 517, 245, 325, 525, "bottom");
Insert("오리아나", 517, 334, 325, 525, "mid");
Insert("트위치", 525, 287, 330, 550, "jungle");
Insert("앨리스", 529, 324, 335, 550, "jungle");
Insert("바드", 535, 350, 330, 500, "bottom");
Insert("코그모", 546, 322, 325, 500, "bottom");
Insert("룰루", 552, 292, 325, 550, "suppot");
Insert("모데카이저", 555, 120, 340, 120, "mid");
Insert("드레이븐", 557, 310, 330, 550, "bottom");
Insert("자르반4세", 571, 302, 340, 175, "jungle");
Insert("케일", 574, 322, 335, 125, "top");
Insert("블리츠크랭크", 582, 267, 325, 125, "suppot");
Insert("문도박사", 582, 0, 345, 125, "top");
Insert("다이애나", 589, 297, 345, 150, "mid");
Insert("워윅", 592, 240, 345, 125, "jungle");
Insert("잭스", 592, 288, 350, 125, "top");
Insert("트린다미어", 625, 100, 345, 125, "top");
Insert("갱플랭크", 631, 282, 345, 125, "top");
while ( 1 )
{
switch ( Menu() )
{
case 1 :
Search();
break;
case 2 :
InputData();
Insert(::inputName, ::inputHp, ::inputMp, ::inputSpeed, ::inputRange, ::inputPosition);
break;
case 3 :
Delete();
break;
case 4 :
PositionDeleteAll();
break;
case 5 :
PrintAll();
break;
case 6 :
FindMaxHp();
break;
case 7 :
SortByHp();
break;
default :
break;
}
}
}
int Menu()
{
int num;
cout << "--------------Menu---------------" << endl;
cout << "1. 챔피언 Search" << endl;
cout << "2. 챔피언 Insert" << endl;
cout << "3. 챔피언 Delete" << endl;
cout << "4. Position DeleteAll" << endl;
cout << "5. PrintAll" << endl;
cout << "6. FindMaxHp" << endl;
cout << "7. SortByHp" << endl;
cout << "----------------------------------" << endl;
cout << "메뉴를 입력하세요 [ 1 ~ 7 ] : ";
cin >> num;
if ( 0 < num && num < 8)
return num;
}
void Insert(char* name, int hp, int mp, int speed, int range, char* position)
{
Node* temp = head;
if ( temp != NULL && temp->next != head ){
while ( temp->next != head)
temp = temp->next;
temp->next = new Node;
temp = temp->next;
temp->next = head;
temp->m_iHp = hp;
temp->m_iMp = mp;
temp->m_iSpeed = speed;
temp->m_iRange = range;
strcpy(temp->m_cName, name);
strcpy(temp->m_cPosition, position);
}
else if (head == NULL){
head = new Node;
head->next = head;
head->m_iHp = hp;
head->m_iMp = mp;
head->m_iSpeed = speed;
head->m_iRange = range;
strcpy(head->m_cName, name);
strcpy(head->m_cPosition, position);
}
else if ( temp->next == temp){
temp->next = new Node;
temp->next->next = head;
temp->next->m_iHp = hp;
temp->next->m_iMp = mp;
temp->next->m_iSpeed = speed;
temp->next->m_iRange = range;
strcpy(temp->next->m_cName, name);
strcpy(temp->next->m_cPosition, position);
}
}
void PrintAll()
{
Node *temp = head;
if ( head != NULL && (
!strcmp(temp->m_cPosition, "jungle") ||
!strcmp(temp->m_cPosition, "suppot") ||
!strcmp(temp->m_cPosition, "bottom") ||
!strcmp(temp->m_cPosition, "mid") ||
!strcmp(temp->m_cPosition, "top")) ){
while (temp->next != head)
{
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
temp = temp->next;
}
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
}
void Search()
{
Node* temp = head;
char name[20] = "NULL";
cout << "검색할 챔피언의 이름을 입력해주세요 : ";
cin >> name;
while ( temp->next != head){
if ( !strcmp(name, temp->m_cName) ){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
temp = temp->next;
}
if ( !strcmp(name, temp->m_cName) ){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
}
void Delete()
{
Node* temp = head;
Node* p = NULL;
char name[20] = "NULL";
cout << "삭제할 챔피언의 이름을 입력해주세요 : ";
cin >> name;
while ( temp->next != head){
if ( !strcmp(name, temp->next->m_cName) ){
p = temp->next;
temp->next = temp->next->next;
p->next = nullptr;
delete p;
}
else
temp = temp->next;
}
if ( !strcmp(name, head->m_cName) ){
p = head;
p = head->next;
delete head;
head = p;
temp->next= head;
}
}
void PositionDeleteAll()
{
Node* temp = head;
Node* p = NULL;
char position[20] = "NULL";
cout << "삭제할 Position을 입력해주세요 : ";
cin >> position;
while ( temp->next != head){
if ( !strcmp(position, temp->next->m_cPosition) ){
p = temp->next;
temp->next = temp->next->next;
p->next = nullptr;
delete p;
}
else
temp = temp->next;
}
if ( !strcmp(position, head->m_cPosition) ){
p = head;
p = head->next;
delete head;
head = p;
temp->next= head;
}
};
void InputData()
{
cout << "이름을 입력하세요: ";
cin >> ::inputName;
cout << "체력을 입력하세요: ";
cin >> ::inputHp;
cout << "마력을 입력하세요: ";
cin >> ::inputMp;
cout <<"속도 입력하세요: ";
cin >> ::inputSpeed;
cout << "범위를 입력하세요: ";
cin >> ::inputRange;
cout << "포지션을 입력하세요: ";
cin >> ::inputPosition;
}
void FindMaxHp()
{
Node* temp = head;
if ( head->m_iHp > maxHp)
maxHp = head->m_iHp;
while(temp->next != head)
{
if ( temp->m_iHp > maxHp)
maxHp = temp->m_iHp;
temp = temp->next;
}
if (temp->m_iHp > maxHp)
maxHp = temp->m_iHp;
cout << "가장 높은 체력 : ";
cout << maxHp << endl;
temp = head;
if ( head->m_iHp == maxHp){
cout << "이름 : " << head->m_cName << endl;
cout << "체력 : " << head->m_iHp << endl;
cout << "마력 : " << head->m_iMp << endl;
cout << "속도 : " << head->m_iSpeed << endl;
cout << "범위 : " << head->m_iRange << endl;
cout << "포지션 : " << head->m_cPosition << endl;
}
while(temp->next != head)
{
if ( temp->m_iHp == maxHp){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
temp = temp->next;
}
if (temp->m_iHp == maxHp){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
::maxHp = 0;
}
void SortByHp()
{
Node* temp = head;
Node* rotate = head;
Node* whileNode = head;
Node* remember = nullptr;
Node* prv = nullptr;
while(temp->next!= head){
if( temp->m_iHp > temp->next->m_iHp){
if ( temp == head){
if ( temp->next->next != head){
rotate = head;
while(rotate->next != head)
rotate = rotate->next;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
head = remember;
rotate->next = head;
temp = head;
}
else if ( temp->next->next == head){
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
head = remember;
temp->next->next = head;
temp = head;
}
}
else if ( temp->next->next != head){
rotate = head;
while(rotate->next != temp){
rotate = rotate->next;
}
prv = rotate;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
prv->next = remember;
temp = head;
}
else if ( temp->next->next == head){
rotate = head;
while(rotate->next != temp){
rotate = rotate->next;
}
prv = rotate;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
prv->next = remember;
temp->next = head;
temp = head;
}
}
temp = temp->next;
}
sortFlag = 1;
}



















'프로그래밍 > C++언어' 카테고리의 다른 글

[ 기술면접 정리 서버 / C++ ]  (0) 2019.03.06

1. 원이 두 점에서 만나는 경우
r2 - r1 < d < r1 + r2


2. 두 원이 외접하는 경우 (한점에서 만난다)

d = r1 + r2


3. 두 원이 내접하는 경우 (한점에서 만난다)
d = r2 - r1
and
d != 0


4. 하나의 원이 다른 원을 포함하는 경우 (만나지 않는다)
d < r2 - r1


5. 두 원이 멀리 떨어져 만나지 않는 경우
d > r1 + r2


6. 두 원이 일치하는 경우 (무수히 많은 점에서 만난다)
d = 0
r1 = r2



1. 문자열


파이썬에서는 문자를 " 혹은 '로 묶어서 표현 합니다. 서로 쌍이 맞아야 합니다.


' string ', " string " 처럼!


만약 print 함수를 통하여 인용을 나타내고 싶을때는 """ 혹은 '''을 사용하면 표현 가능합니다.


예를들어 print(""" 영원에 살고 순간에 살아라 영원히 살 것처럼 일하고 금방 죽을 것 처럼 사람들을 대하라. - 리히텐베르크""")와 같이 말이죠!!!


또는 \' \"의 에스케이프 문자를 이용하여 표현이 가능합니다.


문자열을 더하거나 같은 문자열을 반복 하고싶을때는 +, *의 연산자를 사용하면 됩니다.

"hello" + "world" = "hello world"

"re" * 3 = "rerere"


문자열의 각 문자는 인덱스를 통하여 접근 가능합니다.


c = "hello"

c[0] = h 출력

c[1] = e 출력


** 문자열 슬라이싱 **


변수명 [시작위치:끝위치]를 이용하여 문자열을 꺼낼수 있습니다.

c = "hello"

c[0:3] = 'hel'과 같이 말이죠!

시작이나 끝을 생략 할 경우는 시작 혹은 끝으로 간주 됩니다. 또한 -를 통하여 문자열 끝부터 문자열 시작 까지도 가능!

c[-1] = "hello


2. 리스트


값의 나열을 담는 자료형. 순서가 존재하며 여러 종류의 값을 담을 수 있을뿐 아니라 인덱싱을 통한 접근, 슬라이싱을 통한 접근이 가능합니다.

리스트를 만드는 방법은 다음과 같습니다.

animal = ['dog', 'bird', 'cow']


 멤버함수명

설명 

 append()

 리스트의 뒤에 값을 추가.

 insert()

 원하는 위치에 값을 추가. 

 extend()

 튜플 혹은 리스트 등의 여러 값을 한 번에 삽입 

 index()

 어떤 값이 어디에 존재하는지 반환 

 count()

 현재 값의 개수를 반환 

 pop()

뒤에서 부터 값을 뽑아낸다.  

  remove()

 해당 값을 삭제 

  sort()

 순방향으로 정렬

  reverse()

 역방향으로 정렬


+연산자를 통하여 삽입이 가능하다. 그러나 튜플이나 리스트가 아닌 문자열을 'abc'와 같이 넣을 경우 'a' 'b' 'c'의 형태로 쪼개어 들어갑니다.


3. 세트 


수학의 집합과 같다.


union

매개변수로 들어가는 세트와의 합집합을 반환 

intersection() 

매개변수로 들어가는 세트와의 교집합을 반환 

- 연산자 

 차집합을 반환

| 연산자

 합집합을 반환

& 연산자

 교집합을 반환





4. 튜플


()로 묶어서 표현하며 읽기 전용이다. 속도는 리스트에 비해 빠르다.


 count()

 현재 값의 개수를 반환 

 index()

 어떤 값이 어디에 존재하는지 반환 



5. 딕셔너리


key와 value로 구성되어 있으며 가장 많이 사용하는 자료구조

예) a = dict(a=0, b=1, c=2)

   >>>a

   {'a':0, 'b':1, 'c':2} 

없는 키를 사용 할 경우 오류가 발생.

 item()

 딕셔너리의 모든 키와 값을 튜플로 묶어 반환

 key()

 키를 반환

 value()

 값을 반환


6. 얕은복사와 깊은 복사


파이썬에서의 모든 변수는 해당 객체의 주소를 갖고 있다. 그러므로 주의 해야 할 점이 있는데

아래의 예제와 같은 경우와 같이 복사 생성을 할 때에는 주솟값이 복사가 된다.

a = [1, 2, 3]

b = a 

a[0] = 4

>> b

b [ 4, 2, 3] 의 결과와 같이 b는 a의 주소값을 복사 한 것이다.

고유한 값인 아이디를 반환하는 함수를 사용하면 다음과 같다.

id(a), id(b)

(180000, 1800000 )


이를 해결하는 방법은 copy 모듈을 import하고 deepcopy()함수를 사용하면 해결 할 수 있다.





'프로그래밍 > Python' 카테고리의 다른 글

[파이썬 기초 문법 - 3] 제어관련  (0) 2019.02.20
[파이썬 기초 문법 - 2] 함수  (0) 2019.02.20

+ Recent posts