Python 12

[BOJ] 11066. 파일합치기 ( python, 그림낙서, DP, 회고록 )

https://www.acmicpc.net/problem/11066 11066번: 파일 합치기 소설가인 김대전은 소설을 여러 장(chapter)으로 나누어 쓰는데, 각 장은 각각 다른 파일에 저장하곤 한다. 소설의 모든 장을 쓰고 나서는 각 장이 쓰여진 파일을 합쳐서 최종적으로 소설의 완성본 www.acmicpc.net DP는 풀어도 적응이 안되고, 난이도가 높아지면 높아질수록 적용방법을 모르겠다 이 문제를 풀 때, 순서에 따라 계산을 하면 결과가 달라지기 때문에 조합을 이용해야 할 것 같다 조합되는 개수가 홀수, 짝수에 의해 달라지는 최솟값을 도출해야 할 것 같다 연속되는( 3 다음에 3과 같은 연속 ) 숫자를 기반으로 찾아 최솟값을 추론할 수 있을 것 같다 라고 생각했다. 결론적으로는 1번 조합을 추..

asyncio를 활용해 간단하게 서버 구현한 코드 리뷰하기

asyncio로 서버를 구성하는 코드예제를 보고, 그냥 넘어가는 것보단 정리하면서 개념도 같이 정리해보면 좋을 것 같아서 코드리뷰 느낌으로 글을 작성해보았습니다! 전체코드를 보고 싶으신 분들은 아래 깃헙주소를 참고해주시면 좋을 것 같아요 https://github.com/bslatkin/effectivepython/blob/master/example_code/item_61.py#L278 또한 해당 코드에서의 목적은 클라이언트와 서버와의 숫자맞추기 게임로직을 구현한 것인데, 게임로직 함수 구현내용은 거의 생략을 했음을 참고해주시면서 보면 좋을 것 같습니다. 코드는 최대한 발생순서대로 정리하였습니다 async def main_async(): address = ('127.0.0.1', 4321) server ..

소켓코드를 보고 현상정리 ( feat. 버퍼 )

class EOFError(Exception): pass # 서버는 한번에 하나씩 처리, 클라이언트 세션상태 유지하는 클래스 class ConnectionBase: # 3 def __init__(self, connection): self.connection = connection self.file = connection.makefile('rb') def send(self, command): line = command + '\\n' data = line.encode() self.connection.send(data) def receive(self): line = self.file.readline() if not line: raise EOFError('Connection closed') return line..

with와 @contextlib.contextmanager

파이썬으로 작성된 소켓연결 코드를 보는 와중에 소켓연결할 때, with 접두사로 활용하는 모습들이 보였다. 혹은, @contextlib.contextmanager 라는 데코레이터를 붙힌 후, 해당 fn 를 with문으로 활용하는 문법들을 보면서, 대체 with를 왜 쓰는것이고, 무엇을 하는 역활인지 궁금했고 찾아보았다. with 문은 Python의 컨텍스트 관리 프로토콜을 사용하는 문법이며, 주로 리소스 관리에 사용되며, 이를 통해 파일, 네트워크 연결, 데이터베이스 연결 등의 리소스를 안전하게 사용하고 정리할 수 있다고 한다. with 문의 3단계로 걸쳐 실행된다 진입: with 블록에 진입할 때, 컨텍스트 관리자의 enter 메서드가 호출됩니다. 이 메서드는 필요한 리소스를 할당하거나 초기화할 수 있..

컨텍스트 스위칭으로부터의 예상치 못한 결과 ( feat.GIL )

파이썬에서 동시성,병렬성에 대한 학습을 하면서 이해했던 것들을 재검토하는 시간에 Thread 안에 subprocess를 만나면 블로킹을 하고 다음 Thread로 넘어가는지에 대한 궁금증이 생겼다 바로 코드로 확인해보았다 import threading import subprocess import time def run_command(): print("Starting command...") subprocess.run(["sleep", "5"]) # 5초 동안 sleep하는 외부 명령 print("Command finished.") def do_other_stuff(): for i in range(3): print("Doing other stuff...") time.sleep(1) run_command() d..

Thread와 Queue를 활용한 파이프라인 구현하기( feat. 콘웨이 생명게임 )

더보기 콘웨이의 생명 게임(Conway's Game of Life)은 1970년에 수학자 존 콘웨이(John Conway)에 의해 고안된 세포 자동자(cellular automaton)입니다. 이 게임은 "게임"이라는 이름을 가지고 있지만, 플레이어의 참여 없이 자동으로 진행되는 시뮬레이션입니다. 게임의 규칙은 다음과 같습니다: 생존: 어떤 세포에 인접한 8개의 세포 중 정확히 2개 또는 3개가 살아 있으면, 다음 세대에서 그 세포는 살아 있습니다. 사망: 어떤 세포에 인접한 8개의 세포 중 살아 있는 세포가 2개 미만이면, 그 세포는 고립되어 사망합니다. 또한, 살아 있는 세포가 3개 초과로 인접해 있으면, 그 세포는 과밀로 인해 사망합니다. 번식: 어떤 세포에 인접한 8개의 세포 중 정확히 3개가 살..

파이썬에서 외부 터미널 명령어 사용하기 ( subprocess )

파이썬에서 subprocess 를 활용해 자식 프로세스를 실행하면서, 자식 프로세스의 입출력 스트림을 관리 및 활용할 수 있습니다 import subprocess result = subprocess.run(['echo', 'Hello from subprocess!'], capture_output=True, text=True) print(result.stdout) # Hello from subprocess! 위 코드를 통해 subprocess에 터미널 명령을 넣어주면 아래와 같은 결과값을 얻을 수 있음을 확인할 수 있습니다. 만약 내가 터미널 명령을 통한 결과값을 이용해 파이프라인을 구축하고 싶다면 Popen 클래스를 활용해 유닉스 스타일의 파이프라인을 구축해볼 수 있을 것 같은데요. 여기서 유닉스 스타일..

GIL를 무조건 신뢰하면 안되는 이유( feat.스레드 감수성 )

나는 생각했다. 그러면 GIL 때문에 쓰레드 작업에서 락걸거나, 따로 통제할 필요가 없겠네. GIL 특성상 무조건 딱 하나의 스레드만 실행시켜주니깐! 하지만 이 말은 틀렸다. GIL는 동시접근을 보장해주는 락역활이라고 생각했지만 그렇지않다. 그 이유는 코드로 확인해보자. class Counter: def __init__(self): self.count = 0 def increment(self, offset): self.count += offset def worker(sensor_index, how_many, counter): BARRIER.wait() for _ in range(how_many): counter.increment(1) # Example 3 from threading import Barri..

두 코드의 차이점을 설명하시요( feat. Python,쓰레드, GIL, 병렬 I/O)

import select import socket def slow_systemcall(): select.select([socket.socket()], [], [], 0.1) start = time.time() for _ in range(5): slow_systemcall() end = time.time() delta = end - start print(f'Took {delta:.3f} seconds') # Took 0.526 seconds import select import socket def slow_systemcall(): select.select([socket.socket()], [], [], 0.1) start = time.time() threads = [] for _ in range(5): t..

디스크립터 __set_name__ 의 활용방법

__ set_name __ 를 활용하기 이전에, 해당 디스크립터가 필요하게 된 상황을 알아보자 class Field: def __init__(self, name): self.name = name self.internal_name = '_' + self.name def __get__(self, instance, instance_type): if instance is None: return self return getattr(instance, self.internal_name, '') def __set__(self, instance, value): setattr(instance, self.internal_name, value) class Customer: first_name = Field('first_nam..