파이썬 기말시험
강화 시뮬레이션 (작성 완료)
-
문제 : 시험 문제
import pandas as pd
import numpy as np
class execution_sword():
def __init__(self):
self.upgradestate = pd.DataFrame({'day0':[0] * 100})
self.prob = 0.3
self.day = 0
def add_day(self):
self.day = self.day + 1 ## 날짜를 하루 더한다
def attempt(self):
self.attemptresult = np.random.binomial(n = 1, p = self.prob, size = 100)
def update(self):
self.upgradestate['day%s' % self.day] = np.minimum(self.upgradestate['day%s' % (self.day - 1)] + self.attemptresult, 5) ## +5이후로는 증가하지 않는다
self.ratio = sum(self.upgradestate.loc[:, 'day%s' % self.day] == 5) / 100
def return_ratio(self):
return self.ratio ## ratio(성공한 사람 수 / 전체 사람 수)를 리턴한다
#1-(1)
test1 = execution_sword()
for test1.day in range(1, 63):
test1.attempt()
test1.update()
100 * test1.ratio ## 62일후 100명중 몇명이 +5강화 상태인가?
## 시뮬레이션 결과 100명이였다
-
위에처럼 test.i
를 함수 외부에서 조작하는 것은 좋지 않다
-
마찬가지로 test1 클래스의 멤버변수(ratio)에 직접 접근하는 것도 좋지 않다
-
이를 조작할 수 있는 함수를 새로 만들고 코드를 다시 구현하자
test_1 = execution_sword()
for k in range(1, 63):
test_1.add_day()
test_1.attempt()
test_1.update()
100 * test_1.return_ratio()
class execution_sword2(execution_sword):
def __init__(self):
super().__init__() ## 함수 오버라이딩
self.prob = 0.7
self.failstate = pd.DataFrame({'day0':[0] * 100})
def update(self):
super().update() ## 함수 오버라이딩
self.failstate['day%s' % self.day] = self.failstate['day%s' % (self.day - 1)] + (self.attemptresult == 0) * 1
for j in range(100):
if self.upgradestate.iloc[j, self.day] == 0:
self.failstate.iloc[j, self.day] = self.failstate.iloc[j, self.day] - 1
## i-1번째 + 강화시도(0 or 1) = i번째
## i, i-1번째 강화상태가 0이라는 의미는 i-1째에 시도한 강화가 실패했다는 의미
## upgradestate가 0이라는 의미는 실패했다는 것이므로 실패횟수가 하나 쌓인다
## +0에서는 실패횟수가 쌓이지 않으므로 failstate값을 하나 뺀다
if (self.upgradestate.iloc[j, self.day] == 5) and (self.attemptresult[j] == 0):
## i-1번째 + 강화시도(0 or 1) = i번째
## i번째가 +5강화이면서 i-1번째 시도한 강화가 실패라는 의미는
## i-1번째가 +5강화였다는 의미이다. 그러므로 i번째 실패횟수가 +1 됐을것이다
## +5강화에서는 강화를 도전하지 않을 것이다
## 그러므로 i번째 실패횟수를 1을 감소시킨다
self.failstate.iloc[j, self.day] = self.failstate.iloc[j, self.day] - 1
## +5에서는 강화를 시도하지 않을것이므로
## 만약 실패했다면 failstate값을 하나 뺀다
def reset(self):
for j in range(100):
if (self.upgradestate.iloc[j, self.day] > 0) and (self.upgradestate.iloc[j, self.day] < 5):
if self.failstate.iloc[j, self.day] == 2:
self.failstate.iloc[j, self.day] = 0
self.upgradestate.iloc[j, self.day] = 0
## 실패스택이 2라면 실패스택을 0으로 바꾸고 강화상태를 +0으로 바꾼다
def arrangeprobt(self):
if self.ratio >= 0.5:
self.prob = 0.9
## +5강 비율이 50%이상이라면 전체유저의 강화 성공확률을 90%로 바꾼다
@property
def return_ratio(self):
return self.ratio
-
위에서 멤버변수 ratio
를 반환하는 return_ratio
라는 함수를 만들었다
-
그런데 전에는 인스턴스.ratio
를 사용했는데 이제는 인스턴스.return_ratio()
를 써야한다
-
전에 사용하던 것처럼 값으로 쓰고싶다(괄호를 생략하여 메소드를 값처럼 사용하고 싶다)
-
@property
를 사용!
#2-(1)
test2 = execution_sword2()
for k in range(1, 63):
test2.add_day()
test2.attempt()
test2.update()
test2.reset()
100 * test2.return_ratio ## 괄호 생략 가능 ## 그런데 메소드 이름이 return_ratio라 괄호가 있는 것이 자연스러운 것 같음
## 시뮬레이션 결과 100명이였다
#2-(2)
test3 = execution_sword2()
for k in range(1, 32):
test3.add_day()
test3.attempt()
test3.update()
test3.reset()
100 * test3.return_ratio ## 31일후 100명중 몇명이 +5강화 상태인가?
## 시뮬레이션 결과 99명이였다
#2-(3)
test4 = execution_sword2()
for k in range(1, 63):
test4.add_day()
test4.attempt()
test4.update()
test4.reset()
test4.arrangeprobt()
100 * test4.return_ratio ## 과반수가 +5강화 일때 성공확률을 0.9로 바꾼다, 62일후 100명중 몇명이 +5강화 상태인가?
## 시뮬레이션 결과 100명이였다
-
다음문장을 잘 읽고 참 거짓을 판단하여라 (10점)
1.
tuple은 원소의 값을 임의로 바꿀 수 있다 ---> 거짓
2.
class 에 정의된 함수(=메서드)는 self 만을 인자로 받을수 있다 ---> 거짓