iterable

enumerate()를 쓰다보면 어쩔 수 없이 iterableiterator라는 개념을 학습해야 합니다. iterable이 내용물을 차례대로 반환할 수 있는 객체라면 iteratornext()로 데이터를 순차적으로 호출할 수 있는 객체를 가리킵니다. 생긴 건 비슷하지만 둘은 완전히 별개의 대상으로 생각하는 게 차라리 속 편합니다.

iterable

Iterable

An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict and file and objects of any classes you define with an iter() or getitem() method. Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), …). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.

via python glossary

liststr 같은 객체는 순서대로 그 내용물을 꺼내어 쓸 수 있습니다. range()의 경우도 마찬가지이고 dict 같은 경우도 순서는 없지만 하나하나 꺼내어 쓸 수 있다는 점에서 iterable이라고 불립니다.zip()이나 map() 같은 경우도 마찬가집니다.

iterator

Iterator

An object representing a stream of data. Repeated calls to the iterator’s next() method return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. Iterators are required to have an iter() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container.

via python glossary

next() 메소드로 다음 항목을 불러올 수 있는 객체를 iterator라고 합니다. 마지막 데이터에서 다음 항목을 불러올 수 없을 경우 StopIteration exception을 발생시키며 이후 시도되는 어떠한 next() 메소드에 대하여도 StopIteration exception을 발생시키게 됩니다. 모든 iterator 객체는 __iter__() 함수를 내장해야 하므로 모든 iterator 객체는 iterable 합니다.

다만 list와 같은 컨테이너 객체는 for 반복문이나 iter() 함수에 넘길 때마다 새로운 iterator 객체를 발생시키므로 매번 iterator 객체를 새로 생성할 필요가 없습니다. 이외의 경우에는 iterator 객체를 새로 생성하지 않는 한 빈 컨테이너에 대해서 반복문을 실행하는 것과 같은 효과를 내게 됩니다.


enumerate()

파이선을 쓰다보면 종종 만나게 되는 기본 함수 중에 하나가 enumerate() 입니다. 그럼에도 불구하고 다른 언어에서는 자주 보이지 않아서 낯선 함수이기도 하죠.

코드

def enumerate(sequence, start=0)
	n = start
	for elem in sequence:
		yield n, elem
		n += 1

enumerate() 함수는 sequence 안의 element를 받아서 각 인자의 인덱스 값과 내용을 튜플 값으로 내보내도록 되어 있는 것을 알 수 있습니다.

용례

튜플 형태로 값이 반환되며 보통 for 문과 함께 사용됩니다.

for i, item in enumerate(['apple','banana','tomato'])
	print(i,item)
# 0 apple
# 1 banana
# 2 tomato

개인적으로는 리스트 안에서 찾는 값의 위치를 알고 싶을 때 요긴하게 썼습니다.

[i for i, x in enumerate([1,2,3,4,3,2]) if x == 2] # [1, 5]

유의사항

enumerate()는 어찌됐든 반복문이기 때문에 입력하는 시퀀스는 iterable이어야 합니다.


alfred-2do 1.1 뒷이야기

alfred-2do는 2do에서 할 일 입력할 때 자연어 입력에 가깝게 만들어보자는 의도로 만들어졌습니다. 때문에 맨 앞에 시작 키워드인 2d와 할 일 내용을 맨 앞에 순서대로 놓는 것 외에는 생각나는대로 입력할 수 있도록 하고 싶었죠.

입력 방식

제 Alfred 사용 환경은 영어 입력으로 강제 전환하도록 맞추어져 있기 때문에 .split() 함수를 써서 전치사들을 기준으로 입력을 분해하도록 했습니다. on을 기준으로 뒤에 붙는 건 날짜, at 뒤에 붙는 건 시간, in 뒤에 붙는 건 장소 같은 식이죠.

여기에는 근본적으로 한 가지 문제가 있는데 이런 전치사들의 활용이 때때로 바뀐다는 점입니다. 예를 들어 at은 시간을 나타내기도 하지만 위치를 나타낼 때에도 쓰이고 in도 장소 뿐만 아니라 시간을 나라내도록 기능할 수 있죠. 그렇기 때문에 사실은 이런 접근방식은 편법이고 입력하는 값의 형식을 기준으로 판단하는 게 가장 바람직하겠습니다만 거기까지는 제 능력 밖에더군요.

1.1

v 1.1에서 가장 크게 바뀐 점은 입력을 받는 방식입니다. 기존에는 script filter를 써서 입력과 동시에 처리를 하도록 하는 방식이었습니다. 실시간으로 결과를 볼 수 있다는 점에서는 분명한 강점이 있지만 입력을 마치고 스크립트가 입력값 파싱을 끝낼 때까지 종료를 할 수 없다는 사용상의 치명적인 단점이 있었죠. 만약 파싱이 끝나기 전에 엔터를 치게 되면 아직 파싱이 안 된 부분의 데이터는 소실되어 입력되게 됩니다. 때문에 편법으로 할 일을 입력하고 약간의 텀(0.7초에서 1초 가량)을 두고 엔터를 치도록 했었습니다.

알프레드를 이용해서 할 일을 입력하는 건 바로 그 자리에서 할 일을 쉽게 추가하자는 취진데 그 다음에 1초를 기다리는 것은 기본적으로 방향성이 글러먹었따고 생각했습니다. 능력이 모자라 해결하는 데 시간이 좀 걸리긴 했지만요.

v 1.1에서는 script filter 대신 키워드 방식으로 2d 입력 외에 뒤에 따라오는 내용은 argument로 받아서 다음 element로 넘기도록 했습니다. 이런 경우 실시간으로 확인은 불가능하지만 입력 후에 텀을 두어야 하는 단점은 없게 됩니다. 빠르게 할 일을 작성하는 것에 초점을 두는 alfred-2do의 취지와 이 쪽이 더 어울린다고 생각해서 워크플로우를 변형하게 되었습니다. 구 버전들은 깃헙에 올라가 있으니 내려받아서 사용하시면 됩니다.

기타

워크플로우 변경 중에 hylo님이 몇 가지 제안을 해주셨습니다.

1. 미리 입력해 둔 리스트 명 자동 완성

2. next week 키워드

3. 할 일 입력 전에 입력 내용 검토.

이 중 3. 항목은 script filter에 기반하는 기능이라 배제하였습니다. 1. 항목 또한 전체 리스트를 가져오는 것이 아닌1 미리 입력해 둔 리스트로만 자동 완성이 가능하기 때문에 일단은 적용하지 않았습니다. 2. 항목은 일요일을 기점으로 해당 요일을 넘으면2 다음 주로 넘기도록 설계했기 때문에 따로 옵션을 두지는 않았습니다만 생각해보니 필요한 경우도 종종 있을 것 같아서 넣어야 할 것 같네요.

할 일 내용에 non-ascii 캐릭터가 있는 경우에 인코딩을 하도록 pr해주셨는데 저같은 경우는 그렇게 하니 입력한 할 일 사이에 whitespace가 전부 %20로 인코딩되어 버리는 일이 있어서 도로 뺐습니다.3 혹여나 알프레드에서 한글로 입력하시는 분 중에 제 워크플로우거 작동하지 않는다면 hylo님의 워크플로우를 써보시는 것도 좋을 듯 합니다.

이후

사실 이제 제 능력으로는 여기에 더 추가할 수 있는 게 없을 것 같습니다. 각 구분자 뒤에 오는 형식을 구분해서 구분자를 할 일 내용에 추가시켜야 할 지 argument로 분류해야 할 지 정도가 마지막 업데이트가 될 것 같네요.

  1. 해당 기능은 2Do에서 애초에 지원하지 않는 기능이어서 구현하기 위해서는 이 방법이 거의 유일한 방법입니다. 

  2. 예를 들어 금요일에 on thu 하면 자동으로 다음 주로 입력하는 식입니다. 지난 일을 입력하는 경우는 없을 테니까요. 

  3. 예를 들어 태그에 macbook air라고 치면 macbook%20air라고 태그가 입력되어버리는 식인거죠 


곰곰이

본인도 한국어를 모국어로 하는 화자이지만 참 불만스러운게 사동사를 만들 때에는 접사 이히리기 를 붙인다고 해놓고서 어느 경우에 어느 접사가 붙는지 명확하게 규정해놓은 게 없다는 점입니다. 1 그냥 밑도끝도 없이 표준어가 아니다2 라고만 답변하고 있죠. 이러니 사람들이 맨날 붙히다 라고 적지. 그냥 확실히 -히- 가 붙는 게 아니면 이로 적고 있긴 합니다만, 이것도 정확한 건 아니죠.

그러다보니 곰곰이 였는지 곰곰히 였는지 헷갈리는 겁니다. 찾아보니 곰곰히는 아예 사동 접사 -히- 와는 관련이 없고 부사의 끝음절이 분명히 ‘이’로만 나는 것은 ‘-이’로 적고, 에 해당하여 곰곰이 라고 합니다.

좀 더 찾아보니 깨끗이도 히 대신 이로 적는다고 합니다. 딱히 구별하는 기준은 없다고.


라즈비안에 가상 키보드 설치하기

원래는 스마트 미러를 만들기 위해서 라즈베리 파이3를 구입했었습니다만, 프로젝트는 잠정적으로 중단되고 방구석에서 썩어가는 신세가 되어버렸습니다.

자주 쓰는 녀석이 아니기 때문에 별도로 키보드를 배분하기도 그렇고1 Synergy를 쓰자니 v2부터는 굉장히 불안정해서 연결이 되다말다 하더군요. 그렇다고 TeamViewer를 쓰기는 과도한 것 같고.

찾아보니 간단하게 가상 키보드를 설치할 수 있는 방법이 있었습니다.

1. sudo apt-get update;sudo apt-get upgrade;로 리포를 업데이트합니다. 필수는 아니지만 권장항목입니다.

2. sudo apt-get install matchbox-keyboard를 입력하여 패키지를 설치합니다

3. sudo reboot 를 입력하여 재부팅합니다.

이후 Menu » Accessories » Keyboard 항목을 클릭하여 가상 키보드를 사용할 수 있습니다. Keyboard 항목이 나타나지 않을 경우 Menu » Preferences » Main Menu Editor 에서 Keyboard 항목을 활성화할 수 있습니다.


via

  1. 심지어 Plum84를 물려주니 전원부족으로 부팅자체가 안 됩니다 ㅎ