KT AIVLE School/[TIL] AIVLE School 당일 복습

[TIL] [KT AIVLE School] KT 에이블스쿨 6기(DX 트랙) 2주차 1일(2). while 문과 제어문 심화

guoyee94 2024. 9. 10. 21:16
목차
1. while 문
2. 제어문 심화

 

시간이 모자랐던 어제, 밀린 TIL을 마무리해본다. 이미 TIL에서 Today는 물건너갔다.

 


while 문

 

정해진 조건에 해당하지 않게 될 때까지 반복적으로 수행한다.

 

반복시킨다는 점에서는 for문과 비슷하지만 일반적으로 사용법이 다르다고 한다.

 

각자가 동작하는 원리를 보면

 

  • for 문 : iterabel한 자료형의 요소들을 하나씩 훑으며 시행한다.
  • while 문 : 특정 조건을 충족하는 한 무한히 수행한다.

 

이런 차이가 있는데, 따라서 for문list, dict등을 채우거나,

해당 자료의 요소마다 연산을 시행할 때 쓴다.

 

하지만 while문은 심플하게 동작을 반복한다.

 

강사님 설명으로는 while문이 잘 안 쓰인다던데,

for문으로 대체가능해서 그런 걸까...?

 

여튼 while문은 일반적으로 두 방법으로 쓴다.

 

 

  • 조건 변수가 변할 때, while 문의 조건을 변수 범위처럼 사용
# 리스트 만들기
fruits = ['apple', 'banana', 'cherry']

# 요소 출력
i = 0                     # i를 0으로 초기화함
while i < len(fruits) :
    print(fruits[i])
    i += 1

apple
banana
cherry

 

0으로 초기화한 반복자 i를 매 iteration마다 1씩 증가시켜

 

리스트 fruits의 각 인덱스를 돌게 만든다.

 

확실히 for문으로 대체 가능해 보인다.

 

# 리스트 만들기
fruits = ['apple', 'banana', 'cherry']

# 요소 출력
for i in fruits:
	print(i)
    
apple
banana
cherry

 

이게 더 간단한 것 같기도 하고.

 

1부터 100까지 3의 배수를 더한다 치면

# while을 사용한 방법
tot = 0
n = 0

while n < 101:
    if n % 3 == 0:
        tot += n
        n = n + 1
    else :
        n = n + 1

print(tot)

#for을 사용한 방법
tot = 0
n = 0

for i in range(101):
    if n % 3 == 0:
        tot += n
        n = n + 1
    else :
        n = n + 1

print(tot)

 

이것도 큰 차이는 없는 것 같다.

 

생각해보면 어차피 지정된 범위 안에서 돌리는 거나 마찬가지라서, 별로 유용하지는 않아 보인다.

 

 

 

  • 무한루프에 빠뜨리고 break 조건 달기

그래서일까, 지금은 while문을 쓰는게 더 좋은 상황을 이것밖에 모르겠다.

# 변수 선언
tot, i = 0, 0

# 100까지 짝수 합 구하기
while True:                  ## 무한루프 설정
    i = i + 1                ## i를 1식 누적시키며 진행
    if i > 100:              ## 100부터 종료
        break

    if i % 2 == 0:           ## 짝수합 구하기
        tot = tot + i
    
# 확인
print(tot)
2550

 

뭐... 이것도 for문으로 범위 지정하면 되는 문제지만, 범위에 대한 정보가 없거나 할 때 유용하지 않을까?

 

무엇보다 문돌이 눈에는 직관적이어서 마음에 든다(...)

 

마지막으로 while문 심화 문제로 배운 건데,

 

  1. 5,000원의 돈을 갖고 있습니다. 동료들과 AIVLE 로봇카페에서 아메리카노를 구매하려고 합니다. (아메리카노는 한잔에 1,300원)
  • 갖고 있는 돈을 변수 money, 커피 한 잔의 가격을 변수 coffee에 저장합니다.
  • '아메리카노를 구입하시겠습니까?'에 대한 대답을 입력받아, 대답이 '네'일 경우 커피가 판매됩니다.
  • 다른 대답을 할 경우 '다시 입력해 주세요.'라고 출력합니다.
  • 한 잔을 구매할 때마다 남은 돈을 변수 money에 저장하여 출력합니다.
  • 커피를 살 돈이 모자랄 경우 '돈이 모자랍니다. 커피를 구입할 수 없습니다.'라고 출력하고 종료합니다.
  • 힌트: while 문 내에서 if 조건문을 중첩해서 사용해야 합니다.
# 내 코드
money = 5000
coffee = 1300

while True:
    s = input('아메리카노를 구입하시겠습니까?')
    if (s == '네') & (money >= coffee):
        money -= coffee
        print(f'남은 소지금: {money}원')
    elif (s == '네') & (money < coffee):
        print('돈이 모자랍니다. 커피를 구입할 수 없습니다.')
        break
    else:
        while True:
            s1 = input('다시 입력해 주세요.')
            if s1 == '네':
                break

 

원래 코드에서 많이 수정했다.

 

맨 처음에는 '아니오'를 입력했을 때 '다시 입력해 주세요'에서 한번 더 '아니오'를 하면 처음으로 돌아오는 문제를 겪었다.

 

그래서 시행착오 끝에 '다시 입력해 주세요'를 무한루프에 한번 더 빠뜨렸는데.....

 

# 정답 코드
money = 5000
coffee = 1300

while True:
    print('커피를 구입하시겠습니까?')
    a = input()
    if a == '네':
        if money < coffee:         
            print('돈이 모자랍니다. 커피를 구입할 수 없습니다.')
            break
        money -= coffee             
        print(money)                
    else:
        print('다시 입력해 주세요.')

 

if문을 중첩하지 않고 조건을 한 줄에 다 달아 버린 것이 문제였던 것 같다.

 

 

 

 

 

 

제어문 심화

 

크게 두 가지를 배웠다.

 

  • for문으로 반복자를 리스트나 딕셔너리에 태우기
  • 확장 문법

전자는 AICE 준비하면서 몇번 본 적 있고,

후자는 난생 처음 본다.

 

 

  • 리스트나 딕셔너리에 태우기
# 리스트 만들기
member = ['홍길동', '한사랑', '일지매', '박여인', '강우동']
index_num = 0

# 루프 돌면서 이름 출력
for name in member:
    index_num += 1
    print(f'{index_num}. {name}', sep='')

 

너무나 많이 쓰이는 방법, 반복자가 리스트의 값들을 하나씩 돈다.

 

enumerate()라는 함수도 같이 배웠는데, 리스트의 index와 value를 튜플로 반환한다.

 

리스트를 묶어서 item화 된다는 점에서는 좋은데, 인덱스가 딸려 나오는 건 좀 불편할 것 같다.

 

한편 이 방법은 너무나 중요하게 쓰이는데, 예를 들어

 

sample_list = ['1', '2', '3', '4', '5']
new_list = []
for i in sample_list:
    i = int(i)
    new_list.append(i)

print(type(new_list[0]))

 

이렇게 리스트의 타입을 바꿀 수 있다.

 

여기서 중요한 것, 확장 문법이 등장한다.

 

 

 

 

  • 확장 문법

나는 이 방법이 아주 마음에 들었다. 

 

바로 위에 나오는 리스트 타입 바꾸기는 빈 리스트도 선언해야 하고,

또 조건이라도 붙는 순간 몇 줄이 되어 버린다.

 

하지만 위의 코드를 확장 문법으로 쓰면

sample_list = ['1', '2', '3', '4', '5']
new_list = [int(i) for i in sample_list]
print(type(new_list[0]))

 

이렇게 줄어든다.

 

지금 진행중인 코딩마스터스 문제에 적절한 예시가 있는데,

사족이나, 나중에 코딩마스터스 문제도 쭉 풀이하는 카테고리를 팠으면 좋겠다.

 

문제
등차수열에서 첫 항인 a, 두 항의 차인 b, 몇번째 항인지 나타내는 n이 입력되었을 때 n번째 항을 출력하는 프로그램을 짜라.

 

입력받아야 하기 때문에 sys.stdin.readline().strip()을 쓰게 되는데,

input()도 그렇지만 사용자에게 입력받는 녀석은 늘 문자열이다.

 

어떻게든 계산을 위해 저 문자열을 정수인 리스트로 만들어야 하는데,

이때도 코드 한 줄로 가능하다.

 

input_list = [int(x) for x in input_str.split()]

 

강사님 스타일로 해석하자면

 

나 리스튼데([])

정수 x를 쓸거야(int(x))

근데 얘는 input_str.split()에서 하나씩 빼온 거야(for x in input_str.split())

 

이런 방식이지.

 

그리하여 완성된 정답

import sys
input_str = sys.stdin.readline()       			# 문제 조건 : 세 수가 공백으로 구분되어 주어진다.

# 리스트로 변환 후 변수 할당
input_list = [int(x) for x in input_str.split()]
A, B, N = input_list

# 함수 선언
def ap(A, B ,N):
    print(A + (B * (N-1)))

# 출력
ap(A, B, N)