<오늘 한 일>
- 페어프로그래밍(pair programing)
- 알고리즘 문제시트 (notion.site)
- 여기서 1~5번을 팀원과 같이 풀어보았다
- 가장 풀기 어려웠던 문제는 2번 최빈값 구하기였다
- 개인적으로 먼저 풀어봤었는데도 풀이방법이 생각이 안 났다ㅠㅠ복습의 중요성....
- 첫 번째 시도: for문 2번 돌리기
def solution(array):
answer = 0
for num in array:
for num2 in array:
answer = print(num, num2)
return answer
- 이게 어떻게 나오는지 궁금해서 print문을 돌려봤는데
1 1
1 2
1 3
1 3
1 3
1 4
2 1
2 2
2 3
2 3
2 3
2 4
3 1
3 2
3 3
3 3
3 3
3 4
3 1
3 2
3 3
3 3
3 3
3 4
3 1
3 2
3 3
3 3
3 3
3 4
4 1
4 2
4 3
4 3
4 3
4 4
- 원래는 왼쪽 값과 오른쪽 값을 비교해서 같으면 count를 1 더하고 다르면 pass하는 식으로 하려고 했는데 이렇게 하니까 중복되는 값 때문에 원하는 대로 나오지 않을 것 같았다
- 첫 번째 for문에서 중복값을 제외하고 돌려야 할 텐데...그렇게 하더라도 count변수를 숫자마다 계속 만들어 줘야 하니 뭔가 접근 자체가 틀린 것 같다고 생각했다
- 결국 힌트를 보았고...
def solution(array):
answer = 0
check = {}
for ar in array: # array에서 하나씩 돌아라
if not ar in check: # check 딕셔너리의 키값에 ar이 없으면
check[ar] = 1 # check 딕셔너리의 키값이 ar인 곳에 밸류로 1을 넣어라
else:
check[ar] += 1 # 만약 키로 ar이 있으면 밸류에 +1 하라
- 여기까지는 이해가 갔다
- 근데 그 다음에 람다식이 나오니까...무슨 말인지 몰라서 튜터님을 찾아갔다
- 이해가 쏙쏙 가는 설명을 듣고 나니 완전히 이해가 됐다
def solution(array):
answer = 0
check = {}
for ar in array: # array에서 하나씩 돌아라
if not ar in check: # check 딕셔너리의 키값에 ar이 없으면
check[ar] = 1 # check 딕셔너리의 키값이 ar인 곳에 value로 1을 넣어라
else:
check[ar] += 1 # 만약 키로 ar이 있으면 밸류로 +1 하라
# check 딕셔너리를 가져와서 밸류값을 기준으로 내림차순 정렬
sorted_check = sorted(check.items(), reverse=True,
key=lambda item: item[1])
if len(sorted_check) > 1: # 정렬된 check 튜플리스트의 길이가 1보다 크면, 즉 데이터가 2개 이상이면
if sorted_check[0][1] != sorted_check[1][1]: # check 튜플 첫 번째 값 중 1번째 인덱스(=딕셔너리 밸류값=숫자가 나온 횟수)와 튜플 두 번째 값의 1번째 인덱스 값이 다르면
answer = sorted_check[0][0] # check 튜플 첫 번째 데이터의 1번째 인덱스를 answer 변수에 넣어라
else: # check 튜플 첫 번째 값의 1번째 인덱스 값와 튜플 두 번째 값의 1번째 인덱스 값이 같으면
answer = -1 # answer 변수에 -1을 넣어라
else: # 정렬된 check 튜플리스트의 값이 1개뿐이면
answer = sorted_check[0][0] # 그 값의 1번째 인덱스 값을 answer에 넣어라
return answer
- 정답을 완성했다
- 그러고나니 람다식을 어떤 때에 사용해야 하는지 람다식을 쓰지 않으려면 어떤 식으로 써야 하는지 궁금해졌다
- 팀원과 구글링 및 고민을 했다
- 저런 경우에 원래는 함수를 사용해야 한다
def value(item):
return item[1]
- 정렬하기 전에 이런 함수를 선언해주어야 한다
- 매개변수로 check딕셔너리의 키, 밸류값이 들어가고 그 중 밸류값을 반환하는 함수다
File "c:\Users\l\Desktop\coding\sparta\study\prac.py", line 11, in value
return item[1]
~~~~^^^
TypeError: 'dict_items' object is not subscriptable
- 이런 오류가 떴다
- 도저히 왜 그러는 건지 감이 안 잡혀서 다시 튜터님을 찾아갔다
- 튜터님은 return 값 item을 list로 감싸주어야 한다고 말씀하셨다
- 감싸지 않으면 item은 개별적인 값들이라서(?) 암튼 뭐라고 말씀하셨는데 기억이 안 난다...여튼 [1] 이런 식으로 접근이 불가능한 상태였고 리스트로 감싸줘야 [1]을 붙이는 게 가능하다고 하셨다
def value(item):
return list(item)[1]
# check 딕셔너리를 가져와서 밸류값을 기준으로 내림차순 정렬
sorted_check = sorted(check.items(), reverse=True,
key=value(check.items()))
- 그래서 이렇게 수정했는데 아래와 같은 오류가 떴다
File "c:\Users\l\Desktop\coding\sparta\study\prac.py", line 14, in solution
sorted_check = sorted(check.items(), reverse=True,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'tuple' object is not callable
- 튜터님이 보시더니 value함수에 매개변수를 빼야 한다고 하셨다
# check 딕셔너리를 가져와서 밸류값을 기준으로 내림차순 정렬
sorted_check = sorted(check.items(), reverse=True, key=value)
- 이렇게 하니까 오류가 안 나왔다
- 튜터님께 왜 이런 건가요? 질문하니 이건 왜? 가 아니라 그냥 받아들여야 한다고 하셨다
- sorted()함수에 매개변수로 key값에 함수가 들어오는 경우 매개변수를 sorted 매개변수에서 알아서 찾도록 저렇게 설정된 것이었다
- 드디어 완성된 코드..!!!
def solution(array):
answer = 0
check = {}
for ar in array: # array에서 하나씩 돌아라
if not ar in check: # check 딕셔너리의 키값에 ar이 없으면
check[ar] = 1 # check 딕셔너리의 키값이 ar인 곳에 value로 1을 넣어라
else:
check[ar] += 1 # 만약 키로 ar이 있으면 밸류로 +1 하라
# check 딕셔너리를 가져와서 밸류값을 기준으로 내림차순 정렬
sorted_check = sorted(check.items(), reverse=True,
key=lambda item: item[1])
if len(sorted_check) > 1: # 정렬된 check 튜플리스트의 길이가 1보다 크면, 즉 데이터가 2개 이상이면
# check 튜플 첫 번째 값 중 1번째 인덱스(=딕셔너리 밸류값=숫자가 나온 횟수)와 튜플 두 번째 값의 1번째 인덱스 값이 다르면
if sorted_check[0][1] != sorted_check[1][1]:
# check 튜플 첫 번째 데이터의 1번째 인덱스를 answer 변수에 넣어라
answer = sorted_check[0][0]
else: # check 튜플 첫 번째 값의 1번째 인덱스 값와 튜플 두 번째 값의 1번째 인덱스 값이 같으면
answer = -1 # answer 변수에 -1을 넣어라
else: # 정렬된 check 튜플리스트의 값이 1개뿐이면
# 그 값의 1번째 인덱스 값을 answer에 넣어라
answer = sorted_check[0][0]
return answer
- 아래 코드는 람다식을 안 썼을 때의 코드다
def solution(array):
answer = 0
check = {}
for ar in array: # array에서 하나씩 돌아라
if not ar in check: # check 딕셔너리의 키값에 ar이 없으면
check[ar] = 1 # check 딕셔너리의 키값이 ar인 곳에 value로 1을 넣어라
else:
check[ar] += 1 # 만약 키로 ar이 있으면 밸류로 +1 하라
def value(item):
return list(item)[1]
# check 딕셔너리를 가져와서 밸류값을 기준으로 내림차순 정렬
sorted_check = sorted(check.items(), reverse=True, key=value)
if len(sorted_check) > 1: # 정렬된 check 튜플리스트의 길이가 1보다 크면, 즉 데이터가 2개 이상이면
# check 튜플 첫 번째 값 중 1번째 인덱스(=딕셔너리 밸류값=숫자가 나온 횟수)와 튜플 두 번째 값의 1번째 인덱스 값이 다르면
if sorted_check[0][1] != sorted_check[1][1]:
# check 튜플 첫 번째 데이터의 1번째 인덱스를 answer 변수에 넣어라
answer = sorted_check[0][0]
else: # check 튜플 첫 번째 값의 1번째 인덱스 값와 튜플 두 번째 값의 1번째 인덱스 값이 같으면
answer = -1 # answer 변수에 -1을 넣어라
else: # 정렬된 check 튜플리스트의 값이 1개뿐이면
# 그 값의 1번째 인덱스 값을 answer에 넣어라
answer = sorted_check[0][0]
return answer
- 람다식을 어떨 때 보통 쓰냐고 활용방법에 대해서도 질문을 했는데 튜터님은 정렬할 때 말고는 거의 안 쓴다고 하셨다
- 자료구조/알고리즘 강의 1주차
- 장고 기초 강의 2주차
- 2-4강까지밖에 못 들었다
- 나는 강의 그대로 따라했는데 오류가 떴다...
- 일단 앱 설치까지는 오류없이 잘 해냈다
1번째 시련: 데이터베이스 연결하기
- 데이터베이스 탭에서 Data Source from Path를 눌러서 장고가 생성한 db.splite3을 선택하는 것까지는 잘 됐다
- 그 다음 연결에 필요한 드라이버를 설치하는데 노트북이 렉걸려서 그만 설치를 못했다...
- 그대로 파이참을 강제종료하고 다시 들어가서 드라이버를 설치하는 데까지는 또 성공을 했다
- 근데 무슨 switch 어쩌고 창이 떴다...
- 영어를 모르는 게 죄지....다시 껐다가 켜도 떴다...
- 왠지 눌러보고 싶게 switch가 버튼처럼 생겨서 눌렀다
- 그러고 Test Connection을 누르니 허무하게도 그냥 연결이 잘 됐다^^!
- 사실 이건 시련 축에도 못 낀다
2번째 시련: admin 페이지 TypeError
- 또 튜터님이 하라는 대로 장고 서버를 실행시키고 http://127.0.0.1:8000/admin 여기로 접속을 했다
- 일단 구글에 'set' object is not reversible 라고 검색했다
- 여러 페이지를 둘러봤는데 나에게 맞는 정보가 없었다
- 결국 튜터님을 찾아갔다 화면공유를 했는데 튜터님이 직접 파일을 봐야 할 것 같다고 하셔서 파일을 압축해서 보내드렸다
- 튜터님이 해내셨다!
- urls.py 파일 안에
urlpatterns = {
path('admin/', admin.site.urls),
path('test/', views.base_response, name='first_test'),
path('first/', views.first_view, name='first_view'),
}
- 이 부분이 있는데 []로 감싸져야 하는 게 {}로 감싸져 있어서 그런 것이라고 하셨다
- 튜터님이 말씀하신 대로 {}를 []로 바꾸니 admin 페이지가 잘 나온다!
- 근데 사실 내가 찾아본 페이지 중에 튜터님이랑 똑같이 얘기한 사람이 있었다
- 근데 내가 에러에 지쳐있어서 눈여겨보지 않았다....
- python - TypeError at /admin/ 'set' object is not reversible and argument( ) to reverse must be a sequence - Stack Overflow
- TypeError: 'set' object is not reversible · Issue #781 · axnsan12/drf-yasg (github.com)
- 심지어 2군데서 봤다 저 얘기를....근데 뭔소린지도 모르겠고...해서 넘겼는데....저게 답이었다
3번째 시련: superuser 계정 삭제
- 이건 사실 시련까지는 아니고 강의 내용 외에 내가 알고 싶어서 찾아봤다
- 왜냐하면 superuser 계정을 만들 때 비밀번호가 안 보여서 이게 뭐야! 하고 막 쳤는데 그게 그대로 계정이 생성되어버려서...ㅎㅎ....
- 근데 비밀번호 바꾸는 법 찾아볼 생각을 안 하고 계정을 하나 더 만들었다 그래서 처음 만든 계정을 삭제하고 싶어져서 찾아봤다
- 구글에 django superuser 삭제 라고 검색했다ㅋㅋ
- 장고(django)에서 superuser를 삭제하는 방법. : 네이버 블로그 (naver.com)
- 여기서 삭제하는 방법을 잘 알려줬다
- 하라는 대로 삭제 명령어까지 썼는데 저기에서 나가지지가 않는 게 또 문제.......
- 뭐지 싶어가지고 블로그를 다시 봤는데 맨 마지막에 exit가 있어가지고 ㅋㅋㅋ그대로 따라 썼다
- 그랬더니 나가지는 게 아니라 나가는 방밥을 알려준다
- 컨트롤z 했는데도 아무 반응이 없길래 3번이나 씀 ㅋㅋㅋ
- 근데 컨트롤z 하고 엔터 누르면 되는 거였다 어렵구만~
참고: superuser 계정 비밀번호 변경하는 방법
- 처음에 바꿀 비밀번호를 썼는데 너무 짧다그래서 당황해서 아무거나 썼다가 2번째 again이랑 안 맞다고 넘어감ㅋㅋ
- 다시 제대로 비밀번호를 설정하고 엔터 눌렀더니 끝!
- 비밀번호 변경 명령어: python manage.py changepassword <유저이름>
<오늘 새롭게 배운 것>
- 람다식 사용 방법 및 활용
- lamda 매개변수(인자): 매개변수 활용식(표현식)
- 예시: (lambda x: x*2)(2) 를 출력하면 4가 나온다
- 함수를 축소한 것이라고 이해하면 된다
- 튜터님은 람다식을 정렬할 때 말고는 거의 안 쓴다고 하심
- 시간복잡도 vs 공간복잡도
- 공간복잡도보다 시간복잡도에 따라 알고리즘 성능이 크게 차이남
- 시간복잡도도 상수는 거의 의미없고 N의 지수(거듭제곱)에 따라 성능 차이가 커짐
- 코드를 짤 때 공간복잡도를 늘리더라도 시간복잡도를 최대한 줄이는 것이 중요함
- Django superuser 계정 삭제 및 비밀번호 변경
- 계정 삭제 명령어:
- python manage.py shell
- from django.contrib.auth.models import User
- User.objects.get(username="<유저이름>", is_superuser=True).delete()
- exit
계정 비밀번호 변경 명령어: python manage.py changepassword <유저이름>
<느낀 점>
- 오늘 굉장히 TIL이 길어서 알차게 공부한 느낌...!
- 실제로도 밀도있게 공부한 것 같다
- 뭔가 에러만 안 떴어도 장고 2주차 끝낼 수 있었을 텐데....아쉽당....
- 내일은 오늘보다 더 집중하겠다!!!
<내일 목표>
- 페어 프로그래밍 잘하기
- 알고리즘 2주차 강의 수강하기
- 장고 3주차 강의 수강하기
- 시간 남으면 파이썬 300제 남은 30문제 풀기...(자꾸 밀린다)
- 개인과제...!!!!!