프로그램 설명과 함께 한, 개선된 랜덤 번호 추첨기

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@gyeryak·
0.000 HBD
프로그램 설명과 함께 한, 개선된 랜덤 번호 추첨기
<center>![도전하는 모든 사람에게 행복이 있기를](https://steemitimages.com/0x0/https://steemitimages.com/0x0/http://i.imgur.com/ob6vZoK.jpg)</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>![큰 문제점이 있는 프로그램이다](https://i.imgur.com/nODbPz8.png)</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>![불러오고, 입력받기](https://i.imgur.com/tJ7CJno.png)</center>
```import random``` 는 간단하게 생각했을 때, 있어야만 하는 것(...)입니다.  
없으면 랜덤 수를 생성하는 방법이 매우 어려워지니, 간단하게 하자는 거죠.  
``` ~~ = int(input()) ``` 는 정수를 입력받는 것입니다.  
```input()```는 의미 그대로 입력이고, ```int```는 정수를 뜻하는 integer의 약자로, 받은 입력을 정수로 바꿔준다는 뜻이 되겠죠.  

여기까지는 특별한 내용이 아닙니다.  
저번의 프로그램이랑 어떤 면이 달라졌는지 봅시다.

<center>![리스트를 만드는건 상자를 만드는 것](https://i.imgur.com/KSIwG7h.png)</center>
```gen = list(range(1,lastNum))```은 아까 입력받은 마지막 번호까지 하나씩 들어가 있는 리스트를 만드는 것입니다.  
리스트는 사물함이라고 생각하시면 됩니다.  
1번부터 10번까지의 사물함에, 1부터 10까지가 차례대로 들어가 있습니다.  
그런 모양이 대충 그려지시죠?

<center>![일단 반복을 한다.](https://i.imgur.com/973eGTP.png)</center>
저 부분은 나중에 다시 설명드릴게요.  
```while``` 아래 줄부터, 띄워진 부분들은 반복된다는 것입니다.

<center>![너무 어려워졌다!](https://i.imgur.com/CSphHZK.png)</center>
이렇게 대충 넘어가면 안 되겠죠. 설명 들어갑니다.
> 배열은 0번부터 시작합니다만, 이해를 돕기 위해 1번부터 들어가는 것을 가정을 합니다.

<center>![사물함은 언제나 평화롭다](https://i.imgur.com/TFzg04h.png)</center>
처음에는 이렇게 사물함이 다 그대로 있습니다.  
자기 번호에, 그 숫자가 그대로 들어가 있습니다.

<center>![하지만 선생님이 나타났다](https://i.imgur.com/Kqv3oqm.png)</center>
고런데, 여기서 선생님이 학생 한명을 뽑아서 부르듯  
사물함 번호 하나가 뽑힙니다.  
여기서는 6번이 뽑혔네요.

<center>![희생자가 탄생했고](https://i.imgur.com/wyux8Dv.png)</center>  
사물함 6번에 있던 번호는 6입니다.  
remove는 없앤다는 뜻을 가지고 있어요.  
그래서 6은 사라지게 되었습니다.  
6이 사라진 뒤가 중요합니다.

<center>![하이에나가 몰려들었으며](https://i.imgur.com/VbeK4po.png)</center>
왜인진 잘 몰라도, 사물함 번호가 작은게 좋나 봅니다.  
앞에가 빠지면 우르르 몰려들어요.  
그래서 7부터 10이, 한 칸씩 앞으로 왔습니다.  

그리고 방 빠진 10번 사물함은 고독사합니다.

<center>![이것은 반복되었고](https://i.imgur.com/kv5nT7I.png)</center>
선생님은 똑똑하십니다.  
결석자는 부르지 않아요.  
그래서 10번 사물함이 불릴 일은 없습니다.  
1번 사물함부터 9번 사물함 중 하나가 불릴 것입니다.  

이번에는 7번이 뽑혔네요.  
그런데 7번 사물함에는 8이 들어있습니다.


<center>![한명씩 사라졌다](https://i.imgur.com/FcsTf7O.png)</center>
그러면 이번엔 8이 빠질 것입니다.  
그리고 9와 10이 앞으로 올 것이고, 9번 사물함도 고독사하겠죠.  

이런식으로 반복되면서,  
**한번 뽑힌 숫자는 사라집니다!**  

그리고 사물함 번호를 뽑는 것이기 때문에, 삽질할 우려도 없죠.  
이렇게 앞서 만든 코드보다 개선된 코드가 완성되었습니다.

```while lastNum-numCount-len(gen)-1```이 부분은 상당히 복잡하게 적은 부분입니다.  
그래도 간단하게 설명하자면, 고독사한 사물함의 개수가 뽑고자 하는 수의 개수만큼 되었을 때 까지 반복하라는 의미입니다.  

어찌 되었든, 이렇게 해서 적절한 랜덤 번호 뽑기 프로그램이 완성되었습니다.
  
직접 실행해봅시다.  
파이썬을 여기서 설치한다는 것은 귀찮으므로,  
웹에서 바로 실행해봅시다.  
http://ideone.com/cETEQe
이 곳으로 들어가셔서  
<center>![fork](https://i.imgur.com/Fv9b2fV.png)</center>  
왼쪽 위의 fork를 누르시고  
<center>![enter input](https://i.imgur.com/va3Qs4Q.png)</center>  
enter input부분에   
```[참가자 수]```  
```[뽑을 인원]```  
을 적으시고
<center>![Run](https://i.imgur.com/i0UDj7r.png)</center>  
오른쪽 밑의 Run을 누르시면   
<center>![뿅!](https://i.imgur.com/3r5WBVn.png)</center>  
이렇게 추첨이 완료됩니다.

---

이렇게 해서 코드를 간략하게 알아봤습니다.  
아마... 어려우셨을 것 같습니다... 
 
그래도,
<center>![도전하는 모든 사람에게 행복이 있기를](https://steemitimages.com/0x0/https://steemitimages.com/0x0/http://i.imgur.com/ob6vZoK.jpg)</center><div class="pull-right">바랍니다.</div>
<p style="clear:both;">&nbsp;</p>


위 캘리그라피를 만들어주신 @hellojun 님께 감사의 말씀 올립니다.
👍 , , , , , , , , , , , ,