지금까지 배운 내용으로 조편성 코드를 만들어 볼 것이다.
random
을 사용하여 무작위로 배정로또 추첨상자를 생각한다고 코드를 짠 후 치환하니 편했다.
이제 이렇게 가정하고 코드를 작성한다
random
을 사용하여 무작위 개수의 로또 공을 추첨로또 추첨 상자 = list(range(1, 45개+1)
random.sample(리스트, 개수)
메서드를 사용하여 임의의 요소를 추출한다. 메서드 결과물의 반환형 또한 리스트이다.당첨된 공 = random.sample(로또 상자, 6개)
# ex print(추첨된 공)
>> [1, 7, 41, 42, 31, 19]
append()
를 사용하면 된다.로또 당첨 숫자 세트 = []
로또 당첨 숫자 세트.append(당첨된 공 세트)
if 당첨된 공 in 로또 상자:
로또상자.remove(당첨된 공)
remove(값)
메서드는 value
기준으로 list의 요소를 삭제해주기 때문에 편리하게 사용할 수 있다.
여기까지를 코드로 옮기면
import random
# 로또 당첨 숫자 세트
cls = []
# 총 공의 개수는?
total = list(range(1, 45+1))
# 당첨 숫자 조합은 몇 개?
group = 25//4
# 공을 뽑기 시작하는데
for _ in range(1, group+1):
# 상자에 적어도 6개는 남아 있어야 추첨이 가능하다
if len(total) >= 6:
# 로또 상자에서 6개의 요소를 임의로 꺼내 '당첨된 공 세트'로 만든다
picker = random.sample(total, 6)
# 로또 당첨 숫자 세트에 넣는다
cls.append(picker)
# 뽑은 공은 상자에선 사라져야 한다
for val in picker:
# 뽑은 공을 상자에서 확인하고
if val in total:
# 삭제한다
total.remove(val)
# 초기 조건인 공의 개수가 6개가 아니라면
else:
# 반복문을 종료한다
break
print(cls.a)
[
[1, 8, 9, 17, 18, 25, 34],
[2, 5, 3, 44, 41, 31, 37],
....
]
이런 식으로 나올 것이다.
로또 당첨 숫자를 중복없이 뽑는 방법은 여기서 끝.
이제 다시 조 편성으로 돌아오겠다.
'로또 당첨 숫자 세트'는 '반'이 된다.
'당첨된 공 세트'는 '조'가 된다.
로또와 달리, 조 편성에서 남는 인원이 있다면 이미 편성된 조에 적절히 나눠줘야 한다.
조 편성 인원보다 남은 인원이 적은 경우, 남은 인원 중 임의의 1명을 뽑는다.
이미 편성된 조에서도 임의의 조를 하나 뽑는다.
임의로 선택된 조에 임의로 선택된 남은 인원을 붙인다.
남은 인원은 전체 인원 리스트에서 삭제해준다.
반복한다.
남은 인원이 없을 때 반복을 종료한다.
...
while True:
# 남은 인원이 조 편성 인원보다 적을 때
if 0 < len(total) < num_member:
# 남은 인원 중 무작위 한 명을 뽑는다
picker = random.sample(total, 1)
# 이미 편성된 조들 중에 하나의 조를 무작위로 뽑는다
group_picker = random.sample(cls, 1)
# 남은 인원이 들어갈 조에 직접 접근하기 위해 인덱스를 알아낸다
group_index = cls.index(group_picker_last)
# 인덱스를 통해 본 값에 접근하여 남은 인원을 집어 넣는다
cls[group_index].append(picker[0])
# 조에 들어간 인원은 총원에서 삭제한다
total.remove(picker[0])
# 남은 인원이 0명이 되면
if len(total) == 0:
# 반복을 종료한다
break
이렇게 하면 끝이 난다.
만약 이 코드로 총원 25명을 4명씩 한 조로 만든다면
[
[8, 1, 9, 14],
[10, 13, 6, 15],
[17, 3, 2, 23],
[18, 21, 16, 20],
[5, 24, 7, 19, 12],
[11, 4, 22, 25]
]
이렇게 번호로된 조 편성 값을 볼 수 있다.
이 번호를 딕셔너리를 통해 매핑할 수도 있다.
name_tag = {
1:'홍길동', 2:'이순신', 3:'김유신', 4:'강감찬', 5:'이산',
6:'정조', 7:'정지상', 8:'고이왕', 9:'이성계', 10:'왕건', 11:'박혁거세', 12:'내물마립간',
13:'광개토', 14:'허준', 15:'장금', 16:'이승만', 17:'박경종', 18:'이하응', 19:'윤관', 20:'효녀지은',
21:'최승로', 22:'정몽주', 23:'신립', 24:'원효', 25:'지눌'
}
코드의 앞부분에 미리 딕셔너리를 정의한다.
### mapping ###
# 매핑을 하면서 새로운 반을 만들 것이다
r_cls = []
# 조를 하나하나 불러오면서
for r_group in cls:
# 번호를 이름으로 바꿔 새롭게 만들 준비를 한다
map_group = []
# 인덱스를 따라 요소를 조회하고
for index in range(len(r_group)):
# 요소를 딕셔너리의 값으로 매핑한다
map_group.append(name_tag[r_group[index]])
r_cls.append(map_group)
### end of mapping
이렇게 하면 매핑된 이름으로 조를 볼 수 있다.
[
['허준', '내물마립간', '박경종', '최승로', '신립'],
['정조', '이승만', '이산', '원효', '광개토'],
['효녀지은', '이하응', '홍길동', '김유신', '장금'],
['정몽주', '고이왕', '이순신', '윤관', '이성계'],
['지눌', '왕건', '강감찬', '박혁거세', '정지상']
]
이렇게 역사상 유래 없는 드림팀을 임의로 짜볼 수도 있다.
전체 코드를 함수로 묶어서 작성하면 다음과 같다.
def group_selector(total, num_member):
import random
name_tag = {
1:'홍길동', 2:'이순신', 3:'김유신', 4:'강감찬', 5:'이산',
6:'정조', 7:'정지상', 8:'고이왕', 9:'이성계', 10:'왕건', 11:'박혁거세', 12:'내물마립간',
13:'광개토', 14:'허준', 15:'장금', 16:'이승만', 17:'박경종', 18:'이하응', 19:'윤관', 20:'효녀지은',
21:'최승로', 22:'정몽주', 23:'신립', 24:'원효', 25:'지눌'
}
cls = []
group = total//num_member
if group < 2:
return "조를 나눌 수 없습니다"
total = list(range(1, total+1))
for _ in range(1, group+1):
if len(total) >= num_member:
picker = random.sample(total, num_member)
cls.append(picker)
for val in picker:
if val in total:
total.remove(val)
else:
break
while True:
if 0 < len(total) < num_member:
picker = random.sample(total, 1)
group_picker = random.sample(cls, 1)
group_index = cls.index(group_picker)
cls[group_index].append(picker[0])
total.remove(picker[0])
if len(total) == 0:
break
### mapping ###
r_cls = []
for r_group in cls:
map_group = []
for index in range(len(r_group)):
map_group.append(name_tag[r_group[index]])
r_cls.append(map_group)
### end of mapping
return r_cls
만약 인원이 많아져서 x조의 인원만 확인하고 싶다면 이렇게 해볼 수 있겠다.
def group_reader(cls, number):
index = number
data = cls
return f"{index}조:",data[index]
앞서 작성했던 함수의 리턴값을 cls라는 변수로 받고, number에는 몇 조인지(1조, 2조...) 번호를 입력한다.
이를 실행하면 원하는 번호의 조원들을 조회할 수 있다.
a = group_selector(25, 5)
group_reader(a, 1)
>>
('1조:', ['이하응', '박혁거세', '이승만', '강감찬', '내물마립간'])
이렇게 함수의 리턴값을 이용하여 여러가지 접근이 가능하고, 여러 가지 보조 함수들을 만들어 사용할 수 있다.
재밌다!