프로그램 설명과 함께 한, 개선된 랜덤 번호 추첨기
kr-dev·@gyeryak·
0.000 HBD프로그램 설명과 함께 한, 개선된 랜덤 번호 추첨기
<center></center>
### 안녕하세요, 계략입니다. ###
---
지난번
https://steemit.com/kr-dev/@gyeryak/random-number-with-python
게시글에서 번호 추첨기를 만들었던 적이 있습니다.
여기에는 아주 큰 문제가 있습니다.
import random
def generate_random(endNum, numTot):
alreadyGenerated = set([])
numCount = 0
while numCount != numTot and numCount != endNum:
ranNum = random.randint(1,endNum)
if ranNum not in alreadyGenerated:
alreadyGenerated.add(ranNum)
numCount += 1
print("%d번째 생성된 수는 %d입니다." %(numCount, ranNum) )
generate_random(50,3)
이 프로그램이 동작하는 방법을 간단하게 설명해드릴게요
<center></center>
쉽게 얘기해서, 숫자를 생성하고 중복인지 확인합니다.
중복이면 다시 만들고, 아니라면 그대로 출력하는 것이죠.
여기서 문제가 발생합니다.
엄청난 확률로 계속 중복이 발생한다면?
> 망한 겁니다.
프로그램은 종료되지 않을 것입니다.
그래서, 이런 부분이 개선될 필요가 있었습니다.
---
그리하여 개선된 프로그램을 들고 왔습니다.
Python 3으로 작성된 프로그램입니다.
import random
lastNum = int(input())
numCount = int(input())
gen = list(range(1,lastNum+1))
while lastNum - len(gen) < numCount:
r = gen[random.randrange(0,len(gen))]
gen.remove(r)
print("생성된 수는 %d입니다." %(r))
이제는 조금 친절하게 설명드리겠습니다.
하나하나 살펴봅시다!
<center></center>
```import random``` 는 간단하게 생각했을 때, 있어야만 하는 것(...)입니다.
없으면 랜덤 수를 생성하는 방법이 매우 어려워지니, 간단하게 하자는 거죠.
``` ~~ = int(input()) ``` 는 정수를 입력받는 것입니다.
```input()```는 의미 그대로 입력이고, ```int```는 정수를 뜻하는 integer의 약자로, 받은 입력을 정수로 바꿔준다는 뜻이 되겠죠.
여기까지는 특별한 내용이 아닙니다.
저번의 프로그램이랑 어떤 면이 달라졌는지 봅시다.
<center></center>
```gen = list(range(1,lastNum))```은 아까 입력받은 마지막 번호까지 하나씩 들어가 있는 리스트를 만드는 것입니다.
리스트는 사물함이라고 생각하시면 됩니다.
1번부터 10번까지의 사물함에, 1부터 10까지가 차례대로 들어가 있습니다.
그런 모양이 대충 그려지시죠?
<center></center>
저 부분은 나중에 다시 설명드릴게요.
```while``` 아래 줄부터, 띄워진 부분들은 반복된다는 것입니다.
<center></center>
이렇게 대충 넘어가면 안 되겠죠. 설명 들어갑니다.
> 배열은 0번부터 시작합니다만, 이해를 돕기 위해 1번부터 들어가는 것을 가정을 합니다.
<center></center>
처음에는 이렇게 사물함이 다 그대로 있습니다.
자기 번호에, 그 숫자가 그대로 들어가 있습니다.
<center></center>
고런데, 여기서 선생님이 학생 한명을 뽑아서 부르듯
사물함 번호 하나가 뽑힙니다.
여기서는 6번이 뽑혔네요.
<center></center>
사물함 6번에 있던 번호는 6입니다.
remove는 없앤다는 뜻을 가지고 있어요.
그래서 6은 사라지게 되었습니다.
6이 사라진 뒤가 중요합니다.
<center></center>
왜인진 잘 몰라도, 사물함 번호가 작은게 좋나 봅니다.
앞에가 빠지면 우르르 몰려들어요.
그래서 7부터 10이, 한 칸씩 앞으로 왔습니다.
그리고 방 빠진 10번 사물함은 고독사합니다.
<center></center>
선생님은 똑똑하십니다.
결석자는 부르지 않아요.
그래서 10번 사물함이 불릴 일은 없습니다.
1번 사물함부터 9번 사물함 중 하나가 불릴 것입니다.
이번에는 7번이 뽑혔네요.
그런데 7번 사물함에는 8이 들어있습니다.
<center></center>
그러면 이번엔 8이 빠질 것입니다.
그리고 9와 10이 앞으로 올 것이고, 9번 사물함도 고독사하겠죠.
이런식으로 반복되면서,
**한번 뽑힌 숫자는 사라집니다!**
그리고 사물함 번호를 뽑는 것이기 때문에, 삽질할 우려도 없죠.
이렇게 앞서 만든 코드보다 개선된 코드가 완성되었습니다.
```while lastNum-numCount-len(gen)-1```이 부분은 상당히 복잡하게 적은 부분입니다.
그래도 간단하게 설명하자면, 고독사한 사물함의 개수가 뽑고자 하는 수의 개수만큼 되었을 때 까지 반복하라는 의미입니다.
어찌 되었든, 이렇게 해서 적절한 랜덤 번호 뽑기 프로그램이 완성되었습니다.
직접 실행해봅시다.
파이썬을 여기서 설치한다는 것은 귀찮으므로,
웹에서 바로 실행해봅시다.
http://ideone.com/cETEQe
이 곳으로 들어가셔서
<center></center>
왼쪽 위의 fork를 누르시고
<center></center>
enter input부분에
```[참가자 수]```
```[뽑을 인원]```
을 적으시고
<center></center>
오른쪽 밑의 Run을 누르시면
<center></center>
이렇게 추첨이 완료됩니다.
---
이렇게 해서 코드를 간략하게 알아봤습니다.
아마... 어려우셨을 것 같습니다...
그래도,
<center></center><div class="pull-right">바랍니다.</div>
<p style="clear:both;"> </p>
위 캘리그라피를 만들어주신 @hellojun 님께 감사의 말씀 올립니다.👍 gyeryak, sesangsokuro, rlawls1991, honna, lawmance, nhj12311, ubg, proctologic, kdj, geusgod, agile, ineedthesleep,