■ JITHub 개발일지(TIL : Today I Learned) 11일차
□ TIL ::
파이썬 클래스, 축약식, lambda, 계산기 만들기
1. 클래스
- str 메서드(__str__) : init에서 규정한 클래스 자체 내용을 출력하고 싶을 때, 형식을 지정하는 메서드
*인스턴스를 그냥 출력하면 주소값으로 나오는데, str을 지정해주면 지정된 형식의 값으로 출력됨
class Profile():
def __init__(self, profile):
self.profile = profile
def __str__(self):
return str(self.profile)
profile = Profile({
"name" : "lee",
"gender" : "man",
"birthday" : "01/01",
"age" : 32,
"phone" : "01012341234",
"email" : "python@sparta.com"
})
print(profile)
# __str__이 없을 경우
"""
<__main__.Profile object at 0x000001A2B53E3F10>
"""
# __str__이 있을 경우
"""
{'name': 'lee', 'gender': 'man', 'birthday': '01/01', 'age': 32, 'phone': '01012341234', 'email': 'python@sparta.com'}
"""
class Profile():
def __init__(self, profile):
self.profile = profile
def __str__(self):
return "프로필의 인스턴스 입니다!"
profile = Profile({
"name" : "lee",
"gender" : "man",
"birthday" : "01/01",
"age" : 32,
"phone" : "01012341234",
"email" : "python@sparta.com"
})
print(profile)
"""
프로필의 인스턴스 입니다!
"""
2. try/exception
- 파이썬에서는 try, except 문법을 사용하여 에러가 발생했을 때 처리해줄 수 있다.
number = input()
try:
int(number)
10 / number
except ValueError: # int로 변환하는 과정에서 에러가 발생했을 떄
print(f"{number}은(는) 숫자가 아닙니다.")
except ZeroDivisionError: # 0으로 나누면서 에러가 발생했을 때
print("0으로는 나눌수 없습니다.")
except Exception as e: # 위에서 정의하지 않은 에러가 발생했을 때(권장하지 않음)
print(f"예상하지 못한 에러가 발생했습니다. error : {e}")
# except 문법 또한 if / elif와 같이 연달아서 작성할 수 있습니다.
- 아래 식을 보면 if문과 try문을 비교하고 있는데, if문의 경우 num.isdigit(): 분기문을 무조건 타지만, try except문은 에러가 발생하지 않을 경우 num = int(num)만 수행하기 때문에 양이 많을 경우 처리 속도가 상대적으로 빠르다.
# case 1
num = "abc"
if num.isdigit:
num = int(num)
else:
num = '-'
print(num)
# case 2
num = "10"
try:
num = int(num)
except:
num = "-"
3. stacktrace
- stacktrace : 에러가 발생했을 때 에러가 발생 한 위치를 찾아내기 위해 호출 된 함수의 목록을 보여주고
개발자는 stacktrace를 따라가며 에러가 발생한 위치를 추적할 수 있다.
def 집까지_걸어가기():
print(error) # 선언되지 않은 변수를 호출했기 때문에 에러 발생
def 버스_탑승():
집까지_걸어가기()
def 환승():
버스_탑승()
def 지하철_탑승():
환승()
def 퇴근하기():
지하철_탑승()
퇴근하기()
"""
Traceback (most recent call last):
File "sample.py", line 17, in <module>
퇴근하기()
File "sample.py", line 15, in 퇴근하기
지하철_탑승()
File "sample.py", line 12, in 지하철_탑승
환승()
File "sample.py", line 9, in 환승
버스_탑승()
File "sample.py", line 5, in 버스_탑승
집까지_걸어가기()
File "sample.py", line 2, in 집까지_걸어가기
print(error)
NameError: name 'error' is not defined. Did you mean: 'OSError'?
4. 축약식
- 축약식의 장점 : 긴 코드를 간략하게 줄일수 있다
- 축약식의 단점 : 남용할 경우 가독성이 떨어지고 추후 코드 관리가 힘들수 있다.
- list, set, tuple, dict 자료형이 축약식으로 표현이 가능하며, 기본적인 구조는 동일하고, 어떤 괄호 기호를 사용하는지 / 어떤 형태로 사용하는지에 따라 저장되는 자료형이 달라진다.
1) 리스트, 튜플, 셋 축약식 활용방법
# 기본적인 활용 방법
# [list에 담길 값 for 요소 in 리스트]
numbers = [x for x in range(5)] # [0, 1, 2, 3, 4]
# 조건문은 축약식 뒷부분에 작성하며, 축약식이 True인 경우 list에 값이 담긴다.
even_numbers = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# 아래와 같이 활용할 수도 있다.
people = [
("lee", 32),
("kim", 23),
("park", 27),
("hong", 29),
("kang", 26)
]
average_age = sum([x[1] for x in people]) / len(people)
print(average_age) # 27.4
#list 축약식의 []를 ()혹은 {}로 바꿔주면 tuple, set 축약식을 사용하실수 있습니다.
※ 리스트 축약식을 사용하여 코드 문장 간소화 예시
people = [
("lee", 32),
("kim", 23),
("park", 27),
("hong", 29),
("kang", 26),
]
# case 1
sum_age = 0
for i in people:
sum_age += i[1]
average_age = sum_age / len(people)
print(average_age)
# case 2
ages = [x[1] for x in people]
sum_ages = sum(ages)
average_age = sum_ages / len(people)
print(average_age)
# case 3
average_age = sum([x[1] for x in people]) / len(people)
print(average_age)
2) 딕셔너리 축약식 활용법
# dictionary 축약식의 구조는 list와 동일하지만, key / value 형태로 지정해야 합니다.
people = [
("lee", 32, "man"),
("kim", 23, "man"),
("park", 27, "woman"),
("hong", 29, "man"),
("kang", 26, "woman")
]
people = {name: {"age": age, "gender": gender} for name, age, gender in people}
print(people)
# result print
"""
{
'lee': {'age': 32,
'gender': 'man'},
'kim': {'age': 23,
'gender': 'man'},
'park': {'age': 27,
'gender': 'woman'},
'hong': {'age': 29,
'gender': 'man'},
'kang': {'age': 26,
'gender': 'woman'}
}
"""
5. lambda / map / filter / sort 활용
1) lambda
- lambda는 다른 말로 익명 함수(anonymous function)이라고도 불리며, 보통 map, filter, sort와 함께 사용된다.
# map은 함수와 리스트를 인자로 받아 리스트의 요소들로 함수를 호출해줍니다.
string_numbers = ["1", "2", "3"]
integer_numbers = list(map(int, string_numbers))
print(integer_numbers) # [1, 2, 3]
# map 함수를 사용하지 않는 경우 아래와 같이 구현할 수 있습니다.
string_numbers = ["1", "2", "3"]
integer_numbers = []
for i in string_numbers:
integer_numbers.append(int(i))
print(integer_numbers) # [1, 2, 3]
# list 축약식으로도 동일한 기능을 구현할 수 있습니다.
# map과 list 축약식 중 어떤걸 써야 할지 고민된다면 이 글을 읽어보시는것을 추천합니다.
string_numbers = ["1", "2", "3"]
integer_numbers = [int(x) for x in string_numbers]
print(integer_numbers) # [1, 2, 3]
# map 함수와 lambda 함수를 함께 사용하면 더 다채로운 기능을 구현할 수 있습니다.
numbers = [1, 2, 3, 4]
double_numbers = list(map(lambda x: x*2, numbers))
print(double_numbers) # [2, 4, 6, 8]
# 바로 위의 식을 축약식을 활용해서 코드를 짤 수도 있다.
numbers = [1, 2, 3, 4]
double_numbers = [x*2 for x in numbers]
print(double_numbers) # [2, 4, 6, 8]
2) filter
# filter 함수는 map과 유사한 구조를 가지고 있으며, 조건이 참인 경우 저장합니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = list(filter(lambda x: x%2 == 0, numbers))
print(even_numbers) # [2, 4, 6, 8]
# filter 함수 또한 list 축약식으로 동일한 기능을 구현할 수 있습니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = [x for x in numbers if x%2 == 0]
print(even_numbers) # [2, 4, 6, 8]
3) sort
# sort 함수를 사용하면 list를 순서대로 정렬할 수 있습니다.
numbers = [5, 3, 2, 4, 6, 1]
numbers.sort()
print(numbers) # [1, 2, 3, 4, 5, 6]
# 역순으로 정렬시키기
numbers = [5, 3, 2, 4, 6, 1]
numbers.sort(reverse=True)
print(numbers) # [6, 5, 4, 3, 2, 1]
# sort와 lambda 함수를 같이 사용하면 복잡한 구조의 list도 정렬할 수 있습니다.
people = [
("lee", 32),
("kim", 23),
("park", 27),
("hong", 29),
("kang", 26)
]
# 나이 순으로 정렬하기
people.sort(key=lambda x: x[1])
print(people)
# result print
"""
[
("kim", 23),
("kang", 26),
("park", 27),
("hong", 29),
("lee", 32)
]
"""
# 나이 역순으로 정렬하기
people.sort(key=lambda x: x[1], reverse=True)
print(people)
# 2개의 우선순위 기준 주기 (우선순위를 튜플로 주면 된다)
people.sort(key=lambda x: (x[0], x[1]))
print(people)
# filter가 쓰인 문을 축약식 + if문을 사용하여 간소화하기
people = [x for x in people if x[1] >= 30]
print(people)
6. 계산기 만들기
- 조건 추가
- 클래스를 활용해 작성했던 계산기 코드를 활용해주세요
- 기존처럼 사용자의 입력을 받고 출력하되, try / except를 활용해 사용자의 입력을 검증하는 코드를 추가해주세요
- 두 번쨰 숫자에 0을 입력하고 나누기를 시도할 경우 “0으로 나눌 수 없습니다” 문구를 출력해주세요
- 숫자가 아닌 다른 값을 입력했을 경우 “숫자만 입력 가능합니다” 라는 문구를 출력해 주세요
# 계산기 만들어보기(with class)
class Calc:
# def __init__(self, a, b):
# self.a = a
# self.b = b
def set_number(self, a, b):
self.a = a
self.b = b
def plus(self):
result = self.a + self.b
return result
def minus(self):
result = self.a - self.b
return result
def multiple(self):
result = self.a * self.b
return result
def divide(self):
result = self.a / self.b
return result
# try except문 안에는 에러가 발생할 수 있는 코드만 들어가도록 하는 것이 좋다.
try:
calc = Calc()
a, b = map(int, input().split())
calc.set_number(a, b)
print(calc.plus()) # 더한 값
print(calc.minus()) # 뺀 값
print(calc.multiple()) # 곱한 값
print(calc.divide()) # 나눈 값
# Data validation : 데이터 유효성 검사
except ValueError: # int로 변환하는 과정에서 에러가 발생했을 때
print("숫자만 입력 가능합니다.")
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
7. 유저 관리 및 내용 출력
- 조건
- filter 혹은 리스트 축약식을 사용해 코드를 작성해주세요
- 제공 된 사용자들 중 나이가 20살 미만인 사람들은 제외해주세요
- 사용자들을 나이 순으로 정렬해주세요
from pprint import pprint
people = [
("Blake Howell", "Jamaica", 18, "aw@jul.bw"),
("Peter Bowen", "Burundi", 30, "vinaf@rilkov.il"),
("Winnie Hall", "Palestinian Territories", 22, "moci@pacivhe.net"),
("Alfred Schwartz", "Syria", 29, "ic@tolseuc.pr"),
("Carrie Palmer", "Mauritius", 28, "fenlofi@tor.aq"),
("Rose Tyler", "Martinique", 17, "as@forebjab.et"),
("Katharine Little", "Anguilla", 29, "am@kifez.et"),
("Brent Peterson", "Svalbard & Jan Mayen", 22, "le@wekciga.lr"),
("Lydia Thornton", "Puerto Rico", 19, "lefvoru@itbewuk.at"),
("Richard Newton", "Pitcairn Islands", 17, "da@lasowiwa.su"),
("Eric Townsend", "Svalbard & Jan Mayen", 22, "jijer@cipzo.gp"),
("Trevor Hines", "Dominican Republic", 15, "ev@hivew.tm"),
("Inez Little", "Namibia", 26, "meewi@mirha.ye"),
("Lloyd Aguilar", "Swaziland", 16, "oza@emneme.bb"),
("Erik Lane", "Turkey", 30, "efumazza@va.hn"),
]
people = [x for x in people if x[2] >= 20]
people.sort(key=lambda x: x[2])
pprint(people)
"""
[('Winnie Hall', 'Palestinian Territories', 22, 'moci@pacivhe.net'),
('Brent Peterson', 'Svalbard & Jan Mayen', 22, 'le@wekciga.lr'),
('Eric Townsend', 'Svalbard & Jan Mayen', 22, 'jijer@cipzo.gp'),
('Inez Little', 'Namibia', 26, 'meewi@mirha.ye'),
('Carrie Palmer', 'Mauritius', 28, 'fenlofi@tor.aq'),
('Alfred Schwartz', 'Syria', 29, 'ic@tolseuc.pr'),
('Katharine Little', 'Anguilla', 29, 'am@kifez.et'),
('Peter Bowen', 'Burundi', 30, 'vinaf@rilkov.il'),
('Erik Lane', 'Turkey', 30, 'efumazza@va.hn')]
"""
■ TIT :: Today I thought
- 파이썬 문법을 배우면서 점점 복잡해짐을 느끼고 있다. 다양한 용법이 나오고 있는데 그날그날 익히지 않으면 금방 잊혀질까 두려울 정도이다. 정리해둔 내용들을 꼼꼼히 다시 하나하나 정리해볼 필요가 있겠다.
- 지난주에 정리하지 못했던 깃에 대한 내용을 주로 확인했다. 로컬 저장소(repo)에서 git bash를 활용하여 작업하는 것을 주로 정리하고 있다. 소스트리를 사용해도 좋지만 CLI 환경에서 모든 기능을 사용할 수 있다고 하니, 개념만 꽉 잡고 CLI 환경에서 작업하는 것을 더 익숙하게 만드는 것을 목표로 해야겠다.
- 금일은 백준 문제 풀이를 할 시간이 없었다.. 지난주에 git을 정리하지 못했던 것이 가장 컸다.
- 백준 문제, 그리고 자료구조와 알고리즘에서 앞으로 갈수록 깊은 내용을 공부해볼 예정이다. 각오 단단히 하자
'DEV > 파이썬 이론' 카테고리의 다른 글
파이썬 코딩 :: 파이썬 알고리즘, 시간복잡도, Linked list, 이진탐색, 재귀, 백준_TIL#13 (0) | 2022.09.17 |
---|---|
파이썬 코딩 :: 파이썬 클래스, 함수, arg/kwarg, 패킹/언패킹, 객체지향, 유효성검사_TIL#12 (1) | 2022.09.16 |
파이썬 코딩 :: 파이썬 클래스, 숫자 야구 만들기_TIL#10 (0) | 2022.09.13 |
파이썬 웹 프로그래밍 :: 9월 둘째주 WIL #02 (0) | 2022.09.09 |
파이썬 코딩 :: 파이썬 문법(반복문, 모듈)_TIL#08 (0) | 2022.09.07 |
댓글