220112 실습문제
생각보다 markdown을 그대로 붙여넣는게 ui가 안예쁘다는 걸 알아버렸다....
너무 안예뻐서 이걸 어떻게 해야하나 고민이 크다..ㅠㅠㅠ
하지만 수업시간에 실습하는 내용은 꽤 코드가 길고 많아서 그걸 하나하나 예쁘게 만들기는 어려울 것 같고 대신 실습코드는 예쁘게 정리하기로 했다. 오늘 실습문제 되게 재밌었어!
Q1. num = 716의 모든 약수를 구하는 제어문을 작성해보세요.(예를 들어, 6의 약수는 1, 2, 3, 6입니다.)
- 조건1: for문과 if문을 사용하세요.
- 조건2: 문자열 포맷팅을 응용하여 '1은(는) 716의 약수입니다.'라는 형식으로 출력되도록 하세요
1) 풀이1
for i in range(1, 717):
if 716 % i == 0:
print("%d은(는) 716의 약수입니다" % i)
1은(는) 716의 약수입니다
2은(는) 716의 약수입니다
4은(는) 716의 약수입니다
179은(는) 716의 약수입니다
358은(는) 716의 약수입니다
716은(는) 716의 약수입니다
2) 풀이2
num = 716
for i in range(1, num + 1):
if not (num % i):
print("%d은(는) %d의 약수입니다." % (i, num))
1은(는) 716의 약수입니다.
2은(는) 716의 약수입니다.
4은(는) 716의 약수입니다.
179은(는) 716의 약수입니다.
358은(는) 716의 약수입니다.
716은(는) 716의 약수입니다.
출력값은 같지만 풀이2의 경우
(1) 716을 num이라는 변수에 입력하였다
(2) if not을 사용하였다
는 차이점이 있다. 숫자 자료형의 경우 false가 나오는 경우는 비어있거나, 0인 경우이다.
따라서 num % i == 0인 경우(약수인 경우) false이기 때문에 앞에 not을 붙여주면 true가 되고 해당 조건이 성립된다.
Q2. 1~200 사이의 정수 가운데 7의 배수이면서 5의 배수는 아닌 모든 숫자들을 찾아 콤마(,)로 구분된 문자열을 구성하여 출력해보세요
1) 풀이1
for i in range(1, 201):
if i % 7 == 0 and i % 5 != 0:
print(i, end = ',') #end 로 문자열의 구분자를 설정해줄 수 있음
#마지막에 콤마가 나온다는 한계가 있음
7,14,21,28,42,49,56,63,77,84,91,98,112,119,126,133,147,154,161,168,182,189,196,
약수의 특성(나누면 나머지0)을 이용한 풀이이다. print(end=',')를 사용하는 경우에 문자열 마지막에 ,가 나온다는 한계가 존재한다.
2) 풀이2
result=""
for i in range(1, 201):
#if i % 7 == 0 and i % 5 != 0:
if not (i % 7) and (i % 5):
#7의 배수 #5의 배수가 아닐 때
"""숫자 자료형의 false는 0일 때 혹은 비어있을 때
따라서 i가 7의 배수일 때 (i % 7)은 false이므로
not (i % 7)은 true가 됨.
5의 배수가 아닌 경우(i % 5)는 true임(나머지가 0이 아니므로)
따라서 둘 다 true"""
result += str(i) + ','
print(result[:-1]) #슬라이싱을 통해 마지막 콤마가 나오지 않게 해줌
7,14,21,28,42,49,56,63,77,84,91,98,112,119,126,133,147,154,161,168,182,189,196
풀이2의 경우 i가 7의 배수이며 5의 배수가 아닐 경우에는 (i%7)은 False(결괏값이 0이기 때문에), (i%5)는 True가 된다.
따라서 not을 붙여 True를 만들어준다. 14생각해보면 간단할듯. 약수에 대한 접근이 새로운데 조금 더 간결한 표현방식이기 때문에 익숙해지는 것이 좋겠다
Q3. 100~300 사이의 정수에서 각각의 자리 숫자가 짝수인 정수를 찾아 콤마(,)로 구분하여 출력해보세요.
1) 풀이1
#내 풀이
for i in range(100, 301):
if int(str(i)[0]) % 2 == 0 and int(str(i)[1]) % 2 == 0 and int(str(i)[2]) % 2 == 0:
print(i, end=',')
200,202,204,206,208,220,222,224,226,228,240,242,244,246,248,260,262,264,266,268,280,282,284,286,288,
수를 문자열로 변환하여(str), 문자열의 인덱스를 반환하고 이걸 다시 정수형으로 바꿔 짝수인지를 알아보는 식이다.
조금 복잡해 보일 수는 있겠지만 세 개 중 하나만 이해하면 나머지는 같은 내용이니까..!
print에서 end=','를 사용해 문자열을 ,를 구분자로 해 연결하였다.
2) 풀이2
# 논리 이해하는게 중요함
result = []
for i in range(100, 301):
a = i
t = False
#일의 자리 숫자 확인
for k in range(3): #전부 세자리
#1의 자리 수가 홀수인지 확인(홀수라면 t=True)
#10의 자리 수가 홀수인지 확인(홀수라면 t=True)
#100의 자리 수가 홀수인지 확인(홀수라면 t=True)
if (i % 10) % 2 != 0: #1의 자리 숫자가 홀수일 때
t = True
break
#1의 자리 수가 홀수가 아니라면 10으로 나누어 10의 자리 수가 홀/짝인지 확인
#10의 자리 수가 홀수가 아니라면 다시 10으로 나누어 100의 자리 수가 홀/짝인지 확인
i = i // 10
if t == False: #or not t 다 짝수인 애들만
result.append(str(a))
print(",".join(result))
200,202,204,206,208,220,222,224,226,228,240,242,244,246,248,260,262,264,266,268,280,282,284,286,288
나의 경우 이해하는데 시간이 꽤 걸렸다. 당장 이런 풀이를 해낼 수 없더라도 코드를 보고 이해하는 힘이 필요하다.
------------------------------------------------------설명-------------------------------------------------------------
(1) 6번째 줄 for k in range(3): 에서 루프를 돌며 일의 자리, 십의 자리, 백의 자리 하나씩 비교한다고 생각하면 된다.
(2) if (i % 10) % 2 != 0은 i의 일의 자리 수가 홀수라는 것을 의미한다. 위 경우 t를 True로 변환하며 더이상 루프를 진행하지 않는다.(break)
(3) 일의 자리 수가 짝수라서 루프가 계속 진행된다면, 십의 자리 수를 비교하기 위해 i를 10으로 나눈 몫을 가지고 한 번 더 루프를 진행한다.
(4) 십의 자리 수가 홀수라면 루프를 멈추고, 짝수라면 백의 자리 수를 비교하기 위해 또다시 해당 수를 10으로 나눈 몫을 가지고 루프를 진행한다.
(5) 루프를 모두 진행하였는데도 t가 True로 변환되지 않았다면(False라면), 해당 수의 자리는 모두 짝수임으로 리스트에 넣는다.
(6) 출력을 위해 구분자를 ,로 하여 join으로 붙여준다.
3) 풀이3
for i in range(100, 301):
if (i // 100) % 2 == 0 and (i-(i//100)*100)//10%2 == 0 and (i % 10) % 2==0:
print(i, end=',')
#백의 자리 숫자 확인: (i//100)%2==0
#십의 자리 숫자확인: (i-(백의자리숫자*100))//10%2==0 10으로 나눠서 십의자리수만 남기고 이게 나머지0인가
#일의 자리 숫자확인: 10으로 나눈 몫이 0인가
200,202,204,206,208,220,222,224,226,228,240,242,244,246,248,260,262,264,266,268,280,282,284,286,288,
다른 분이 푸신 내용인데 이 분은 숫자와 연산에 익숙하신 것 같다.
(1) 백의 자리 수 확인: (i//100)%2==0
(2) 십의 자리 숫자확인: (i-(백의자리숫자*100))//10%2==0 10으로 나눠서 십의 자리수만 남기고 이게 나머지0인가
(3) 일의 자리 숫자확인: 10으로 나눈 몫이 0인가
이 풀이가 언뜻 복잡해보일 수는 있는데 사실 십의 자리 수만 제외하면 백의자리 수와 일의 자리 수를 확인하는 매커니즘은 간단하다. 그래서 이 방법으로 풀어보려고 선택하신 것 같다. 십의 자리 수가 맞추려면 계산이 조금 복잡하기는 하지만 그래도 나머지가 간단하니까.
4) 풀이4(문자열 + if not활용)
#if not 이용하기
for i in range(100, 301):
if not (int(str(i)[0])%2) and not (int(str(i)[1])%2) and not (int(str(i)[2])%2):
print(i, end=',')
200,202,204,206,208,220,222,224,226,228,240,242,244,246,248,260,262,264,266,268,280,282,284,286,288,
여기서도 세 개 중 하나만 이해하면 나머지는 저절로 따라온다
i를 문자열로 바꿔 그 중 n(0, 1, 2)번째 수를 골라 이걸 숫자형(int)로 바꾸는 건 풀이1과 같다.
해당 숫자가 짝수라면 % 2 에서 0이 나오므로 해당 구문은 False이다. 따라서 not을 붙여 True로 만들어준다.
십의 자리, 일의 자리 수들도 and로 연결해서 비교해주면 된다.
Q4. while문을 이용하여 아래와 같이 별(*)을 표시하도록 출력해보세요.
1) 풀이1
star = '*'
i = 5
while i > 0:
print(star * i)
i -= 1
*****
****
***
**
*
하다보니 *가 따옴표로 싸여지기는 하지만 곱하기 연산(*)과 같아서 조금 혼란스러워서 아예 변수에 넣었다.
무리 없는 풀이일 듯하다.
2) 풀이2
i = 5
while i: #0부터는 출력값이 나오지 않으니까 이렇게 해도 되는 듯
print("*" * i)
i -= 1
*****
****
***
**
*
while i: 로 한 부분이 조금 걸렸는데 0부터는 출력값이 나오지 않으니까 이렇게 해도 되는 것 같다.
Q5. while문을 이용하여 아래와 같이 별(*)을 표시하도록 출력해보세요.
앞 문제들은 모두 풀이1이 내가 한 풀이인데 이건 못풀었다.. 가운데 정렬을 어떻게 하지???!? 하고 고민하다가 끝남..
선생님과 다른 분들의 멋진 풀이를 보도록 하자.
1) 풀이1
### 선생님 풀이 ###
#format함수 이용하기
i, k = 7, 0 #튜플로 인식되어 각각 할당해줄 수 있다
while i > 0:
print("{0}{1}".format((" " * k), ("*" * i)))
i -= 2
k += 1
*******
*****
***
*
왼쪽 공백을 고려한 풀이이다.
format함수를 이용해 왼쪽 공백은 하나씩 증가하되, *의 개수는 2개씩 감소시켜 역피라미드형태를 만들었다.
2) 풀이2
num = 8
while num > 0:
num -= 1
if num % 2 == 0:
continue #num이 홀수인 경우에만 밑으로 내려감
print(" " * ((7-num)//2) + "*" * num + " " * ((7-num)//2))
#공백: " " * (7-홀수인 숫자)//2(양쪽에 있어야하니 2로 분할)
*******
*****
***
*
왼쪽과 오른쪽 공백 모두를 고려한 풀이이다.
continue는 다음 코드로 넘어가는게 아니라 다시 루프로 올라간다.
공백(" ")은 왼쪽과 오른쪽 모두를 고려해야하기 때문에 2로 나눈 몫을 값으로 한다.
3) 풀이3
# 가운데 기준으로 4개씩 되도록
num = 4
row_num = num
while num > 0:
print(" " * (row_num - num), '*' * (num-1), '*'*num, sep='')
num -= 1
*******
*****
***
*
가운데를 기준으로 공백은 row_num - num,
왼쪽은 "*" * (num-1), 오른쪽은 "*" * num 으로 해서 홀수를 맞추었다.
print함수의 경우 ,로 구분하면 공백이 생기는데 이를 막기 위해 sep=''로 해주었다.
코드의 장점은 숫자를 확장하더라도 똑같은 형태의 피라미드를 만들 수 있다는 것!
***다른 수 넣어보기***
# 장점: 숫자를 확장하더라도 똑같은 형태의 피라미드를 만들 수 있다.
num = 7
row_num = num
while num > 0:
print(" " * (row_num - num), '*' * (num-1), '*'*num, sep='')
num -= 1
*************
***********
*********
*******
*****
***
*