(study) 파이썬 입문 (13주차) 5월23일
클래스 공부 6단계
-
(1/4) 인사관리 예제 (1)
-
(2/4) 인사관리 예제 (2)
-
(3/4) 리스트의 상속
-
(4/4) 사용자정의 자료형의 유용함
-
상속
-
아래와 같은 클래스를 만들자.
- 이름, 직급, 연봉에 대한 정보가 있다.
- 연봉을 올려주는 메소드가 존재함.
class Employee:
def __init__(self,name,position=None,pay=0):
self.name = name
self.position = position
self.pay = pay
def _repr_html_(self):
html_str = """
이름: {} <br/>
직급: {} <br/>
연봉: {} <br/>
""".format(self.name,self.position,self.pay)
return html_str
def giveraise(self,pct):
self.pay = self.pay * (1+pct)
-
확인
iu=Employee('iu',position='staff',pay=5000)
hynn=Employee('hynn',position='staff',pay=4000)
hd=Employee('hodong',position='mgr',pay=8000)
iu
iu.giveraise(0.1)
iu
hynn.giveraise(0.2)
hynn
-
회사의 모든 직원의 연봉을 10%씩 올려보자.
iu=Employee('iu',position='staff',pay=5000)
hynn=Employee('hynn',position='staff',pay=4000)
hd=Employee('hodong',position='mgr',pay=8000)
for i in [iu, hynn, hd]:
i.giveraise(0.1)
iu
hynn
hd
-
매니저직급은 일반직원들의 상승분에서 5%의 보너스가 추가되어 상승한다고 가정하고 모든 직원의 연봉을 10%씩 올리는 코드를 구현해보자.
(구현1)
iu=Employee('iu',position='staff',pay=5000)
hynn=Employee('hynn',position='staff',pay=4000)
hd=Employee('hodong',position='mgr',pay=8000)
for i in [iu,hynn,hd]:
if i.position == 'mgr':
i.giveraise(0.1 + 0.05)
else:
i.giveraise(0.1)
iu
hynn
hd
(구현2) 새로운 클래스를 만들자
class Manager:
def __init__(self,name,position=None,pay=0):
self.name = name
self.position = position
self.pay = pay
def _repr_html_(self):
html_str = """
이름: {} <br/>
직급: {} <br/>
연봉: {} <br/>
""".format(self.name,self.position,self.pay)
return html_str
def giveraise(self,pct):
self.pay = self.pay * (1+pct+0.05)
iu=Employee('iu',position='staff',pay=5000)
hynn=Employee('hynn',position='staff',pay=4000)
hd=Manager('hodong',position='mgr',pay=8000)
for i in [iu,hynn,hd]:
i.giveraise(0.1)
iu
hynn
hd
(구현3) 상속이용!
class Manager(Employee):
def giveraise(self,pct):
self.pay = self.pay * (1+pct+0.05)
iu=Employee('iu',position='staff',pay=5000)
hynn=Employee('hynn',position='staff',pay=4000)
hd=Manager('hodong',position='mgr',pay=8000)
for i in [iu,hynn,hd]:
i.giveraise(0.1)
iu
hynn
hd
-
요약: 이미 만들어진 클래스에서 대부분의 기능은 그대로 쓰지만 일부기능만 변경 혹은 추가하고 싶다면 클래스를 상속하면 된다!
-
list와 비슷한데 멤버들의 빈도가 계산되는 메소드를 포함하는 새로운 나만의 list를 만들고 싶다.
lst = ['a','b','a','c','b','a','d']
lst
-
아래와 같은 딕셔너리를 만들고 싶다.
freq = {'a':3, 'b':2, 'c':1, 'd':1}
freq
-
lst.frequency()
를 입력하면 위의 기능이 수행되도록 변형된 list를 쓰고 싶다.
-
구현
(시도1) 반쯤 성공?
lst
freq = {'a':0, 'b':0, 'c':0, 'd':0}
freq
for item in lst:
freq[item] = freq[item] + 1
freq
(시도2) 실패
lst
freq = dict()
freq
for item in lst:
freq[item] = freq[item] + 1
에러이유? freq['a']
를 호출할 수 없다 -> freq.get('a',0) 이용
freq['a']
freq.get?
- key에 대응하는 값이 있으면 그 값을 리턴하고 없으면 default를 리턴
freq.get('a') # freq['a']에 해당하는 자료가 없어도 에러가 나지 않음
freq.get('a',0) # freq['a']에 해당하는 자료가 없어도 에러가 나지 않음 + freq['a']에 해당하는 자료가 없으면 0을 리턴
(시도3)
lst
freq = dict()
freq
for item in lst:
freq[item] = freq.get(item,0) + 1
freq
-
이것을 내가 정의하는 새로운 list의 메소드로 넣고 싶다.
class L(list):
def frequency(self):
freq = dict()
for item in self:
freq[item] = freq.get(item,0) + 1
return freq
lst = L([1,1,1,2,2,3])
lst # 원래 list에 있는 repr 기능을 상속받아서 이루어지는 결과
lst?
_lst = L([4,5,6])
lst + _lst # L자료형끼리의 덧셈
lst + [4,5,6] # L자료형과 list자료형의 덧셈도 가능
- L자료형의 덧셈은 list의 덧셈과 완전히 같음
lst.append(10) # append함수도 그대로 쓸 수 있음
lst
-
기존리스트에서 추가로 frequency() 메소드가 존재함.
lst.frequency()
-
사용자정의 자료형이 어떤 경우에는 유용할 수 있다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
-
예제1
year = ['2016','2017','2017','2017',2017,2018,2018,2019,2019]
value = np.random.randn(9)
df= pd.DataFrame({'year':year,'value':value})
df
plt.plot(df.year,df.value)
에러의 이유: df.year에 str, int가 동시에 있음
np.array(df.year)
자료형을 바꿔주면 해결할 수 있다.
np.array(df.year, dtype=np.float64)
#np.array(df.year).astype(np.float64)
#df.year.astype(np.float64)
plt.plot(df.year.astype(np.float64),df.value,'.')
-
예제2
year = ['2016','2017','2017','2017년','2017년',2018,2018,2019,2019]
value = np.random.randn(9)
df= pd.DataFrame({'year':year,'value':value})
df
np.array(df.year,dtype=np.float64) # 타입을 일괄적으로 바꾸기 어렵다.
L(df.year).frequency()
- '2016'와 같은 형태, '2017년'와 같은 형태, 숫자형이 혼합 -> 맞춤형 변환이 필요함
'2017년'.replace("년","")
L(df.year)
def f(a): ## 사실 데이터의 구조를 모르면 이런 함수를 짤 수 없음 --> 자료의 구조를 확인해준다는 의미에서 freq가 있다면 편리하다.
if type(a) is str:
if "년" in a:
return int(a.replace("년",""))
else:
return int(a)
else:
return a
[f(a) for a in df.year]
df.year= [f(a) for a in df.year]
df
plt.plot(df.year, df.value, '.')