파이썬 함수 (다른 글)
파이썬 함수 코딩1
은행 계좌가 있다고 가정하고, 각 상황 (계좌 개설, 입금, 출금 등)에 맞는 코드가 실행되게 하기 위해 함수를 지정한다.
def open_account():
print("새로운 계좌가 개설되었습니다.")
def deposit(balance, money):
print("입금이 완료되었습니다. 잔액은 {0}원 입니다.".format(balance + money))
return balance + money
def withdraw(balance, money):
if balance >= money:
print("출금이 완료되었습니다. 잔액은 {0}원 입니다.".format(balance - money))
return balance - money
else:
print("출금이 불가합니다. 잔액은 {0}원 입니다.".format(balance))
return balance
def withdraw_night(balance, money): # 저녁에 출금
com = 100 # 출금 수수료
return com, balance - money - com
balance = 0 # 잔액
balance = deposit(balance, 10000) # 입금액
print(balance)
balance = withdraw(balance, 2000) # 출금액
print(balance)
com, balance = withdraw_night(balance, 2000) # 야간 출금액
print("수수료는 {0}원 이며, 잔액은 {1}원입니다.".format(com, balance))
- open_account 함수: 계좌가 개설되면 실행되는 함수로, 계좌 개설 안내
- deposit 함수: 입금 시 실행되는 함수로, balance와 money를 인자로 받아 입금 안내와 잔액을 안내
- withdraw 함수: 출금 시 실행되는 함수로, balance와 money를 인자로 받아 출금 안내와 잔액을 안내하는데, if문을 통해 balance가 money 보다 작을 경우에는 출금 불가 안내와 잔액 안내
- withdraw_night 함수: 은행 업무 종료 후 출금 시 실행되는 함수로, withdraw와 비슷하나, com 이라는 인자를 받아 출금 수수료를 안내하며 잔액에서 차감
해당 코드를 입금액, 출금액 등을 키보드로 직접 입력받아 실행되도록 보완해 보도록 한다.
balance = 0 # 초기 잔액
def open_account(balance):
print("새로운 계좌가 개설되었습니다. 잔액은 {0}원입니다.".format(balance))
return balance
def deposit(balance):
money = int(input("입금할 금액을 입력하세요: "))
print("입금이 완료되었습니다. 잔액은 {0}원 입니다.".format(balance + money))
return balance + money
def withdraw(balance):
money = int(input("출금할 금액을 입력하세요: "))
if balance >= money:
print("출금이 완료되었습니다. 잔액은 {0}원 입니다.".format(balance - money))
return balance - money
else:
print("출금이 불가합니다. 잔액은 {0}원 입니다.".format(balance))
return balance
def withdraw_night(balance): # 저녁에 출금s
com = 100 # 출금 수수료
money = int(input("(수수료 제외) 출금할 금액을 입력하세요:"))
if balance >= money + com:
print("{0}원이 출금되었습니다. -출금수수료: {1}원. 잔액은 {2}원 입니다".format(money, com, balance, balance - money - com))
return money, com, balance - money - com
else:
print("출금이 불가합니다. 잔액은 {0}원 입니다.".format(balance))
return 0, 0, balance
balance = open_account(balance) # 계좌 개설
balance= deposit(balance) # 입금액
balance = withdraw(balance) # 출금액
money, com, balance = withdraw_night(balance) # 야간 출금액
함수에서 기본값 설정하기
아래와 같이 이름, 나이, 주 사용 언어를 인자로 받는 profile 함수를 생성한 뒤 실행하면
def profile(name, age, main_lang):
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}"\
.format(name, age, main_lang))
profile("원빈", 42, "파이썬")
profile("김우빈", 35, "자바")
profile("조인성", 40, "C++")
위와 같은 내용이 출력된다.
그런데, 만약 이들이 모두 같은 나이면서, 주 사용 언어가 같다고 할 경우에는 위와 같이 모든 값을 입력하지 않고, 함수에만 기본값을 설정하여 값이 전달되지 않았을 경우에는 함수에 설정된 기본값을 출력하도록 할 수 있다.
def profile(name, age=20, main_lang="파이썬"):
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}"\
.format(name, age, main_lang))
profile("원빈", 42, "파이썬")
profile("김우빈", 35, "자바")
profile("조인성", 40, "C++")
profile("변우석")
위와 같이 가장 하단에는 "변우석" 이라는 name 인자에만 값을 추가해줬는데, 이를 실행하면
▶ 이렇게 나머지 나이와 주 사용 언어 부분은 설정된 값이 자동으로 입력되어 출력된다.
가변인자 (가변 매개변수)
매번 함수에 들어가는 인수의 개수가 변하는 것
아래와 같이 이름, 나이, 언어1~언어5를 출력하는 profile 이라는 함수가 있고, 이 함수에 값을 입력한 뒤 실행하면
def profile(name, age, lang1, lang2, lang3, lang4, lang5):
print("이름: {0}\t나이: {1}\t".format(name, age), end=" ")
print(lang1, lang2, lang3, lang4, lang5)
profile("원빈", 42, "파이썬", "자바", "C", "C++", "C#")
profile("김우빈", 35, "자바스크립트", "html", "CSS", "", "")
위와 같은 값이 출력된다.
그러나, 만약 "원빈" 씨가 사용할 줄 아는 언어가 하나가 더 늘어났을 경우에는 함수를 수정해줘야 하고,
언어를 1개만 할 줄 아는 사람이 추가된다면 "" 와 같은 공백처리를 많이 해줘야 한다. (원빈씨의 구사 언어가 늘어날수록 기존의 있던 김우빈씨의 값도 늘어나야 한다)
아무튼, 매우 번거롭고 비효율적인 작업이 될 수 있는데, 이럴때 사용하는 것이 바로 가변인자이다.
가변인자를 적용하기 위해서는 인자 앞에 '*' 을 붙여주면 된다.
아래는 가변인자를 적용하여 보완한 코드이다.
def profile(name, age, *language):
print("이름: {0}\t나이: {1}\t".format(name, age), end=" ")
for lang in language:
print(lang, end=" ") # 줄바꿈 없애기 위해
print()
profile("원빈", 42, "파이썬", "자바", "C", "C++", "C#", "자바스크립트")
profile("김우빈", 35, "자바스크립트", "html", "CSS")
profile("변우석", 20, "자바")
이를 실행하면
가변 매개변수는 매개변수의 맨 뒤에 들어가야 하고, 매개변수 중 하나만 설정할 수 있다.
def print_n_times(n, *values):
# n번 반복
for i in range(n):
# values는 리스트처럼 활용
for value in values:
print(value)
# 단순한 줄바꿈
print()
# 함수 호출
print_n_times(3, "즐거운", "파이썬 프로그래밍")
아래와 같이 가변매개변수를 앞에다 놓고, 코드를 실행하면
def print_n_times(*values, n=2):
# n번 반복
for i in range(n):
# values는 리스트처럼 활용
for value in values:
print(value)
# 단순한 줄바꿈
print()
# 함수 호출
print_n_times("즐거운", "파이썬 프로그래밍", 3)
▶ "3" 역시 values 의 인자로 인식되어 같이 출력된다.
또한, 가변 매개변수와 기본 매개변수가 같이 있을 때 (+ 기본 매개변수가 앞에 있을 때), 기본 매개변수를 인자 값으로 입력하지 않으면 매개변수의 개수와 인자의 개수가 맞지 않으므로 오류가 발생한다.
def print_n_times(n=2, *values):
# n번 반복
for i in range(n):
# values는 리스트처럼 활용
for value in values:
print(value)
# 단순한 줄바꿈
print()
# 함수 호출
print_n_times("즐거운", "파이썬 프로그래밍")
TypeError: 'str' object cannot be interpreted as an integer
(문자형 객체는 정수로 해석될 수 없습니다.)
리턴값
함수의 결과
# input() 함수의 리턴값을 변수에 저장
value = input("> ")
# 출력
print(value)
◆ 자료 없이 리턴하는 유형
def return_test():
print("A 위치입니다.")
return # 리턴
print("A 위치입니다.")
# 함수 호출
return_test()
◆ 자료와 함께 리턴하는 유형
def w_material():
return f"자료와 함께 리턴합니다."
w_material()
◆ 아무것도 리턴하지 않는 유형
def nothing():
return
nothing()
◆ 일반적인 유형
두 수를 포함한 두 수 사이의 누적합을 구하는 함수 만들기
def sum_all(start, end):
output = 0
for i in range(start, end+1):
output += i
return f"{start}와 {end}의 누적합: {output}"
sum_all(1, 100)
지역변수와 전역변수
- 지역변수: 함수 내에서 만들어진 함수이며, 함수 내에서만 사용 가능한 변수로 함수가 호출되면 만들어져서 함수의 실행이 끝날 때 함께 없어짐.
- 전역변수: 함수 밖에서 만들어진 함수. 함수와는 관계없이 사용할 수 있는 변수. 프로그램 내에서 어디서든지 부를 수 있음.
군인들이 경계 근무 나갈 때마다 남아 있는 총의 수가 출력되는 함수를 작성하였고, 초기 총은 10자루로 설정하였다.
gun = 10
def checkpoint(soldiers): # 경계 근무
gun = gun - soldiers
print("[함수 내] 남은 총: {0}".format(gun))
print("전체 총 : {0}".format(gun))
checkpoint(2) # 2명이 경계 근무 나감
print("남은 총: {0}".format(gun))
그러나 이를 실행하면
UnboundLocalError: local variable 'gun' referenced before assignment
이라는 에러가 실행되는데, 이는 함수에서 실행되는 변수가 밖에 있다라는 의미이다.
그리하여,
gun = 10
def checkpoint(soldiers): # 경계 근무
gun = 20
gun = gun - soldiers
print("[함수 내] 남은 총: {0}".format(gun))
print("전체 총 : {0}".format(gun))
checkpoint(2) # 2명이 경계 근무 나감
print("남은 총: {0}".format(gun))
함수 내에 20 자루의 총을 넣고 이를 실행하면 함수 내의 남은 총은 8자루가 될까, 18자루가 될까?
정답은
함수 내의 남은 총은 18자루가 된다.
여기서 'gun=20'을 지역변수라고 한다.
그렇다면, 'gun=10' 이라는 변수를 함수 내에 적용하기 위해서는 아래와 같이
gun = 10
def checkpoint(soldiers): # 경계 근무
global gun
gun = gun - soldiers
print("[함수 내] 남은 총: {0}".format(gun))
print("전체 총 : {0}".format(gun))
checkpoint(2) # 2명이 경계 근무 나감
print("남은 총: {0}".format(gun))
global 이라는 키워드를 변수 앞에 붙여주면 해당 변수는 함수 내에서 값을 변경하더라도 새로운 지역 변수가 되지 않고 함수 밖에서 이미 선언된 전역 변수를 가리키게 된다.
위 코드를 실행해보면
이전과는 달리 남은 총은 8자루라고 출력이 된다.
단, 전역변수의 경우 많이 사용할 경우 코드를 관리하기가 어려워지기 때문에 일반적으로 권장되지는 않는다고 한다.
이번엔 함수의 전달값으로 파라미터를 주고, 반환값으로 받아서 사용하는 방법을 사용해 본다.
gun = 10
def checkpoint(soldiers): # 경계 근무
#gun = 20 # 지역변수
global gun # 전역 공간에 있는 gun 사용 (전역변수)
gun = gun - soldiers
print("[함수 내] 남은 총: {0}".format(gun))
def checkpoint_ret(gun, soldiers):
gun = gun - soldiers
print("[함수 내] 남은 총: {0}".format(gun))
return gun
print("전체 총 : {0}".format(gun))
# checkpoint(2) # 2명이 경계 근무 나감
gun = checkpoint_ret(gun, 2)
print("남은 총: {0}".format(gun))
checkpoint_ret 함수에서,
- gun = gun - soldiers: 여기서 gun은 지역 변수
- return gun: gun을 리턴하여 밖으로 내보냄
밖에서는,
gun = checkpoint_ret(gun, 2): gun 이라는 변수에 checkpoint_ret 함수를 호출하여 받은 gun 변수와 soldiers를 의미하는 숫자를 계산하여 저장한 뒤 print 문에 출력한다.
◆ 리스트나 딕셔너리 같은 가변 객체의 전역변수
# 리스트
list_a = ["a","b","c"]
def append_list():
list_a.append("d")
print(f"함수 내부: {list_a}")
append_list()
print(f"함수 외부: {list_a}")
# 딕셔너리
dict_a = {"a": 1, "b": 2, "c": 3, "d": 4}
def append_dict():
dict_a[-1] = ({"e":5})
print(f"함수 내부: {dict_a}")
append_dict()
print(f"함수 내부: {dict_a}")
가변 객체인 리스트, 딕셔너리, 집합은 함수 내에서 수정할 수 있다.
[가변 객체, 불변 객체]
- 가변 객체: 값이 변할 수 있는 객체. 객체에 할당된 값을 수정할 수 있으며 가변 객체로는 리스트, 집합(set), 딕셔너리가 있다.
- 불변 객체: 값이 변하지 않는 객체. 객체에 할당된 값을 수정할 수 없으며, 불변 객체로는 정수형(int), 실수형(float), 튜플, 문자형(string), 유니코드 등이 있다.
예제
표준 체중을 구하는 프로그램 작성하기
- 남자: 키(m) * 키(m) * 22
- 여자: 키(m) * 키(m) * 21
- 조건1 - 표준 체중은 std_weight 함수 내에서 계산. 전달값: 키(height), 성별(gender)
- 조건2 - 표준 체중은 소수점 둘째 자리까지 표시
- 출력 예시: 키 175cm 남자의 표준 체중은 67.38kg 입니다.
[필자가 작성한 코드]
def std_weight (height, gender):
if gender == "남자":
height_cm = height / 100
weight = round(height_cm * height_cm * 22, 2)
print("키 {0}cm {1}의 표준 체중은 {2}kg 입니다.".format(height, gender, weight))
elif gender == "여자":
height_cm = height / 100
weight = round(height_cm * height_cm * 21, 2)
print("키 {0}cm {1}의 표준 체중은 {2}kg 입니다.".format(height, gender, weight))
else:
print("성별이 잘못되었습니다.")
std_weight(180, "남자")
std_weight(168, "여자")
std_weight(52, "외계인")
Q. 문자를 * 로 감싸는 함수를 만들어라.
내가 만든 코드
# 알파벳을 감싸는 테두리 출력하는 함수
def get_bordered_str(c):
return "*" + ("*" * (len(c)+2)) + "*" + "\n* " + c + " *" + "\n*" + ("*" * (len(c)+2)) + "*"
print(get_bordered_str("boa"))
print(get_bordered_str("Hello, World!"))
▶ 값은 잘 나오나, 코드의 가독성이 매우 떨어진다.
선생님의 조언을 받아 완성된 코드
def get_bordered_str(c):
result = ""
result = "*" * (len(c) + 4) + "\n"
result = result + "* " + c + " *" + "\n*"
result = result + "*" * (len(c) + 3)
return result
print(get_bordered_str("boa"))
print(get_bordered_str("Hello, World!"))
▶ 가독성을 높였다.
만약, * 이 아닌 다른 특수문자로 글자를 감싸는 함수를 만들고 싶은 경우에는 매개변수를 하나 더 늘려서 수정하는 방법으로 함수를 만들 수 있다.
def get_bordered_str(c, sep):
result = ""
result = sep * (len(c) +1) + "\n"
result = result + sep + " " + c + " " + sep + " " + "\n"
result = result + sep * (len(c) + 1)
return result
print(get_bordered_str("boa", "🧡"))
Q. 리스트 요소들의 합계와 평균을 구하는 함수를 만들어라
리스트 요소가 없는 경우 리스트 요소의 개수 계산, 0인 경우 오류 리턴
인자: 숫자 데이터가 저장된 리스트 1개
리턴값: 합계와 평균이 저장된 딕셔너리 1개
내가 풀이한 코드
def get_sum_and_average(a):
if len(a) == 0:
return "[오류] 요소의 개수가 0입니다."
add = sum(a)
avg = add / len(a)
result = {"합계": add, "평균": avg}
return result
print(get_sum_and_average([3, 4]))
print(get_sum_and_average([]))
선생님이 풀어낸 코드
def get_sum_and_average(arg):
length = len(arg)
if length == 0:
return "[오류] 요소의 개수가 0입니다."
total = 0
for x in arg:
total = total + x
return {"합계": total, "평균": total / length}
print(get_sum_and_average([3, 4]))
print(get_sum_and_average([]))
Q. 초를 시간, 분으로 변환하는 함수 만들기
초를 시간, 분으로 변환: 정수 나누기 연산자(//), 나머지 연산자(%) 활용
인자: 변환할 초를 나타내는 정수 1개
출력값: 초가 시간, 분으로 변환된 문자열 1개
def convert_seconds (time_sc):
time = time_sc
hour = time // (60 * 60) # 1시간은 60초(1분)가 60번
time %= (60 * 60)
minute = time // 60 # 1분은 60초
time %= 60
second = time
return f"{time_sc}초는 {hour}시간 {minute}분 {second}초 입니다."
print(convert_seconds(3600))
print(convert_seconds(6000))
print(convert_seconds(30000))
만약, 위의 3600초처럼 시간으로 딱 떨어지거나, 3초처럼 0시간 0분 3초의 경우 해당 시간만 출력되게 코드를 작성하려면
ex) 3초 / 3600초는 1시간
def convert_seconds(time):
if time < 60:
return f"{time}초: " + str(time) + "초"
second = time % 60
minute = time // 60
if minute < 60:
return f"{time}초: " + str(minute) + "분 " + str(second) + "초"
hour = minute // 60
minute = minute % 60
if hour < 60:
return f"{time}초: " + str(hour) + "시간 " + str(minute) + "분 " + str(second) + "초"
print(convert_seconds(3))
print(convert_seconds(60))
print(convert_seconds(323))
print(convert_seconds(60 * 60 + 323 * 2))
- %: 나머지 반환
- /: 나누기
- //: 몫만 반환
다음 내용
[참고]
나도코딩 유튜브 - 파이썬 기본편
다빈치코딩 파이썬
https://velog.io/@hyoniii_log
'[파이썬 Projects] > <파이썬 기초>' 카테고리의 다른 글
[파이썬] 파이썬 기초 - 동전 개수 구하기 (0) | 2025.01.14 |
---|---|
[Visual Studio Code] VS CODE 다운로드 (0) | 2025.01.13 |
[파이썬] 시각화 - 타이타닉 데이터셋 활용 seaborn 실습 (0) | 2024.11.06 |
[파이썬] 파이썬 기초: 파이썬 프로그래밍 (1) | 2024.10.18 |
[파이썬] 파이썬 기초: 라이브러리-2 (0) | 2024.10.16 |