콘텐츠로 건너뛰기
Home » Development » Page 4

Development

프로그래밍 언어 및 환경

같은 것을 포함하는 순열 생성기

표준 라이브러리 itertools를 사용하면 주어진 집합의 원소로 만들 수 있는 모든 순열과 조합을 생성해 볼 수 있다. 이 모듈은 순열, 조합, 중복조합에 관한 제너레이터 함수를 제공하지만, 좀 더 개별적인 케이스에서 활용할 수 있는 함수는 제공해주지 않는 아쉬움이 있다. 예를 들면 중복 순열(사실 중복 순열은 itertools.product()를 활용해서 구할 수 있다.)이라든지, 이 글에서 설명하고자 하는 같은 것을 포함하는 순열을 만드는 경우가 이에 해당한다.

더 보기 »같은 것을 포함하는 순열 생성기

(Python) prompt_toolkit 사용법

prompt_toolkit은 xNIX 계열의 쉘에서 사용되는 readline 라이브러리를 순수 파이썬으로 구현한 것으로 명령줄 도구를 사용할 때 히스토리 탐색이나 자동 추천, 자동 완성등의 기능을 쓸 수 있게 해주는 라이브러리이다. readline 자체가 제공하는 기능이 워낙 다양하고 유용하기 때문에 대화형 쉘과 같은 프로그램을 매우 쉽게 만들 수 있게 해준다. prompt toolkit의 제작자는 이 라이브러리의 기능을 활용하여 ptpython이라는 개선된 파이썬 대화형 쉘을 제작하였으며, vim의 기능을 흉내낸 pyvim 프로젝트도 개발하고 있다. (공식문서보기)

prompt_toolkit은 입력 프롬프트 상에서 표시되는 내용과 입력에 대한 검증을 실시간으로 가능하게 하기 때문에, 입력을 특정한 규격에 맞춰야 하는 프로그램에서 아주 유용하다. 또한 텍스트에 컬러를 지정하는 것도 가능하며, 입력 중인 내용에 대해 구문 강조를 적용하는 것도 가능하기 때문에 예쁜 CLI 프로그램을 만드는데 도움을 준다.

오늘은 prompt_toolkit에 대해 좀 알아보도록 하자.

더 보기 »(Python) prompt_toolkit 사용법

(Swift) 폰트의 포스트 스크립트 이름 확인 방법

CATextLayer에서 텍스트의 폰트를 지정해주려면, CTFontRef를 만들어서 넘겨주어야 한다. 이 값은 CTFont 나 CGFont 타입과 브릿징되기 때문에 CTFont를 만들어야 한다. 만약 시스템에 설치된 서드파티 폰트를 사용해서 CTFont 객체를 만들려면 해당 폰트의 포스트 스크립트 이름을 알고 있어야 한다. 즉 CATextLayer에서 커스텀 폰트를 사용하려면 해당 커스텀 폰트의 포스트스크립트 이름이 필요하다는 이야기이다. macOS에서는 간단하게 서체 관리자에서 해당 폰트를 선택하여 정보보기(cmd + i)를 통해 PostScript Name을 확인해서 이 값을 알 수 있다. 그런데 iOS에서는 서체 관리자가 없기 때문에 이 방법을 쓸 수 없다. 대신에 다음… 더 보기 »(Swift) 폰트의 포스트 스크립트 이름 확인 방법

matplotlib의 기본 사용법 및 다른 시각화 라이브러리

오늘은 파이썬의 시각화 부분에서 가장 널리 쓰이고 있는 matplotlib에 대해서 알아보도록 하자.

matplotlib을 사용할 때 주로 서브패키지인 pyplot을 사용한다. pyplot은 MATLAB의 인터페이스와 유사하게 작동할 수 있도록 하여 MATLAB을 사용하는 사용자층이 쉽게 matplotlib으로 옮겨오도록 하고 있다. 문제는 MATLAB의 인터페이스가 그모양이어서 그런지 모르겠는데, matplotlib의 인터페이스가 일관성도 없는 편이고 그다지 객체지향적이지도 않아서 사실상 API 문서만으로도 사용이 어렵고 관련 예제를 보면서 코드를 따라써야 하는 수준으로 처리해야 하는 경우가 많다는 것이다.

더 보기 »matplotlib의 기본 사용법 및 다른 시각화 라이브러리

파이썬으로 이진 탐색 구현하기

이진 탐색(binary search)은 정렬된 데이터에서 특정한 값을 아주 빠르게 찾는 방법이다. N개의 데이터 중에서 특정한 값 x를 찾을 때, 최악의 경우 N번의 비교가 필요한데, 이진 탐색의 경우 최대 log_{2}N만큼의 비교를 하게 된다. 즉 자료의 크기가 클수록 선형 탐색에 비해 성능이 매우 우수해진다. 다만 이진 탐색은 자료가 정렬되어 있다는 전제가 필요하다. (이 때문에 컴퓨터 과학에서는 정렬이 매우 중요하고, 성능이 좋은 정렬 알고리듬을 만들기 위해 많은 노력이 있어왔다.)

더 보기 »파이썬으로 이진 탐색 구현하기

생일 문제

30명의 사람이 있을 때, 이 중 생일 같은 사람이 최소 2명 있을 확률을 구하고 싶다. 어떻게 계산할 수 있을까? 이러한 문제를 생일 문제라 한다. 흥미로운 점은 생일 문제가 우리의 직관을 비웃는 것 같은 결과를 보인다는 것이다.

예를 들어 당신이 누군가를 만났다고 하자. 그 사람이 당신과 생일이 같을 확률은 얼마일까? 당신의 생일이 정해져 있으므로 그 사람의 생일은 365일 중 같은 날인 하루여야 한다. 이 때의 확률은 1/365로 약 0.274% 밖에 안된다. 이처럼 1년의 날 수가 365일이나 되기 때문에 생일이 같아질 확률이 매우 작아 보인다.

더 보기 »생일 문제

asyncio의 동기화수단들

asyncio는 단일 스레드에서 비동기 코루틴을 사용하여 동시성 처리를 한다. 따라서 asyncio의 세계에서는 적어도 멀티 스레드에서 발생할 수 있는 자원 선점문제가 없을 것이라 생각할 수 있다. 전적으로 틀린 것은 아니다. 스레드가 1개밖에 없기 때문에 메모리 내의 특정한 객체를 동시에 액세스하는 일은 없을 것이다. 그러나 그외의 IO와 관련된 자원은 여전히 선점 문제가 발생할 수 있다. 이러한 문제를 피하기 위해서 asyncio는 threading과 유사한 동기화 수단들을 제공하고 있으며, 이들의 사용 방법 또한 거의 유사하다. asyncio에서 제공하는 동기화 수단에는 다음과 같은 것들이 있다.

  • 락(Lock)
  • 이벤트(Event)
  • 컨디션(Condition)
  • 세마포어(Semaphore)
  • 바운디드세마포어(BoundedSemaphore)
더 보기 »asyncio의 동기화수단들

Opaque 리턴타입(Swift 5.1)

이 블로그의 다른 글에서 Swift의 타입 지우기에 대해서 살펴본 바 있습니다. 특정한 연관 타입에 의존하지 않는 프로토콜은 그 자체로 타입처럼 취급될 수 있지만, 연관 타입에 의존하는 프로토콜은 일종의 제네렉과 비슷하기 때문에 구체적인 타입처럼 사용될 수 없습니다. 타입 지우기(Type Erasure)는 특정한 프로토콜을 따르는 Any 타입을 만들어서 프로토콜을 채택한 실제 타입을 감추고 프로토콜의 기능적 잇점은 누릴 수 있게 하는 기법입니다. 하지만 타입 지우기를 사용하려면 특정 타입을 감싸는 별도의 타입을 만들어야 하고, 성능상으로도 오버헤드가 발생하는 제약이 있습니다. Swift는 프로토콜을 실제 구체적인 타입으로 사용할… 더 보기 »Opaque 리턴타입(Swift 5.1)

컨디션을 통한 스레드 동기화 예제

동시성을 다룰 때 여러 스레드가 하나의 자원에 순차적으로 접근하게 하거나, 반대로 특정한 시점에 동시에 작동하도록 하는 등의 상황에 제대로 대응할 수 있도록 락이나 이벤트와 같은 동기화 수단을 사용한다. 컨디션은 컨디션 락이라고도 하는데, 간단히 말하자면 이벤트와 락을 적절히 결합한 것이다. 락이나 R락을 사용하는 경우, 락을 획득한 구간의 코드는 항상 하나의 스레드만 진행할 수 있다. 락을 사용하는 중간에 다른 스레드로 사용 권한을 넘기려 한다면 현재 획득한 락을 해제하여 크리티컬 구간을 끝내야 한다. 그런데, 경우에 따라서는 atomic한 자원을 사용하려는 구간에서 해당 자원이 준비되지 않아 구간 내에서 일시적으로 실행을 중단하고 대기해야 하는 상황이 될 수 있다. 이런 경우에 컨디션 락을 사용한다.

컨디션은 락을 획득한 구간내에서 락을 일시적으로 반환하고 기다리는 역할을 가능하게 한다. 컨디션 락을 기다리는 스레드는 락을 해제하면서 블럭된다. 그러면 같은 컨디션락을 획득하려는 다른 스레드에게 제어권이 넘어가는데, 이러한 스레드 중에 해당 자원을 생성하는 역할을 담당하는 스레드가 있다면 이 생산자 스레드는 자원을 생성한 후, 이벤트와 비슷하게 대기 중인 다른 스레드를 깨워주게 된다. 생산자 스레드가 락을 반환하고 나면 중단됐다가 깨어난 스레드는 락을 다시 획득해서 해당 자원을 독점적으로 사용할 수 있게 된다.

중요한 것은 컨디션락은 락의 한 종류이기 때문에 대기중인 상태에서 깨어난 스레드는 그 즉시 실행을 재개하는 것이 아니라, 해당 락을 선점한 다른 스레드가 (이 스레드가 자신을 깨워주었을 것이다.) 락을 반환한 후 다시 그 락 객체를 획득해야 실행을 재개할 수 있게 된다는 것이다.

더 보기 »컨디션을 통한 스레드 동기화 예제