Python.use(better) #課題:組み込み型 list《source code》
‖記事一覧‖ Python.use(better)《Python3.1》
《余録》課題:組み込み型 list《source code》
《著》森こねこ、小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28
組み込み型と同等の機能を実現する課題を通して「OOP」の理解を深めます。
※ Python1.5 で作成した例題を、Python3.1 で再構成しました。
課題:ソースコード
#! /usr/bin/env python # coding: utf-8 ## ---------------------------------------- ## ## (C) Copyright 2000-2009, 小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部 ## ## ---------------------------------------- # ..+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 """ >>> None >>> ## ---------------------------------------- >>> None version: #1.0.51 """ ## ---------------------------------------- SPEC = "list" SPEC = "myList" ## ---------------------------------------- def step00(): """class myList(object)""" class myList(object): def __init__(self): #@: self.head = self.tail = Node() class Node(object): def __init__(self, item=None, next=None): #@: self.item = item self.next = next ## ---------------------------------------- def ex___init__(spec, local): #@: X = 's = %s(); s'%spec print(">>>",X) eval(compile(X,"","single"),globals(),local) ## ---------------------------------------- local = locals() #@: ex___init__(SPEC, local) ## ---------------------------------------- def step01(): """def __repr__(self)""" class myList(object): def __init__(self): self.head = self.tail = Node() def __repr__(self): #@: s = node = self.head.next while node: s.append(repr(node.item)) node = node.next return "[%s]"%", ".join(s) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- def ex___init__(spec, local): X = 's = %s(); s'%spec print_(X, local) ## ---------------------------------------- local = locals() ex___init__(SPEC, local) ## ---------------------------------------- def step02(): """def append(self, item)""" class myList(object): def __init__(self): self.head = self.tail = Node() def append(self, item): #@: node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): s = node = self.head.next while node: s.append(repr(node.item)) node = node.next return "[%s]"%", ".join(s) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- def ex___init__(spec, local): X = 's = %s(); s'%spec print_(X, local) ## ---------------------------------------- local = locals() #@: ex___init__(SPEC, local) ex_append(SPEC, local) ## ---------------------------------------- def step03(): """def __init__(self, sequence=None)""" class myList(object): def __init__(self, sequence=None): #@: self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): s = node = self.head.next while node: s.append(repr(node.item)) node = node.next return "[%s]"%", ".join(s) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", #@: for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step04(): """def __len__(self)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): s = node = self.head.next while node: s.append(repr(node.item)) node = node.next return "[%s]"%", ".join(s) def __len__(self): #@: n = 0 node = self.head.next while node: n += 1 node = node.next return n class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", "__len__", for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step05(): """def __iter__(self)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): #@: s = [] for e in self: s.append(repr(e)) return "[%s]"%", ".join(s) def __len__(self): #@: n = 0 for _ in self: n += 1 return n def __iter__(self): #@: node = self.head.next while node: yield node.item node = node.next class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", "__len__", for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step06(): """def __contains__(self, value)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): #@: return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): #@: return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): #@: for e in self: if e==value: return True return False #### def __contains__(self, value): #### for e in self: #### if e==value: return True #### else: #### return False class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", "__len__", "__contains__", for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step07(): """def count(self, value)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): #@: return any(e==value for e in self) def count(self, value): n = 0 for e in self: if e==value: n += 1 return n class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", "__len__", "__contains__", "count", for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step08(): """def index(self, value)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) #### def count(self, value): #### return reduce(lambda n,e: n+(e==value), self, 0) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: %s.index(x): x not in %s"%(s,s)) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = "__init__", "append", "__len__", "__contains__", "count", "index", for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step09(): """def __getitem__(self, key)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step10(): """def __setitem__(self, key, value)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step11(): """def insert(self, index, item)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 def insert(self, index, item): prev,node = self.head,self.head.next n = 0 while node: if n==index: prev.next = Node(item, prev.next) break prev,node = node,node.next n += 1 else: prev.next = Node(item, prev.next) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", "insert", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step12(): """def extend(self, iterable)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 def insert(self, index, item): prev,node = self.head,self.head.next n = 0 while node: if n==index: prev.next = Node(item, prev.next) break prev,node = node,node.next n += 1 else: prev.next = Node(item, prev.next) def extend(self, iterable): if not iterable: return prev,node = self.head,self.head.next while node: if node==self.tail: del self.tail.next new = myList(iterable) node.next = new.head.next self.tail = new.tail del new.head break prev,node = node,node.next class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", "insert", "extend", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step13(): """def __delitem__(self, key)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 def insert(self, index, item): prev,node = self.head,self.head.next n = 0 while node: if n==index: prev.next = Node(item, prev.next) break prev,node = node,node.next n += 1 else: prev.next = Node(item, prev.next) def extend(self, iterable): if not iterable: return prev,node = self.head,self.head.next while node: if node==self.tail: del self.tail.next new = myList(iterable) node.next = new.head.next self.tail = new.tail del new.head break prev,node = node,node.next def __delitem__(self, key): prev,node = self.head,self.head.next n = 0 while node: if n==key: prev.next = node.next; del node break prev,node = node,node.next n += 1 else: s = "IndexError: {0} assignment index out of range" name = self.__class__.__name__ raise IndexError(s.format(name)) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", "insert", "extend", "__delitem__", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step14(): """def remove(self, value)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = self.__class__.__name__ raise IndexError( "IndexError: %s index out of range"%s) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 def insert(self, index, item): prev,node = self.head,self.head.next n = 0 while node: if n==index: prev.next = Node(item, prev.next) break prev,node = node,node.next n += 1 else: prev.next = Node(item, prev.next) def extend(self, iterable): if not iterable: return prev,node = self.head,self.head.next while node: if node==self.tail: del self.tail.next new = myList(iterable) node.next = new.head.next self.tail = new.tail del new.head break prev,node = node,node.next def __delitem__(self, key): prev,node = self.head,self.head.next n = 0 while node: if n==key: prev.next = node.next; del node break prev,node = node,node.next n += 1 else: s = "IndexError: {0} assignment index out of range" name = self.__class__.__name__ raise IndexError(s.format(name)) def remove(self, value): prev,node = self.head,self.head.next while node: if node.item==value: prev.next = node.next; del node break prev,node = node,node.next else: s = "ValueError: {0}.remove(x): x not in {0}" name = self.__class__.__name__ raise ValueError(s.format(name)) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", "insert", "extend", "__delitem__", "remove", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- def step15(): """def pop(self)""" class myList(object): def __init__(self, sequence=None): self.head = self.tail = Node() if sequence: for e in sequence: self.append(e) def append(self, item): node = Node(item, self.tail.next) self.tail.next = node self.tail = node def __repr__(self): return "[%s]"%", ".join(repr(e) for e in self) def __len__(self): return sum(1 for _ in self) def __iter__(self): node = self.head.next while node: yield node.item node = node.next def __contains__(self, value): return any(e==value for e in self) def count(self, value): return sum(1 for e in self if e==value) def _name(self): return self.__class__.__name__ def index(self, value): for i,e in enumerate(self): if e==value: return i else: s = self.__class__.__name__ raise ValueError( "ValueError: {0}.index(x): x not in {0}".format(s)) def __getitem__(self, key): for i,e in enumerate(self): if i==key: return e else: s = "IndexError: {0} index out of range" n = self._name() raise IndexError(s.format(n)) def __setitem__(self, key, value): node,n = self.head.next,0 while node: if n==key: node.item = value; break node,n = node.next,n+1 def insert(self, index, item): prev,node = self.head,self.head.next n = 0 while node: if n==index: prev.next = Node(item, prev.next) break prev,node = node,node.next n += 1 else: prev.next = Node(item, prev.next) def extend(self, iterable): if not iterable: return prev,node = self.head,self.head.next while node: if node==self.tail: del self.tail.next new = myList(iterable) node.next = new.head.next self.tail = new.tail del new.head break prev,node = node,node.next def __delitem__(self, key): prev,node = self.head,self.head.next n = 0 while node: if n==key: prev.next = node.next; del node break prev,node = node,node.next n += 1 else: s = "IndexError: {0} assignment index out of range" n = self._name() raise IndexError(s.format(n)) def remove(self, value): prev,node = self.head,self.head.next while node: if node.item==value: prev.next = node.next; del node break prev,node = node,node.next else: s = "ValueError: {0}.remove(x): x not in {0}" n = self._name() raise ValueError(s.format(n)) ## ======================================== def pop(self): prev,node = self.head,self.head.next while node: if node==self.tail: value = node.item self.tail = prev prev.next = node.next del node return value prev,node = node,node.next else: s = "IndexError: pop from empty {0}" n = self._name() raise IndexError(s.format(n)) class Node(object): def __init__(self, item=None, next=None): self.item = item self.next = next ## ---------------------------------------- local = locals() tips = ( "__init__", "append", "__len__", "__contains__", "count", "index", "__getitem__", "__setitem__", "insert", "extend", "__delitem__", "remove", "pop", ) for e in tips: print(">>> #","-"*40,e) eval("ex_%s(SPEC, local)"%e) ## ---------------------------------------- ## ---------------------------------------- ## ---------------------------------------- def print_(source, local): #@: print(">>>",source) eval(compile(source,"","single"),globals(),local) ## ---------------------------------------- def ex___contains__(spec, local): X = 's = %s(); s, len(s)'%spec print_(X, local) for e in "A@": X = "{0!r} in s".format(e) print_(X, local) X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) for e in "A@": X = "{0!r} in s".format(e) print_(X, local) def ex___delitem__(spec, local): try: for i in range(4): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) X = 'del s[{0}]; s, len(s)'.format(i) print_(X, local) except IndexError as error: print(error) def ex___getitem__(spec, local): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) try: for i,e in enumerate(s): X = "s[{0!r}]".format(i) print_(X, local) except IndexError as error: print(error) def ex___init__(spec, local): #@: X = 's = %s(); s'%spec print_(X, local) X = 's = %s("ABC"); s'%spec print_(X, local) def ex___len__(spec, local): X = 's = %s(); s, len(s)'%spec print_(X, local) for e in "ABC": X = 's.append({0!r}); s, len(s)'.format(e) print_(X, local) def ex___setitem__(spec, local): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) try: for i,e in enumerate("XYZ"): X = "s[{0!r}] = {1!r}; s, len(s)".format(i,e) print_(X, local) except IndexError as error: print(error) def ex_append(spec, local): X = 's = %s(); s'%spec print_(X, local) for e in "ABC": X = 's.append({0!r}); s'.format(e) print_(X, local) def ex_count(spec, local): X = 's = %s("as happy as happy can be"); s'%spec print_(X, local) for e in "python": X = "s.count({0!r})".format(e) print_(X, local) def ex_extend(spec, local): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) for e in "","D","EF": X = 's.extend({0!r}); s, len(s)'.format(e) print_(X, local) def ex_index(spec, local): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) try: for e in "ABC@": X = "s.index({0!r})".format(e) print_(X, local) except ValueError as error: print(error) def ex_insert(spec, local): for i in range(4): X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) X = 's.insert({0},"_"); s, len(s)'.format(i) print_(X, local) def ex_pop(spec, local): X = 's = %s("ABC"); s'%spec print_(X, local) try: for i in range(4): X = 's.pop(), s' print_(X, local) except IndexError as error: print("IndexError:",error) def ex_remove(spec, local): try: for e in "ABC@": X = 's = %s("ABC"); s, len(s)'%spec print_(X, local) X = 's.remove({0!r}); s'.format(e) print_(X, local) except ValueError as error: print("ValueError:",error) ## ======================================== ## ======================================== s = "step" DIR = [e for e in dir() if e.startswith(s)] DIR = dict*1 DIR = list(DIR.items()); DIR.sort() def ex(): n = len(DIR)/10+1 for k,v in DIR: source = ''' x = eval("%%s.__doc__"%%v) print("%%%dd: %%s -- %%s"%%(k,v,x)) '''%n eval(compile(source,"","exec")) def do_all(): for k,v in DIR: print(">>> #","="*40,v) print(">>> #") eval("%s()"%v) def do(k=None): if k is None: ex(); return try: k,v = DIR[k] eval("%s()"%v) except IndexError: print("(x_x) too bad: #%s"%k) ## ---------------------------------------- from time import ctime def time_stamp(): print("="*24) print(ctime()) print("="*24) ## ---------------------------------------- from doctest import testmod from sys import argv if __name__=='__main__': print("%s #1.0a*0"%argv[0].split("/")[-1]) time_stamp() testmod() ## ========================================
↑TOP
*1:i,e) for i,e in enumerate(DIR