Twitter の JSON をテキストに変換

検索結果の json をテキストに変換した. きっとまた使うので残しておく.

import json
from glob import glob
from datetime import datetime, timedelta

txtconv_table = {
    '&lt;': '<',
    '&gt;': '>',
    '&quot;': '"',
    '\r': '',
    '\n': ' '
}

def dtconv(s):
    return (datetime.strptime(s, '%a, %d %b %Y %H:%M:%S +0000') + timedelta(hours = 9)).strftime('%Y-%m-%d %H:%M')

def txtconv(s):
    for k in txtconv_table:
        s = s.replace(k, txtconv_table[k])
    return s.replace('&amp;', '&')

result = []
for filename in glob('search*.json'):
    with open(filename) as f:
        result += ['%s (@%s) %s' % (dtconv(t['created_at']), t['from_user'], txtconv(t['text'])) for t in json.load(f)['results']]

print '\n'.join(sorted(result)).encode('utf-8')

無理やり with 対応

追記: contextlib.closing を使えばよかったのこと(^^;
GzipFile が標準ライブラリのくせに with に対応していなくてカッとなってやった. つか、close メソッド呼べばいいだけのクラスって多いと思うんだけど・・・.

import gzip
from new import instancemethod

def with_support(obj):
    obj.__enter__ = instancemethod(lambda self: self, obj, obj.__class__)
    obj.__exit__ = instancemethod(lambda self, type, value, traceback: self.close(), obj, obj.__class__)
    return obj

with with_support(gzip.open('hello.txt.gz', 'w')) as f:
    f.write('Hello World!')

って、Python 2.6 のマニュアルに new は deprecated だから types を使えーと書いてあるではないか. じゃあ、ということで.

import gzip
from types import MethodType

def with_support(obj):
    obj.__enter__ = MethodType(lambda self: self, obj, obj.__class__)
    obj.__exit__ = MethodType(lambda self, type, value, traceback: self.close(), obj, obj.__class__)
    return obj

with with_support(gzip.open('hello.txt.gz', 'w')) as f:
    f.write('Hello World!')

Python で png 画像を自力で生成する(パレット編)

特に何かが難しかったりするわけでもないですが.

from sys import stdout
from struct import pack
from zlib import crc32, compress

def chunk(type, data):
  return pack('!I4s%dsi' % len(data), len(data), type, data, crc32(type + data))

width, height = 100, 20
depth, color_type = 8, 3

palette_data = pack("%dB" % (width * 3), *sum([[i * 255 / (width - 1), 0, 0] for i in range(width)], []))
img_data = pack("%dB" % (width + 1), *([0] + range(width))) * height

stdout.write('\x89PNG\r\n\x1a\n')
stdout.write(chunk('IHDR', pack("!IIBBBBB", width, height, depth, color_type, 0, 0, 0)))
stdout.write(chunk("PLTE", palette_data))
stdout.write(chunk("IDAT", compress(img_data, 9)))
stdout.write(chunk('IEND', ''))

Nimrod で空ウインドウを出してみた

force7.de で、空ウインドウを出してみた.

import
  windows

const
  NULL = 0

proc wndProc(hWnd: HWND, msg: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT{.stdcall.} =
  case msg
  of WM_DESTROY:
    PostQuitMessage(0)
  else:
    return DefWindowProc(hWnd, msg, wParam, lParam)
  return 0

proc winMain(hinst: HINST, hinstPrev: HINST, lpszCmdLine: LPSTR, nCmdShow: int): int{.stdcall.} = 
  const
    szClassName = "WCN_HELLO_WINDOWS"

  var
    wndClass: WNDCLASS
    hWnd: HWND
    msg: MSG

  wndClass.style = CS_HREDRAW or CS_VREDRAW
  wndClass.lpfnWndProc = wndProc
  wndClass.cbClsExtra = 0
  wndClass.cbWndExtra = 0
  wndClass.hInstance = hInst
  wndClass.hIcon = NULL
  wndClass.hCursor = LoadCursor(0, IDC_ARROW())
  wndClass.hbrBackground = GetStockObject(WHITE_BRUSH)
  wndClass.lpszMenuName = nil
  wndClass.lpszClassName = szClassName

  if RegisterClass(wndClass) == 0:
    return 0

  hWnd = CreateWindow(
    szClassName,
    "Hello Windows!",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    NULL,
    NULL,
    hInst,
    nil)

  discard ShowWindow(hWnd, nCmdShow)
  discard UpdateWindow(hWnd)
  while GetMessage(msg, NULL, 0, 0) != 0:
    discard TranslateMessage(msg)
    discard DispatchMessage(msg)
  return msg.wParam

var
  hInst: HINST
  si: STARTUPINFO
  nCmdShow: int

hInst = GetModuleHandle(nil)
si.dwFlags = 0
GetStartupInfo(si)
nCmdShow = if (si.dwFlags and STARTF_USESHOWWINDOW) != 0: int(si.wShowWindow) else: SW_SHOWDEFAULT

discard winMain(hinst, 0, "", nCmdShow)

Nimrod 0.8.8 で試したところ、OS ビルトインの DLL にしか依存しない実行ファイルが 96.3KB (strip で 69.0KB) で生成されたので、なかなか良い感じ. が、余りにも情報がなさすぎてアレですw

Python で png 画像を自力で生成する

Ruby で png 画像を自力で生成する - まめめもPython に移植しただけw

# -*- coding: utf-8 -*-
from sys import stdout
from struct import pack
from zlib import crc32, compress

width, height = 100, 20
depth, color_type = 8, 2

# グラデーションのベタデータ
line = [[x * 255 / width, 0, 0] for x in range(width)]
raw_data = [line] * height

# チャンクのバイト列生成関数
def chunk(type, data):
  return pack('!I4s%dsi' % len(data), len(data), type, data, crc32(type + data))

# ファイルシグニチャ
stdout.write('\x89PNG\r\n\x1a\n')

# ヘッダ
stdout.write(chunk('IHDR', pack("!IIBBBBB", width, height, depth, color_type, 0, 0, 0)))

# 画像データ
img_data = ''.join(pack("%dB" % (width * 3 + 1), *sum([[0]] + line, [])) for line in raw_data)
stdout.write(chunk("IDAT", compress(img_data)))

# 終端
stdout.write(chunk('IEND', ''))

* が使える Ruby の pack が羨ましいです><

# -*- coding: utf-8 -*-

# http://www.physics.sfasu.edu/astro/color/spectra.html
def wavelength_to_rgb(n):
  if   n < 380: rgb = [0.0               , 0.0               , 0.0               ]
  elif n < 440: rgb = [(440.0 - n) / 60.0, 0.0               , 1.0               ]
  elif n < 490: rgb = [0.0               , (n - 440.0) / 50.0, 1.0               ]
  elif n < 510: rgb = [0.0               , 1.0               , (510.0 - n) / 20.0]
  elif n < 580: rgb = [(n - 510.0) / 70.0, 1.0               , 0.0               ]
  elif n < 645: rgb = [1.0               , (645 - n) / 65.0  , 0.0               ]
  elif n < 780: rgb = [1.0               , 0.0               , 0.0               ]
  else:         rgb = [0.0               , 0.0               , 0.0               ]

  if   n < 380: factor = 0.0
  elif n < 420: factor = 0.3 + 0.7 * (n - 380.0) / 40.0
  elif n < 700: factor = 1.0
  elif n < 780: factor = 0.3 + 0.7 * (780.0 - n) / 80.0
  else:         factor = 0.0

  return map(lambda c: 0 if c == 0.0 else 255 * ((c * factor) ** 0.8), rgb)

# generate png

from sys import stdout
from struct import pack
from zlib import crc32, compress

width, height = 100, 20
depth, color_type = 8, 2

line = map(lambda x: wavelength_to_rgb(380 + x * 400 / width), range(width))
raw_data = [line] * height

def chunk(type, data):
  return pack('!I4s%dsi' % len(data), len(data), type, data, crc32(type + data))

stdout.write('\x89PNG\r\n\x1a\n')
stdout.write(chunk('IHDR', pack("!IIBBBBB", width, height, depth, color_type, 0, 0, 0)))
img_data = ''.join(pack("%dB" % (width * 3 + 1), *sum([[0]] + line, [])) for line in raw_data)
stdout.write(chunk("IDAT", compress(img_data)))
stdout.write(chunk('IEND', ''))

さすがに芸が無いかなと思ったので、Sub フィルタを突っ込んでみたw

# -*- coding: utf-8 -*-
from sys import stdout
from struct import pack
from zlib import crc32, compress

width, height = 100, 20
depth, color_type = 8, 2

line = [[x * 255 / width, 0, 0] for x in range(width)]
# Sub フィルタを適用
for i in range(width - 1, 0, -1):
  line[i][0] = (line[i][0] - line[i - 1][0] + 255) % 255
raw_data = [line] * height

def chunk(type, data):
  return pack('!I4s%dsi' % len(data), len(data), type, data, crc32(type + data))

stdout.write('\x89PNG\r\n\x1a\n')
stdout.write(chunk('IHDR', pack("!IIBBBBB", width, height, depth, color_type, 0, 0, 0)))
img_data = ''.join(pack("%dB" % (width * 3 + 1), *sum([[1]] + line, [])) for line in raw_data)
stdout.write(chunk("IDAT", compress(img_data)))
stdout.write(chunk('IEND', ''))

ffftp.ini パスワードデコーダ

諸事情で書いたので. 入力は標準入力、出力は標準出力.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sys import stdin, stdout

def decode(s):
    result = ''
    t = [ord(c) for c in s] + [0]
    i = 0
    while i < len(s):
        rnd = (t[i] >> 4) & 0x3
        ch = (t[i] & 0xf) | ((t[i + 1] & 0xf) << 4)
        ch <<= 8
        if (t[i] & 0x1) != 0:
            i += 1
        i += 2
        ch >>= rnd
        ch = (ch & 0xff) | ((ch >> 8) & 0xff)
        result += chr(ch)
    return result

def main():
    for s in stdin:
        s = s.rstrip('\r\n')
        if s.startswith('HostAdrs'):
            stdout.write('\n[%s]\n' % (s.split('=')[1],))
        elif s.startswith('UserName'):
            stdout.write('ID: %s\n' % (s.split('=')[1],))
        elif s.startswith('Password'):
            stdout.write('PW: %s\n' % (decode(s.split('=')[1].replace('\\\\', '\\')),))

if __name__ == "__main__":
    main()