Python : Repl.it - 답안 비교 #1

채록·2021년 1월 17일
0

짜투리

목록 보기
11/26
post-thumbnail

들어가는 말

문제를 풀면서 해당 문제가 요구하는 풀이법이 있지만 내가 아는 다른 개념을 사용하여 푼 문제들이 있다. 물론 그 풀이법이 잘못된것은 아니지만 문제에서 요구한 풀이대로도 풀줄알아야 그 문제 주제의 개념을 더 잘 이해할 수 있다 생각한다!
따라서 문제를 다 풀고 난 뒤 모델 솔루션과 내 답을 비교하면서 복습하고자 한다.

#13 : Concatenating Text Strings

이 문제는 풀이와 다른건 아니었다. 다만 더 효율적으로 코드를 작성하는 방법을 알게되어 다시 풀었다.


똑같은 단어를 4번 반복해서 출력해야 하는데 문제는 그 단어들 사이에 space가 있다는 것이다.
단순하게 {new_gee}*4를 하면 GeeGeeGeeGee로 출력이 되기 때문에 space를 넣는 방법을 생각해야 한다.


결론적으로 문자열 연산을 이용하기로 했다!

* 내 코드

new_gee = input("Gee 를 입력해주세요: ")

print(f'''
너무 너무 멋져 눈이 눈이 부셔
숨을 못 쉬겠어 떨리는 Girl
{new_gee} {new_gee} {new_gee} {new_gee}
Baby Baby Baby Baby
{new_gee} {new_gee} {new_gee} {new_gee}
Baby Baby Baby Baby''')

->
너무 너무 멋져 눈이 눈이 부셔
숨을 못 쉬겠어 떨리는 Girl
Gee Gee Gee Gee
Baby Baby Baby Baby
Gee Gee Gee Gee
Baby Baby Baby Baby

* 수정 후 코드

new_gee = input("Gee 를 입력해주세요: ")

print(f'''
너무 너무 멋져 눈이 눈이 부셔
숨을 못 쉬겠어 떨리는 Girl
{(new_gee+" ")*4}
Baby Baby Baby Baby
{(new_gee+" ")*4}
Baby Baby Baby Baby''')

->
출력 결과 위와 같음


#24 : Testing set of conditions

맞은줄 알았는데 여러 테스트를 진행해보니 틀렸다는걸 알 수 있었다...

* 내 코드

month = int(input("월(month) 를 숫자로 입력해주세요: "))
day = int(input("일(day) 를 숫자로 입력해주세요: "))

if (month%2!=0 and day<31) or (month==2 and day<28) or (month%2==0 and month!=2 and day<3):
  day +=1
elif (month%2!=0 and day==31) or (month%2==0 and month!=2 and day==30) or (month==2 and day==28):
  month +=1
  day = 1
else:
  print("Wrong!")

print(month)
print(day)

내가 착각했던 부분은
단순히 홀수달이라고 해서 31일까지 있는게 아니라는 것이다!! 8월을 기점으로 8월부턴 짝수달이 31일까지 있는데!!;;;

때문에 내가 작성한 방식인 (해당 달의 수가 2월이 아닌 짝수라면 30일 / 홀수라면 31일 까지 있다고 생각) 이것이 잘못되었다!

1월부터 7월 / 8월부터 12월까지 day의 흐름이 반대이므로, 가장 간단한 방법은 조건에 해당되는 month를 직접 지정해 주는 것이다. (범위 지정 말고!)

* 수정 후 코드

먼저 조건을 잡아야 한다.

1. month가 하나 증가하고, day가 1로 바뀌는 경우

  • 30일까지 있는 달에서 day가 30 일때
  • 31일까지 있는 달에서 day가 31 일때
  • month가 2 이고 day가 28 일때 (문제의 기준이 되는 2020년의 2월은 28일 까지 있다.)

2. month는 그대로이고, day만 하루 늘어나는 경우 (1조건 이외의 조건일 때 이므로 else로 표현 가능하다.)

  • 30일 까지 있는 달에서 day가 1~29 일때
  • 31일까지 있는 달에서 day가 1~30 일때
  • month가 2 이고 day가 1~27일때

위의 조건식을 작성한 후, 또 다른 조건식을 작성해야 한다. 바로 month가 13으로 되었을 때

3. 1의 조건문 결과로 month가 13이 되었을 때

  • month가 13으로 되었다면 month의 값을 1로 변경해준다.

이러한 조건을 토대로 코드를 작성하였다.

month = int(input("월(month) 를 숫자로 입력해주세요: "))
day = int(input("일(day) 를 숫자로 입력해주세요: "))

if ((month==4, 6, 9, 11)and(day==30))or((month==1, 3, 5, 7, 8, 10, 12)and(day==31))or((month==2)and(day==28)) :
  month += 1
  day = 1
else:
  day += 1

if month == 13:
  month = 1

print(month)
print(day)


#25 : Nested if Statements

내가 작성한 코드가 모델 솔루션 보다 3줄이나 더 길다! 나도 줄여보자

* 내 코드

a = int(input("첫 번째 숫자를 입력해주세요: "))
b = int(input("두 번째 숫자를 입력해주세요: "))

if a!=0:
  if b==0:
    print(0)
  elif b%a==0:
    print(b//a)
  else:
    print('No Solution')
else:
  if b==0:
    print('Many Solutions')
  else:
    print('No Solution')

코드를 설명하자면

1. a가 0이 아닐 때
1) b가 0 이라면 x는 항상 0이다. x=0
2) b가 a로 나눴을 때 나머지가 0 이라면 부합하는 정수 x가 하나 존재한다.
3) b를 a로 나눴을 때 나머지가 0이 아니라면 정수 x는 존재하지 않는다. No Solution


2. a가 0일때
1) b도 0 이라면, 어떠한 정수를 곱해도 식이 성립한다.Many Solutions
2) a가 0인데 b가 0이 아니라면, 이를 만족하는 x는 존재하지 않는다 *No Solution

* 수정 후 코드

조건을 보다 체계적으로 (??) 구성해 보았다.

If) a가 0 일때
If) b도 0 이라면 Many Solutions
else) b가 0이 아니라면 No Solution

elif) b%a == 0일때
해당되는 정수 x를 출력한다.

else (a가 0인데 b가 0이 아닌때)
No solution

여기서 마지막 else의 조건을 파악하는 것이 조금 어려웠다.
위 조건의 흐름대로 코드를 작성하였다.

a = int(input("첫 번째 숫자를 입력해주세요: "))
b = int(input("두 번째 숫자를 입력해주세요: "))

if a == 0:
  if b == 0:
    print('Many Solutions')
  else:
    print('No Solution')
elif b%a == 0:
  print(b//a)
else:
  print('No Solution')


#37 : Adding and Changing Elements to lists


* 내 코드

내가 작성하면서도 "야,,, 이거 꽤 더러운데?" 싶었던 코드였다.

def merge_and_swap(list1, list2):

  if len(list2) != 0 and len(list1) != 0:
    list1 = list1 + list2
    list1.append(list1[0])
    list1[0] = list1[-2]
    list1[-2] = list1[-1]
    list1.pop()

  elif (len(list2) == 0 and len(list1) != 0) or (len(list2) != 0 and len(list1) == 0):
    list1 = list1 + list2
    if len(list1) == 1:
      return list1
    elif len(list1) > 1:
      list1.append(list[0])
      list1[0] = list1[-2]
      list1.pop()
  
  else: #생략 가능
    return list1
  return list1

merge_and_swap([1,2,3], [5])

정리되지 않고 의식의 흐름대로 써내려간 코드들;;;;

* 수정 후 코드

먼저 두개의 list를 합치는 것 부터 시작해야 한다. (리스트가 비었든 안비었든 일단 합치는건 틀린게 아니니까!!)

list1 = list1 + list2
length = len(list1)

그리고 나서 조건을 살펴본다

If) 합쳐진 후 list1의 길이가 1보다 크다면

first = list1[0] # 변수 first에 list의 제일 앞의 수를 저장한다.
last = list1[length-1] # 변수 last에 list의 제일 마지막 수를 저장한다.
# 첫번째와 마지막 element 바꿔주기!
list1[0] = last
list1[length-1] = first

else)
list의 길이가 0이거나 1개라면 어쨌든 list1을 그대로 출력하면 된다.

조건을 토대로 코드를 수정하였다.

def merge_and_swap(list1, list2):
  list1 = list1 + list2
  length = len(list1)
  
  if length > 1:
    first             = list1[0]
    last              = list1[length - 1]
    list1[0]          = last
    list1[length - 1] = first
    return list1
  else:
    return list1


#39 : Deleting Elements from list

나는 for loops개념을 알고 있으니까 그냥 이걸 사용해서 문제를 풀려고 했는데....... 코드는 맞는거 같은데 Fail이 뜬다ㅠㅠㅠ 왜!?!?!?!?!?!?


* 내 코드

def remove_odd_numbers(numbers):

  for number in numbers:
    if number%2 == 1:
      numbers.remove(number)
  return numbers

아니!!! numbers라는 리스트에서 숫자 하나씩 실행하면서 그 숫자를 2로 나눴을때 나머지가 1이라면!! (홀수라는 뜻!!) 그 number를 numbers에서 지우겠다는데!
아, 혹시 remove로 인해서 숫자가 지워질때, list 의 배열이 흐뜨러 져서 제대로 for loops이 진행이 안되기 때문인가!?

그렇다면 바꿔보자, for loops에서 흐름이 뒤->앞으로 되도록

이럴때 필요한 것이 reversed(리스트이름)이다.
reversed()를 통해 for loops에서 반복 진행 상황을 해당 list의 뒤->앞 (기본상태의 거꾸로)으로 진행시킬 수 있다.

* 수정 후 코드

def remove_odd_numbers(numbers):

  for number in reversed(numbers):
    if number%2 == 1:
      numbers.remove(number)
  return numbers

됐다 ^0^

* 문제 의도대로 푼 코드

하.. 이건진짜 하기 싫다... 너무 비효율적이야ㅠㅠㅠ!!!!!!!!!!!!!!!!
그래도 일단 작성은 해봤다...
이것 역시 뒤에서부터 앞으로 진행시켜야만 홀수 수를 제거해도 list의 배열이 망가지지 않는다.

def remove_odd_numbers(numbers):

if numbers[4]%2 == 1:
  del numbers[4]
if numbers[3]%2 == 1:
  del numbers[3]
if numbers[2]%2 == 1:
  del numbers[2]
if numbers[1]%2 == 1:
  del numbers[1]
if numbers[0]%2 == 1:
  del numbers[0]
return numbers


#40 : Tuples

이건 내가 푼 방식이 생각보다 더 짧아서 놀래서 리뷰한다;;


* 내 코드

def convert_list_to_list_of_tuples(my_list):
  my_list = tuple(my_list[:2]), tuple(my_list[2:4]), tuple(my_list[4:])

  return list(my_list)

만약에 return 시 my_list를 list 형식으로 변환하지 않는다면 답은 ((1,2), (3,4), (5,6))이런 형식으로 나온다. 최종적으로 원하는 결과가 list 형식이므로 꼭 변환을 해 주어야 한다.

모델솔루션에서는 임의로 비어있는 list를 만들어 거기에 append하는 방식을 택했는데 그럼 총 3번 append 해주면 된다.

이때 코드 한줄을 살펴보면

new_list=[]
new_list.append((my_list[0], my_list[1]))

이런식으로 append에 두개의 괄호를 사용하였다.
이는 append는 한번에 한가지의 요소만 넣을수 있기 때문에 my_list[0]과 [1]을 한개로 묶기위해서 이다. 두개가 아닌 하나의 괄호를 사용하면 다음과 같은 오류 문구가 나온다.

new_list.append(my_list[0], my_list[1])
->
TypeError: append() takes exactly one argument (2 given)


#42 : Dictionary

출력 결과물에 차이가 있어 리뷰한다.

* 내 코드

Jimin = {"가명" : "지민(Jimin)", "본명" : "박지민", "생년월일" : "1995.10.13", "출생지" : "부산", "포지션" : "리드래퍼와 메인댄서", "학력" : "글로벌사이버대학교"}

for key in Jimin:
  print(f'{key} : {Jimin[key]}')

만약 print()를 입력할때

print(Jimin)

이렇게만 입력하면

너무나도 정직한... dictionary형태를 확인할 수 있다...



#43 : 리스트 내 중복없는 수 출력하기

이게 좀 오래걸렸다.. 문제에서 의도한 방식대로만 문제를 풀려고 하니 넘!!!!! 어려웠다!!!! 결국 다른 함수를 이용함 ㅎㅎ


* 내 코드

count() 함수는 해당 element의 갯수를 세어준다.
이를 이용해 list 안에 1개만 존재하는 수를 출력시키게 하였다.

my_list = [1, 2, 3, 4, 5, 1, 2, 3, 7, 9, 9, 7]

for i in my_list:
    list = my_list.count(i)
    if list == 1:
        print(i)
->
4
5

* 문제 의도대로 푼 코드

이 문제는 중첩 For loops를 이용해 문제를 풀기 원했다... 어려워 중첩;;ㅜㅠㅠ

중첩의 조건은 다음과 같다.

첫번째 For loop

  • list 안의 element들 하나씩 검사하기

두번째 For loop

  • 검사하고자 하는 element를 제외한 나머지 element들 중 검사하고자 하는 element가 또 존재하는지 확인하기

두번째 For loop 에서는 조건문이 필요하다

두번째 For loop 에서의 조건문
If) 검사하고 있는 element와 그 element를 제외한 나머지 요소들 중 똑같은 것이 있다면
-> 중복되었다!
else) 똑같은 것이 없다면
-> 중복되지 않는다! 출력하기!

위 조건대로 문제를 풀기 위해선 새로운 변수들이 필요하다.

  • 중복되지 않음을 뜻하는 only_one 을 True로 지정 (boolean)
  • 검사하는 element를 제외한 나머지 요소들로 꾸러진 list check_list
  • 검사하는 index 값을 하나씩 증가시켜줄 check_index

이를 기준으로 코드를 작성했다.

my_list = [1, 2, 3, 4, 5, 1, 2, 3, 7, 9, 9, 7]

check_index = 0

for list in my_list:
  only_one = True
  check_list = my_list[0:check_index] + my_list[check_index+1:]
  for element in check_list:
    if list == element:
      only_one = False
      break
  if only_one:
    print(list)
  check_index += 1

check_index를 하나씩 늘려주어야 검사하는 list와 함께 위치가 이동된다 !



#48 : For Loops - get_all_letters

내가 푼 방식이 덜 효율적이다!! 괜히 변수만 하나 더 사용했다.


* 내 코드

def get_all_letters() :
  str_list = []
  mission_str = "wecode"
  
  for i in range(0, len(mission_str)):
    j = mission_str[i]
    str_list.append(j)
  
  return str_list

* 수정 후 코드

수정한 부분은 for문의 범위였다.
나는 범위를 range로 주어 시작과 끝을 정해주었다.
하지만 range로 하지않고 범위를 주어진 단어로 하면 해당 단어에 사용된 문자 요소 하나하나에 대해 for 문이 진행된다.

def get_all_letters() :
  str_list = []
  mission_str = "wecode"
  
  for i in mission_str:
    str_list.append(i)
  
return str_list


#49 : While loops

내가 푼 방식이 덜! 효율적이다.
추가적인 list 변수를 선언해 주었는데 그렇게 하지 않아도 된다...


* 내 코드

def find_smallest_integer_divisor(numb): 
  answer = []
  i = 2
  while i <= numb:
    if numb%i == 0:
      answer.append(i)
      i += 1
    else:
      i += 1

  return min(answer)

나는 numb를 나눌수 있는 정수 i 를 answer 라는 list에 모두 모아서 그 중 가장 작은 값을 return 하는 방식을 사용했다.
다만 어떤 포스트에서 min 함수를 사용해 출력할 경우 처리속도가 느리다는걸 본 적이 있다.
위 문제는 크게 처리속도가 느려질 만큼은 아니지만,, 만약 엄청나게 큰 문제라면! 처리속도가 느려져 비효율적이겠지?

따라서 추가적으로 list 변수를 만들지 않고 코드를 짜 보았다.

* 수정 후 코드

1) 수정#1

솔루션 답을 습득하기 전, 바꾸고 싶은 형태가 생겨 코드를 수정해 보았다.

def find_smallest_integer_divisor(numb): 
  i = 2
  while i <= numb:
    if numb%i != 0:
      i += 1
    if numb%i == 0:
      break
  return i

그렇다. break를 활용해 보고 싶었다. ㅋㅋㅋㅋㅋㅋㅋ

2) 수정#2

가장 짧은 형태의 코드가 아닐까 생각한다.
while문은 조건이 True일때만 반복을 계속한다는 점을 들어, 원하는 i값이 나오게 한 후 조건이 False가 되도록 하여 반복을 멈추게 한다.

def find_smallest_integer_divisor(numb): 
  i = 2
  while numb%i != 0:
    i += 1
  return i

while 의 조건이 False가 될때, 즉 numb%i 의 값이 0이 될때 반복은 멈추고, 해당되는 i 값은 return 된다.



#52 : More Complex Function Parameterese

이건 문제에 대한 리뷰가 아니고, 내가 작성한 코드 중 한줄을 f-string으로 표현하는걸 리뷰하기 위해 작성했다.

* 내 코드

  else:
    return (kwargs["last_name"] + " " + kwargs["first_name"])

* 수정 후 코드

  else:
    return f'{kwargs["last_name"]} {kwargs["first_name"]}'




2편에 계속

profile
🍎 🍊 🍋 🍏 🍇

0개의 댓글