<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 인자의 기본값
Step1:  함수 인자
함수의 인자를 학습하는 예시
Step2:  두 개 이상의 결과 반환(return)
Step3:  인자에 미치는 효과
Step4:  함수의 스코프에서 선언된 변수는 지역변수
Step5:  제네레이터 (Generator)
Step6:  도전과제
리스트, 문자열과 같은 시퀀스를 받아서 홀수번째 원소만 선택해 반환하는 함수 its_odd를 정의하시오.
예
Step7:  그런데, 유니코드 저장을 하려고 하니까 ... ?
Step8:  도전과제
피보나치 수열은 다음과 같다.
0 1 1 2 3 5 8 ... 
a. 임의의 n개의 피보나치 수열을 리스트로 반환하는 함수 generate_fibo를 작성하시오.
b. generate_fibo 호출 시, 시작 숫자 두 개를 지정할 수 있도록 하시오. 인자를 설정하지 않으면 수열은 0,1로 시작한다. 생성 개수를 지정하지 않으면, 기본적으로 10개의 숫자를 생성하도록 만드시오.
Step9:  도전과제
포커 카드 52장을 게임 참가자에게 각각 5장씩 나눠주는 프로그램을 작성하시오. 포커 카드는 참가자에게 나눠주기 전에 무작위로 섞여야 한다. 참가자의 수는 2-4명이 될 수 있다.
a. 포커 카드를 나눠주고 나서 각 참가자가 받은 포커 카드를 모두 출력한다.
예
Step11:  도전과제
52장의 포커 카드가 있다. 이 카드를 사용해 블랙잭 게임을 한다.
블랙잭 게임은 각 참가자가 처음에 두 장의 카드를 받는다.
각 카드의 숫자를 모두 더 해 21인지 확인한다.
21이면 블랙잭! 게임이 종료되고 승리한다.
숫자의 합이 21보다 작으면 한 장의 카드를 더 받는다.
숫자의 합이 21보다 크면 게임에서 패배한다.
a. 받은 카드패를 파일로 출력해 저장한다.
참가자
Step15:  도전과제
5개의 임의의 카드패 100개 정보를 담은 파일을 생성한다. 이 파일의 각 카드패에 포커 (같은 숫자 4개)가 있는지 확인하는 프로그램을 작성한다.
<ASSISTANT_TASK:>
Python Code:
def greetings(hour, lang='kr', extra_msg=None):
    # 시간값 확인
    if hour < 0 or hour > 24:
        return
    
    # 언어에 따라 메시지 설정
    msgs = {'kr': [u'좋은', u'아침', u'오후', u'저녁', u'밤'],
            'en': [u'Good', u'morning', u'afternoon', u'evening', 
                   u'night']}
    # 별도로 설정된 메시지가 있으면, 해당 메시지 반영
    if not extra_msg is None:
        for key, value in extra_msg.items():
            msgs[key] = value
    
    # 해당 언어가 없으면 함수 종료
    if not lang in msgs:
        return
    
    msg_prefix = msgs[lang][0]
    
    # 시간에 따른 메시지 설정
    msg = msg_prefix + ' '
    if 6 < hour < 12:
        msg += msgs[lang][1]
    elif 12<= hour < 18:
        msg += msgs[lang][2]
    elif 18<= hour < 21:
        msg += msgs[lang][3]
    else:
        msg += msgs[lang][4]
    return msg
print(greetings(9, lang='fr', 
                extra_msg={'fr': 
                           ['bon', 
                            'jour', 'soir', 'nuit']}))
print(greetings(13))
print(greetings(19))
print(greetings(22))
print(greetings(-2))
# return의 효과
def many_exits(exit_no):
    if exit_no==1:
        return 'Exit 1'
    if exit_no==2:
        return 'Exit 2'
    if exit_no==3:
        return 'Exit 3'
    
    return '그런 출구는 없습니다.'
print(many_exits(1))
print(many_exits(2))
print(many_exits(9))
Explanation: 인자의 기본값
End of explanation
def juicer(ingredient, customer_name):
    result = customer_name + u' 님, '
    # TODO: 가능한 메뉴인지 확인
    menu = [u'딸기', u'사과', u'망고']
    if not ingredient in menu:
        return None
    
    result += ingredient + u' 주스'
    if ingredient == u'딸기':
        price = 10
    elif ingredient == u'사과':
        price = 15
    elif ingredient == u'망고':
        price = 20
   
    return result, price
result = juicer(u'딸기', u'성주')
if result is None:
    print('그런 메뉴 없습니다.')
else:
    msg, price = result # 결과 튜플 언패킹
    print(msg + u' 나왔습니다.')
    print('가격: ' + str(price))
# 출력 예시: 성주 님, 딸기 주스 나왔습니다.
# 딸기 주스는 10원입니다.
# 사과 주스는 15원입니다.
# 망고 주스는 20원입니다.
Explanation: 함수 인자
함수의 인자를 학습하는 예시
End of explanation
def swap(x,y):
    return (y,x)
print(swap(1,2))
# 함수 정의
def foo(a,b):
    return a*2, b*2
# 함수 호출
aa, bb = foo(1,2)
print(aa,bb)
result = foo(1,2)
print(type(result))
print(result[0], result[1])
Explanation: 두 개 이상의 결과 반환(return)
End of explanation
def double(x):
    x = x*2
    
x = 1
double(x)
print(x)
def square_not_safe(seq):
    for i, n in enumerate(seq):
        seq[i] = seq[i]**2
def square_safe(seq):
    # 값 복사
    seq = list(seq[:])
    for i, n in enumerate(seq):
        seq[i] = seq[i]**2
        
    return seq
nums = [1,2,3,4]
result = square_safe(nums)
print(nums)
print(result)
# list --> tuple
nums = tuple(nums)
square_not_safe(nums)
Explanation: 인자에 미치는 효과
End of explanation
def func(x):
    y = x
    
func(1)
print(y)
Explanation: 함수의 스코프에서 선언된 변수는 지역변수
End of explanation
def countdown(n):
    print('카운트 다운 시작!')
    while n>0:
        yield n
        n -=1
c = countdown(10)
c.next()
c.next()
for c in countdown(10):
    print(c, end=' ')
Explanation: 제네레이터 (Generator)
End of explanation
def its_odd(seq):
    result = seq[::2]
    return result
result = its_odd(u'파이썬')
print(result)
print(its_odd([1,2,3,4,5]))
type(its_odd)
its_odd(range(10))
xx = its_odd
xx(range(10))
def save_to_file(func, input_seq, filename, str_format=u'{} --> {}'):
    output_seq = func(input_seq)
    f = open(filename, 'w')
    # TODO: 문자열 인코딩 수행
    text_encoded = str_format.format(input_seq, output_seq).encode('utf-8')
    f.write(text_encoded)
    f.close()
save_to_file(its_odd, [1,2,3,4,5], 'its_odd_result.txt')
def its_even(seq):
    return seq[1::2]
save_to_file(its_even, [1,2,3,4,5], 'its_even_result.txt')
Explanation: 도전과제
리스트, 문자열과 같은 시퀀스를 받아서 홀수번째 원소만 선택해 반환하는 함수 its_odd를 정의하시오.
예: 
result = its_odd(u'파이썬')
print(result) # '파썬'
result = its_odd([1,2,3,4,5])
print(result) # [1,3,5]
a. 입력과 출력을 다음 형식으로 파일 its_odd_result.txt에 저장하시오.
파이썬 --> 파썬
[1,2,3,4,5] --> [1,3,5]
End of explanation
save_to_file(its_odd, u'파이썬', 'its_odd_result.txt')
Explanation: 그런데, 유니코드 저장을 하려고 하니까 ... ?
End of explanation
def generate_fibo(a=0,b=1,n=10):
    fibos = [a,b]
    # 지정된 개수만큼 원소 추가
    while len(fibos)<n:
        # 새 원소 생성 후 a, b 값 교체
        a,b = (b, a+b)
        # 새로 생성된 값을 결과에 추가
        fibos.append(b)
    
    return fibos
generate_fibo()
Explanation: 도전과제
피보나치 수열은 다음과 같다.
0 1 1 2 3 5 8 ... 
a. 임의의 n개의 피보나치 수열을 리스트로 반환하는 함수 generate_fibo를 작성하시오.
b. generate_fibo 호출 시, 시작 숫자 두 개를 지정할 수 있도록 하시오. 인자를 설정하지 않으면 수열은 0,1로 시작한다. 생성 개수를 지정하지 않으면, 기본적으로 10개의 숫자를 생성하도록 만드시오.
End of explanation
from __future__ import print_function
import random
# 1. 카드덱 생성
def generate_card():
    # 52장 카드 덱 생성
    suits = ['Heart', 'Diamond', 'Clover', 'Spade']
    ranks = range(2,11)+['J', 'Q', 'K', 'A']
    deck = []
    for s in suits:
        for r in ranks:
            card = s + str(r)
            deck.append(card)
    return deck
# 2. 카드덱 나눠주기
def play_card_game(deck, players):
    # 나눠주기 전에 섞어야지
    random.shuffle(deck)
    
    # 인제 나눠줘야지 ...
    for person in players:
        person['hand'] = deck[:5]
        deck = deck[5:]
        
    return
deck = generate_card()
players = [{'name':'이성주'}, {'name':'김성주'}]
play_card_game(deck, players)
print(len(deck))
for person in players:
    print(person['name'], end=': ')
    print(person['hand'])
Explanation: 도전과제
포커 카드 52장을 게임 참가자에게 각각 5장씩 나눠주는 프로그램을 작성하시오. 포커 카드는 참가자에게 나눠주기 전에 무작위로 섞여야 한다. 참가자의 수는 2-4명이 될 수 있다.
a. 포커 카드를 나눠주고 나서 각 참가자가 받은 포커 카드를 모두 출력한다.
예:
이성주 : H2, D2, SJ, C10, S3
김성주 : C3, D4, CK, SK, H9
b. 각 참자자의 카드의 숫자를 기준으로 오름차순으로 정렬해 출력한다.
End of explanation
from __future__ import print_function
import random
# 52장의 카드덱 생성
def gen_deck():
    ranks = list(range(2,11))+['J', 'Q', 'K', 'A']
    suits = ['Spade', 'Heart', 'Diamond', 'Clover']
    
    deck = [] # 카드덱 초기화
    for s in suits:
        for r in ranks:
            deck.append((s, r))
            
    # 잘 섞기
    random.shuffle(deck)
    return deck
def get_card_value(hand):
    카드패의 숫자값 합계
    # 현재 hand의 카드의 숫자를 모두 더한다.
    value=0
    for card in hand:
        # 현재 카드의 숫자값
        rank = card[1]
        if rank=='A':
            value = value + 14
        elif rank=='K':
            value = value + 13
        elif rank == 'Q':
            value = value + 12
        elif rank == 'J':
            value = value + 11
        else:
            # 숫자인 경우는 그냥 더해준다.
            value = value + rank
                
    return value
def play_blackjack(player, output_file=None):
    # 블랙잭 게임 시작
    deck=gen_deck()
    # 카드 두 장 받기
    player['hand'] = [deck.pop(), deck.pop()]
    while True:
        play_log = u'카드패: {}'.format(player['hand'])
        play_log += u'\n'
        # 카드패 숫자값 합계
        hand_value = get_card_value(player['hand'])
        play_log += u'카드 숫자값= {}'.format(hand_value)
        play_log += u'\n'
        if hand_value == 21:
            play_log += u'블랙잭!!!!!!!' 
            play_log += u'\n'
            print(play_log)
            break
        elif hand_value > 21:
            play_log += u'돈 잃었다...'
            play_log += '\n'
            print(play_log)
            break
        elif hand_value < 21:
            # 카드를 한 장 더 받는다.
            player['hand'].append(deck.pop())
            play_log += u'인생을 계속 살아봐야 아는 거지 ... 한 장 더'
            play_log += u'\n'
            print(play_log)
            
    # 게임 결과를 파일로 출력
    if output_file is not None:
        f = open(output_file, 'a')
        text_encoded = play_log.encode('utf-8')
        f.write(text_encoded)
        f.close()
            
play_blackjack({'name':u'이성주'}, output_file='blackjack_log.txt')
deck = gen_deck()
hand = deck[:3]
print(hand)
get_card_value(hand)
Explanation: 도전과제
52장의 포커 카드가 있다. 이 카드를 사용해 블랙잭 게임을 한다.
블랙잭 게임은 각 참가자가 처음에 두 장의 카드를 받는다.
각 카드의 숫자를 모두 더 해 21인지 확인한다.
21이면 블랙잭! 게임이 종료되고 승리한다.
숫자의 합이 21보다 작으면 한 장의 카드를 더 받는다.
숫자의 합이 21보다 크면 게임에서 패배한다.
a. 받은 카드패를 파일로 출력해 저장한다.
참가자: 이성주
2015-07-08
HJ, HK 패!
HJ, S10 블랙잭!
End of explanation
# list의 원소를 문자열로 반환하는 구문
text = ''
for c in ['a','b','c']:
    text += c
print(text)
# sequence 형의 원소를 문자열로 반환
# 파이썬 표준 라이브러리 활용
import string
text = string.join(('Spade', str(6)), sep=' ')
print(text)
# 문자열을 list로 변환
'a,b,c'.split(',')
import string
def card_to_string(card):
    return string.join((str(card[0]), str(card[1])), sep=' ')
def gen_hands(filename = 'hand_100.txt', n=100):
    # 카드패 파일 생성
    f = open(filename, 'w')
    for i in range(n):
        hand = gen_deck()[:5]
        # 카드패 정보를 문자열로 변환
        for card in hand:
            card_str = card_to_string(card)
            f.write(card_str)
            f.write(',')
        f.write('\n')
    
    f.close()
from __future__ import print_function
def is_pocker(hand):
    카드패가 포커(4장의 같은 숫자 포함)인지 확인
    # TODO: 포커 탐지
    
    X O O O O
    O X O O O
    O O X O O
    O O O X O
    O O O O X
    
    # 카드패에서 숫자만 추출
    ranks = []
    for card in hand:
        ranks.append(str(card[1]))
    #print(ranks) # 디버깅용 출력
    
    # 자료 구조를 바꾸는 방법
    # 더 좋은 방법을 찾아야 할 듯 ...
    if len(set(ranks)) == 2:
        return True
    
    return False
def to_list(hand_str_list):
    hand_list = []
    for l in hand_str_list:
        # 카드패를 list로 변환
        hand_str = l.split(',')[:-1]
        # 카드패의 각 원소를 튜플로 변환
        hand = []
        for card in hand_str:
            hand.append(tuple(card.split()))
        hand_list.append(hand)
    return hand_list
def check_pockers(filename):
    파일을 읽어들여, 카드패에서 포커 패턴 탐지
    f = open(filename)
    hand_list = to_list(f.readlines())
    f.close() # 파일 읽기 종료
    
    # 각 패의 포커 탐지
    for hand in hand_list:
        if is_pocker(hand):
            print(hand, end=': ')
            print('포커!')
is_pocker([('H',7), ('D',7), ('S',7), ('D',2), ('C',7)])
filename = 'hand_10000.txt'
gen_hands(filename, n=10000)
check_pockers(filename)
Explanation: 도전과제
5개의 임의의 카드패 100개 정보를 담은 파일을 생성한다. 이 파일의 각 카드패에 포커 (같은 숫자 4개)가 있는지 확인하는 프로그램을 작성한다.
End of explanation
<END_TASK>