-Summary-
FizzBuzz 문제 풀이, turtle 모듈, list tuple 메서드
01-25 (Unit 20.1~ Unit 21.6)
-FizzBuzz 문제-
(이번 파트는 FizzBuzz 문제 풀이 파트이므로, 풀이 학습에 앞서 혼자서 문제를 풀어보고 학습한 후 내가 작성한 코드를 보완하는 식으로 정리하겠다.)
FizzBuzz 문제란 간단한 프로그래밍 문제다.
- 1에서 100까지 출력
- 3의 배수는 Fizz 출력
- 5의 배수는 Buzz 출력
- 3과 5의 공배수는 FizzBuzz 출력
규칙은 다음과 같다. 3의 배수, 5의배수, 3,5 공배수에 따라 출력하는 문자열을 다르게하는 간단한 문제다.
for i in range(1,101):
if i % 3 == 0 and i % 5 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
위 코드가 문제만 보고 혼자 작성해본 코드다.
먼저 1~100까지 출력해야하므로 range는 1로 시작 끝값은 101로 설정해두고, 맨 먼저 3과 5의 공배수인지 확인한다. 왜냐하면 3,5 공배수는 각각 3의 배수, 5의 배수에 해당하므로 공배수 조건문을 뒤에다 둔다면 Fizz 혹은 Buzz가 출력될 수 있다. 그다음에는 3의 배수인지 5의 배수인지 확인하는 elif문을 만들고 해당 문자열을 출력하면 된다.
마지막에는 else : print(i)를 써둬서 3,5 공배수, 3의 배수, 5의 배수가 아닐경우 숫자를 출력하도록 한다.
for i in range(1, 101): # 1부터 100까지 100번 반복
if i % 15 == 0: # 15의 배수(3과 5의 공배수)일 때
print('FizzBuzz') # FizzBuzz 출력
elif i % 3 == 0: # 3의 배수일 때
print('Fizz') # Fizz 출력
elif i % 5 == 0: # 5의 배수일 때
print('Buzz') # Buzz 출력
else:
print(i) # 아무것도 해당되지 않을 때 숫자 출력
위 코드가 FizzBuzz문제의 정답코드다. 내가 작성한 코드도 맞긴하지만, 이 코드는 3과 5의 공배수는 곧 15의 배수란 점을 이용해 if i % 15 == 0이란 조건을 써줘서 가독성이 좋아졌다.
for i in range(1, 101):
print('Fizz' * (i % 3 == 0) + 'Buzz' * (i % 5 == 0) or i)
# 문자열 곱셈과 덧셈을 이용하여 print 안에서 처리
위 코드는 FizzBuzz 해결 코드를 더더 줄인 것이다. Fizz * (i%3==0) 이부분을 보면 i % 3 == 0 이라는 조건문을 써줌으로써 만약 3으로 나눠진다면 True의 값이 1이 나오게 되어 Fizz * 1이 된다. Fizz가 출력되는 것이다. 뒤에도 마찬가지로 조건식을 통해서 더욱 간결하고 가독성 있게 FizzBuzz 문제를 해결했다.
또한 'Buzz' * (i % 5 == 0) or i 부분은 어째서 i가 출력되는지 의문이 들 수 있는데, 이는 앞서 배운 단락평가의 원리를 이용한 것 같다. 만약 i가 5의 배수가 아닐시 'Buzz'에는 0이 곱해져서 ''이 되는데, 아무것도 없는 문자열은 False를 의미하게 된다. 적힌 논리식이 or고 앞은 이미 False가 됐으므로 단락평가에 의해 뒤의 값을 그대로 출력하게 된다.
처음 봤을때는 "엄청 쉬운데?"라는 생각을했지만 가독성을 높히는 간결한 코드들을 보면서 많이 배운 것 같다.
i가 6의 배수인지 확인하는 방법은 i를 6으로 나눴을 때 나머지가 0인지를 확인하면 된다. 따라서 i % 6 == 0이 적힌 d가 정답이다.
공배수를 확인하는 방법은 and 조건을 걸어서 두수로 각각 나눴을 때 나머지가 0인지 확인하는 방법과, 두 수를 곱한 값으로 i를 나눠서 나머지가 0인지 확인하는 방법을 쓰거나 두수가 서로 배수 관계일 경우 배수인 수로 나눴을 때 0이 되는지 확인하는 방법이 있다. 따라서 i % 5 == 0 and i % 10 == 0인 d가 맞다. 또한 e도 맞다.
3, 5의 배수, 공배수일때 각각 Fizz, Buzz, FizzBuzz를 출력하는 FizzBuzz문제를 변형시킨 것이다. 위의 FizzBuzz 문제 풀이 방식과 비슷하게 각 조건문의 빈칸을 채우면 된다.
for i in range(1, 101):
if i % 2 == 0 and i % 11 == 0:
print('FizzBuzz')
elif i % 2 == 0:
print('Fizz')
elif i % 11 == 0:
print('Buzz')
else:
print(i)
입력한 두 값을 범위로 숫자를 하나하나 출력하는데 5의 배수일 경우 Fizz, 7의 배수인 경우 Buzz, 5,7 공배수일 경우 FizzBuzz를 출력하는 것이 문제다.
mn, mx = map(int,input().split())
for i in range(mn,mx+1):
print("Fizz" * (i % 5 == 0) + "Buzz" * (i % 7 == 0) or i)
위에서 배운 가독성을 신경쓰며, 최대한 간결하게 코드를 작성했다. 조건식의 결과 값을 "Fizz", "Buzz"에 각각 곱해서 올바른 결과 값을 출력해준다.
-Turtle graphics-
터틀 그래픽스는 그림을 그리는데 사용하는 모듈이다. 거북이가 기어가는 모양대로 그림을 그린다고 해서 터틀이라 한다고 한다.
-shape('turtle')
shape('turtle')를 작성하면 gui 창이 뜨고 거북이가 나타나게 해준다.
화면에 나타난 이 거북이가 그림을 그릴 때 사용하게 된다.
-forward
forward 명령어는 거북이를 원하는 값만큼 앞으로 가도록 하는 명령어다. 줄여서 fd로 쓸 수 있다.
forward(100)을 입력하니 거북이가 100만큼 현재 보고 있는 방향으로 전진했고, 전진한 경로에는 선이 그어졌다. 이런식으로 거북이를 움직여 선으로 그림을 그리는 것 같다.
-right
right 명령어는 거북이를 오른쪽 방향으로 원하는 각도만큼 회전시키는 명령어다. 줄여서 rt로 쓸 수 있다.
right 명령어를 실행시키니 위 사진처럼 거북이의 방향이 90도 만큼 오른쪽으로 꺽였다.
위에서 다룬 명령어 말고도 여러가지가 있다.
뒤로 이동: backward, bk, back
왼쪽으로 회전: left, lt
앞에서 배운 반복문을 응용해서 다양한 모양의 도형을 그릴 수 있다.
import turtle as t
t.shape('turtle')
for i in range(4):
t.forward(100)
t.right(90)
위 코드는 앞으로 100 전진, 오른쪽으로 90도 회전하는 코드를 4번 반복시켜 사각형을 만들어주는 코드다.
import turtle as t
t.shape('turtle')
for i in range(5):
t.forward(100)
t.right(360/5)
위는 오각형을 만들어주는 코드다. 6행을 보면 right(360/5)를 써줬는데, 360 / (도형의 각 수)를 해주면 그 도형의 외각의 크기가 나온다는 점을 이용한 것이다.
import turtle as t
count = int(input())
t.shape('turtle')
for i in range(count):
t.forward(100)
t.right(360/count)
위 코드는 360 / (도형의 각 수)를 해주면 그 도형의 외각의 크기가 나온다는 점을 이용해 사용자로 부터 입력을 받아서 원하는 각의 도형을 그려준다.
-color
color 함수는 원하는 색으로 색을 준비시켜주는 함수다. 이 함수 자체로 색칠이 되지 않고 begin_fill()등과 응용하면 색을 칠할 수 있다.
-begin_fill(), end_fill()
begin_fill은 color 함수로 정한 색으로 색칠을 시작해주는 함수다. end_fill 함수는 begin_fill로 시작한 색칠을 멈춰주는 역할이다.
import turtle as t
count = int(input())
t.shape('turtle')
t.color('green')
t.begin_fill()
for i in range(count):
t.forward(100)
t.right(360/count)
t.end_fill()
위 코드는 color, begin_fill, end_fill 함수를 이용해서 사용자가 정한 만큼의 각 수의 도형을 출력하는 프로그램에 색을 입혀줬다. 먼저 5행에서 색을 선택해주고, 6행에서 색칠 시작, for문 루프를 돌아서 원하는 각 수의 도형을 만들어주고 10행에서 색칠을 중단해 준다.
-circle
circle 함수는 정한 값을 반지름으로 가지는 원을 그려주는 함수다.
import turtle as t
t.shape('turtle')
t.circle(100)
100으로 반지름을 설정해서 사용하니 100만큼을 반지름으로 가지는 원이 출력됐다.
import turtle as t
n = 500
t.shape('turtle')
t.speed('fastest')
for i in range(1,n,5):
t.circle(i)
지금까지 배웠던 것을 응용해서 만들어본 코드다.
speed는 다루지 않았지만 그리는 속도를 조정해주는 함수다.
range 함수로 초기값, 끝 값을 지정하고 반복문을 돌려 만들어낸 것이다.
import turtle as t
t.shape('turtle')
t.speed('fastest')
for i in range(300):
t.forward(i)
t.right(91)
위 코드는 코딩도장에 있던 예제를 실습한 코드다. 기본적으로 사각형을 그리는데 반복할 때 마다 선의 길이를 달라지게 해서 결과화면이 만들어졌다.
d : lt는 left명령어의 약자로 왼쪽으로 회전한다. X
원을 그리는 함수는 circle()로 괄호 안에 원하는 반지름을 넣어주면 된다. 또한 색을 칠하는 방법은 color, begin_fill,end_fill 함수를 이용하면 된다. 따라서 d가 맞다.
위 사진처럼 오각별이 그려지게 하는 것이 목적이다. 문제에 주어진 조건에 맞게 터틀 그래픽스 함수를 이용해 코드를 짜면 된다.
import turtle as t
t.shape('turtle')
for i in range(5):
t.forward(100)
t.right(144)
t.forward(100)
t.left(72)
앞으로 100만큼 전진하고 144도로 오른쪽으로 꺾은 후 100만큼 전진, 그리고 왼쪽으로 72도로 회전을 5번 반복해서 오각별을 그리는 코드다. 연습문제 form에는 조금 어긋났지만 변수부분만 고치면 완성할 수 있다.
꼭지점 개수, 선의 길이를 입력받고 그에 따른 별을 그려지게 하는 것이 목적이다.
import turtle as t
n, line = map(int, input().split())
t.shape('turtle')
for i in range(n):
t.forward(line)
t.right((360/n)*2)
t.forward(line)
t.left(360/n)
연습문제에서 배웠던 것을 응용해서 작성한 코드다. 꼭짓점 만큼 반복시키고 (360/n)*2, 360/n으로 꼭짓점 하나하나를 그려주면 된다.
01-27 (Unit 22.1~ Unit 22.10)
-리스트-
-append
append는 리스트에 요소를 하나 추가해주는 명령이다. 사용은 <변수명>.append(<요소>) 이렇게 사용하면 된다.
append(5)를 사용하니 위 사진처럼 list a에 5가 들어간다. 또한 리스트안에 리스트를 넣을 수 있는데 위 사진처럼 append(<리스트>)를 써주면 리스트 안에 리스트가 들어간다.
-extend
extend는 리스트와 리스트를 연결해주는 역할을한다. 사용은 <변수명>.extend(<리스트>)를 써주면 원래 리스트 끝에 extend에 넣어준 리스트가 붙여진다.
위 사진처럼 list a에 extend를 써주니 a에 5,6,7,8이 연결된 것을 알 수 있다.
-insert
insert는 append, extend와 달리 원하는 위치에 값을 추가해주는 함수다. insert(<인덱스>,<요소>)로 써주면 된다.
위 사진처럼 원하는 인덱스를 지정하고 들어갈 값을 넣어주면 그 위치에 값이 들어가는 것을 볼 수 있다.
-pop
pop 명령어는 리스트의 마지막 요소를 삭제하고 그 값을 반환해주는 함수다. 어셈블리어의 pop 명령어와 같은 기능이라 보면 된다.
위 사진처럼 pop 명령어를 사용한다면 리스트의 마지막 값이 출력되고 삭제된 것을 볼 수 있다.
-remove
pop,del 같은 함수는 인덱스로 요소를 삭제한다. remove는 앞의 함수들과 다르게 인덱스를 지정해줄 필요없이, 지울 값을 지정해주면 알아서 찾아서 삭제해준다.
위 처럼 remove(<값>)을 입력하면 해당 값을 리스트에서 찾아 삭제해준다.
-리스트의 할당과 복사-
위 코드는 a에 1,2,3,4 값을 넣고 b에다가 a를 넣어준 모습이다. 그 결과 is를 써봤을 때 두 객체는 같다는 결과가 나왔다.
두 객체가 같기에 두 객체중 한 요소의 값을 바꾸니 나머지 객체도 자동으로 값이 바뀌었다.
위처럼 list를 할당해준다면, 두 객체가 같게 되어 한 객체의 값이 바뀌면 다른 객체에 영향을 주게 되는데, 이를 방지하려면 copy 함수를 사용하면 된다. copy 함수는 이름처럼 복사를 해주는 함수다.
위처럼 copy를 이용해서 데이터 복사를 하니 두 객체가 다름을 알 수 있다. 따라서 한 객체의 요소를 변경해도 다른 객체에 영향을 주지 않는다!
-for문으로 인덱스, 요소 출력-
앞에서 for와 in으로 리스트의 요소들을 출력하는 법을 배웠었다. 이번에는 enumerate를 사용해서 인덱스, 요소를 한번에 꺼내올 것이다.
위 사진처럼 in 뒤에 enumerate(a)를 써준다면 요소 뿐만 아니라 index까지 갖고오게 된다. 주의할점은 2가지 값을 in으로 전달하기 때문에 이 값들을 담을려면 2개의 변수가 필요하다. 사진에는 index, val을 사용했다.
for가 리스트를 출력하기 간편하긴 하지만 while로도 역시 리스트를 출력할 수 있다.
변수 i를 인덱스 용도로 쓰고 while의 조건식을 a의 길이에 벗어났는지를 측정하는데 쓰면 리스트의 요소들을 오류없이 출력해낼 수 있다.
-가장 작은 수와 가장 큰 수 구하기-
앞서 배운 반복문을 이용한다면 가장 작은 수, 가장 큰 수를 구할 수 있다.
a = [5,7,2,4,1]
small = a[0]
for i in a:
if i < small:
small = i
print(small)
1행에서 리스트 변수를 선언해주고, 2행에서 리스트의 맨 처음 값을 small 변수에 넣어준다. 맨 처음 값을 small 변수에 넣어주는 이유는 비교 방식을 for문을 돌려서 small 변수보다 작다면 그 값을 다시 small 변수에 넣어주고 다음 값이랑 비교하는 식으로 해서 작은 값을 가려낼 것이기 때문이다. 4행에서 i < small로 현재까지 작은 값과 i를 비교해서 i가 작다면 그 값을 small에 넣어서 다음 값과 비교한다.
그렇게 해서 모든 값과 비교해서 나온 small의 값이 바로 가장 작은 값이다.
이걸 응용해서 가장 큰 수도 구할 수 있다. 위처럼 변수 하나를 만들어주고 그 변수에 맨 첫 값을 넣은 후, 리스트에 존재하는 다른 값들과 비교해서 큰수를 가려내면 된다.
위처럼 여러코드를 작성해서 큰 수와 작은 수를 가려낼 수 있지만 더 간단한 방법이 있다.
-min, max
min과 max 함수는 리스트에서 가장 큰 값, 가장 작은 값을 구해주는 함수다. 이 함수를 사용한다면 위 처럼 긴 알고리즘을 짤 필요없이 1줄로도 구할 수 있다.
위 사진처럼 min(<변수>) 혹은 max(<변수>)를 써준다면 그 리스트에서의 큰값 작은값을 구해준다.
-sort
sort 함수는 리스트 요소들을 정렬해주는 함수다.
위 사진은 1,2,3,4,5 값들을 순서를 바꿔서 a 변수에 넣어준 모습이다. 그 상태에서 sort 함수를 쓰니 값들이 내림차순으로 자동 정렬되는 모습을 볼 수 있다. 또한 sort에 reverse=True 옵션을 주면 오름차순으로 정렬을 해준다.
-sum
리스트의 값들을 모두 더하는 방법으로는 첫번째로 알고리즘을 통한 방법이 있다.
a = [5,7,2,4,1]
temp = 0
for i in a:
temp+=i
print(temp)
위 코드로 리스트의 값들을 모두 더해줄 수 있다.
하지만 파이썬이 제공하는 sum 함수를 써준다면 위 코드처럼 복잡한(?) 코드를 써줄 필요없이 1줄 코드로도 값들을 모두 더해줄 수 있다.
위 사진처럼 sum(<변수명>)을 써준다면 더한 값을 반환해주는 것을 볼 수 있다.
-list 표현식-
파이썬의 리스트는 리스트안에 for 반복문, if 조건문을 사용할 수 있다. 리스트 안에 식을 통해서 리스트를 생성하는 것을 리스트 컴프리헨션이라 부른다.
리스트 표현식은 위 사진처럼 쓸 수 있다. 위에서는 []를 통해 썻는데 list()의 괄호안에 표현식을 써줘도 작동한다. 하지만 성능은 [] 형식이 더 좋기 때문에 []를 사용하겠다. 동작은 for i in range(10)으로 range(10)의 값들을 i로 빼내는데 i로 빼낸 값을 for 앞에 있는 i에 넣어서 리스트를 생성하는 것이다.
위 사진처럼 for 앞의 i에 +-*등 사칙연산을 해준다면 리스트의 값들이 사칙연산된 값으로 생성된다.
이번에는 if 조건문을 list 표현식안에 적어 보겠다.
단 if문은 리스트를 만들 때 단독으로는 생성이 불가하므로 for문과 보통 같이 쓰인다.
위 코드는 for로 list를 생성하면서 그 수가 홀수인 값만 뽑아서 리스트에 저장하는 동작을 한다.
먼저 for문으로 range에서 숫자를 하나하나 뽑아 i에 넣으면 i % 2 != 0인지 확인하고 참이면 그 값을 for 앞의 i에 넣어 리스트를 생성해주는 방식이다.
이런식으로 리스트 표현식안에 식을 여러개 중첩해서 넣을 수 있다. 식이 여러개일시 맨 처음부터 차례로 연산한다 한다.
위의 경우 range로 생성되는 값들을 하나씩 뽑아 i에 넣어주고 그 다음 j in range(1,10)으로 생성되는 숫자들을 i에 하나하나 곱해주는 방식으로 구구단을 출력해준다.
-list, tuple, map-
리스트나 튜플의 값들을 map을 사용한다면 모든 요소들을 한번에 다른 자료형으로 바꿔줄 수있다.
튜플은 값의 변환, 수정이 안되기에 의문이 들 수 있지만 map은 원본 리스트를 변경하는게 아니라 새 리스트를 생성해 주기 때문에 튜플에도 사용이 가능하다.
위 사진처럼 map을 사용한다면 리스트, 튜플의 값들의 자료형을 한번에 바꿔줄 수 있다. 만약 map을 사용하지 않고 변환한다면 for문을 이용해서 변환할 수 있는데 몇줄 차이는 안나지만 map이 훨씬 간결하게 변환이 가능하다.
이전에 input.split() 같이 사용자의 입력을 map을 이용해서 한번에 바꿔주는 것을 많이 썻는데, 이 또한 split()함수가 입력 받은 값을 잘라서 list형으로 저장했기에 map함수로 한번에 자료형을 바꿔줄 수 있던 것이다.
-튜플-
-index
배웠듯이 튜플은 값을 변경할 수 없기 때문에 튜플에 사용할 수 있는 함수들은 대부분 튜플의 정보를 구해주는 함수들이다. 그중 index는 특정 값의 index 번호를 구해주는 함수다.
위 사진처럼 index 괄호안에 찾을 값을 넣어주면 그 값의 인덱스번호를 구해주는 것을 볼 수 있다.
-count
count는 특정 값의 개수를 구해주는 함수다.
위 사진처럼 괄호안에 구할 값을 써준다면, 튜플 안에서 그 값의 개수를 구해준다.
튜플의 요소들을 출력하는 방법, 튜플 표현식, 튜플 min, max 함수는 list와 똑같이 사용하면 된다.
append는 리스트에 요소를 추가해주는 함수다.
a : insert에 len으로 길이를 구해서 그 인덱스에 값을 넣어준다면 append와 똑같이 맨 끝에 요소를 추가해준다.
d : a[len(a):]이면 맨 끝이므로 거기에 [40]을 추가해주는 식이므로 append와 똑같다.
리스트의 모든 요소를 삭제하는 메서드는 clear다. 답 : e
a,d,e : for문으로 index에 해당하는 요소를 출력, while로 변수 하나를 index에 사용해서 요소들을 출력하는 방법 이 두가지가 올바르다. 또한 가장 간편한 방법으로 for i in a를 써주면 a의 요소들이 하나씩 i에 들어가므로 이 i를 출력하면 모든 요소를 출력할 수 있다.
튜플은 값의 변환, 삭제가 불가능하다. pop은 값을 삭제하는 명령어이므로 튜플에는 사용할 수 없다.
답 : b
d : 표현식을 이용한 방법인데, 먼저 범위는 20까지 주어지고 3보다 작거나 같거나, 17보다 크거나 같은 값을 i에 넣는다면 주어진 리스트를 만들 수 있다.
리스트는 map 함수를 이용한다면 한번에 자료형을 변환할 수 있다.
c : 다른 보기들과 달리 map으로 변환한 값을 a에 바로 넣어주지 않고 list로 형 변환을 시켜서 변환했다.
실행 결과처럼 문자열의 길이가 5인 값들만 리스트형태로 출력되게 하는 것이다. 주어진 줄이 1줄이므로 리스트 표현식을 사용하면 될 것 같다.
a = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india']
b = [i for i in range(a) if len(i) == 5]
print(b)
len(i)를 이용하면 문자열의 길이를 구할 수 있다. 이를 이용해서 len(i) == 5만 i에 넣어준다면 위 실행결과처럼 출력할 수 있다.
입력 받은 첫번째 값부터 두번째 값까지를 지수로하는 2의 거듭제곱 리스트를 출력하는 것이 목적이다.
start, last = map(int,input().split())
answer=[2 ** i for i in range(start, last + 1)]
del answer[1]
del answer[-2]
print(answer)
1행에서 시작값, 끝 값을 int형으로 받아오고 2행에서 list 표현식을 이용해서 거듭제곱한 값을 answer에 넣는다. 참고로 **은 제곱하는 연산기호다. 그리고 두번째 요소와 뒤에서 두번째 요소는 삭제한 뒤 출력하라는 조건이 있으므로 del 함수로 두번째 요소의 인덱스 값인 1, 뒤에서 두번째 요소의 인덱스 값이 -1를 넣어서 삭제해준 후 출력한다.
'Old (2021.01 ~ 2021.12) > Programming' 카테고리의 다른 글
파이썬 코딩도장 Unit 27 ~ 37 (0) | 2021.01.31 |
---|---|
파이썬 코딩도장 Unit 23 ~ 26 (0) | 2021.01.27 |
파이썬 코딩도장 Unit 12 ~ 19 (0) | 2021.01.24 |
파이썬 코딩도장 Unit 8 ~ 11 (0) | 2021.01.21 |
파이썬 코딩도장 Unit 1 ~ 7 (0) | 2021.01.19 |