- 関数 def_to_cls(クラス名, テキスト)を作る
- 関数の第一引数にself(def hogehoge(self,~))
- 使用する関数にself.を追加(self.hogehoge())
- 関数たちのインデントを右にシフト
- 「class Hogehoge」とかクラス名を挿入。
サンプルコードは「『マッチ箱の脳』人工知能ジェネテックアルゴリズムをPythonでやってみた - 牌語備忘録 - pygo」を使用
わかりやすくするため関数の名前を一部変更(「def genetic_algorithm」を「def answer_display」に)
とりあえず変換スクリプト
#!/usr/bin/env python # *-# -*- coding: utf-8 -*- #def_to_cls.py import re def def_to_cls(cls_name, text): #def "name" to list r = re.compile("(?<=^def )\w+", re.M) def_lst = re.findall(r, text) #"def xxx" to "def xxx(self, " r = re.compile("(?<=^def )(\w+\()", re.M) result_txt = re.sub(r, r"\1self, ", text) #non "def xxx" lines "name" to "self.name" for def_name in def_lst: r = re.compile("(?<!def )(?<!\w)(%s)(?!\w)" % def_name) result_txt = re.sub(r, r"self.\1", result_txt) #indent shift right r = re.compile("^", re.M) result_txt = re.sub(r, " ", result_txt) print "\nclass %s:\n%s" % (cls_name, result_txt) #test if __name__ == '__main__': t = r""" def matchbox(num = 10, kind = 1, to_kind = 3): return [random.randint(kind, to_kind) for n in range(num)] def amount_of_box(amount = 10): return [matchbox() for count in range(amount)] aa_matchbox matchbox_bb """ def_to_cls("ClsName", t)
実行してみる
(サンプルコードから一部抜粋したもの)
>>> class ClsName: def matchbox(self, num = 10, kind = 1, to_kind = 3): return [random.randint(kind, to_kind) for n in range(num)] def amount_of_box(self, amount = 10): return [self.matchbox() for count in range(amount)] aa_matchbox matchbox_bb
サンプルコードを変換してみた
- 頭に「#!/usr/bin/env python 〜 import random」
- 変換したコード
- 最後に少々書き換えた「if __name__ == 〜」
#!/usr/bin/env python # *-# -*- coding: utf-8 -*- # Genetic Algorithm # ga2.py import random class GeneticAlgorithm: def matchbox(self, num = 10, kind = 1, to_kind = 3): return [random.randint(kind, to_kind) for n in range(num)] def amount_of_box(self, amount = 10): return [self.matchbox() for count in range(amount)] def del_duplication(self, box_seq): set_tu = set(map(tuple,box_seq)) set_lst = map(list, set_tu) n = len(set_lst) if n < 10: add_box = [self.matchbox() for i in range(10 - n)] return set_lst + add_box return box_seq def rating(self, ans, box_seq): point_lst = [] for box in box_seq: point = 0 for a, b in zip(ans, box): if a == b: point += 10 point_lst.append([point, box]) return sorted(point_lst, reverse = True) def parent(self, rate_seq, choice = 2): return [rate_seq[0][1], rate_seq[1][1]] def mutation(self, kids_seq): p = random.randint(0, len(kids_seq)) if p < 10: change = lambda x:x + 1 if x < 3 else x - 2 kids_seq[p] = change(kids_seq[p]) return kids_seq def recombination(self, parent_seq): crossing = random.randint(0, 10) kid_a = parent_seq[1][:crossing] + parent_seq[0][crossing:] kid_b = parent_seq[0][:crossing] + parent_seq[1][crossing:] return [self.mutation(kid_a), self.mutation(kid_b)] def answer_display(self, ans, count = 200): log = [] all_box = self.amount_of_box() for i in range(count): dd_box = self.del_duplication(all_box) rate_seq = self.rating(ans, dd_box)[:] log.append("Generation: %d" % (i + 1)) log.append("\n".join(["%d %s" % (n,l) for n,l in rate_seq])) all_box = [l for n,l in rate_seq] parent_seq = self.parent(rate_seq) top = all_box[:2] tail = all_box[2:-2] all_box = self.recombination(parent_seq) + tail + top if rate_seq[0][0] == 100: break else: log.append("break: over %d Generation!" % count) return "\n".join(log) if __name__ == "__main__": answer = [3, 1, 2, 2, 2, 3, 1, 3, 2, 1] ga = GeneticAlgorithm() print ga.answer_display(answer)
実行して問題なければ、できあがり(゚Д゚)b
簡単に済ますはずが、ややこしくなった(つдT)