やたーPythonの無名関数で再帰出来たよー(^o^)ノ
import sys, new for i in xrange(10): print i, (lambda n: n if n <= 1 else new.function(sys._getframe().f_code, globals(), None, None, None)(n - 1) + new.function(sys._getframe().f_code, globals(), None, None, None)(n - 2))(i)
実行結果:
0 0 1 1 2 1 3 2 4 3 5 5 6 8 7 13 8 21 9 34
ちゃんと動いてますね。
sys._getframe().f_codeに引数を渡してevalする方法が見つからなかったのでfunctionオブジェクトを作って呼んでいます。
もっと良い方法があれば教えてくださいヽ(´ー`)丿
プロセスを一時停止/再開するプログラムをPythonで書いた。標準ライブラリのみで行いたかったのでpywin32などサードパーティー製のライブラリは使用していない。
プロセスを一時停止/再開させる(ドキュメント化された)Windows APIは残念ながら存在しないので、SuspendThreadとResumeThreadにより一時停止/再開させたいプロセスが所有する全てのスレッドを一時停止/再開させるという手法を採っている。また、SuspendThreadとResumeThreadのサスペンドカウントを増減させ、0になったら再開するという仕様により、例えばこのプログラムを使用して3回プロセスを一時停止させたならば、再開するためには3回プロセスを再開させねばならない。
psusres.py
で、何もオプションを指定しなければプロセスIDとプロセスの名前の一覧を表示し、
psusres -s PID
で、PIDで指定されたプロセスの一時停止、
psusres -r PID
で指定されたプロセスの再開をする。
ソースコードを以下に示す。ここで使用しているWindows APIのラッパーは少し長いのでgithubに置いた。
#!/usr/bin/env python # coding: utf-8 # psusres: a tool to suspend/resume a process from __future__ import print_function from optparse import OptionParser from winapi import * def PauseResumeThreadList(dwOwnerPID, bSuspendThread): hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwOwnerPID) if hThreadSnap == INVALID_HANDLE_VALUE: return te32 = Thread32First(hThreadSnap) if te32: while True: if te32.th32OwnerProcessID == dwOwnerPID: hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID) if bSuspendThread: print("Suspending Thread 0x{0:04X}".format(te32.th32ThreadID)) SuspendThread(hThread) else: print("Resuming Thread 0x{0:04X}".format(te32.th32ThreadID)) ResumeThread(hThread) CloseHandle(hThread) te32 = Thread32Next(hThreadSnap) if not te32: break CloseHandle(hThreadSnap) def ProcessList(): hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) pe32 = Process32First(hProcessSnap) if (pe32): while True: print('PID\t', pe32.th32ProcessID, '\t', pe32.szExeFile, sep='') pe32 = Process32Next(hProcessSnap) if not pe32: break CloseHandle(hProcessSnap) def main(): usage = 'usage: %prog [options] PID' parser = OptionParser(usage) parser.add_option('-s', '--suspend', action='store_true', dest='suspend', help='suspend a specified process') parser.add_option('-r', '--resume', action='store_false', dest='suspend', help='resume a specified process') options, args = parser.parse_args() if options.suspend is None: parser.print_help() print() ProcessList() elif len(args) == 0: parser.print_help() else: try: pid = int(args[0]) except: print("Invalid PID number:", args[0]) else: PauseResumeThreadList(pid, options.suspend) return if __name__ == '__main__': main()
ちょっと必要になったのでDelphi互換の擬似乱数を生成するプログラムを書いた。
Linear congruential generator - Wikipedia, the free encyclopediaを参考にした。
class DelphiRandom: def __init__(self, seed=0): self.seed = seed def __call__(self, max): self.seed = (self.seed * 134775813 + 1) & 0xFFFFFFFF result = (self.seed * max) & 0xFFFFFFFFFFFFFFFF return result >> 32
再帰下降構文解析を用いて数式を評価するプログラムを書いた。四則演算と括弧の使用ができる。演算子の優先順位は通常通り。以下にソースコードを示す。
ExpressionEvaluaterはクラスではなく関数にしても良いかもしれない。
#!/usr/bin/env python # coding: utf-8 # expression evaluater import re class Queue(list): def get(self): if len(self) == 0: raise IndexError('get from empty list') else: temp = self[0] self[:1] = [] return temp def put(self, value): list.append(self, value) class ExpressionLexer(): def __init__(self, expr): self.cur = None self.queue = Queue() callback = lambda scanner, token: self.queue.put(token) scanner = re.Scanner([ (r'\+|\-|\*|\/', callback), (r'[0-9]+(\.[0-9]+)?', callback), (r'\(|\)', callback), (r'\s+', None), ]) scanner.scan(expr) def next(self): try: self.cur = self.queue.get() except IndexError: self.cur = None class ExpressionEvaluater(): def eval(self, expr): self.lexer = ExpressionLexer(expr) self.lexer.next() return self.expression() def number(self): sign = '+' if self.lexer.cur == '-': sign = self.lexer.cur self.lexer.next() num = float(self.lexer.cur) self.lexer.next() if sign == '-': return -num else: return num def factor(self): if self.lexer.cur != '(': return self.number() self.lexer.next() x = self.expression() if self.lexer.cur != ')': raise Exception() self.lexer.next() return x def term(self): x = self.factor() while True: if self.lexer.cur == '*': self.lexer.next() x *= self.factor() elif self.lexer.cur == '/': self.lexer.next() y = self.factor() if y == 0: raise Exception() x /= y else: break return x def expression(self): x = self.term() while True: if self.lexer.cur == '+': self.lexer.next() x += self.term() elif self.lexer.cur == '-': self.lexer.next() x -= self.term() else: break return x def eval_expr(expr): return ExpressionEvaluater().eval(expr) def main(): import sys def puts(*text): text = ' '.join(map(str, text)) sys.stdout.write(text) sys.stdout.write('\n') sys.stdout.flush() def readline(): sys.stdout.write('>>> ') sys.stdout.flush() return sys.stdin.readline() for line in iter(readline, ''): t = line.rstrip() if t != '': try: puts(eval_expr(t)) except: puts('An error has occured.') if __name__ == '__main__': main()