(not done) 2021년 1학기 파이썬입문 기말고사
공부
가위바위보 예제 함수 구현해보기
- 복원추출 가능?
import pandas as pd
import numpy as np
player1 = ['rock', 'paper', 'scissors']
player2 = ['rock', 'paper', 'scissors']
np.random.choice(['rock', 'paper', 'scissors'],2,p=[1/3,1/3,1/3])
np.random.choice(player1,2,p=[1/3,1/3,1/3])
def double(n):
result = np.random.choice(n,2,p=[1/3,1/3,1/3])
return result
def choice(n):
result = np.random.choice(n,1,p=[1/2,1/2])
return result
choice(double(player1))
choice(double(player1)) == choice(double(player2))
def winner(v1,v2):
if v1 == v2 : print('same')
elif (v1 == 'rock') and v2 == 'scissors' :print('winner')
elif (v1 == 'paper') and v2 == 'rock' :print('winner')
elif (v1 == 'scissors') and v2 == 'paper' :print('winner')
elif (v1 == 'rock') and v2 == 'paper' :print('loser')
elif (v1 == 'scissors') and v2 == 'rock' :print('loser')
elif (v1 == 'paper') and v2 == 'scissors' :print('loser')
winner('rock','rock')
winner('rock','scissors')
winner('scissors','rock')
winner(choice(double(player1)),choice(double(player2)))
winner(choice(double(player1)),choice(double(player2)))
winner(choice(double(player1)),choice(double(player2)))
시도1
class RSP:
def __init__(self,n):
self.n = n
self.num = 0
self.tab = pd.DataFrame({'n':[0]*self.num})
def number(self):
self.num += 1
def double(self):
self.double = np.random.choice(self.n,2,p=[1/3,1/3,1/3])
self.choice = np.random.choice(self.double,1,p=[1/2,1/2])
self.tab['r'] = self.double,self.choice
return self.tab
def winner(v1,v2):
if v1 == v2 : print('same')
if (v1 == 'rock') :
if (v2 == 'scissors') :
print('player1 is winner')
else:
print('player1 is loser')
if (v1 == 'paper') :
if (v2 == 'rock') :
print('player1 is winner')
else:
print('player1 is loser')
if (v1 == 'scissors') :
if (v2 == 'paper') :
print('player1 is winner')
else :
print('player1 is loser')
try1 = RSP(player1)
try2 = RSP(player2)
#print(try1.double()['r'][1])
#print(try2.double())
RSP.winner(try1.double()['r'][1],try2.double()['r'][1])
시도2
def double(a):
return np.random.choice(np.random.choice(a,2,p=[1/3,1/3,1/3]),1,p=[1/2,1/2])
double(player1)
double(player1)
class RSP:
def __init__(self,n,n2):
self.n = n
self.n2 = n2
self.num = 0
self.prob = 0
def double(self):
self.double = np.random.choice(self.n,2)
self.choice = np.random.choice(self.double,1)
return self.choice
def double(self):
self.double = np.random.choice(self.n,2)
self.choice = np.random.choice(self.double,1)
if self.choice == self.n2 : self.prob += 0
if (self.choice == 'rock') :
if (self.n2 == 'scissors') :
self.prob += 1
else:
self.prob += -1
if (self.choice == 'paper') :
if (self.n2 == 'rock') :
self.prob += 1
else:
self.prob += -1
if (self.choice == 'scissors') :
if (self.n2 == 'paper') :
self.prob += 1
else :
self.prob += -1
return self.prob
try1 = RSP(player1,double(player2))
print(try1.double())
try1 = RSP(player1,double(player2))
for i in range(1):
print(try1.double())
for i in range(2):
print(try1.double())
평가: 함수만 사용하는 것과 다른 점을 모르겠음. 함수에 클래스 변수만 입력해준 느낌
시도3
class RSP:
def __init__(self, low, high):
self.current = low - 1
self.high = high
def __iter__(self):
return self
def __next__(self): # Python 2: def next(self)
self.current += 1
self.user = np.random.choice(np.random.choice(['rock','sicssors','paper'],2,p=[1/3,1/3,1/3]),1,p=[1/2,1/2]).tolist()
if self.current < self.high:
return self.user
raise StopIteration
for c in RSP(1, 10):
print(c)
5/18 면담 이후 추가 시도
class RPS:
def __init__(self,set):
self.p1 = 1
self.p2 = 1
self.p3 = 1
self.n = 3
self.set = set
def next(self):
self.user = np.random.choice(['rock','paper','scissors'],1,p=[self.p1/self.n,self.p2/self.n,self.p3/self.n])
if self.n < self.set:
if self.user == 'rock':
self.p1 = self.p1 + 1
elif self.user == 'paper':
self.p2 = self.p2 + 1
elif self.user == 'scissors':
self.p3 = self.p3 +1
elif self.n == self.set:
return self.user
elif self.n > self.set:
return self.n
self.n = self.n + 1
c = RPS(5)
c.next()
c.next()
c.next()
n=3
a = pd.DataFrame({'시도' :[1/n, 1/n, 1/n]})
a
np.random.choice(['r','s','p'],1,p=a.iloc[:,0])
n = 4
a['시도2'] =[1/n, 1/n, 2/n]
np.random.choice(['r','s','p'],1,p=a.iloc[:,1])
추가시도..
class SRP:
def __init__(self,x2):
self.x = ['scissors','rock','paper']
self.x2 = x2
self.trd = list()
def f(self):
self.fst = np.random.choice(self.x)
self.trd.append(self.fst)
#self.y = self.y + 1
def __repr__(self):
return "{} 중에\n{} 냄\n상대방은 {}냄".format(self.x,self.trd,self.x2)
a = SRP('scissors')
for i in range(5):
a.f()
a
추가 시도 2
class SRP:
def __init__(self,x,x2):
self.x = np.random.choice(x,2).tolist()
self.x2 = x2
self.fst = list()
def f(self):
self.fst = self.fst + self.x
def f2(self):
self.snd = np.random.choice(self.fst)
#print(self.fst)
def f3(self):
if self.snd == self.x2 :
None
elif (self.snd == 'rock') and (self.x2 == 'scissors') :
self.fst.append(self.snd)
elif (self.snd == 'paper') and (self.x2 == 'rock') :
self.fst.append(self.snd)
elif (self.snd == 'scissors') and (self.x2 == 'paper') :
self.fst.append(self.snd)
elif (self.snd == 'rock') and (self.x2 == 'paper') :
self.fst.remove(self.snd)
elif (self.snd == 'scissors') and (self.x2 == 'rock') :
self.fst.remove(self.snd)
elif (self.snd == 'paper') and (self.x2 == 'scissors') :
self.fst.remove(self.snd)
def __repr__(self):
return "상대방이 {} 내서\n결국 {}에 수렵".format(self.x2,self.snd)
a = SRP(player1,'scissors')
for i in range(1000):
a.f()
a.f2()
a.f3()
a
a.fst
a.snd
b = SRP(player1,'paper')
for i in range(1000):
b.f()
b.f2()
b.f3()
b
b.fst
b.snd
c = SRP(player1,'rock')
for i in range(1000):
c.f()
c.f2()
c.f3()
c
c.fst
c.snd
비복원 시도
class SRP:
def __init__(self,x,x2):
self.x = np.random.choice(x,2,replace=False).tolist()
self.x2 = x2
self.fst = list()
def f(self):
self.fst = self.fst + self.x
def f2(self):
self.snd = np.random.choice(self.fst)
#print(self.fst)
def f3(self):
if self.snd == self.x2 :
None
elif (self.snd == 'rock') and (self.x2 == 'scissors') :
self.fst.append(self.snd)
elif (self.snd == 'paper') and (self.x2 == 'rock') :
self.fst.append(self.snd)
elif (self.snd == 'scissors') and (self.x2 == 'paper') :
self.fst.append(self.snd)
elif (self.snd == 'rock') and (self.x2 == 'paper') :
self.fst.remove(self.snd)
elif (self.snd == 'scissors') and (self.x2 == 'rock') :
self.fst.remove(self.snd)
elif (self.snd == 'paper') and (self.x2 == 'scissors') :
self.fst.remove(self.snd)
def __repr__(self):
return "상대방이 {} 내서\n결국 {}에 수렵".format(self.x2,self.snd)
a = SRP(player1,'scissors')
for i in range(1000):
a.f()
a.f2()
a.f3()
a
a.fst
a.snd
b = SRP(player1,'paper')
for i in range(1000):
b.f()
b.f2()
b.f3()
b
b.fst
b.snd
c = SRP(player1,'rock')
for i in range(1000):
c.f()
c.f2()
c.f3()
c
c.fst
c.snd
함수가 int 가지고 있어야 반복문 쓸 수 있지
a=[1,22,3]
for i in a:
print(i)
b=a.__iter__()
b.__next__()
b.__next__()
b.__next__()
b.__next__()
가지고 있는 개 끝나면 자동으로 Stopiteration 작동해서 무한 loop에 빠지지지 않게 만들어 줌
빅데 21년 거 14주차에클래스 있음ㅎ
import numpy as np
# 1. (20점)
N사에서 게임유저들에게 여름방학 기념이벤트로 진명왕의 집판검이라는 이름의 아이템을 선물했다고 하자. 진명왕의 집판검은 총 5회에 걸쳐서 강화(upgrade)될 수 있되 강화의 성공확률은 10%라고 하자. 강화가 5번성공하면 더 이상 강화가 진행되지 않는다고 하자. (따라서 더 이상 강화시도를 하지 않아도 무방하다) 아래는 이 아이템에 강화를 진행하였을때 각 강화상태를 설명한 예시이다.
시도횟수 | 강화성공여부 | 강화상태 | 비고 |
---|---|---|---|
1 | 강화실패 | +0 $\to$ +0 | 강화실패로 인하여 강화상태 변화없음 |
2 | 강화성공 | +0 $\to$ +1 | 강화성공으로 인한 강화상태 변화 |
3 | 강화실패 | +1 $\to$ +1 | 강화실패로 인하여 강화상태 변화없음 |
4 | 강화성공 | +1 $\to$ +2 | 강화성공으로 인한 강화상태 변화 |
5 | 강화성공 | +2 $\to$ +3 | 강화성공으로 인한 강화상태 변화 |
6 | 강화성공 | +3 $\to$ +4 | 강화성공으로 인한 강화상태 변화 |
7 | 강화실패 | +4 $\to$ +4 | 강화실패로 인하여 강화상태 변화없음 |
8 | 강화성공 | +4 $\to$ +5 | 모든 강화 성공 |
9 | - | +5 $\to$ +5 | 더 이상 강화시도 하지 않음 |
10 | $\dots$ | $\dots$ | $\dots$ |
강화는 하루에 한 번씩만 시도할 수 있으며 시도가능한 기간은 7월1일부터 8월31일까지로 한정되어 있다고 하자. 따라서 방학동안 유저들은 총 62번 시도를 할 수 있다. 방학이 끝난이후 100명 유저중 대략 몇명정도 +5 강화상태에 있겠는가? 파이썬을 통한 시뮬레이션을 활용하여 추론하라. (단, +5강화에 성공하지 못한 모든 유저는 반드시 하루에 한번 강화를 시도해야 한다고 가정하자.)
class RL:
def __int__(self,day):
self.day = day
self.n = 0
def user(self):
self.user = np.random.binomial(1,0.1,self.day)
def next(self):
self.n = np.sum(self.user)
if rl >= 5 :
self.n += 1
return self.n
def RL(n):
total = 0
for i in range(0,n+1):
if sum(np.random.binomial(1,0.1,62))>=5 : total+=1
return total
RL(100)
(풀이1)
import numpy as np
np.random.seed(1)
sum(np.random.binomial(n=62, p=0.1, size=10000)>=5)/10000
(풀이2)
class ExecutionSword():
def __init__(self,prob):
self.nuser=100000
self.prob=prob
self.attemptresult=None
self.upgradestate=pd.DataFrame({'day0':[0]*self.nuser})
self.failstate=pd.DataFrame({'day0':[0]*self.nuser})
self.ratio=0
self.day=0
def addday(self):
self.day=self.day+1
def attempt(self):
self.attemptresult = np.random.binomial(n=1, p=self.prob, size=self.nuser)
def update(self):
# 강화상태 업데이트
self.upgradestate['day%s' % self.day] = np.minimum(5,self.upgradestate['day%s' % (self.day-1)]+self.attemptresult)
# 강화실패누적횟수 업데이트
self.failstate['day%s' % self.day]=self.failstate['day%s' % (self.day-1)]+(self.attemptresult==0)*1
# 강화상태==5 or 강화상태==0 일 경우 강화실패누적횟수 초기화
self.failstate['day%s' % self.day][self.upgradestate['day%s' % self.day]== 0]=0
self.failstate['day%s' % self.day][self.upgradestate['day%s' % self.day]== 5]=0
def reset(self):
# 실패횟수 = 2 인것을 찾아 index_ 에 저장 -> index_ 에 해당하는 유저의 강화횟수와 실패횟수를 모두 0으로 초기화
index_= self.failstate['day%s' % self.day]==2
self.failstate['day%s' % self.day][index_] = 0
self.upgradestate['day%s' % self.day][index_] = 0
def arrangeprob(self):
self.ratio=sum(self.upgradestate['day%s' % self.day]==5) / self.nuser
if self.ratio > 0.5:
self.prob = 0.9
import pandas as pd
s1=ExecutionSword(0.1)
for i in range(62):
s1.addday()
s1.attempt()
s1.update()
sum(s1.upgradestate.day62==5)/s1.nuser
# 2. (70점)
강화성공확률을 40%로 수정한다. 강화에 누적2회 실패하면 강화상태가 초기화 된다고 하자. (따라서 강화실패 누적횟수를 카운트하는 변수가 필요하다) 단, 강화실패 누적횟수는 누적2회 달성시 0으로 초기화 된다. 또한 강화상태가 +0인 경우는 실패하여도 강화실패 누적횟수가 추가되지 않는다.
시도횟수 | 강화성공여부 | 강화상태 | 강화실패누적 | 비고 |
---|---|---|---|---|
1 | 강화성공 | +0 $\to$ +1 | 0 $\to$ 0 | - |
2 | 강화성공 | +1 $\to$ +2 | 0 $\to$ 0 | - |
3 | 강화실패 | +2 $\to$ +2 | 0 $\to$ 1 | - |
4 | 강화성공 | +2 $\to$ +3 | 1 $\to$ 1 | - |
5 | 강화실패 | +3 $\to$ +0 | 1 $\to$ 0 | 강화실패로 누적2회로 인한 초기화 |
6 | 강화실패 | +0 $\to$ +0 | 0 $\to$ 0 | 강화실패 누적횟수 증가하지 않음 |
7 | 강화성공 | +0 $\to$ +1 | 0 $\to$ 0 | - |
8 | 강화성공 | +1 $\to$ +2 | 0 $\to$ 0 | - |
9 | 강화성공 | +2 $\to$ +3 | 0 $\to$ 0 | - |
10 | 강화성공 | +3 $\to$ +4 | 0 $\to$ 0 | - |
11 | 강화성공 | +4 $\to$ +5 | 0 $\to$ 0 | 모든 강화 성공 |
12 | - | +5 $\to$ +5 | 0 $\to$ 0 | 더 이상 강화시도 하지 않음 |
13 | $\dots$ | $\dots$ | $\dots$ | $\dots$ |
(1)
이 경우 62일의 방학뒤에 100명의 유저중 대략 몇명정도 +5 강화상태에 있겠는가? 시뮬레이션을 활용하여 추론하라. (단, +5강화에 성공하지 못한 모든 유저는 반드시 하루에 한번 강화를 시도해야 한다고 가정하자.)
def RL(n):
total = 0
a = 0
for i in range(0,n+1):
for i in range(1,63):
a += np.random.binomial(1,0.1,62)[i]
if a > 1 & np.random.binomial(1,0.1,62)[i]+np.random.binomial(1,0.1,62)[i+1]==0 : break
a = 0
if a >= 5 : total+=1
return total
RL(100)
(2)
31번째 시도 이후 대략 몇명의 유저가 +5 강화상태에 있겠는가?
def RL(n):
total = 0
a = 0
for i in range(0,n+1):
for i in range(1,32):
a += np.random.binomial(1,0.1,31)[i]
if a > 1 & np.random.binomial(1,0.1,31)[i]+np.random.binomial(1,0.1,31)[i+1]==0 : break
a = 0
if a >= 5 : total+=1
return total
RL(31)
s2=ExecutionSword(0.4)
for i in range(62):
s2.addday()
s2.attempt()
s2.update()
s2.reset() ## 초기화가 되는 조건이 있으므로 문제1에서 reset함수만 추가하면 된다.
sum(s2.upgradestate.day31==5)/s2.nuser
sum(s2.upgradestate.day62==5)/s2.nuser
(3)
100명의 유저중 50명이상의 유저가 +5 강화상태에 도달하는 순간 모든 유저의 강화성공확률을 90%로 증가시킨다고 하자. 62일의 방학뒤에 100명의 유저 중 몇명 정도가 +5 강화상태에 있겠는가?
s3=ExecutionSword(0.4)
for i in range(62):
s3.addday()
s3.attempt()
s3.update()
s3.reset() ## 초기화가 되는 조건이 있으므로 reset함수 추가
s3.arrangeprob() ## 전체유저의 50%가 강화성공하면 강화확률이 조정되는 조건이 있으므로 arragneprob 추가
sum(s3.upgradestate.day62==5)/s3.nuser