2023.03.14 AM TIL

hodeethelion·2023년 3월 14일
0

SW Intense Academy

목록 보기
2/12
post-thumbnail

오전 9 ~ 12

아니 이제 앞으로 좀 매일 배운것을 적는 시간을 가져야할 것 같다.
생각도 정리할겸사겸사 그래서 하루를 파트를 최소한 3개로 나눠서 매 시간을 한 것을 좀 분배하고 써 놓으면 좋을것 같다 아 좀 배고픈듯...

백준11279 최대 힙

heapq 모듈에서는 최소힙밖에 만들 수 없기 때문에 다음과 같은 방법이 있다.
1. 튜플로 (-value, value)로 heap으로 넣어주는 법

from heapq import heappush, heappop
nums =[4,1,7,3,8,5]
heap =[]
for num in nums:
    heappush(heap, (-num, num))
    
while heap:
    print(heappop(heap))
  1. -value로 넣어주고 빼낼 때 마이너스를 곱해서 빼내주는 방법
import heapq

heap = []
values = [1,5,3,2,4]

# 아래 for문을 실행시키고 나면 heap은 [-5,-4,-3,-1,-2]가 된다.
for value in values:
	heapq.heappush(heap, -value)

# 아래 for문을 실행시키면 5,4,3,2,1이 출력된다. 즉, 큰 숫자부터 출력이 된다.
for i in range(5):
	print(-heapq.heappop(heap))

9시 20분 문제 발생!
TypeError: pop() takes 0 positional arguments but 1 was given
라고 뜬다...

와... 이거는 좀 중요!
function을 class안에서 만들 때 self를 꼭 넣어주도록 하자!
self를 넣어줘야만 자신의 정보를 끌어낼 수 ? 있는 것 같다

class 만들기

먼저 class 만들 때 함수를 설정할때

def __init__(self):
	self.items = []
    self.info = info

와 같이 설정을 꼭 해주는데 객체생성에 필수적이니까 까먹지 않도록 하자

튜플이란?

  1. 튜플과 리스트의 가장 큰 차이는 요소값을 변화시킬수 있는가의 여부
    요솟값을 삭제 혹은 변경 하려 하면
  2. 공통점은 인덱싱이 가능하다는 점인데 set은 인덱싱이 불가능하다는 것을 기억하는 것이 좋다.
  3. 요솟값을 변경할 수 없기 때문에 sort, insert, remove, pop이런 것들이 불가능하다
TypeError: 'tuple' object doesn't support item deletion

이렇게 타입에러가 난다고 볼 수 있고 처리하려면 요즘 즐겨 쓰는 try, except TypeError로 처리해주면 좋을 것 같다.

백준1655 가운데를 말해요

일단 이 문제를 야무지게 풀기전에 heapq에 모듈들이 생각보다 많던데 읽어보도록 하자.

파이썬 heapq

  • heapify: 기존 리스트를 heap의 형태로 만들어주기
  • heappushpop: heap에서 item 푸시하고 하나 또 반환하기, 따로하는 것 보다 더 효율적으로 실행
  • nlargest(개수, heap리스트): heap에서 가장 큰거에서부터 몇개의 아이템을 반환

이제 알겠는데 가운데를 말해요에서 nlargest가 쓰일 수도 있을 것 같다는 생각을 해본다.

  1. 생각 구현: nsmallest로 풀어볼려고 했음
    결과: 시간 초과
from heapq import heappush, nsmallest
import sys
heap = []
n_command = int(sys.stdin.readline()) 
for _ in range(n_command):
    heappush(heap, int(sys.stdin.readline()))
    # 짝수 일 때
    if len(heap) % 2 == 0:
        print(nsmallest(len(heap)//2, heap)[-1])
    else:
        print(nsmallest((len(heap)+1)//2, heap)[-1])

아 젬장 답지 참고하기 싫은데
2. 두개의 힙을 이용 leftheap, rightheap이라고 가정
leftheap은 최대힙으로 가정
rightheap은 최소힙으로 가정

가장 중요한 heap의 성질을 사용한다는 것! root를 꺼내는 것의 장점

1) 하나 들어왔을 때
-> leftheap에 넣기
-> leftheap에서 꺼내기

2) 두번째 들어왔을 때
-> rightheap에 넣기
-> root 비교해주기! 비교한다면 왼쪽이 더 크면 바꿔서 넣어주기
여기서 왠지 heappushpop을 쓸 수 있을 까 싶긴한데~~ 더 깔끔하게 써볼수 있을 것 같당
-> leftheap에서 꺼내기

한두번 해보면 야무지게 확인가능하다! 좋아좋아

역시 어제 한 10시에 자고 오늘 일곱시쯤 일어나니까 뭔가 머리가 팽글팽글 도는구먼
한 몇시간 잔거지 10시부터 잣으니까 거의 9시간 잔것! 확실히 잠을 잘 자고 카페인 아침 점심으로 사발로 때려주면 컨디션이 꽤 낟밷낟밷
또 아침에 라떼 우유반 샷추가 했더니 약간 이게 내 컨디션 회복의 근원인듯
근데 이렇게 아침에 정리하는 것 생각보다 좋은 것 같다
Any funckin ways

다음과 같이 heap을 왼쪽 오른쪽으로 나누어서 풀게 되면 다음과 같다

from heapq import heappush, heappop
import sys
left_heap = [] # 최대 힙
right_heap = [] # 최소 힙
n_command = int(sys.stdin.readline())
for _ in range(n_command):
    going_in = int(sys.stdin.readline())
    if len(left_heap) == len(right_heap):
        heappush(left_heap, (-going_in, going_in))
    else:
        heappush(right_heap, (going_in, going_in))
    # check_stage
    try:
        if left_heap[0][1] > right_heap[0][0]:
            left_out = heappop(left_heap)[1]
            right_out = heappop(right_heap)[0]
            heappush(right_heap, (left_out, left_out))
            heappush(left_heap, (-right_out, right_out))
    except IndexError:
        pass
        
    print(left_heap[0][1])

파이썬 중급

클래스 & 메소드 심화(2-1)

왠지 알고리즘만 푸는 것 물론 좋긴한데... 파이썬을 야무지게 쓰고 싶은 욕심이 크기 때문에 왠만하면 좀 정리도 같이 하려고한다.

일단 클라쓰를 작성할때에는

class Sample:
 '''
  Sample Class
  Author: Hojun
  Date: 2023. 03. 14
 '''
 	car_count = 0
    
	def __init__(self, item):
    	self._item = item
        
    def some_function(self):
    	
    	

여기서

  • init : double leading underscore 스페셜 변수나 매직 메서드에 사용되는 컨벤션, 특정문법적 기능을 제공하거나 특정한 일 수행.

  • _happy : single leading underscore, 프라이빗 변수,클라스, 메서드를 선언할 때 사용되는 컨벤션으로 from module import *하게 되면 모두 임포트에서 모두 무시하게된다.

  • happy_ : single trailing underscore, 키워드 충돌을 피할려고 쓰는데 별로 안쓸것.

와 같이 특별한 네이밍을 할 경우가 있다고 한다.

클라쓰에서 다음과 같이 넣어주면서 내용을 적어주는게 고수의 길이라고 한다

"""
내용을 넣기
"""

또한 def method(self): 와 같이 항상 이렇게 self를 넣어야만 자기 인스턴스에 있는 value를 가지고 올 수 있다는 것아다.

방금 확인한건데

str 이랑 repr 은 프린트를 해보면 알 수 있다
1) print(객체) -> str 에 적어놓은 값이 나오고
2) 객체 -> repr 이 나온다고 할 수 있다

#1. 상위로부터 상속받은 모든 메소드를 넣어 리스트를 만들어서 준다
print(dir(car1))

#2. 내가 지정한 메소드들을 받아올 수 있다
print(sameple_class_object.__dict__)

#3. 앞에 적어둔 내용 """내용"""을 출력해서 적어줄 수도 있다.
print(Class 혹은 오브젝트.__doc__)

해준다면 확실히 이 클라스의 정보를 압축해서 읽을 수 있다.

  • Dictionary에서 .get('key') 를 해주게 되면 오류 없이 value 값을 가져올 수 도 있다.

클래스 & 메소드 심화(2-2)

self 인자를 꼭 넘겨줘야만하는데 예를 들어 class Car: 이렇게 define 해서 하나를 만들었을 때

Car.detail_info() 만 햇을때는 self 인자를 불러오지 않았기 때문에

TypeError: detail_info() missing 1 required positional argument: 'self'

가 뜨게 된다!

해결 방법은 다음과 같다
1. car2.detail_info()를 하게 되면 자연스레 self를 불러오게 되니까 성립
2. Car.detail_info(car2)를 하게되면 성립

1번이 성립되는 이유는 init 을 해줄 때 가지고 올 수 있어서인가?

class에서 변수를 생성해놓을 때 세팅을 해논다고 생각해야 될 것 같다. self가 없다면 세팅이 없는 것을 자겨온다는 의미?

class 변수는
Sample.car_count 를 뽑아보게 된다면 모든 클라스가 함께 공유하는 변수를 의미하게 된다.

profile
가슴을 따라가자

0개의 댓글

관련 채용 정보