'devel'에 해당되는 글 2건

  1. 2008/02/27 Decorate-Sort-Undecorate by K-Dog
  2. 2007/06/02 Skype-Style Firewall Busting with Ruby and UDP by K-Dog

Decorate-Sort-Undecorate

devel 2008/02/27 00:52
 리스트에 숫자값이 들어있다고 치자.

(Language : python)
L = [2, 1, 6, 4, 0, 0, 7, 9, 0, 8]
L.sort()
#L 은 [0, 0, 0, 1, 2, 4, 6, 7, 8, 9]

음... 리스트 내장함수로 간단하게 소트가 되었다. 근데... L이 변경이 되었다.
자 어쨌든, 그럼 이번엔, 리스트 안에 튜플이 여러개 있다.
거기서 1번째 원소를 기준으로 소트를 한다고 치자.

(Language : python)
L = [(9, 2), (4, 6), (4, 6), (4, 5), (1, 8), (7, 3), (0, 5), (8, 1), (0, 4), (9, 4)]
L.sort(lambda x,y: cmp(x[1],y[1]))

뭐... 2003년 부터 요즘까지는 항상 이런 식으로 썼는데,
200만개의 딕셔너리를 조건으로 소팅을 할 일이 있었다.
cmp 가 최소한 .....휴 어쨌든 무지 많이 실행이 될 텐데, 그걸 여러 조건으로 실행해야 했다.

obj 의 name 으로 소트를 한다....
name 끼리 같으면 age 로 소트를 한다....
age 끼리 같으면 location 으로 소트를 한다....

뭐 이런식. "야 찌질아 퍼올 때 ORDER BY 를 달고 오면 되잖아~?" 글쎄.
만약에 데이터셋 하나를 표현하는 데 5k byte가 들고, 하루에 천만개씩의 데이터가 쌓인다고 가정하면,
반복되는 데이터를 key 값으로 빼내서 (ex: korea = 1, america = 2) 5k -> 1k 로 줄였다고 하면,
하루에 스토리지를 4,000 * 10,000,000 byte 만큼 아낄 수 있다는 뜻이다. 그래봤자 40기가네 음-0-
ㅎㅎ 요즘 같어서는 돈으로 처발라서 해결할 수 있는 양이다.

회사를 관두면 되지 않냐고? -0- 그럴싸~ 한데?
끙~ 이제 졸업해서 학생 신분도 아닌데... 휴.........비굴하군.
키보드 놓는 순간, 바로 비상 걸리는거다. 그렇다고 모아논 돈이 있나.

술도 암캐나 막 먹고 된장질도 좀 하고 전화비도 내야지.

음... 끙끙대다가 보스께 전수받은 방법이 있는데, Decorate - Sort - Undecorate 일명 DSU 라는 방법이다.
List Comprehension 을 두번 이용하는 뭐 대략 꽁수라고 할 수 있는데, 예를 들면.

(Language : python)
u1 = {'age':37, 'name':'lee-yong'}
u2 = {'age':27, 'name';'kdog'}
ulist = [u1,u2]

decoratedList = [(each['age'], each) for each in ulist]
decoratedList.sort()
newList = [each[-1] for each in decoratedList]

list 내장 함수인 sort() 를 그대로 이용할 수 있다. ulist 안의 객체는 dictionary 로, 어떤 순서로 들어가 있는지 보장할 수 없지만,
decorate 를 해서, age value 를 복사한 소팅 가능한 튜플의 리스트를 만들어서 소팅한 뒤,
다시 필요한 부분만 잘라내는 기법이다.

이걸 좀 더 응용해 볼 수 있는데,
DB에서 데이터셋을 가져온 뒤(이때는 ORDER BY를 이용했다고 쳐도), 각 객체를 가공해서 어딘가로 던져줘야 할 경우,
여러 키값을 decorate 할 수 있다. 위의 경우에는 (each['name'] ,each['age'], each) 를 이용.
이 방법의 장점은, (무지 많지만)
sort 되지 않은 원본 데이터셋의 list 를 유지할 수 있다는 것과,
파이썬 내장 함수를 이용해서 무지하게 빠르다는 점(정말 대단히 빠르다!!),
sortable 키가 여러 개여도 무난하게 돌려볼 수 있다는 점 등이다.

파이썬 쿡북 찾아보니까 역시나 관련 내용이 나오는데, 파이썬 2.4인가 2.5에서 부터는
sort된 리스트를 반환하는 내장 함수 sorted(aList) 가 추가되었는데,
DSU 방식과 비슷하게 이용할 수가 있다. (속도는 2.5배 정도 빠르다고 한다)


(Language : python)
import operator
def sort_by_attr(seq, attr):
    sorted_copy = sorted(seq, key=operator.attrgetter(attr))

혹은

def sort_by_attr(seq, attr):
    sorted_copy = sorted(seq, key=lambda x: x.get(attr))

아.. 회사에서 할 때는 위에 코드도 분명히 돌아갔는데, 집에 와서 하니까 이상한 에러를 뿜는다.
원래 람다스타일로 하기 때문에 어쨌든, 패스.
소트할 condition 이 n개일 때는 전통적인 DSU 기법을 쓰고, 1개일 때는 더 빠르고 더 간지나는 sorted 를.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by K-Dog

Skype-Style Firewall Busting with Ruby and UDP (Language : ruby)
  1. require 'socket'
  2.  
  3. remote_host = ARGV.first
  4.  
  5. # Punches hole in firewall
  6. punch = UDPSocket.new
  7. punch.bind('', 6311)
  8. punch.send('', 0, remote_host, 6311)
  9. punch.close
  10.  
  11. # Bind for receiving
  12. udp_in = UDPSocket.new
  13. udp_in.bind('0.0.0.0', 6311)
  14. puts "Binding to local port 6311"
  15.  
  16. loop do
  17.   # Receive data or time out after 5 seconds
  18.   if IO.select([udp_in], nil, nil, rand(4))
  19.         data = udp_in.recvfrom(1024)
  20.         remote_port = data[1][1]
  21.         remote_addr = data[1][3]
  22.         puts "Response from #{remote_addr}:#{remote_port} is #{data[0]}"
  23.   else
  24.         puts "Sending a little something.."
  25.         udp_in.send(Time.now.to_s, 0, remote_host, 6311)
  26.   end
  27. end

 스카이프는 양방이 NAT인 환경에서도 아주 잘 작동한다.
UDP 펀치홀 이라고 불리는 이 기법을 이용하면, NAT 상황에서도 문제없이 데이터를 주고 받을 수 있다.
맨 처음, 어떤 의미에서는 SYN 패킷에 해당하는 짭 UDP 패킷을 dest로 보낸다.
이때 NAT에서는 내부 src의 port 와 NAT port 를 매핑하고 dest와 port 정보를 캐싱한다.
그리고 나면 dest의 특정 port 에서 NAT port 로 오는 패킷은 NAT가 자동으로 src 의 port로 매핑하게 되는데
이것이 NAT이고 NAT가 작동하는 자연스러운 방식 그대로이다.

단지, dest에서 특정 port를 사용해서 src의 NAT의 port로 통신해야 한다는 것.
어쨌든 요로코롬 하면 몇 단계의 NAT가 있건 뭐가 중간에 있건 상관없다.

그럼 방화벽이 뚫렸나? 뚫렸다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by K-Dog