데이터분석

[23.06.07] Python 함수 - 04(3)

gmwoo 2023. 6. 7. 17:38

1. 함수

1) 정의

 - 파이썬이 함수는 def 키워드로 시작
 - 동일한 이름의 함수 못 만듦

def display():
    print("--------------------")

# 함수 호출
display()
display()
display()
display()

def display2(line):
    for i in range(0, line):
        print("**************")

# 이 함수는 매개변수가 있음
display2(3)
display2(5)

def display3(mark, line, cnt):
    for i in range(0, line):
        for j in range(0,cnt):
            print(mark, end=' ')
        print()
        
display3('^', 3, 5)
display3('$', 4, 10)
display3('@', 5, 30)

 
예제 1) 함수가 일을 처리하고 값을 반환하는 경우 작성

def add(x, y):
    return x+y  # return 구문이 함수를 종료하는 기능, 값을 반환하는 기능이 있다
                # 값은 하나만 반환할 수 있다
# 함수 호출시 매개변수에 값을 전달해야만한다
# 매개변수 - 함수 외부와 함수 내부를 연결하는 역할, 외부에서 값 전달목적으로 사용하는 변수
# def add(x, y): 이때 x와 y가 매개변수이다.
# 매개체가 되는 변수(파라미터, 아규먼트) 라고도 부른다

print(add(4,5))
print (display()) #파이썬은 return 이 없네 그럼 None 이 반환된다

 
예제 2) 1 ~ N 까지의 합계를 구해서 반환하는 함수 만들기

def sigma(limit):
    result = 0
    for i in range(1, limit+1):
        result += i   # result = result + i 일 때, 좌변에 동일한 변수일 때 사용 가능
    
    return result

print(sigma(10))
print(sigma(100))
print(sigma(1000))

 

2) 문법 

 - 객체지향 언어의 특징이 오버로딩(함수의 이름은 같지만 형태가 다른 함수 만들 수 있음)
 - C언어 str->int ==> int("1234")   atoi(문자열을 정수), atof(문자열을 실수)

 - atoi(4), atoi(4.5)  ==> 함수 두 개를 만들어, 하나는 매개변수가 정수, 하나는 매개변수가 실수
 
 - 파이썬은 문법을 버림(만들지 않음)

 

print(1)
print(3.4)
print("test")

# 매개변수에 기본값을 부여해서 호출 시에 새로운 값을 부여하는 방식에 따라 오버로딩과 유사한 효과를 가짐
def myadd(x,y,z):
    return x+y+z
print(myadd(10, 20, 30))

# 기본값: 매개변수를 선언하면서 값을 줄 수 있으며 이를 기본값이라고 함
# 함수호출 시 매개변수에 값을 전달하지 않으면 기본값이 사용
def myadd2(x=1,y=2,z=3):
    return x+y+z
print(myadd2())
print(myadd2(10))
print(myadd2(10, 20))
print(myadd2(10, 20, 30))

# 매개변수 값을 따로 지정 가능
print(myadd2(x=100))
print(myadd2(z=50))
print(myadd2(y=100))

 

3) 함수의 지역변수와 전역변수 

 - 지역변수: 함수 내에서만 존재
 - 전역변수: 함수 외부에서 존재 (모든 함수가 하나의 변수를 사용하고자 할 때 사용 (자주 사용X)

g_x = 1  # 전역변수

def myfunc():
    x = 2  # 지역변수, 함수 내에서만 사용 가능
    # g_x = g_x + 1  -> 함수 내에 있으므로 지역변수로 인식하므로 에러
    global g_x   # 전역변수임을 지정
    g_x = g_x + 1
    print("지역변수 ", x)
    print("전역변수 ", g_x)
    
myfunc()  # 함수 호출   2 2
myfunc()  # 함수 호출   2 3
myfunc()  # 함수 호출   2 4
myfunc()  # 함수 호출   2 5
myfunc()  # 함수 호출   2 6

 
 - 반환 값 문제: 반환이 값이 하나만 됨

def doubleValue(x, y):
    # 함수 내의 매개변수는 함수 외부로부터 읽어만 오며, 보내지 못함
    x = x + 2
    y = y + 2
    print("x = ", x)
    print("y = ", y)  # 함수가 종료되면 메모리도 사라짐, 따라서 함수 밖의 값이 바뀌지 않음

a = 5
b = 7
doubleValue(a, b)
print("a = ", a)
print("b = ", b)

 - 다른 언어의 경우, a라는 변수의 주소와 b라는 변수의 주소를 전달할 방법이 있음 (파이썬은 없음)
 - 따라서 tuple로 변환해서 return

# 함수 외부의 값 변환
def doubleValue(x, y):
    # 함수 내의 매개변수는 함수 외부로부터 읽어만 오며, 보내지 못함
    x = x + 2
    y = y + 2
    return x, y  # 자동으로 tuple로 바뀌면서 하나가 return

a = 5
b = 7
result = doubleValue(a, b)
print(result, type(result))   # 출력: (7, 9) <class 'tuple'>

a , b = doubleValue(a, b)
print("a = ", a)
print("b = ", b)  # 출력: a = 7, b = 9

 

문제 1) 주급 문제
  - 위치를 찾는 함수: 검색해서 출력, 수정, 삭제 시에 사용
    >> 선형 검색 => 람다, 컴프리헨션
    >> 처음 데이터부터 찾는 데이터를 나올 때까지 차례대로 읽어 봄 -> 데이터가 없으면 None 반환

#1. 추가
#2. 수정
#3. 삭제
#4. 주급계산 및 출력
# 함수를 잘 만드는 방법은 [책. 클린코드-자바] => 1. 작게 만들어라  2. 더 작게 만들어라  3. 더더 작게 만들어라
# 함수는 한 가지의 기능에 집중하라
# -> 함수를 여러 개 만들어 '기능1 함수', '기능2 함수', '통합함수'를 만들어서 서로 연결하라

payList = []  # 공유 메모리, 모든 함수에서 사용

def init():
    payList.append({"name": '홍길동', "work_time":40, "per_pay":20000})
    payList.append({"name": '임꺽정', "work_time":30, "per_pay":20000})
    payList.append({"name": '장길산', "work_time":20, "per_pay":30000})

def append():    # 데이터 추가만 담당
    data = dict()
    data["name"] = input("이름: ")
    data["work_time"] = int(input("일 한 시간: "))
    data["per_pay"] = int(input("시간 당 단가: "))
    payList.append(data)

def oputput():    # payList(dict table) 출력
    for item in payList:
        print(f"{item['name']} {item['work_time']} {item['per_pay']}")

def process():    # 주급 계산
    for cal in payList:
        print(f"{cal['name']}의 주급: {cal['work_time']*cal['per_pay']} 원")
    
def menuDisplay():  # 처음 값을 위한 메뉴
    print("1. 추가")
    print("2. 출력")
    print("3. 주급 계산")
    print("4. 검색")
    print("5. 수정")
    print("6. 삭제")
    print("0. 종료")

def start():    # append(), output() 호출
    init()
    while True:
        menuDisplay()
        sel = input("선택: ")
        if sel=="1":
            append()
        elif sel=="2":
            oputput()
        elif sel=="3":
            process()
        elif sel=="4":
            search()
        elif sel=="5":
            modify()
        elif sel=="6":
            delete()
        else:
            return  # 함수 종료, while 종료
        
# 위치를 찾는 함수 - 검색해서 출력, 수정, 삭제 시에도 사용
def find(name):
    for i in range(0, len(payList)):
        if name == payList[i]['name']:
            return i  # 서로 일치하는 데이터가 있으면 위치를 반환하고 함수 종료
        
    return None  # for문에서 끝나도록 못찾은 경우, 없다는 의미(None 반환)
    # 파이썬의 경우 함수에서 목적 달성을 못할 때 주로 None 반환
    
def search():  # 검색
    name = input("찾을 이름: ")
    pos = find(name)
    if pos == None:
        print(name + "을 찾지 못했습니다.")
        return    # 더이상 수행을 하지 않음. 이미 오류이므로 여기서 else를 쓰지 않는 것이 프로그램의 확장성 더 높여줌
    # if error1: return 구조로  기술하면 함수를 보다 깔끔하고 확장성 있게 만들 수 있음
    
    # 에러가 아닐 때 처리
    item = payList[pos]  # 해당 위치 값을 가져와서 출력
    print(f"{item['name']} {item['work_time']} {item['per_pay']}")
    
def modify():  # 수정
    name = input("수정할 이름: ")
    pos = find(name)
    if pos == None:
        print(name + "을 찾지 못했습니다.")
        return    
    data = payList[pos]  # 해당 위치 값 가져와서 다시 입력
    data["name"] = input("이름: ")
    data["work_time"] = int(input("일 한 시간: "))
    data["per_pay"] = int(input("시간 당 단가: "))   
    
def delete():  # 삭제
    name = input("삭제할 이름: ")
    pos = find(name)
    if pos == None:
        print(name + "을 찾지 못했습니다.")
        return    
    del payList[pos]  # 해당 위치 값 가져와 삭제
    
    
start()

 
문제 2) 성적 처리

# 성적처리: 이름, 국어, 영어, 수학 입력 받아서 총점 및 평균 구하기
# 수우미양가 까지 구하기 (90, 80, 70, 60, 50)

scoreLst = []

def append():
    data = dict()
    data["name"] = input("이름: ")
    data["국어"] = int(input("국어: "))
    data["영어"] = int(input("영어: "))
    data["수학"] = int(input("수학: "))
    scoreLst.append(data)
    
def sum():
    for cal in scoreLst:
        cal["총점"] = cal["국어"] + cal["영어"] + cal["수학"]

def avg():
    for cal in scoreLst:
        cal["평균"] = cal["총점"] / 3

def score():
    for x in scoreLst:
        if x["평균"] >= 90:
            x["등급"] = "수"
        elif x["평균"] >= 80:
            x["등급"] = "우"
        elif x["평균"] >= 70:
            x["등급"] = "미"
        elif x["평균"] >= 60:
            x["등급"] = "양"
        else:
            x["등급"] = "가"            

def out_put():
    print(scoreLst)

def start():
    while True:
        print("1. 추가")
        print("2. 출력")
        print("0. 종료")
        sel = input("선택: ")
        if sel=="1":
            append()
            sum()
            avg()
            score()
        elif sel=="2":
            out_put()
        else:
            return  # 함수 종료, while 종료

start()

 
 

반응형