継続は力にゃりん。毎日続けることができるのか? とばし * filecmp 大半 * イテレータ型 * a.copy() * MatchObject オブジェクト expand(template) * 6.9.6 tzinfo オブジェクト * 6.1.2 ファイルオブジェクトの生成 * 6.1.3 ファイル記述子の操作 積み残し * オブジェクト指向な機能:継承。親のメソッドを呼ぶ。super 使用 進捗 * 2007-11-01 中断 * 2007-10-14 xml.parsers.expat (途中) * 2007-10-03 HTMLParser * 2007-09-24 shutil * 2007-09-14 string.Template * 2007-08-30 itertools * 2007-07-30 operator * 2007-07-28 cStringIO * 2007-07-15 StringIO * 2007-05-06 プログラミング言語 Cアンサー・ブック * 2007-04-05 unittest * 2007-03-09 types * 2007-02-21 zipfile * 2007-01-25 tarfile * 2007-01-02 日本語の扱い * 2006-11-20 optparse * 2006-10-25 set(集合)型 * 2006-09-05 オブジェクト指向な機能 * 2006-08-13 mhlib * 2006-07-29 csv * 2006-06-26 sys * 2006-06-11 urllib * 2006-05-20 shlex * 2006-05-15 放浪 * 2006-04-29 platform * 2006-04-10 Ruby との比較 正規表現 関係(String, Enumerable) * 2006-04-02 Ruby との比較 Dir * 2006-02-19 Ruby との比較 File * 2006-01-20 Ruby との比較 ハッシュ * 2006-01-09 Ruby との比較 配列(Enumerable) * 2005-11-25 Ruby との比較 配列 * 2005-10-11 Ruby との比較 文字列 * 2005-09-20 Ruby との比較 数 * 2005-09-18 Ruby との比較 Bool * 2005-08-26 勝手に例題 フィルタ編 * 2005-04-28 チュートリアル * 2005-04-23 filecmp * 2005-04-22 pydoc * 2005-04-21 __future__ * 2005-04-20 __main__ * 2005-04-19 __builtin__ * 2005-04-18 dl * 2005-03-29 difflib * 2005-03-21 zlib * 2005-03-20 getpass * 2005-03-14 urlparse * 2005-03-13 fnmatch * 2005-03-12 glob * 2005-03-08 getopt * 2005-02-01 os * 2005-01-04 os.path * 2004-12-25 fileinput * 2004-12-02 Set * 2004-11-22 calendar * 2004-10-26 datetime * 2004-10-15 textwrap * 2004-10-05 random * 2004-09-17 math * 2004-08-18 re * 2004-07-18 string !2007-10-31 Wed >>> import xml.parsers.expat >>> def processing_instruction(target, data): ... print 'ProcessingInstruction:', target, data ... >>> p = xml.parsers.expat.ParserCreate() >>> p.ProcessingInstructionHandler = processing_instruction >>> p.Parse(""" ... Text goes here ... More text ... """) 1 >>> p = xml.parsers.expat.ParserCreate() >>> p.ProcessingInstructionHandler = processing_instruction >>> p.Parse(""" ... ... ... ... """) 1 ? !2007-10-30 Tue >>> import xml.parsers.expat >>> import xml.parsers.expat >>> def attlistdecl(elname, attname, type, default, required): ... print 'AttlistDecl: ', elname ... print 'AttlistDecl: ', attname ... print 'AttlistDecl: ', type ... print 'AttlistDecl: ', default ... print 'AttlistDecl: ', required ... >>> p = xml.parsers.expat.ParserCreate() >>> p.AttlistDeclHandler = attlistdecl >>> p.Parse(""" ... Text goes here ... More text ... """) 1 ? !2007-10-29 Mon >>> import xml.parsers.expat >>> def element_decl(name, model): ... print 'Element Decl:', name, model ... >>> p = xml.parsers.expat.ParserCreate() >>> p.ElementDeclHandler = element_decl >>> p.Parse(""" ... Text goes here ... More text ... """) 1 >>> import xml.parsers.expat >>> def element_decl(name, model): ... print 'Element Decl:', name, model ... >>> p = xml.parsers.expat.ParserCreate() >>> p.ElementDeclHandler = element_decl >>> p.Parse(""" ... ... ... ... """) 1 ? !2007-10-28 Sun >>> import xml.parsers.expat >>> def end_doctype(): ... print 'End DocType' ... >>> p = xml.parsers.expat.ParserCreate() >>> p.EndDoctypeDeclHandler = end_doctype >>> p.Parse("""""") End DocType 1 !2007-10-27 Sat >>> import xml.parsers.expat >>> def start_doctype(doctypeName, systemId, publicId, has_internal_subset): ... print 'Start DoctypeDecl:', doctypeName, systemId, publicId, has_internal_subset ... >>> p = xml.parsers.expat.ParserCreate() >>> p.StartDoctypeDeclHandler = start_doctype >>> p.Parse("""""") Start DoctypeDecl: html http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd -//W3C//DTD XHTML 1.1//EN 0 1 >>> def start_doctype(doctypeName, systemId, publicId, has_internal_subset): ... print 'Start DoctypeDecl1:', doctypeName ... print 'Start DoctypeDecl2:', systemId ... print 'Start DoctypeDecl3:', publicId ... print 'Start DoctypeDecl4:', has_internal_subset ... >>> p = xml.parsers.expat.ParserCreate() >>> p.StartDoctypeDeclHandler = start_doctype >>> p.Parse("""""") Start DoctypeDecl1: html Start DoctypeDecl2: http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd Start DoctypeDecl3: -//W3C//DTD XHTML 1.1//EN Start DoctypeDecl4: 0 1 !2007-10-26 Fri >>> import xml.parsers.expat >>> def xml_decl(version, encoding, standalone): ... print 'XmlDecl:', version, encoding, standalone ... >>> p = xml.parsers.expat.ParserCreate() >>> p.XmlDeclHandler = xml_decl >>> p.Parse("""""") XmlDecl: 1.0 None -1 1 !2007-10-25 Thu >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.ErrorByteIndex -1 >>> p.ErrorCode 0 >>> p.ErrorColumnNumber 0 >>> p.ErrorLineNumber 1 !2007-10-24 Wed >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.specified_attributes False !2007-10-23 Tue >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.returns_unicode True !2007-10-22 Mon >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.ordered_attributes False >>> def start_element(name, attrs): ... print 'Start element:', name, attrs ... >>> p.StartElementHandler = start_element >>> p.ordered_attributes = 1 >>> p.Parse(""" ... Text goes here ... More text ... """) Start element: parent [u'id', u'top'] Start element: child1 [u'name', u'paul'] Start element: child2 [u'name', u'fred'] 1 !2007-10-21 Sun >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.buffer_text = True >>> p.buffer_used 0 >>> p.Parse("""""") 1 >>> p.buffer_used 0 !2007-10-20 Sat >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.buffer_text False >>> p.Parse("""""") 1 >>> p.buffer_text False >>> p.buffer_text = True >>> p.buffer_text True 自分で設定するもののようだ !2007-10-19 Fri >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.buffer_size 8192 !2007-10-18 Thu >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> def start_element(name, attrs): ... print 'Start element:', name, attrs ... >>> p.StartElementHandler = start_element >>> p.ParseFile(open('foo')) Start element: parent {u'id': u'top'} Start element: child1 {u'name': u'paul'} Start element: child2 {u'name': u'fred'} 1 !2007-10-17 Wed >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> p.Parse("") 1 「最後に呼び出す時」って何のこと? !2007-10-16 Tue >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate() >>> def start_element(name, attrs): ... print 'Start element:', name, attrs ... >>> p.StartElementHandler = start_element >>> p.Parse(""" ... ... ... ... """) Start element: root {u'xmlns:py': u'http://www.python.org/ns/', u'xmlns': u'http://default-namespace.org/'} Start element: py:elem1 {} Start element: elem2 {u'xmlns': u''} 1 >>> p = xml.parsers.expat.ParserCreate('ASCII', ' ') >>> p.StartElementHandler = start_element >>> p.Parse(""" ... ... ... ... """) Start element: http://default-namespace.org/ root {} Start element: http://www.python.org/ns/ elem1 {} Start element: elem2 {} 1 !2007-10-15 Mon >>> import xml.parsers.expat >>> p = xml.parsers.expat.ParserCreate('ASCII') >>> p.Parse("""""") 1 >>> def start_element(name, attrs): ... print 'Start element:', name, attrs ... >>> p = xml.parsers.expat.ParserCreate('ASCII') >>> p.StartElementHandler = start_element >>> p.Parse("""""") Start element: parent {u'id': u'top'} 1 !2007-10-14 Sun まんま >>> import xml.parsers.expat >>> def start_element(name, attrs): ... print 'Start element:', name, attrs ... >>> def end_element(name): ... print 'End element:', name ... >>> def char_data(data): ... print 'Character data:', repr(data) ... >>> p = xml.parsers.expat.ParserCreate() >>> p.StartElementHandler = start_element >>> p.EndElementHandler = end_element >>> p.CharacterDataHandler = char_data >>> p.Parse(""" ... Text goes here ... More text ... """) Start element: parent {u'id': u'top'} Start element: child1 {u'name': u'paul'} Character data: u'Text goes here' End element: child1 Character data: u'\n' Start element: child2 {u'name': u'fred'} Character data: u'More text' End element: child2 Character data: u'\n' End element: parent 1 !2007-10-13 Sat >>> import HTMLParser >>> hp = HTMLParser.HTMLParser() >>> hp.feed("<<") >>> hp.reset() >>> hp.feed("<

>") !2007-10-12 Fri >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_pi(self, data): ... print data ... >>> hp = MyHTMLParser() >>> hp.feed("") proc color='red' >>> hp.feed("") proc color='red'? !2007-10-11 Thu >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_decl(self, decl): ... print decl ... >>> hp = MyHTMLParser() >>> hp.feed('') DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN" !2007-10-10 Wed >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_comment(self, data): ... print data ... >>> hp = MyHTMLParser() >>> hp.feed("") foo !2007-10-09 Tue >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_entityref(self, name): ... print name ... >>> hp = MyHTMLParser() >>> hp.feed(""<foo>") quot lt gt !2007-10-08 Mon >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_charref(self, ref): ... print ref ... >>> hp = MyHTMLParser() >>> hp.feed(""<foo>") >>> hp.feed("&123;") >>> hp.feed("{") 123 !2007-10-07 Sun >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_data(self, data): ... print "data %s" % data ... >>> hp = MyHTMLParser() >>> hp.feed("

h1

foo

h2 1

h2 2

") data h1 data foo data h2 1 data h2 2 >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print "Encountered the beginning of a %s tag" % tag ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... def handle_data(self, data): ... print "data %s" % data ... >>> hp = MyHTMLParser() >>> hp.feed("

h1

foo

h2 1

h2 2

") Encountered the beginning of a html tag Encountered the beginning of a h1 tag data h1 Encountered the end of a h1 tag data foo Encountered the beginning of a h2 tag data h2 1 Encountered the end of a h2 tag Encountered the beginning of a h2 tag data h2 2 Encountered the end of a h2 tag Encountered the end of a html tag >>> hp.feed("

h1

foo

h2 1

h2 2

") Encountered the beginning of a html tag data Encountered the beginning of a h1 tag data h1 Encountered the end of a h1 tag data foo Encountered the beginning of a h2 tag data h2 1 Encountered the end of a h2 tag Encountered the beginning of a h2 tag data h2 2 Encountered the end of a h2 tag Encountered the end of a html tag data !2007-10-06 Sat >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print "Encountered the beginning of a %s tag" % tag ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... def handle_startendtag(self, tag, attrs): ... print "Encountered a %s tag" % tag ... >>> hp = MyHTMLParser() >>> hp.feed("
") Encountered a br tag >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print "Encountered the beginning of a %s tag" % tag ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... >>> hp = MyHTMLParser() >>> hp.feed("
") Encountered the beginning of a br tag Encountered the end of a br tag !2007-10-05 Fri >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print "Encountered the beginning of a %s tag" % tag ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... >>> hp = MyHTMLParser() >>> hp.getpos() (1, 0) >>> hp.feed('

h1') Encountered the beginning of a html tag Encountered the beginning of a h1 tag >>> hp.getpos() (1, 12) >>> hp.get_starttag_text() '

' >>> hp.feed('

') Encountered the end of a h1 tag Encountered the end of a html tag >>> hp.get_starttag_text() '

' >>> hp = MyHTMLParser() >>> hp.feed('') Encountered the end of a html tag >>> hp.feed('>> hp.feed('ML>') Encountered the beginning of a html tag !2007-10-04 Thu >>> import HTMLParser >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print "Encountered the beginning of a %s tag" % tag ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... >>> hp = MyHTMLParser() >>> hp.feed("

h1

foo

h2 1

h2 2

") Encountered the beginning of a html tag Encountered the beginning of a h1 tag Encountered the end of a h1 tag Encountered the beginning of a h2 tag Encountered the end of a h2 tag Encountered the beginning of a h2 tag Encountered the end of a h2 tag Encountered the end of a html tag >>> hp.getpos() (1, 53) >>> hp.get_starttag_text() '

' >>> class MyHTMLParser(HTMLParser.HTMLParser): ... def handle_starttag(self, tag, attrs): ... print tag, attrs ... def handle_endtag(self, tag): ... print "Encountered the end of a %s tag" % tag ... >>> hp = MyHTMLParser() >>> hp.feed("

h1

foo

h2 1

h2 2

") html [] h1 [] Encountered the end of a h1 tag h2 [] Encountered the end of a h2 tag h2 [] Encountered the end of a h2 tag Encountered the end of a html tag >>> hp.feed('

h1

foo

h2 1

h2 2

') html [] h1 [('align', 'CENTER')] Encountered the end of a h1 tag h2 [] Encountered the end of a h2 tag h2 [] Encountered the end of a h2 tag Encountered the end of a html tag !2007-10-03 Wed >>> import HTMLParser >>> hp = HTMLParser.HTMLParser() >>> hp >>> hp.feed("") >>> hp.getpos() (1, 13) >>> hp.get_starttag_text() '' >>> hp.get_starttag_text() '' >>> hp.close() >>> hp >>> hp.getpos() (1, 13) >>> hp.get_starttag_text() '' !2007-10-02 Tue >>> import shutil >>> fs = open('foo') >>> shutil.copyfileobj(fs, fd) Traceback (most recent call last): File "", line 1, in ? NameError: name 'fd' is not defined >>> fd = open('bar', 'w') >>> shutil.copyfileobj(fs, fd) >>> fd.close() !2007-10-01 Mon >>> import shutil >>> shutil.move('bar', 'hoge') !2007-09-30 Sun >>> import shutil >>> shutil.rmtree('.Tgif_copy') !2007-09-29 Sat >>> import shutil >>> shutil.copytree('.Tgif', '.Tgif_copy') >>> shutil.copytree('.Tgif', '.Tgif_copy') Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/shutil.py", line 102, in copytree os.mkdir(dst) OSError: [Errno 17] File exists: '.Tgif_copy' !2007-09-28 Fri >>> import shutil >>> shutil.copy2('foo', 'bar') !2007-09-27 Thu >>> import shutil >>> shutil.copy('foo', 'bar') !2007-09-26 Wed >>> import shutil >>> shutil.copystat('foo', 'bar') !2007-09-25 Tue >>> import shutil >>> shutil.copymode('foo', 'bar') !2007-09-24 Mon >>> import shutil >>> shutil.copyfile('foo', 'bar') >>> shutil.copyfile('foo', 'bar') !2007-09-23 Sun Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('') >>> s.pattern <_sre.SRE_Pattern object at 0x81c4120> >>> s.pattern.pattern '\n \\$(?:\n (?P\\$) | # Escape sequence of two delimiters\n (?P[_a-z][_a-z0-9]*) | # delimiter and a Python identifier\n {(?P[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier\n (?P) # Other ill-formed delimiter exprs\n )\n ' !2007-09-22 Sat Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$foo $foo') >>> s.substitute(foo='hoge') 'hoge hoge' !2007-09-21 Fri Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('') >>> s.delimiter '$' >>> s.idpattern '[_a-z][_a-z0-9]*' >>> s = string.Template('%foo') >>> s.delimiter = '%' >>> s.substitute(foo='hoge') '%foo' >>> s.delimiter '%' >>> s = string.Template('%foo $foo') >>> s.delimiter = '%' >>> s.substitute(foo='hoge') '%foo hoge' !2007-09-20 Thu Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$who likes $what') >>> s.template '$who likes $what' >>> s.template = '$who loves $what' >>> s.substitute(who='tim', what='kung pao') 'tim loves kung pao' !2007-09-19 Wed Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$') >>> s.safe_substitute() '$' !2007-09-18 Tue Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$_foo') >>> s.substitute(_foo='hoge') 'hoge' >>> s = string.Template('$____') >>> s.substitute(____='hoge') 'hoge' !2007-09-17 Mon Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$') >>> s.substitute() Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.4/string.py", line 172, in substitute return self.pattern.sub(convert, self.template) File "/usr/lib/python2.4/string.py", line 169, in convert self._invalid(mo) File "/usr/lib/python2.4/string.py", line 145, in _invalid raise ValueError('Invalid placeholder in string: line %d, col %d' % ValueError: Invalid placeholder in string: line 1, col 1 >>> s = string.Template('$$') >>> s.substitute() '$' !2007-09-16 Sun Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$foo_bar_baz') >>> s.substitute(foo='hoge', foo_bar_baz='FOO') 'FOO' >>> s = string.Template('${foo}_bar_baz') >>> s.substitute(foo='hoge', foo_bar_baz='FOO') 'hoge_bar_baz' !2007-09-15 Sat Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import string >>> s = string.Template('$foo $$') >>> s.substitute(foo='hoge') 'hoge $' >>> s.substitute(foo='hoge', bar='hogehoge') 'hoge $' !2007-09-14 Fri Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from string import Template >>> s = Template('$who likes $what') >>> s.substitute(who='tim', what='kung pao') 'tim likes kung pao' >>> d = dict(who='tim') >>> Template('Give $who $100').substitute(d) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.4/string.py", line 172, in substitute return self.pattern.sub(convert, self.template) File "/usr/lib/python2.4/string.py", line 169, in convert self._invalid(mo) File "/usr/lib/python2.4/string.py", line 145, in _invalid raise ValueError('Invalid placeholder in string: line %d, col %d' % ValueError: Invalid placeholder in string: line 1, col 11 >>> Template('$who likes $what').substitute(d) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.4/string.py", line 172, in substitute return self.pattern.sub(convert, self.template) File "/usr/lib/python2.4/string.py", line 162, in convert val = mapping[named] KeyError: 'what' >>> Template('$who likes $what').safe_substitute(d) 'tim likes $what' !2007-09-13 Thu >>> import itertools Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import itertools >>> i = itertools.tee([1, 2, 3, 4, 5]) >>> i (, ) >>> i[0].next() 1 >>> i[0].next() 2 >>> i[0].next() 3 >>> i[0].next() 4 >>> i[0].next() 5 >>> i[1].next() 1 >>> i[1].next() 2 >>> i[1].next() 3 >>> i[1].next() 4 >>> i[1].next() 5 >>> i[1].next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i[0].next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i = itertools.tee([1, 2, 3, 4, 5], 3) >>> i (, , ) レシピ、標準では入っていないってこと? !2007-09-12 Wed >>> import itertools >>> for x in itertools.takewhile(lambda x: x < 3, [1, 2, 3, 4, 5, 6]): ... print x ... 1 2 !2007-09-11 Tue >>> import itertools >>> import operator >>> for x in itertools.starmap(operator.add, [(1, 10), (2, 20), (3, 30)]): ... print x ... 11 22 33 >>> for x in itertools.starmap(lambda *x: x[0] + x[1], [(1, 10), (2, 20), (3, 30)]): ... print x ... 11 22 33 !2007-09-10 Mon >>> import itertools >>> for x in itertools.repeat(1, 3): ... print x ... 1 1 1 >>> i = 0 >>> for x in itertools.repeat(i, 3): ... print x ... i += 1 ... 0 0 0 >>> i = 0 >>> for x in itertools.repeat(1): ... print x ... if i > 2: break ... i += 1 ... 1 1 1 1 !2007-09-09 Sun >>> import itertools >>> for x in itertools.izip([1, 2, 3], [10, 20, 30]): ... print x ... (1, 10) (2, 20) (3, 30) >>> for x in itertools.izip([1, 2, 3], [10, 20, 30, 40]): ... print x ... (1, 10) (2, 20) (3, 30) >>> for x in itertools.izip([1, 2, 3], [10, 20, 30], [100, 200, 300]): ... print x ... (1, 10, 100) (2, 20, 200) (3, 30, 300) >>> for x, y, z in itertools.izip([1, 2, 3], [10, 20, 30], [100, 200, 300]): ... print x, y, z ... 1 10 100 2 20 200 3 30 300 「バージョン 2.4 で 変更 された仕様」の部分、良く分からない !2007-09-08 Sat >>> import itertools >>> for x in itertools.islice([1, 2, 3, 4, 5], 3): ... print x ... 1 2 3 >>> for x in itertools.islice([1, 2, 3, 4, 5], 1, 3): ... print x ... 2 3 >>> for x in itertools.islice([1, 2, 3, 4, 5], 1, None): ... print x ... 2 3 4 5 >>> for x in itertools.islice([1, 2, 3, 4, 5], 1, None, 2): ... print x ... 2 4 !2007-09-07 Fri >>> import itertools >>> a = [1, 2, 3] >>> for x in itertools.imap(lambda x: x * x, a): ... print x ... 1 4 9 >>> a = [1, 2, 3] >>> for x in itertools.imap(None, a): ... print x ... (1,) (2,) (3,) >>> for x in itertools.imap(None, [1, 2, 3], [10, 20, 30]): ... print x ... (1, 10) (2, 20) (3, 30) >>> for x in itertools.imap(None, [1, 2, 3], [10, 20, 30], [100, 200, 300]): ... print x ... (1, 10, 100) (2, 20, 200) (3, 30, 300) >>> import operator >>> for x in itertools.imap(operator.add, [1, 2, 3], [10, 20, 30]): ... print x ... 11 22 33 map というより zipWith っぽく感じてしまうのだが? !2007-09-06 Thu >>> import itertools >>> a = [1, 2, 3, 4, 5] >>> for x in itertools.ifilterfalse(lambda x: x > 2, a): ... print x ... 1 2 >>> for x in itertools.ifilterfalse(None, [True, False, False, True, True]): ... print x ... False False !2007-09-05 Wed >>> import itertools >>> a = [1, 2, 3, 4, 5] >>> for x in itertools.ifilter(lambda x: x > 2, a): ... print x ... 3 4 5 >>> for x in itertools.ifilter(None, [True, False, False, True, True]): ... print x ... True True True !2007-09-04 Tue Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import itertools >>> d = {"foo" : 1, "bar" : 2} >>> for x in itertools.groupby(d): ... print x ... ('foo', ) ('bar', ) >>> d = {"foo" : 1, "bar" : 2, "baz" : 3} >>> for x in itertools.groupby(d, lambda x: x[0]): ... print x ... ('b', ) ('f', ) ('b', ) >>> a = ["bar", "baz", "foo"] >>> for x in itertools.groupby(a, lambda x: x[0]): ... print x ... ('b', ) ('f', ) >>> a = ["bar", "baz", "foo"] >>> for k, g in itertools.groupby(a, lambda x: x[0]): ... print list(g) ... ['bar', 'baz'] ['foo'] どういうシチュエーションで使うんだっけ? !2007-09-03 Mon >>> import itertools >>> for x in itertools.dropwhile(lambda x: x < 3, [1, 2, 3, 4, 5, 6]): ... print x ... 3 4 5 6 !2007-09-02 Sun >>> import itertools >>> i = itertools.cycle([1]) >>> i.next() 1 >>> i.next() 1 >>> i.next() 1 >>> i = itertools.cycle([1, 2, 3]) >>> i.next() 1 >>> i.next() 2 >>> i.next() 3 >>> i.next() 1 >>> i.next() 2 >>> i.next() 3 >>> i = itertools.cycle("abc") >>> i.next() 'a' >>> i.next() 'b' >>> i.next() 'c' >>> i.next() 'a' !2007-09-01 Sat >>> import itertools >>> for x in itertools.count(): ... if x == 3: break ... print x ... 0 1 2 >>> for x in itertools.count(3): ... if x == 6: break ... print x ... 3 4 5 !2007-08-31 Fri >>> import itertools >>> for x in itertools.chain([1, 2, 3], [4, 5, 6]): ... print x ... 1 2 3 4 5 6 !2007-08-30 Thu まんま >>> amounts = [120.15, 764.05, 823.14] >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... Traceback (most recent call last): File "", line 1, in ? NameError: name 'izip' is not defined >>> from itertools import * >>> amounts = [120.15, 764.05, 823.14] >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... Check 1200 is for $120.15 Check 1201 is for $764.05 Check 1202 is for $823.14 >>> import operator >>> for cube in imap(operator.pow, xrange(1,5), repeat(3)): ... print cube ... 1 8 27 64 >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'mark'] >>> for name in islice(reportlines, 3, None, 2): ... print name.title() ... Alex Laura Martin Walter Mark >>> from operator import itemgetter Traceback (most recent call last): File "", line 1, in ? ImportError: cannot import name itemgetter Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from itertools import * >>> from operator import itemgetter >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) >>> di = sorted(d.iteritems(), key=itemgetter(1)) >>> for k, g in groupby(di, key=itemgetter(1)): ... print k, map(itemgetter(0), g) ... 1 ['a', 'c', 'e'] 2 ['b', 'd', 'f'] 3 ['g'] >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): ... print map(operator.itemgetter(1), g) ... Traceback (most recent call last): File "", line 2, in ? NameError: name 'operator' is not defined >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): ... print map(itemgetter(1), g) ... [1] [4, 5, 6] [10] [15, 16, 17, 18] [22] [25, 26, 27, 28] !2007-08-29 Wed Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import operator >>> f=operator.attrgetter('lower') >>> f("ABC") >>> f("ABC")() 'abc' !2007-08-28 Tue まんま Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from operator import * >>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)] >>> getcount = itemgetter(1) >>> map(getcount, inventory) [3, 2, 5, 1] >>> sorted(inventory, key=getcount) [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)] !2007-08-27 Mon >>> callable(len) True >>> callable(True) False >>> def foo(): ... pass ... >>> callable(foo) True !2007-08-26 Sun まんま >>> import operator >>> d = {} >>> keys = range(256) >>> vals = map(chr, keys) >>> map(operator.setitem, [d]*len(keys), keys, vals) [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None] !2007-08-25 Sat >>> import operator >>> operator.isSequenceType([1, 2, 3]) True >>> operator.isSequenceType("foo") True >>> operator.isSequenceType(1) False !2007-08-24 Fri >>> import operator >>> operator.isNumberType(1) True >>> operator.isNumberType(1.2) True >>> operator.isNumberType('foo') False !2007-08-23 Thu まんま >>> class C: ... pass ... >>> import operator >>> o = C() >>> operator.isMappingType(o) True !2007-08-22 Wed >>> import operator >>> a = [1, 2, 3, 1, 2, 3] >>> operator.setslice(a, 1, 3, [20, 30]) >>> a [1, 20, 30, 1, 2, 3] >>> operator.__setslice__(a, 1, 3, [200, 300]) >>> a [1, 200, 300, 1, 2, 3] !2007-08-21 Tue >>> import operator >>> a = [1, 2, 3] >>> operator.setitem(a, 1, 10) >>> a [1, 10, 3] >>> operator.__setitem__(a, 1, 20) >>> a [1, 20, 3] !2007-08-20 Mon >>> import operator >>> operator.repeat([1, 2, 3], 3) [1, 2, 3, 1, 2, 3, 1, 2, 3] >>> operator.__repeat__([1, 2, 3], 3) [1, 2, 3, 1, 2, 3, 1, 2, 3] !2007-08-19 Sun >>> import operator >>> operator.indexOf([1, 2, 3, 4, 5], 1) 0 >>> operator.indexOf([1, 2, 3, 4, 5], 2) 1 >>> operator.indexOf([1, 2, 3, 4, 5], 10) Traceback (most recent call last): File "", line 1, in ? ValueError: sequence.index(x): x not in sequence また、「_」つきのがないパタン !2007-08-18 Sat >>> import operator >>> operator.getslice([1, 2, 3, 4, 5], 1, 2) [2] >>> operator.getslice([1, 2, 3, 4, 5], 1, 3) [2, 3] >>> operator.__getslice__([1, 2, 3, 4, 5], 1, 2) [2] !2007-08-17 Fri >>> import operator >>> a = [1, 2, 3, 1, 2, 3] >>> operator.getitem(a, 1) 2 >>> a [1, 2, 3, 1, 2, 3] >>> operator.getitem(a, 10) Traceback (most recent call last): File "", line 1, in ? IndexError: list index out of range >>> operator.__getitem__(a, 1) 2 ドキュメントが「要素を削除します」になっているから勘違いしちゃったよ。 ミスのようだ。bug 報告しておいた !2007-08-16 Thu >>> import operator >>> a = [1, 2, 3, 4, 5] >>> operator.delslice(a, 1, 2) >>> a [1, 3, 4, 5] >>> operator.delslice(a, 1, 3) >>> a [1, 5] !2007-08-15 Wed >>> import operator >>> operator.delitem([1, 2, 3], 1) >>> a = [1, 2, 3] >>> operator.delitem(a, 1) >>> a [1, 3] !2007-08-14 Tue >>> import operator >>> operator.countOf([1, 2, 3, 1, 2, 3], 1) 2 >>> operator.countOf([1, 2, 3, 1, 2, 3, 1, 1], 1) 4 >>> operator.__countOf__([1, 2, 3, 1, 2, 3], 1) Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute '__countOf__' !2007-08-13 Mon >>> import operator >>> operator.contains([1, 2, 3], 1) True >>> operator.contains([1, 2, 3], 10) False >>> operator.__contains__([1, 2, 3], 1) True >>> operator.__contains__([1, 2, 3], 10) False !2007-08-12 Sun >>> import operator >>> operator.concat([1, 2, 3], [4, 5, 6]) [1, 2, 3, 4, 5, 6] >>> operator.concat("foo", "bar") 'foobar' >>> operator.__concat__([1, 2, 3], [4, 5, 6]) [1, 2, 3, 4, 5, 6] !2007-08-11 Sat >>> import operator >>> operator.lshift(1, 2) 4 >>> operator.__lshift__(1, 2) 4 >>> operator.rshift(8, 1) 4 >>> operator.__rshift__(8, 1) 4 !2007-08-10 Fri >>> import operator >>> operator.inv(0) -1 >>> operator.inv(1) -2 >>> operator.inv(5) -6 >>> operator.invert(0) -1 >>> operator.__inv__(0) -1 >>> operator.__invert__(0) -1 !2007-08-09 Thu >>> import operator >>> operator.and_(True, True) True >>> operator.__and__(True, True) True >>> operator.or_(True, True) True >>> operator.__or__(True, True) True >>> operator.xor(True, True) False >>> operator.__xor__(True, True) False * 「_」があったりなかったりする違いはどこから? * もとからある名前(予約語?)にバッティングする場合に「_」を後置しているようだ、多分 !2007-08-08 Wed >>> import operator >>> operator.pos(1) 1 >>> operator.pos(-1) -1 >>> operator.__pos__(1) 1 >>> operator.__pos__(-1) -1 何これ? !2007-08-07 Tue >>> import operator >>> operator.mod(10, 3) 1 >>> operator.__mod__(10, 3) 1 >>> operator.pow(3, 2) 9 >>> operator.__pow__(3, 2) 9 >>> operator.neg(1) -1 >>> operator.__neg__(1) -1 !2007-08-06 Mon >>> import operator >>> operator.add(1,2) 3 >>> operator.__add__(1,2) 3 >>> operator.sub(2, 1) 1 >>> operator.__sub__(2, 1) 1 >>> operator.mul(2, 3) 6 >>> operator.__mul__(2, 3) 6 >>> operator.div(10, 3) 3 >>> operator.__div__(10, 3) 3 >>> operator.div(11, 4.0) 2.75 >>> operator.floordiv(10, 3) 3 >>> operator.floordiv(11, 4.0) 2.0 >>> operator.__floordiv__(11, 4.0) 2.0 >>> operator.truediv(10,3) 3.3333333333333335 >>> operator.__truediv__(10,3) 3.3333333333333335 !2007-08-05 Sun >>> import operator >>> operator.abs(-1) 1 >>> operator.__abs__(-1) 1 !2007-08-04 Sat >>> import operator >>> operator.is_not("foo", "bar") True >>> operator.is_not("foo", "foo") False !2007-08-03 Fri >>> import operator >>> operator.is_("foo", "foo") True >>> operator.is_("foo", 2) False !2007-08-02 Thu >>> import operator >>> operator.truth(True) True >>> operator.truth(False) False !2007-08-01 Wed >>> import operator >>> operator.not_(True) False >>> operator.__not__(True) False !2007-07-31 Tue >>> import operator >>> operator.lt(1,2) True >>> operator.lt(2,1) False >>> operator.le(1,2) True >>> operator.le(2,1) False >>> operator.le(1,1) True >>> operator.eq(1,1) True >>> operator.eq(1,2) False >>> operator.ne(1,2) True >>> operator.ne(1,1) False >>> operator.ge(2,1) True >>> operator.ge(1,1) True >>> operator.ge(1,2) False >>> operator.gt(2,1) True >>> operator.gt(2,2) False >>> operator.gt(1,2) False !2007-07-30 Mon >>> import operator >>> operator.add(1,2) 3 >>> operator.__add__(1,2) 3 !2007-07-29 Sun >>> import cStringIO >>> f = cStringIO.StringIO("foo") >>> f >>> f = cStringIO.StringIO() >>> f >>> f.write("foo") >>> f.getvalue() 'foo' >>> f.tell() 3 >>> f.seek(0) >>> f.tell() 0 StringIO となぜ仕様を変えちゃうんだろうか? !2007-07-28 Sat >>> import cStringIO >>> f = cStringIO.StringIO("foo") >>> f.getvalue() 'foo' >>> f.write(" bar") Traceback (most recent call last): File "", line 1, in ? AttributeError: 'cStringIO.StringI' object has no attribute 'write' !2007-07-27 Fri >>> import StringIO >>> f = StringIO.StringIO() >>> f.write('foo') >>> f.flush() >>> f.getvalue() 'foo' !2007-07-26 Thu >>> import StringIO >>> f = StringIO.StringIO("foo\nbar\nbaz") >>> for x in f: ... print x ... foo bar baz >>> f = StringIO.StringIO("foo\nbar\nbaz") >>> f.next() 'foo\n' >>> f.next() 'bar\n' !2007-07-25 Wed >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.writelines([' bar', ' baz']) >>> f.getvalue() ' bar baz' >>> f.tell() 8 >>> f.seek(0) >>> f.getvalue() ' bar baz' >>> f.writelines([' hoge']) >>> f.getvalue() ' hogebaz' >>> f.tell() 5 >>> f.read() 'baz' >>> f = StringIO.StringIO("foo") >>> f.tell() 0 >>> f.seek(2) >>> f.write(' bar') >>> f.getvalue() 'fo bar' >>> f.tell() 6 >>> f.read() '' >>> f.seek(0) >>> f.read() 'fo bar' !2007-07-24 Tue >>> import StringIO >>> f = StringIO.StringIO("foo bar") >>> f.truncate() >>> f.getvalue() '' >>> f.read() '' >>> f = StringIO.StringIO("foo bar") >>> f.truncate(3) >>> f.getvalue() 'foo' >>> f.read() 'foo' !2007-07-23 Mon >>> import StringIO >>> f = StringIO.StringIO("foo\nbar\nbaz\n") >>> f.readlines() ['foo\n', 'bar\n', 'baz\n'] !2007-07-22 Sun >>> import StringIO >>> f = StringIO.StringIO("foo\nbar\nbaz\n") >>> f.readline() 'foo\n' >>> f.readline() 'bar\n' >>> f.readline() 'baz\n' >>> f.readline() '' >>> f = StringIO.StringIO("foo") >>> f.readline() 'foo' >>> f.readline() '' !2007-07-21 Sat >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.read(2) 'fo' !2007-07-20 Fri >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.getvalue() 'foo' >>> f.seek(1) >>> f.getvalue() 'foo' >>> f.tell() 1 >>> f.read() 'oo' >>> f.write(" bar") >>> f.tell() 7 >>> f.getvalue() 'foo bar' >>> f.tell() 7 >>> f.read() '' >>> f.seek(0) >>> f.tell() 0 >>> f.read() 'foo bar' !2007-07-19 Thu >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.tell() 0 >>> f.read() 'foo' >>> f.tell() 3 !2007-07-18 Wed >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.isatty() False !2007-07-17 Tue >>> import StringIO >>> f = StringIO.StringIO() >>> f.getvalue() '' >>> f.write("foo") >>> f.getvalue() 'foo' !2007-07-16 Mon >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f.fileno() Traceback (most recent call last): File "", line 1, in ? AttributeError: StringIO instance has no attribute 'fileno' 全てが同じじゃないのか? !2007-07-15 Sun >>> import StringIO >>> f = StringIO.StringIO("foo") >>> f >>> f.getvalue() 'foo' >>> f.getvalue() 'foo' >>> f.close() >>> f.getvalue() Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/StringIO.py", line 205, in getvalue return self.buf AttributeError: StringIO instance has no attribute 'buf' !2007-07-14 Sat 演習7-1 import fileinput, sys, os.path if os.path.basename(sys.argv[0]) == "lower": f = True else: f = False for line in fileinput.input(): if f: print line.lower(), else: print line.upper(), やろうと思ったのに、できなかったもの * 演習7-8 * 演習7-7 * 演習7-6 * 演習7-5 * 演習7-4 * 演習7-3 * 演習7-2 * 演習6-4 途中 * 演習6-2(仕様が良く分からない…) * 演習5-20 * 演習5-19 * 演習5-18 * 演習5-17 * 演習5-16 sort に -d を追加 * 演習4-5(実装を消してしまった…) * 演習1-22 !2007-07-13 Fri 演習6-6 うーん、不完全な getword() で取っている限り ちゃんとしたプリプロセッサになるとも思えないので適当に… import sys class Reader: def __init__(self): self.buf = [] def getch(self): import sys if len(self.buf) > 0: return self.buf.pop() else: return sys.stdin.read(1) def ungetch(self, c): self.buf.append(c) def ungets(self, s): for i in xrange(len(s)-1, -1, -1): self.ungetch(s[i]) def skip_blanks(self): c = self.getch() while c.isspace(): c = self.getch() self.ungetch(c) def _comment(self): c = self.getch() while c != '': if c == '*': c = self.getch() if c == '/': break else: self.ungetch(c) c = self.getch() return c def getword(self): c = self.getch() w = "" while c.isspace(): w += c c = self.getch() if len(w) > 0: self.ungetch(c) return w if c == '': return c if c == '#': return c w = c if c.isalpha() or c == '_' or c == '#': c = self.getch() while c.isalnum() or c == '_': w += c c = self.getch() self.ungetch(c) return w elif c == "'" or c == '"': d = self.getch() while d != c: w += d if d == '\\': d = self.getch() w += d elif d == '': break d = self.getch() w += d return w elif c == '/': d = self.getch() if d == '*': c = self._comment() return self.getword() else: self.ungetch(d) return c else: return w def error(r, c, s): print "error: %s" % s while c != '' and c != '\n': c = r.getch() def getdef(r, h): r.skip_blanks() w = r.getword() if not w.isalpha(): error(r, w, "getdef: expecting a directive after #") elif w == "define": r.skip_blanks() name = r.getword() if not name.isalpha(): error(r, name, "getdef: non-alpha - name expected") else: r.skip_blanks() define = "" c = r.getch() while c != '' and c != '\n': define += c c = r.getch() if len(define) < 1: error(r, '\n', "getdef: imcomplete define") else: h[name] = define elif w == "undef": r.skip_blanks() name = r.getword() if not name.isalpha(): error(r, name, "getdef: non-alpha in undef") else: del(h[name]) else: error(r, w, "getdef: expecting a directive after #") h = {} r = Reader() w = r.getword() while w != '': if w[0] == '#': getdef(r, h) elif not w[0].isalpha(): sys.stdout.write(w) elif not h.has_key(w): sys.stdout.write(w) else: r.ungets(h[w]) w = r.getword() 最初の getword() だと # は一つのトークンになりそうになかったので、手を入れた !2007-07-12 Thu 演習6-4 Reader クラスは 2007-07-16 Mon のを使用 h = {} r = Reader() w = r.getword() while w != '': if w[0].isalpha(): if h.has_key(w): h[w] += 1 else: h[w] = 1 w = r.getword() for (k,v) in h.items(): print "%2d:%20s" % (v, k) まだ途中(ソート出力がまだ) !2007-07-11 Wed 演習6-3 Reader クラスは 2007-07-16 Mon のを改造(行番号を数えるため) class Reader: def __init__(self): self.lastc = '' def getch(self): import sys if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def _comment(self): c = self.getch() while c != '': if c == '*': c = self.getch() if c == '/': break else: self.ungetch(c) c = self.getch() return c def getword(self): c = self.getch() while c.isspace() and c != '\n': c = self.getch() if c == '': return c w = c if c.isalpha() or c == '_' or c == '#': c = self.getch() while c.isalnum() or c == '_': w += c c = self.getch() self.ungetch(c) return w elif c == "'" or c == '"': d = self.getch() while d != c: w += d if d == '\\': d = self.getch() w += d elif d == '': break d = self.getch() w += d return w elif c == '/': d = self.getch() if d == '*': c = self._comment() return self.getword() else: self.ungetch(d) return c else: return w def noiseword(word): return word in ["a", "an", "and", "are", "in", "is", "of", "or", "that", "the", "this", "to"] h = {} linenum = 1 r = Reader() w = r.getword() while w != '': if w[0].isalpha() and (not noiseword(w)): if h.has_key(w): h[w].append(linenum) else: h[w] = [linenum] elif w == '\n': linenum += 1 w = r.getword() for k in h.keys(): print "%10s: " % k, for n in h[k]: print "%4d " % n, print 本来は単語でソートした値が出力されるのかもしれない !2007-07-10 Tue 演習6-1 class Reader: def __init__(self): self.lastc = '' def getch(self): import sys if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def _comment(self): c = self.getch() while c != '': if c == '*': c = self.getch() if c == '/': break else: self.ungetch(c) c = self.getch() return c def getword(self): c = self.getch() while c.isspace(): c = self.getch() if c == '': return c w = c if c.isalpha() or c == '_' or c == '#': c = self.getch() while c.isalnum() or c == '_': w += c c = self.getch() self.ungetch(c) return w elif c == "'" or c == '"': d = self.getch() while d != c: w += d if d == '\\': d = self.getch() w += d elif d == '': break d = self.getch() w += d return w elif c == '/': d = self.getch() if d == '*': c = self._comment() return self.getword() else: self.ungetch(d) return c else: return w うーん、本に載っている回答だとコメントのところが、 ちゃんとスキップできない気がするのだが? !2007-07-09 Mon 演習5-15 sort に大文字小文字の区別をしない -f を追加 import fileinput, sys from optparse import OptionParser parser = OptionParser() parser.add_option("-n", action="store_true") parser.add_option("-r", action="store_true") parser.add_option("-f", action="store_true") (options, args) = parser.parse_args() sys.argv = [sys.argv[0]] + args def unify(s): if options.f: return s.lower() else: return s def str2float(s): f = 0 length = len(s) for i in xrange(1, length+1): try: f = float(s[:i]) except ValueError: break return f def numcmp(a, b): af = str2float(a) bf = str2float(b) if af < bf: return -1 elif af > bf: return 1 else: return 0 buf = [] for line in fileinput.input(): buf.append(line) if options.n: if options.r: buf.sort(lambda a, b : numcmp(unify(b), unify(a))) else: buf.sort(lambda a, b : numcmp(unify(a), unify(b))) else: if options.r: buf.sort(lambda a, b : cmp(unify(b), unify(a))) else: buf.sort(lambda a, b : cmp(unify(a), unify(b))) for x in buf: print x, sort コマンドとはなんか違ってしまうな。 sort コマンドは安定ソートじゃないのか??? !2007-07-08 Sun 演習5-14 sort -n -r つき import fileinput, sys from optparse import OptionParser parser = OptionParser() parser.add_option("-n", action="store_true") parser.add_option("-r", action="store_true") (options, args) = parser.parse_args() sys.argv = [sys.argv[0]] + args def str2float(s): f = 0 length = len(s) for i in xrange(1, length+1): try: f = float(s[:i]) except ValueError: break return f def numcmp(a, b): af = str2float(a) bf = str2float(b) if af < bf: return -1 elif af > bf: return 1 else: return 0 buf = [] for line in fileinput.input(): buf.append(line) if options.n: if options.r: buf.sort(lambda a, b : numcmp(b, a)) else: buf.sort(lambda a, b : numcmp(a, b)) else: if options.r: buf.sort(lambda a, b : cmp(b, a)) else: buf.sort() for x in buf: print x, !2007-07-07 Sat 演習5-13 tail import fileinput, sys from optparse import OptionParser DEFLINES = 10 LINES = 100 buf = [] buf_num = 0 #if len(sys.argv) < 2: # print "Usage: tail [-n]" # sys.exit(1) parser = OptionParser() parser.add_option("-n", type="int", dest="n", default=DEFLINES) (options, args) = parser.parse_args() sys.argv = [sys.argv[0]] + args if options.n < 1 or options.n > LINES: n = LINES else: n = options.n for line in fileinput.input(): buf.append(line) buf_num += 1 if buf_num > n: buf.pop(0) buf_num -= 1 for x in buf: print x, * optparse でオプション値を取得する方法がすぐには分からなかった… * optparse を使ったときには自分で argv を調整しないとダメなのだろうか?(fileinput を使いたい場合) !2007-07-06 Fri 演習5-12 entab import sys TABINC = 8 class Getch: def __init__(self): self.lastc = '' def getch(self): if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def tabpos(pos): if len(sys.argv) == 1+2 and sys.argv[1][0] == '-' and sys.argv[2][0] == '+': return pos >= int(sys.argv[1][1:]) and ((pos - int(sys.argv[1][1:])) % int(sys.argv[2][1:])) == 0 elif len(sys.argv) > 1: return pos in map(lambda x: int(x), sys.argv[1:]) else: return (pos % TABINC) == 0 pos = 0 nb = 0 nt = 0 gc = Getch() c = gc.getch() while c != '': pos += 1 if c == ' ': if not tabpos(pos): nb += 1 else: nb = 0 nt += 1 else: while nt > 0: sys.stdout.write('\t') nt -= 1 if c == '\t': nb = 0 else: while nb > 0: sys.stdout.write(' ') nb -= 1 sys.stdout.write(c) if c == '\n': pos = 0 elif c == '\t': while not tabpos(pos): pos += 1 c = gc.getch() オプションを間違えると止まってしてしまうが… detab import sys TABINC = 8 class Getch: def __init__(self): self.lastc = '' def getch(self): if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def tabpos(pos): if len(sys.argv) == 1+2 and sys.argv[1][0] == '-' and sys.argv[2][0] == '+': return pos >= int(sys.argv[1][1:]) and ((pos - int(sys.argv[1][1:])) % int(sys.argv[2][1:])) == 0 elif len(sys.argv) > 1: return pos in map(lambda x: int(x), sys.argv[1:]) else: return (pos % TABINC) == 0 pos = 0 nb = 0 nt = 0 gc = Getch() c = gc.getch() while c != '': if c == '\t': while 1: sys.stdout.write(' ') pos += 1 if tabpos(pos): break elif c == '\n': sys.stdout.write(c) pos = 0 else: sys.stdout.write(c) pos += 1 c = gc.getch() オプションを間違えると暴走してしまうが… !2007-07-05 Thu 演習5-11 entab import sys TABINC = 8 class Getch: def __init__(self): self.lastc = '' def getch(self): if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def tabpos(pos): if len(sys.argv) > 1: return pos in map(lambda x: int(x), sys.argv[1:]) else: return (pos % TABINC) == 0 pos = 0 nb = 0 nt = 0 gc = Getch() c = gc.getch() while c != '': pos += 1 if c == ' ': if not tabpos(pos): nb += 1 else: nb = 0 nt += 1 else: while nt > 0: sys.stdout.write('\t') nt -= 1 if c == '\t': nb = 0 else: while nb > 0: sys.stdout.write(' ') nb -= 1 sys.stdout.write(c) if c == '\n': pos = 0 elif c == '\t': while not tabpos(pos): pos += 1 c = gc.getch() detab import sys TABINC = 8 class Getch: def __init__(self): self.lastc = '' def getch(self): if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def tabpos(pos): if len(sys.argv) > 1: return pos in map(lambda x: int(x), sys.argv[1:]) else: return (pos % TABINC) == 0 pos = 0 nb = 0 nt = 0 gc = Getch() c = gc.getch() while c != '': if c == '\t': while 1: sys.stdout.write(' ') pos += 1 if tabpos(pos): break elif c == '\n': sys.stdout.write(c) pos = 0 else: sys.stdout.write(c) pos += 1 c = gc.getch() これだと、タブストップがない位置にタブがあると、永遠に ' ' を出力し続けてしまう… !2007-07-04 Wed 演習5-10 2007-06-14 Thu の 演習4-3 一歩前を改造 import sys val = [] def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def getop(arg): try: return ('NUMBER', int(arg)) except ValueError: try: return ('NUMBER', float(arg)) except ValueError: return (arg, arg) for arg in sys.argv[1:]: type, x = getop(arg) #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif type == '': break else: print "error: unknown command %s" % x print "\t%.8g" % (pop()) で、 $ python expr.py 1 2 + 3 $ python expr.py 1 2 - 4 5 + '*' -9 $ python expr.py 1 2 / 0 $ python expr.py 12.3 3.4 + 15.7 int() でなくて float() で良かったか? !2007-07-03 Tue 演習5-8 >>> daytab = [[0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]] >>> >>> def is_leap(year): ... if year % 4 == 0 and year % 100 != 0 or year % 400 == 0: ... return 1 ... else: ... return 0 ... >>> def day_of_year(year, month, day): ... leap = is_leap(year) ... if month < 1 or month > 12: ... return -1 ... if day < 1 or day > daytab[leap][month]: ... return -1 ... for i in xrange(1, month): ... day += daytab[leap][i] ... return day ... >>> def month_day(year, yearday): ... if year < 1: ... return -1, -1 ... ... leap = is_leap(year) ... for i in xrange(1, 12+1): ... if yearday <= daytab[leap][i]: ... break ... yearday -= daytab[leap][i] ... if i > 12 and yearday > daytab[leap][12]: ... return -1, -1 ... else: ... return i, yearday ... >>> day_of_year(2007, 1, 1) 1 >>> day_of_year(2007, 1, 2) 2 >>> day_of_year(2007, 1, 32) -1 >>> day_of_year(2007, 2, 1) 32 >>> day_of_year(2007, 3, 1) 60 >>> month_day(2007, 60) (3, 1) !2007-07-02 Mon 演習5-5 >>> def strncpy(s, n): ... return s[:n] ... >>> strncpy("abcdef", 0) '' >>> strncpy("abcdef", 1) 'a' >>> strncpy("abcdef", 10) 'abcdef' >>> def strncat(s, t, n): ... return s + t[:n] ... >>> strncat("abc", "def", 0) 'abc' >>> strncat("abc", "def", 1) 'abcd' >>> strncat("abc", "def", 6) 'abcdef' >>> def strncmp(s, t, n): ... return cmp(s[:n], t[:n]) ... >>> strncmp("abcdef", "abcDEF", 3) 0 >>> strncmp("abcdef", "abcDEF", 4) 1 !2007-07-01 Sun 演習5-4 >>> def strend(s, t): ... return s[-len(t):] == t ... >>> strend("abcdef", "def") True >>> strend("abcdef", "abcdef") True >>> strend("abcdef", "0abcdef") False >>> strend("abcdef", "ff") False >>> "abcdef".endswith("def") True >>> "abcdef".endswith("abcdef") True >>> "abcdef".endswith("0abcdef") False >>> "abcdef".endswith("ff") False !2007-06-30 Sat 演習5-3 >>> s1 = "abc" >>> s2 = "def" >>> s1 += s2 >>> s1 'abcdef' >>> s2 'def' !2007-06-29 Fri 演習5-2 import sys lastc = '' def getch(): global lastc if lastc == '': return sys.stdin.read(1) else: r = lastc lastc = '' return r def ungetch(c): global lastc lastc = c def getfloat(): c = getch() while c.isspace(): c = getch() if not c.isdigit() and c != '' and c != '+' and c != '-' and c != '.': ungetch(c) return 0 if c == '-': sign = -1 else: sign = 1 if c == '+' or c == '-': c = getch() r = 0 while c.isdigit(): r = 10.0 * r + (ord(c) - ord('0')) c = getch() if c == '.': c = getch() power = 1.0 while c.isdigit(): r = 10.0 * r + (ord(c) - ord('0')) power *= 10.0 c = getch() r *= sign / power if c != '': ungetch(c) return r !2007-06-28 Thu 演習5-1 import sys lastc = '' def getch(): global lastc if lastc == '': return sys.stdin.read(1) else: r = lastc lastc = '' return r def ungetch(c): global lastc lastc = c def getint(): c = getch() while c.isspace(): c = getch() if not c.isdigit() and c != '' and c != '+' and c != '-': ungetch(c) return 0 if c == '-': sign = -1 else: sign = 1 if c == '+' or c == '-': d = c c = getch() if not c.isdigit(): if c != '': ungetch(c) ungetch(d) return d r = 0 while c.isdigit(): r = 10 * r + (ord(c) - ord('0')) c = getch() r *= sign if c != '': ungetch(c) return r !2007-06-27 Wed 演習4-14 >>> x = 1; y = 2 >>> x, y = y, x >>> x 2 >>> y 1 あまり関係ない? !2007-06-26 Tue 演習4-13 >>> def reverser(s, i, length): ... j = length - (i + 1) ... if i < j: ... s = s[:i] + s[j] + s[i+1:j] + s[i] + s[j+1:] ... return reverser(s, i+1, length) ... else: ... return s ... >>> def reverse(s): ... return reverser(s, 0, len(s)) ... >>> reverse("a") 'a' >>> reverse("ab") 'ba' >>> reverse("abc") 'cba' >>> reverse("abcd") 'dcba' 嬉しくないけど… !2007-06-25 Mon 演習4-12 >>> def itoa(n): ... sign = n ... n = abs(n) ... s = "" ... if n / 10: ... if sign < 0: ... s += itoa(-(n / 10)) ... else: ... s += itoa(n / 10) ... else: ... if sign < 0: ... s += '-' ... s += chr(n % 10 + ord('0')) ... return s ... >>> itoa(1) '1' >>> itoa(12) '12' >>> itoa(-12) '-12' >>> itoa(-1000) '-1000' !2007-06-24 Sun 演習4-11 (小数点の「.」が複数あってもエラーにならない…) 2007-06-14 Thu で getch(), ungetch(c) を変更 import sys lastc = '' val = [] def getch(): global lastc if lastc == '': return sys.stdin.read(1) else: r = lastc lastc = '' return r def ungetch(c): global lastc lastc = c def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def isdigit(c): return c >= '0' and c <= '9' def getop(): s = "" c = getch() while c == ' ' or c == '\t': c = getch() if not isdigit(c) and c != '.': return (c, c) while isdigit(c) or c == '.': s += c c = getch() ungetch(c) return ('NUMBER', float(s)) while 1: type, x = getop() #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x に 1 2 + 1 2 - 4 5 + * 1 2 / を入力すると、 3 -9 0.5 * isdigit(c) はデフォルトで存在した… !2007-06-23 Sat 演習4-10 (小数点の「.」が複数あってもエラーにならない…) * 2007-06-14 Thu で一部差し換え。嬉しくない気が… * そもそもは getch(), ungetch() がなくせるという話で書いてあるのだが、あった方が分かりやすい気が… import sys buf = "" val = [] def getch(): global buf if len(buf) == 0: buf = sys.stdin.readline() if len(buf) == 0: return '' c = buf[0] buf = buf[1:] return c def ungetch(c): global buf buf += c に 1 2 + 1 2 - 4 5 + * 1 2 / を入力すると、 3 -9 0.5 読み込んだときに配列にしたかったのだが、 またしても「文字列→配列」をどうやれば良いか忘れてしまった >>> list("abc") ['a', 'b', 'c'] で良いんだっけ??? !2007-06-22 Fri 演習4-8 import sys buf = 0 def getch(): global buf if buf != 0: c = buf else: c = sys.stdin.read(1) buf = 0 return c def ungetch(c): global buf if buf != 0: print "ungetch: too many characters" else: buf = c 特に嬉しくはない !2007-06-21 Thu 演習4-7 import sys buf = [] def getchar(): if len(buf) > 0: return buf.pop() else: return sys.stdin.read(1) def ungetch(c): buf.append(c) def ungets(s): for i in xrange(len(s)-1, -1, -1): ungetch(s[i]) !2007-06-20 Wed 演習4-6 (小数点の「.」が複数あってもエラーにならない…) import sys buf = [] val = [] def getch(): if len(buf) > 0: return buf.pop() else: return sys.stdin.read(1) def ungetch(c): buf.append(c) def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def clear(): val = [] def isdigit(c): return c >= '0' and c <= '9' def getop(): s = "" c = getch() while c == ' ' or c == '\t': c = getch() if (not isdigit(c)) and (c != '.') and (c != '-'): return (c, c) if c == '-': s += c c = getch() if not (isdigit(c) or c == '.'): ungetch(c) return ('-', '-') while isdigit(c) or c == '.': s += c c = getch() ungetch(c) return ('NUMBER', float(s)) variable = [0] * 26 while 1: type, x = getop() #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '=': pop() if var >= 'A' and var <= 'Z': variable[ord(var) - ord('A')] = pop() else: print "error: no variable name" elif x == '\n': v = pop() print "\t%.8g" % v elif type == '': break else: if type >= 'A' and type <= 'Z': push(variable[ord(type) - ord('A')]) elif type == 'v': push(v) else: print "error: unknown command %s" % x var = type に 1 2 + 1 2 - 4 5 + * 1 2 / 3 A = 2 A + v 1 + を入力すると、 3 -9 0.5 0 5 6 * isdigit(c) はデフォルトで存在した… !2007-06-19 Tue 演習4-5 うー、実装したのに貼付けるのを忘れてしまった… で、 1 2 + 3 1 2 - 4 5 + * -9 1 2 / 0.5 1.2 2.3 + 3.5 0 sin 0 1.5707963267948966 sin 1 0 cos 1 0 exp 1 1 exp 2.7182818 2 3 pow 8 3.14159265 2 / sin 1 3.14159265 2 / sin 0 cos + 2 5 2 pow 4 2 pow + 41 !2007-06-18 Mon 演習4-4 (小数点の「.」が複数あってもエラーにならない…) import sys buf = [] val = [] def getch(): if len(buf) > 0: return buf.pop() else: return sys.stdin.read(1) def ungetch(c): buf.append(c) def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def clear(): val = [] def isdigit(c): return c >= '0' and c <= '9' def getop(): s = "" c = getch() while c == ' ' or c == '\t': c = getch() if (not isdigit(c)) and (c != '.') and (c != '-'): return (c, c) if c == '-': s += c c = getch() if not (isdigit(c) or c == '.'): ungetch(c) return ('-', '-') while isdigit(c) or c == '.': s += c c = getch() ungetch(c) return ('NUMBER', float(s)) while 1: type, x = getop() #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '?': op2 = pop() print "\t%.8g" % op2 push(op2) elif x == 'c': clear() elif x == 'd': op2 = pop() push(op2) push(op2) elif x == 's': op1 = pop() op2 = pop() push(op1) push(op2) elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x に 1 ? 1 2 c 3 ? 1 d + 1 2 s / を入力すると、 1 1 3 3 2 2 * isdigit(c) はデフォルトで存在した… !2007-06-17 Sun 演習4-3 import sys buf = [] val = [] def getch(): if len(buf) > 0: return buf.pop() else: return sys.stdin.read(1) def ungetch(c): buf.append(c) def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def isdigit(c): return c >= '0' and c <= '9' def getop(): s = "" c = getch() while c == ' ' or c == '\t': c = getch() if (not isdigit(c)) and (c != '.') and (c != '-'): return (c, c) if c == '-': s += c c = getch() if not (isdigit(c) or c == '.'): ungetch(c) return ('-', '-') while isdigit(c) or c == '.': s += c c = getch() ungetch(c) return ('NUMBER', float(s)) while 1: type, x = getop() #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '%': op2 = pop() if op2 != 0.0: push(pop() % op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x に 1 2 + 1 2 - 4 5 + * 1 2 / - 1 -1.23 1 -1 + -10 3 % を入力すると、 3 -9 0.5 1 -1.23 0 2 * 小数点の「.」が複数あってもエラーにならない… * isdigit(c) はデフォルトで存在した… !2007-06-16 Sat 演習4-3 一歩前 racc 本のように正規表現で lex import sys, fileinput, re val = [] WORD = 0 NUMBER = 1 def lex(): pat_space = re.compile(r'\s+') pat_word = re.compile(r'[a-zA-Z_]\w*') pat_int = re.compile(r'\d+') pat_float = re.compile(r'\d+\.\d+') pat_others = re.compile(r'.|\n') ret = [] for line in fileinput.input(): while len(line) > 0: if line == '\n': ret.append(('\n', '\n')) m = pat_space.match(line) if m: line = line[m.end():]; continue m = pat_word.match(line) if m: ret.append((WORD, m.group())) line = line[m.end():]; continue m = pat_float.match(line) if m: ret.append((NUMBER, float(m.group()))) line = line[m.end():]; continue m = pat_int.match(line) if m: ret.append((NUMBER, int(m.group()))) line = line[m.end():]; continue m = pat_others.match(line) if m: ret.append((m.group(), m.group())) line = line[m.end():]; continue return ret def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 tokens = lex() for (type, x) in tokens: #print (type, x) if type == NUMBER: push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x パターンマッチの部分はもうちょっとすっきり書きたいなあ〜 !2007-06-15 Fri 演習4-3 一歩前 fileinput もどきを取り入れて import sys val = [] class Getch: def __init__(self): self.lastc = '' if len(sys.argv) > 1: self.files = sys.argv[1:] self.file = file(self.files.pop(0)) else: self.files = sys.stdin self.file = sys.stdin def getch(self): if self.lastc == '': c = self.file.read(1) if c == '': if self.files != sys.stdin and len(self.files) > 0: f = self.files.pop(0) self.file = file(f) return self.file.read(1) else: return c else: return c else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def getop(gc): s = "" c = gc.getch() while c == ' ' or c == '\t': c = gc.getch() if not c.isdigit() and c != '.': return (c, c) while c.isdigit() or c == '.': s += c c = gc.getch() gc.ungetch(c) return ('NUMBER', float(s)) gc = Getch() while 1: type, x = getop(gc) #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x !2007-06-14 Thu 演習4-3 一歩前 ちょっと変えて import sys val = [] class Getch: def __init__(self): self.lastc = '' def getch(self): if self.lastc == '': return sys.stdin.read(1) else: r = self.lastc self.lastc = '' return r def ungetch(self, c): self.lastc = c def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def isdigit(c): return c >= '0' and c <= '9' def getop(gc): s = "" c = gc.getch() while c == ' ' or c == '\t': c = gc.getch() if not isdigit(c) and c != '.': return (c, c) while isdigit(c) or c == '.': s += c c = gc.getch() gc.ungetch(c) return ('NUMBER', float(s)) gc = Getch() while 1: type, x = getop(gc) #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x * isdigit(c) はデフォルトで存在した… !2007-06-13 Wed 演習4-3 一歩前 import sys buf = [] val = [] def getch(): if len(buf) > 0: return buf.pop() else: return sys.stdin.read(1) def ungetch(c): buf.append(c) def push(f): val.append(f) def pop(): if len(val) > 0: return val.pop() else: return 0.0 def isdigit(c): return c >= '0' and c <= '9' def getop(): s = "" c = getch() while c == ' ' or c == '\t': c = getch() if not isdigit(c) and c != '.': return (c, c) while isdigit(c) or c == '.': s += c c = getch() ungetch(c) return ('NUMBER', float(s)) while 1: type, x = getop() #print (type, x) if type == 'NUMBER': push(x) elif x == '+': push(pop() + pop()) elif x == '*': push(pop() * pop()) elif x == '-': op2 = pop() push(pop() - op2) elif x == '/': op2 = pop() if op2 != 0.0: push(pop() / op2) else: raise ZeroDivisionError, "zero diviser" elif x == '\n': print "\t%.8g" % (pop()) elif type == '': break else: print "error: unknown command %s" % x に 1 2 + 1 2 - 4 5 + * 1 2 / を入力すると、 3 -9 0.5 * エラーには弱いかも * 小数点の「.」が複数あってもエラーにならないや * isdigit(c) はデフォルトで存在した… * 素直に ZeroDivisionError を捕捉すれば良い気も !2007-06-12 Tue 演習4-2 def isspace(c): return c == ' ' or c == '\t' def isdigit(c): return c >= '0' and c <= '9' def atof(s): val = 0.0 power = 1.0 i = 0 while i < len(s) and isspace(s[i]): i += 1 if i < len(s) and s[i] == '-': sign = -1 else: sign = 1 if s[i] == '+' or s[i] == '-': i += 1 while i < len(s) and isdigit(s[i]): val = 10.0 * val + (ord(s[i]) - ord('0')) i += 1 if i < len(s) and s[i] == '.': i += 1 while i < len(s) and isdigit(s[i]): val = 10.0 * val + (ord(s[i]) - ord('0')) power *= 10.0 i += 1 val = sign * val / power if i < len(s) and (s[i] == 'e' or s[i] == 'E'): i += 1 if i < len(s) and s[i] == '-': sign = -1 else: sign = 1 if i < len(s) and (s[i] == '+' or s[i] == '-'): i += 1 exp = 0 while i < len(s) and isdigit(s[i]): exp = 10 * exp + (ord(s[i]) - ord('0')) i += 1 if sign == 1: while exp > 0: val *= 10 exp -= 1 else: while exp > 0: val /= 10.0 exp -= 1 return val print atof(" 1") print atof("1") print atof("10") print atof("-10") print atof("1.2") print atof("-1.2") print atof("-1.23") print atof("-12.34") print atof("12.34") print atof("12e-3") print atof("12e+3") print atof("-12e-3") print atof("-12e+3") * うーん、「i < len(s)」だらけで、お間抜け過ぎ… * isspace(c), isdigit(c) はデフォルトで存在した… !2007-06-11 Mon 演習4-1 >>> def strrindex(s, t): ... for i in xrange(len(s)-1, -1, -1): ... if s[i:(i+len(t))] == t: ... return i ... return -1 ... >>> strrindex("abc abc", "abc") 4 >>> strrindex("abc abc", "abc ") 0 >>> strrindex("abc abc", "abcd") -1 !2007-06-10 Sun 演習4-1 >>> "abcdef abcdef".rindex("abc") 7 >>> def strrindex(s, t): ... pos = -1 ... for i in xrange(0, len(s)): ... if s[i:(i+len(t))] == t: ... pos = i ... return pos ... >>> strrindex("abc abc", "abc") 4 >>> "abc abc".rindex("abc") 4 >>> strrindex("abc abc", "abc ") 0 >>> "abc abc".rindex("abc ") 0 >>> strrindex("abc abc", "abcd") -1 >>> "abc abc".rindex("abcd") Traceback (most recent call last): File "", line 1, in ? ValueError: substring not found !2007-06-09 Sat 演習3-6 >>> def itoa(n, w): ... a = [] ... sign = n ... n = abs(n) ... while 1: ... a.append(chr(n % 10 + ord('0'))) ... n /= 10 ... if n == 0: ... break ... if sign < 0: ... a.append('-') ... a.reverse() ... import string ... str = string.join(a, "") ... if len(str) < w: ... str = ' ' * (w - len(str)) + str ... return str ... >>> itoa(1, 3) ' 1' >>> itoa(12, 3) ' 12' >>> itoa(-12, 3) '-12' >>> itoa(100, 3) '100' >>> itoa(1000, 3) '1000' >>> itoa(10000, 3) '10000' !2007-06-08 Fri 演習3-5 >>> def itob(n, b): ... a = [] ... sign = n ... n = abs(n) ... while 1: ... j = n % b ... if j <= 9: ... a.append(chr(j + ord('0'))) ... else: ... a.append(chr(j + ord('a') - 10)) ... n /= b ... if n == 0: ... break ... if sign < 0: ... a.append('-') ... a.reverse() ... import string ... return string.join(a, "") ... >>> itob(10, 2) '1010' >>> itob(10, 8) '12' >>> itob(10, 10) '10' >>> itob(10, 16) 'a' >>> itob(0xff, 16) 'ff' >>> itob(-10, 2) '-1010' !2007-06-07 Thu 演習3-4 >>> def itoa(n): ... a = [] ... sign = n ... n = abs(n) ... while 1: ... a.append(chr(n % 10 + ord('0'))) ... n /= 10 ... if n == 0: ... break ... if sign < 0: ... a.append('-') ... a.reverse() ... import string ... return string.join(a, "") ... >>> itoa(1) '1' >>> itoa(12) '12' >>> itoa(-12) '-12' >>> itoa(-1000) '-1000' また string に reverse ないか探しちゃったよ… なんで、こういう↓ことできないかね〜。 string.join だからしょうがないか… >>> ['a', 'b', 'c'].join("") Traceback (most recent call last): File "", line 1, in ? AttributeError: 'list' object has no attribute 'join' 負の割り算の結果が C とは違うようだ。 #include int main() { printf("%d\n", -1/10); return 0; } で、0 が返ってくる。一方、Python だと >>> -1 / 10 -1 >>> str(1) '1' >>> str(12) '12' >>> str(-12) '-12' !2007-06-06 Wed 演習3-3 >>> def expand(s): ... ret = "" ... i = 0 ... while i < len(s): ... ret += s[i] ... if i+1 < len(s) and s[i+1] == '-' and \ ... i+2 < len(s) and s[i+2] >= s[i]: ... c = ord(s[i]) + 1 ... i += 2; max = ord(s[i]) ... while c <= max: ... ret += chr(c) ... c += 1 ... i += 1 ... return ret ... >>> expand("a-c") 'abc' >>> expand("a-a") 'a' >>> expand("A-C") 'ABC' >>> expand("c-a") 'c-a' >>> expand("ab-d") 'abcd' >>> expand("ab-de") 'abcde' >>> expand("!-~") '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' !2007-06-05 Tue 演習3-2 >>> def unescape(t): ... s = "" ... flag = False ... for c in t: ... if flag == True: ... flag = False ... if c == 'n': ... s += '\n' ... elif c == 't': ... s += '\t' ... else: ... s += '\\' ... s += c ... elif c == '\\': ... flag = True ... else: ... s += c ... if flag == True: ... s += '\\' ... return s ... >>> unescape(escape("abc\t\n")) 'abc\t\n' >>> unescape(escape("abc\\")) 'abc\\' >>> escape("abc\\") 'abc\\' 解答のコードだと最後に「\\」があるとダメなのではないじゃないか? !2007-06-04 Mon 演習3-2 >>> def escape(t): ... s = "" ... for c in t: ... if c == '\n': ... s += "\\n" ... elif c == '\t': ... s += "\\t" ... else: ... s += c ... return s ... >>> escape("abc") 'abc' >>> escape("abc\t\n") 'abc\\t\\n' !2007-06-03 Sun 演習2-10 三項演算子って使えたっけ? >>> def lower(c): ... if c >= 'A' and c <= 'Z': ... return chr(ord(c) + ord('a') - ord('A')) ... else: ... return c ... >>> lower('A') 'a' >>> lower('a') 'a' >>> 'a'.lower() 'a' >>> 'A'.lower() 'a' >>> 'A'.upper() 'A' >>> 'a'.upper() 'A' >>> import string >>> string.upper('a') 'A' >>> string.upper('abc') 'ABC' >>> string.lower('A') 'a' >>> string.lower('ABC') 'abc' !2007-06-02 Sat 演習2-8 とばし。ワード長の求め方が不明なので… 演習2-9 >>> def bitcount(x): ... b = 0 ... while x != 0: ... b += 1 ... x &= x - 1 ... return b ... >>> bitcount(10) 2 >>> bitcount(11) 3 >>> bitcount(15) 4 !2007-06-01 Fri 演習2-7 >>> def invert(x, p, n): ... return x ^ (~(~0 << n) << (p+1-n)) ... >>> invert(0x55, 0, 4) Traceback (most recent call last): File "", line 1, in ? File "", line 2, in invert ValueError: negative shift count >>> invert(0x55, 4, 4) 75 >>> hex(75) '0x4b' >>> invert(0x55, 3, 4) 90 >>> hex(90) '0x5a' !2007-05-31 Thu 演習2-6 >>> def setbits(x, p, n, y): ... return x & ~(~(~0 << n) << (p+1-n)) | (y & ~(~0 << n)) << (p+1-n) ... >>> setbits(0x55, 1, 4, 0xaa) Traceback (most recent call last): File "", line 1, in ? File "", line 2, in setbits ValueError: negative shift count >>> setbits(0x55, 5, 4, 0xaa) 105 正しいかは不明…。そのままだし… !2007-05-30 Wed 演習2-5 >>> def any(s1, s2): ... i = 0 ... for c1 in s1: ... for c2 in s2: ... if c1 == c2: ... return i ... i += 1 ... return -1 ... >>> any("abc", "cbd") 1 >>> any("abc", "ABC") -1 !2007-05-29 Tue 演習2-4 >>> squeeze("abcdefg", "ag") 'bcdef' >>> squeeze("abcdefg", "AB") 'abcdefg' !2007-05-28 Mon 演習2-3 >>> def htoi(s): ... i = 0 ... if len(s) >= 1 and s[i] == '0': ... i += 1 ... if len(s) >= 2 and (s[i] == 'x' or s[i] == 'X'): ... i += 1 ... n = 0 ... index = True ... while i < len(s) and index: ... if s[i] >= '0' and s[i] <= '9': ... hexdigit = ord(s[i]) - ord('0') ... elif s[i] >= 'a' and s[i] <= 'f': ... hexdigit = ord(s[i]) - ord('a') + 10 ... elif s[i] >= 'A' and s[i] <= 'F': ... hexdigit = ord(s[i]) - ord('A') + 10 ... else: ... index = False ... if index: ... n = 16 * n + hexdigit ... i += 1 ... return n ... >>> htoi("1") 1 >>> htoi("10") 16 >>> htoi("a") 10 >>> htoi("0x1") 1 >>> htoi("0xa") 10 >>> htoi("0xf") 15 >>> htoi("0x10") 16 >>> htoi("X") 0 !2007-05-27 Sun 演習2-3 >>> int("0xf") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): 0xf >>> int("0xf", 16) 15 >>> int("f", 16) 15 >>> int("xf", 16) Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): xf !2007-05-26 Sat 演習1-24 import sys brace = 0 brack = 0 paren = 0 def getchar(): return sys.stdin.read(1) def search(c): global brace, brack, paren if c == '{': brace += 1 elif c == '}': brace -= 1 elif c == '[': brack += 1 elif c == ']': brack -= 1 elif c == '(': paren += 1 elif c == ')': paren -= 1 def in_comment(): c = getchar() d = getchar() while c != '*' or d != '/': c = d d = getchar() def in_quote(c): d = getchar() while d != c: if d == '\\': getchar() d = getchar() while 1: c = getchar() if not c: break if c == '/': c = getchar() if c == '*': in_comment() else: search(c) elif c == "'" or c == '"': in_quote(c) else: search(c) if brace < 0: print "Unbalanced braces" brace = 0 elif brack < 0: print "Unbalanced brackets" brack = 0 elif paren < 0: print "Unbalanced parentheses" paren = 0 if brace > 0: print "Unbalanced braces" elif brack > 0: print "Unbalanced brackets" elif paren > 0: print "Unbalanced parentheses" * グローバル変数の扱いではまってしまった… * global なんていうものを使ってみた * 本の通りの移植だが、途中でファイル終端になったらうまく動かない気が !2007-05-25 Fri 演習1-23 import fileinput, sys class Getchar: def __init__(self): self.char_list = [] for line in fileinput.input(): for c in line: self.char_list.append(c) def getchar(self): try: return self.char_list.pop(0) except IndexError: return '' def exists(self): if len(self.char_list) > 0: return True else: return False def rcomment(gc, c): if c == '/': d = gc.getchar() if (d == '*'): in_comment(gc) elif d == '/': sys.stdout.write(c) rcomment(d) else: sys.stdout.write(c) sys.stdout.write(d) elif c == '\'' or c == '"': echo_quote(gc, c) else: sys.stdout.write(c) def in_comment(gc): c = gc.getchar() d = gc.getchar() while c != '*' or d != '/': c = d d = gc.getchar() def echo_quote(gc, c): sys.stdout.write(c) d = gc.getchar() while d != c: sys.stdout.write(d) if d == '\\': sys.stdout.write(gc.getchar()) d = gc.getchar() sys.stdout.write(d) gc = Getchar() while gc.exists(): rcomment(gc, gc.getchar()) * 力尽きて、ほとんどそのまま&手抜きになってしまった… * getchar() 相当は(標準入力読み込みの場合は)、sys.stdin.read(1) で良いようだ… !2007-05-24 Thu 演習1-21 意味を汲み取ると、こんな感じなのだろうか? ちゃんと仕様を理解できているかちょっと不安なのだが、 そのまま移植しても余り意味がなさそうなので、まあいっか。 import fileinput, sys, re TABINC = 8 for line in fileinput.input(): length = len(line) for i in xrange(0, length, TABINC): str = line[i:i+TABINC] sys.stdout.write(re.sub(" +$", "\t", str)) 文字列のスライス指定は範囲を超えていても良かったんだね〜 >>> "1234567812345678"[0:8] '12345678' >>> "12345"[0:8] '12345' !2007-05-23 Wed 演習1-20 import fileinput, sys TABINC = 8 for line in fileinput.input(): nb = 0 pos = 1 for c in line: if c == '\t': nb = TABINC - (pos - 1) % TABINC while nb > 0: sys.stdout.write(' ') pos += 1 nb -= 1 else: sys.stdout.write(c) pos += 1 !2007-05-22 Tue 演習1-19 import fileinput, sys for line in fileinput.input(): l = list(line)[:-1] l.reverse() for c in l: sys.stdout.write(c) print * 改行まわりがいい加減… * list で使える reverse が文字列に適用できない… !2007-05-21 Mon 演習1-18 import fileinput for line in fileinput.input(): length = len(line.rstrip()) if length > 0: print line, len を使わずに「line == ""」の方が良いか??? !2007-05-20 Sun 演習1-17 import fileinput LONGLINE = 80 for line in fileinput.input(): length = len(line) if length > LONGLINE: print line, !2007-05-19 Sat 演習1-16 import fileinput max = 0 for line in fileinput.input(): length = len(line) print "%d, %s" % (length, line), if length > max: max = length longest = line if max > 0: print longest, !2007-05-18 Fri 演習1-15 >>> def celsius(fahr): ... return (5.0/9.0) * (fahr - 32.0) ... >>> lower = 0 >>> upper = 300 >>> step = 20 >>> fahr = lower >>> while fahr <= upper: ... print "%3.0f %6.1f" % (fahr, celsius(fahr)) ... fahr += step ... 0 -17.8 20 -6.7 40 4.4 60 15.6 80 26.7 100 37.8 120 48.9 140 60.0 160 71.1 180 82.2 200 93.3 220 104.4 240 115.6 260 126.7 280 137.8 300 148.9 !2007-05-17 Thu 演習1-14 import fileinput MAXHIST = 15 cc = {} for line in fileinput.input(): for c in line: try: cc[c] += 1 except KeyError: cc[c] = 1 maxvalue = max(cc.values()) for i in xrange(1, 128 + 1): c = chr(i) try: n = cc[c] len = n * MAXHIST / maxvalue if len <= 0: len = 1 except KeyError: n = 0 len = 0 print "%5d - %s - %5d : %s" % (i, repr(c), n, "*" * len) * 印字可能か調べる方法が分からなかった…。はじめは %c で受けていたが、やめて str() で囲って出力することに。と思ったら、str() じゃだめで、repr() を使った。けど、それだと「''」で囲われた文字になってしまう… * string.printable というのはあるな !2007-05-16 Wed 演習1-13 import fileinput, re wl = {} for line in fileinput.input(): list = re.split("[\t\n ]+", re.sub("[\t\n ]+$", "", line)) for w in list: try: wl[len(w)] += 1 except KeyError: wl[len(w)] = 1 for i in xrange(1, max(wl.keys()) + 1): try: print "%5d - %5d : %s" % (i, wl[i], "*" * wl[i]) except KeyError: print "%5d - %5d : " % (i, 0) * 最大長の考慮していなかった〜(MAXHIST 使い忘れた〜) * 垂直方向のヒストグラムは、とばし〜 !2007-05-15 Tue 演習1-12 import fileinput, re for line in fileinput.input(): list = re.split("[\t\n ]+", re.sub("[\t\n ]+$", "", line)) for w in list: print w 元のに近い記述 import fileinput, sys IN = 1 OUT = 0 state = OUT for line in fileinput.input(): for c in line: if (c == ' ') or (c == '\n') or (c == '\t'): if state == IN: sys.stdout.write('\n') state = OUT elif state == OUT: state = IN sys.stdout.write(c) else: sys.stdout.write(c) !2007-05-14 Mon 演習1-10 import sys, fileinput for line in fileinput.input(): for c in line: if c == '\t': sys.stdout.write("\\t") elif c == '\b': sys.stdout.write("\\b") elif c == '\\': sys.stdout.write("\\\\") else: sys.stdout.write(c) バックスペースってどう入力するの? !2007-05-13 Sun 演習1-9 続き import sys, fileinput lastc = 'a' for line in fileinput.input(): for c in line: if c != ' ': sys.stdout.write(c) elif lastc != ' ': sys.stdout.write(c) lastc = c import sys, fileinput lastc = 'a' for line in fileinput.input(): for c in line: if (c != ' ') or (lastc != ' '): sys.stdout.write(c) lastc = c !2007-05-12 Sat 演習1-9 import sys, fileinput lastc = 'a' for line in fileinput.input(): for c in line: if c != ' ': #print c, sys.stdout.write(c) if c == ' ': if lastc != ' ': #print c, sys.stdout.write(c) lastc = c 「print c,」って空白が入っちゃうんだっけ??? import fileinput, sys, re for line in fileinput.input(): sys.stdout.write(re.sub(" +", " ", line)) !2007-05-11 Fri 演習1-8 import fileinput nb = 0 nt = 0 nl = 0 for line in fileinput.input(): #list = line.split('') for c in line: if c == ' ': nb += 1 if c == '\t': nt += 1 if c == '\n': nl += 1 print nb, nt, nl 「else if 」使うなら import fileinput nb = 0 nt = 0 nl = 0 for line in fileinput.input(): #list = line.split('') for c in line: if c == ' ': nb += 1 elif c == '\t': nt += 1 elif c == '\n': nl += 1 print nb, nt, nl fileinput に each_char みたいなのはないのか? >>> "a b c".split() ['a', 'b', 'c'] >>> "a b c".split('') Traceback (most recent call last): File "", line 1, in ? ValueError: empty separator >>> "a b c".split(' ') ['a', 'b', 'c'] うげ(2005-11-20 に気がついているようだが、未決? そもそも文字列がシーケンス型だから split する意味がないという落ちかも) !2007-05-10 Thu 演習1-6 * readlines とか fileinput とか使うと EOF を考える必要はなさそう? * readline とかが '' を返してきたら EOF ということで良いのか? !2007-05-09 Wed 演習1-5 >>> for fahr in xrange(300, -1, -20): ... print "%3d %6.1f" % (fahr, (5.0/9.0)*(fahr - 32)) ... 300 148.9 280 137.8 260 126.7 240 115.6 220 104.4 200 93.3 180 82.2 160 71.1 140 60.0 120 48.9 100 37.8 80 26.7 60 15.6 40 4.4 20 -6.7 0 -17.8 !2007-05-08 Tue 演習1-3 >>> lower = 0 >>> upper = 300 >>> step = 20 >>> print "Fahr Celsius" Fahr Celsius >>> fahr = lower >>> while fahr <= upper: ... celsius = (5.0/9.0) * (fahr - 32.0) ... print "%3.0f %6.1f" % (fahr, celsius) ... fahr += step ... 0 -17.8 20 -6.7 40 4.4 60 15.6 80 26.7 100 37.8 120 48.9 140 60.0 160 71.1 180 82.2 200 93.3 220 104.4 240 115.6 260 126.7 280 137.8 300 148.9 「%3.0f」で「.0」がないと小数点が表示されてしまうのか〜。ふーん。 !2007-05-07 Mon 演習1-2 >>> print "hello, world\y" hello, world\y >>> print "hello, world\7" hello, world >>> print "hello, world\?" hello, world\? 「\7」でブザーなるのかな? !2007-05-06 Sun 演習1-1 >>> print "hello, world" hello, world >>> print 'hello, world' hello, world !2007-05-05 Sat import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print "*test1*" def suite(): suite = unittest.TestSuite() suite.addTest(TestSequenceFunctions("test1")) return suite if __name__ == '__main__': s = suite() runner = unittest.TextTestRunner() r = runner.run(s) print "* 1 *", r.errors print "* 2 *", r.failures print "* 3 *", r.testsRun print "* 4 *", r.wasSuccessful() で、 $ python foo.py *test1* . ---------------------------------------------------------------------- Ran 1 test in 0.002s OK * 1 * [] * 2 * [] * 3 * 1 * 4 * True 「isSuccessful()」でなく「wasSuccessful()」なんだ〜 テストは過去のものだから? TestResult オブジェクトの色々なメソッドは とりあえずサブクラスで拡張するつもりがないので、とばし TestLoader オブジェクトも とばします〜 テストの GUI インタフェースはどこに? (http://pyunit.cvs.sourceforge.net/pyunit/pyunit/unittestgui.py?view=log ?) !2007-05-04 Fri TestSuite#run(result) も、どう使うのか良く分からない。 普通は自分で呼び出す必要はなさそうなのだが (素直に unittest.py を呼んだ方が早いかも) 「5.3.7 TestResultオブジェクト」 TestCaseクラスとTestSuiteクラスのテスト結果を正しく記録しますので、 は、 TestCaseクラスとTestSuiteクラス「は」 ではないだろうか? 原文は、 The TestCase and TestSuite classes ensure that results are properly recorded import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print "*test1*" def suite(): suite = unittest.TestSuite() suite.addTest(TestSequenceFunctions("test1")) return suite if __name__ == '__main__': s = suite() runner = unittest.TextTestRunner() print runner.run(s) で、 $ python foo.py *test1* . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK !2007-05-03 Thu import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*setUp*" def test1(self): print "*test1*" def test2(self): print "*test2*" def suite(): suite = unittest.TestSuite() suite.addTests((TestSequenceFunctions("test1"), TestSequenceFunctions("test2"))) return suite if __name__ == '__main__': s = suite() runner = unittest.TextTestRunner() runner.run(s) で、 $ python foo.py *setUp* *test1* .*setUp* *test2* . ---------------------------------------------------------------------- Ran 2 tests in 0.008s OK !2007-05-02 Wed import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print self.shortDescription() if __name__ == '__main__': unittest.main() で、 $ python foo.py None . ---------------------------------------------------------------------- Ran 1 test in 0.003s OK テストメソッドのdocstringの先頭の一行 import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): "*doc*" print self.shortDescription() if __name__ == '__main__': unittest.main() で、 $ python foo.py *doc* . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK 別に「"""〜"""」でなくて良いのか〜 !2007-05-01 Tue import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print self.id() if __name__ == '__main__': unittest.main() で、 $ python foo.py __main__.TestSequenceFunctions.test1 . ---------------------------------------------------------------------- Ran 1 test in 0.005s OK !2007-04-30 Mon import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print self.defaultTestResult() if __name__ == '__main__': unittest.main() で、 $ python foo.py ---------------------------------------------------------------------- Ran 0 tests in 0.000s OK ? import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print self.defaultTestResult() if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.003s OK !2007-04-29 Sun import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*", self.countTestCases(), "*" def tearDown(self): print "*", self.countTestCases(), "*" def test1(self): print "*test1*" def test2(self): print "*test2*" def suite(): suite = unittest.TestSuite() print "**", suite.countTestCases(), "**" suite.addTest(TestSequenceFunctions("test1")) suite.addTest(TestSequenceFunctions("test2")) print "**", suite.countTestCases(), "**" return suite if __name__ == '__main__': s = suite() runner = unittest.TextTestRunner() runner.run(s) で、 $ python foo.py ** 0 ** ** 2 ** * 1 * *test1* * 1 * .* 1 * *test2* * 1 * . ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK !2007-04-28 Sat import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print "*", self.countTestCases(), "*" if __name__ == '__main__': unittest.main() で、 $ python foo.py * 1 * . ---------------------------------------------------------------------- Ran 1 test in 0.002s OK 複数にしても、 import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print "*", self.countTestCases(), "*" def test2(self): print "*", self.countTestCases(), "*" if __name__ == '__main__': unittest.main() で、 $ python foo.py * 1 * .* 1 * . ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK !2007-04-27 Fri >>> import unittest >>> unittest.failureException Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'failureException' >>> unittest.AssertionError Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'AssertionError' >>> unittest.TestCase.failureException >>> unittest.TestCase.AssertionError Traceback (most recent call last): File "", line 1, in ? AttributeError: type object 'TestCase' has no attribute 'AssertionError' どう使うかは不明 !2007-04-26 Thu import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.fail("*NG*") if __name__ == '__main__': unittest.main() で、 $ python foo.py F ====================================================================== FAIL: test1 (__main__.TestSequenceFunctions) ---------------------------------------------------------------------- Traceback (most recent call last): File "foo.py", line 5, in test1 self.fail("*NG*") File "/usr/lib/python2.3/unittest.py", line 270, in fail raise self.failureException, msg AssertionError: *NG* ---------------------------------------------------------------------- Ran 1 test in 0.008s FAILED (failures=1) どういう時に使うのだろう? 来ちゃいけない条件の時? !2007-04-25 Wed import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.failIf(False) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK なぜか assert 系の対がない !2007-04-24 Tue import unittest def callable(): x #1 / 0 class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertRaises ((ZeroDivisionError, NameError), callable) self.failUnlessRaises((ZeroDivisionError, NameError), callable) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK !2007-04-23 Mon import unittest def callable(): 1 / 0 class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertRaises (ZeroDivisionError, callable) self.failUnlessRaises(ZeroDivisionError, callable) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK !2007-04-22 Sun import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertNotAlmostEqual(1.21, 1.29, 1) self.failIfAlmostEqual (1.21, 1.29, 1) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK !2007-04-21 Sat import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertAlmostEqual (1.201, 1.209, 1) self.failUnlessAlmostEqual(1.201, 1.209, 1) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK 第三引数 places に小数点を与えると出るエラーによると、 「if round(second-first, places) != 0:」のように検査しているようだ。 >>> round(1.21-1.29) -0.0 >>> round(1.21-1.29,0) -0.0 >>> round(1.21-1.29,1) -0.10000000000000001 >>> round(1.21-1.29,2) -0.080000000000000002 >>> round(1.201-1.209,0) -0.0 >>> round(1.201-1.209,1) -0.0 >>> round(1.201-1.209,2) -0.01 !2007-04-20 Fri import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertNotEqual("foo", "bar") self.failIfEqual("foo", "bar") if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK !2007-04-19 Thu import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assertEqual("foo", "foo") self.failUnlessEqual("foo", "foo") if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK 考えてみると、ruby のと違って、assert の数は出力されないな !2007-04-18 Wed import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): #self.failUnless(False, "*message*") self.failUnless(True, "*message*") if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK * failUnless は単なる assert_ への alias かな? * なぜ全てに alias があるのだろうか?互換性の問題?「JUnitのPython版」らしいし !2007-04-17 Tue import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assert_(False, "*message*") #self.assert_(True, "*message*") if __name__ == '__main__': unittest.main() で、 $ python foo.py F ====================================================================== FAIL: test1 (__main__.TestSequenceFunctions) ---------------------------------------------------------------------- Traceback (most recent call last): File "foo.py", line 5, in test1 self.assert_(False, "*message*") File "/usr/lib/python2.3/unittest.py", line 278, in failUnless if not expr: raise self.failureException, msg AssertionError: *message* ---------------------------------------------------------------------- Ran 1 test in 0.006s FAILED (failures=1) !2007-04-16 Mon TestCase#run(), TestCase#debug() はどうやって確かめたら? import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): #self.assert_(False) self.assert_(True) if __name__ == '__main__': unittest.main() で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK 一方、 import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): self.assert_(False) #self.assert_(True) if __name__ == '__main__': unittest.main() で、 $ python foo.py F ====================================================================== FAIL: test1 (__main__.TestSequenceFunctions) ---------------------------------------------------------------------- Traceback (most recent call last): File "foo.py", line 5, in test1 self.assert_(False) File "/usr/lib/python2.3/unittest.py", line 278, in failUnless if not expr: raise self.failureException, msg AssertionError ---------------------------------------------------------------------- Ran 1 test in 0.006s FAILED (failures=1) なんか Traceback 不要な気がするんだけど… !2007-04-15 Sun import unittest def testSomething(): print "*testSomething*" assert "foo" == "foo" def makeSomethingDB(): print "*setUp*" def deleteSomethingDB(): print "*tearDown*" testcase = unittest.FunctionTestCase(testSomething, setUp=makeSomethingDB, tearDown=deleteSomethingDB) runner = unittest.TextTestRunner() runner.run(testcase) で、 $ python foo.py *setUp* *testSomething* *tearDown* . ---------------------------------------------------------------------- Ran 1 test in 0.006s OK !2007-04-14 Sat import unittest def testSomething1(): assert "foo" == "foo" def testSomething2(): assert "foo" == "foo" testcase1 = unittest.FunctionTestCase(testSomething1) testcase2 = unittest.FunctionTestCase(testSomething2) suite = unittest.TestSuite() suite.addTest(testcase1) suite.addTest(testcase2) runner = unittest.TextTestRunner() runner.run(suite) で、 $ python foo.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK 推測で書いてみたのだが良いのだろうか? !2007-04-13 Fri import unittest def testSomething(): assert "foo" == "foo" testcase = unittest.FunctionTestCase(testSomething) runner = unittest.TextTestRunner() runner.run(testcase) で、 $ python foo.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK 推測で書いてみたのだが良いのだろうか? !2007-04-12 Thu import unittest class TestSequenceFunctions(unittest.TestCase): def test1(self): print "*test1*" class TestSequenceFunctions2(unittest.TestCase): def test2(self): print "*test2*" if __name__ == '__main__': suite1 = unittest.TestSuite() suite1.addTest(TestSequenceFunctions("test1")) suite2 = unittest.TestSuite() suite2.addTest(TestSequenceFunctions2("test2")) s = unittest.TestSuite((suite1, suite2)) runner = unittest.TextTestRunner() runner.run(s) で、 $ python foo.py *test1* .*test2* . ---------------------------------------------------------------------- Ran 2 tests in 0.005s OK !2007-04-11 Wed import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*setUp*" def test1(self): print "*test1*" def test2(self): print "*test2*" if __name__ == '__main__': suite = unittest.makeSuite(TestSequenceFunctions) runner = unittest.TextTestRunner() runner.run(suite) で、 $ python foo.py *setUp* *test1* .*setUp* *test2* . ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK !2007-04-10 Tue 昨日ので、「suite.addTest(TestSequenceFunctions("test2"))」を コメントアウトして実行すると、 $ python foo.py *setUp* *test1* . ---------------------------------------------------------------------- Ran 1 test in 0.004s OK !2007-04-09 Mon どうもドキュメント(「テストの構成」の部分)が分かりにくいな〜 順に試せば理解できるように書いて欲しい…。 * runTest() まわりの記述 良く分からない import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*setUp*" def test1(self): print "*test1*" def test2(self): print "*test2*" def suite(): suite = unittest.TestSuite() suite.addTest(TestSequenceFunctions("test1")) suite.addTest(TestSequenceFunctions("test2")) return suite if __name__ == '__main__': s = suite() runner = unittest.TextTestRunner() runner.run(s) で、 $ python foo.py *setUp* *test1* .*setUp* *test2* . ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK !2007-04-08 Sun import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*setUp*" def test1(self): print "*test1" class TestSequenceFunctions2(unittest.TestCase): def setUp(self): print "*setUp2*" def test2(self): print "*test2" if __name__ == '__main__': unittest.main() で、 $ python foo.py *setUp* *test1 .*setUp2* *test2 . ---------------------------------------------------------------------- Ran 2 tests in 0.007s OK !2007-04-07 Sat import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): print "*setUp*" def tearDown(self): print "*terDown*" def test1(self): print "*test1" def test2(self): print "*test2" if __name__ == '__main__': unittest.main() で、 $ python foo.py *setUp* *test1 *terDown* .*setUp* *test2 *terDown* . ---------------------------------------------------------------------- Ran 2 tests in 0.013s OK !2007-04-06 Fri import random import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.seq = range(10) def testshuffle(self): # make sure the shuffled sequence does not lose any elements random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) def testchoice(self): element = random.choice(self.seq) self.assert_(element in self.seq) def testsample(self): self.assertRaises(ValueError, random.sample, self.seq, 20) for element in random.sample(self.seq, 5): self.assert_(element in self.seq) suite = unittest.makeSuite(TestSequenceFunctions) unittest.TextTestRunner(verbosity=2).run(suite) で、 $ python foo.py testchoice (__main__.TestSequenceFunctions) ... ok testsample (__main__.TestSequenceFunctions) ... ok testshuffle (__main__.TestSequenceFunctions) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.003s OK !2007-04-05 Thu まんま import random import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.seq = range(10) def testshuffle(self): # make sure the shuffled sequence does not lose any elements random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) def testchoice(self): element = random.choice(self.seq) self.assert_(element in self.seq) def testsample(self): self.assertRaises(ValueError, random.sample, self.seq, 20) for element in random.sample(self.seq, 5): self.assert_(element in self.seq) if __name__ == '__main__': unittest.main() で、 $ python foo.py ... ---------------------------------------------------------------------- Ran 3 tests in 0.003s OK !2007-04-04 Wed >>> import types >>> isinstance("", unicode) False >>> isinstance("", str) True >>> isinstance("", types.StringTypes) True >>> isinstance(u"", types.StringTypes) True >>> isinstance(u"", unicode) True !2007-04-03 Tue >>> import types >>> types.FrameType >>> types.BufferType !2007-04-02 Mon >>> import types >>> types.TracebackType >>> import sys >>> sys.exc_traceback Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'exc_traceback' !2007-04-01 Sun >>> import types >>> types.EllipsisType >>> ellipsis Traceback (most recent call last): File "", line 1, in ? NameError: name 'ellipsis' is not defined はにゃ? !2007-03-31 Sat >>> import types >>> types.SliceType >>> [][:] [] >>> type([][:]) >>> slice ここでいう slice って? !2007-03-30 Fri >>> import types >>> types.XRangeType >>> xrange >>> type(xrange(1, 4)) >>> xrange(1, 4) xrange(1, 4) >>> isinstance(xrange(1, 4), xrange) True !2007-03-29 Thu >>> import types >>> types.FileType >>> type(open) >>> type(open()) Traceback (most recent call last): File "", line 1, in ? TypeError: file() takes at least 1 argument (0 given) >>> type(open("foo", "r")) >>> import sys >>> sys.stdout ', mode 'w' at 0x401e1060> >>> type(sys.stdout) !2007-03-28 Wed >>> import types >>> types.ModuleType どう確認にすれば? !2007-03-27 Tue >>> import types >>> types.BuiltinFunctionType >>> type(dir) >>> isinstance(dir, types.BuiltinFunctionType) True >>> isinstance(dir, type(type)) False >>> isinstance(dir, type(dir)) True >>> types.BuiltinMethodType !2007-03-26 Mon >>> import types >>> types.MethodType >>> class Foo: ... def foo(self): ... pass ... >>> type(Foo().foo) >>> isinstance(Foo().foo, types.MethodType) True >>> types.UnboundMethodType !2007-03-25 Sun >>> import types >>> types.InstanceType >>> class Foo: ... pass ... >>> type(Foo()) >>> Foo() <__main__.Foo instance at 0x402218ec> >>> isinstance(Foo(), Foo) True !2007-03-24 Sat >>> import types >>> types.ClassType >>> class Foo: ... pass ... >>> type(Foo) >>> Foo !2007-03-23 Fri >>> import types >>> types.CodeType !2007-03-22 Thu >>> import types >>> types.GeneratorType >>> type(iter('abc')) >>> type(iter('abc').next()) >>> type(iter('abc').next) !2007-03-21 Wed >>> import types >>> types.FunctionType >>> function Traceback (most recent call last): File "", line 1, in ? NameError: name 'function' is not defined >>> lambda File "", line 1 lambda ^ SyntaxError: invalid syntax >>> type(dir) >>> def foo(): ... pass ... >>> type(foo) >>> lambda x: x + 1 at 0x40219b1c> >>> type(lambda x: x + 1) >>> types.LambdaType !2007-03-20 Tue >>> import types >>> types.DictType >>> dict >>> dict() {} >>> type({}) >>> isinstance({}, dict) True >>> types.DictionaryType !2007-03-19 Mon >>> import types >>> types.ListType >>> list >>> list() [] >>> type(list()) >>> type([]) >>> isinstance([], list) True !2007-03-18 Sun >>> import types >>> types.TupleType >>> tuple >>> tuple() () >>> type(tuple()) >>> type(()) >>> type((,)) File "", line 1 type((,)) ^ SyntaxError: invalid syntax >>> type((1,2)) >>> isinstance(tuple(), tuple) True !2007-03-17 Sat >>> import types >>> types.UnicodeType >>> u'' u'' >>> type(u'') >>> u Traceback (most recent call last): File "", line 1, in ? NameError: name 'u' is not defined >>> unicode >>> unicode() u'' >>> isinstance(unicode(), unicode) True !2007-03-16 Fri >>> import types >>> types.StringType >>> str >>> str() '' >>> isinstance(str(), str) True !2007-03-15 Thu >>> import types >>> types.ComplexType >>> complex >>> complex() 0j >>> isinstance(complex(), complex) True !2007-03-14 Wed >>> import types >>> types.FloatType >>> float >>> float() 0.0 >>> isinstance(0, float) False >>> isinstance(0.0, float) True !2007-03-13 Tue >>> import types >>> types.LongType >>> long >>> long() 0L >>> isinstance(0, long) False >>> isinstance(0L, long) True !2007-03-12 Mon >>> import types >>> types.IntType >>> type(1) >>> type(int) >>> type(int()) >>> isinstance(1, int) True >>> isinstance(1.0, int) False >>> isinstance(int, int) False >>> isinstance(int(), int) True !2007-03-11 Sun >>> import types >>> types.BooleanType >>> bool >>> type(True) !2007-03-10 Sat >>> import types >>> types.TypeType >>> type >>> isinstance(type, type) True >>> isinstance(types.TypeType , type) True !2007-03-09 Fri types は非推奨とか聞いたような気もするのだが、一応見ておこう >>> import types >>> types.NoneType >>> type(None) >>> types.NoneType == type(None) True >>> isinstance(None, types.NoneType) True >>> isinstance(None, None) Traceback (most recent call last): File "", line 1, in ? TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types !2007-03-08 Thu >>> import zipfile >>> z = zipfile.ZipFile("test.zip", "w") >>> z.write("hoge1") >>> z.write("hoge2") >>> z.write("hoge3") >>> z.close() >>> z = zipfile.ZipFile("test.zip", "a") >>> z.write("hoge4") >>> z.namelist() ['hoge1', 'hoge2', 'hoge3', 'hoge4'] >>> z.close() >>> z = zipfile.ZipFile("test.zip") >>> z.namelist() ['hoge1', 'hoge2', 'hoge3', 'hoge4'] tar のときは圧縮していると追加書き込みできなかったが、zip では大丈夫だった。 !2007-03-07 Wed >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> zi = z.getinfo("PDFJ/Object.pm") >>> zi.filename 'PDFJ/Object.pm' >>> zi.date_time (2003, 8, 17, 23, 52, 4) >>> zi.compress_type 8 >>> zi.comment '' >>> zi.extra '' >>> zi.create_system 0 >>> zi.create_version 20 >>> zi.extract_version 20 >>> zi.reserved 0 >>> zi.flag_bits 0 >>> zi.volume 0 >>> zi.internal_attr 1 >>> zi.external_attr 32L >>> zi.header_offset 0L >>> zi.file_offset 44L >>> zi.CRC 534641135 >>> zi.compress_size 1816L >>> zi.file_size 8222L !2007-03-06 Tue >>> import zipfile >>> z = zipfile.PyZipFile("test.zip", "w") >>> z.writepy(".") >>> z.namelist() ['z.pyc', 'fibo.pyc', 'foo.pyc'] >>> z.close() !2007-03-05 Mon >>> import zipfile >>> z = zipfile.PyZipFile("test.zip", "w") >>> z.writepy("foo.py") >>> z.namelist() ['foo.pyc'] >>> z.close() !2007-03-04 Sun >>> import zipfile >>> z = zipfile.PyZipFile("tmp/archive/PDFJ-0.7.zip") >>> z.namelist() ['PDFJ/Object.pm', ... !2007-03-03 Sat >>> import zipfile >>> z = zipfile.ZipFile("test.zip", "w") >>> z.write("hoge1") >>> z.write("hoge2") >>> z.write("hoge3") >>> z.close() >>> z = zipfile.ZipFile("test.zip") >>> z.namelist() ['hoge1', 'hoge2', 'hoge3'] writestr() って説明を読んだだけでは挙動が良く分からないな !2007-03-02 Fri >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.read("PDFJ/Object.pm") '# classes for PDF objects\r\n# ... !2007-03-01 Thu >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.getinfo("PDFJ/Object.pm") !2007-02-28 Wed >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.close() !2007-02-27 Tue >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.debug 0 !2007-02-26 Mon >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.testzip() >>> print z.testzip() None !2007-02-25 Sun >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.printdir() File Name Modified Size PDFJ/Object.pm 2003-08-17 23:52:04 8222 ... XPDFJ.pm 2003-10-07 10:43:42 15043 !2007-02-24 Sat >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.namelist() ['PDFJ/Object.pm', 'PDFJ/TTF.pm', 'PDFJ/Unicode.pm', 'PDFJ/U2C.pm', 'PDFJ/S2U.pm', 'PDFJ/E2U.pm', 'CHANGES', 'demo.pdf', 'demo.pl', 'demo.xp', 'frame.jpg', 'Makefile.PL', 'nouhinsho.dat', 'nouhinsho.pl', 'of2002.inc', 'of2002.pdf', 'of2002.xp', 'PDFJ.jp.pdf', 'PDFJ.jp.pod', 'PDFJ.pm', 'pod2pdf.pl', 'readme.txt', 'stddefs.inc', 'stdfontsH.inc', 'stdfontsV.inc', 'text2pdf.pl', 'TODO', 'ttcinfo.pl', 'ttfinfo.pl', 'XPDFJ.jp.pdf', 'XPDFJ.jp.pod', 'xpdfj.pl', 'XPDFJ.pm'] !2007-02-23 Fri >>> import zipfile >>> z = zipfile.ZipFile("PDFJ-0.7.zip") >>> z.infolist() [, ... !2007-02-22 Thu >>> import zipfile >>> zipfile.ZIP_STORED 0 >>> zipfile.ZIP_DEFLATED 8 !2007-02-21 Wed >>> import zipfile >>> zipfile.is_zipfile("PDFJ-0.7.zip") True >>> zipfile.is_zipfile(".emacs") False !2007-02-20 Tue >>> import tarfile >>> tarfile.TAR_PLAIN 0 >>> tarfile.TAR_GZIPPED 8 !2007-02-19 Mon >>> tf = tarfile.open("hoge.tar.gz", "a:gz") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/tarfile.py", line 880, in open return func(name, filemode, fileobj) File "/usr/lib/python2.3/tarfile.py", line 926, in gzopen raise ValueError, "mode must be 'r' or 'w'" ValueError: mode must be 'r' or 'w' gz だと a はダメらしい。それはそれで不便だ。 内部で展開するなり何でも良いけど予期に計らってくれると嬉しいなあ〜 !2007-02-18 Sun import sys import tarfile tar = tarfile.open(mode="r|", fileobj=sys.stdin) print tar.getnames() tar.close() で、 $ cat hoge.tar | python foo.py ['hoge1', 'hoge2', 'hoge3', 'hoge4'] !2007-02-17 Sat >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> ti = tf.getmember("hoge1") >>> ti.isfile() True >>> ti.isreg() True >>> ti.isdir() False >>> ti.issym() False >>> ti.islnk() False >>> ti.ischr() False >>> ti.isblk() False >>> ti.isfifo() False >>> ti.isdev() False isreg の reg は regular の reg か? !2007-02-16 Fri >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> ti = tf.getmember("hoge1") >>> ti.name 'hoge1' >>> ti.size 4L >>> ti.mtime 1171962598L >>> ti.mode 420 >>> ti.type '0' >>> ti.linkname '' >>> ti.uid 1000 >>> ti.gid 100 >>> ti.uname 'nnakamur' >>> ti.gname 'users' !2007-02-15 Thu >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> ti = tf.getmember("hoge1") >>> ti.tobuf() 'hoge1\x00\x00\x00\x00\ ... !2007-02-14 Wed >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> ti = tf.getmember("hoge1") >>> ti.frombuf() Traceback (most recent call last): File "", line 1, in ? TypeError: frombuf() takes exactly 2 arguments (1 given) >>> ti.frombuf("foo") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/tarfile.py", line 668, in frombuf tarinfo.mode = int(buf[100:108], 8) ValueError: invalid literal for int(): * 文字列のフォーマットが不明… * マニュアルだと引数さえ必要にも思えないのだが…(文章からは引数が必要だろうと分かるけど) !2007-02-13 Tue >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.errorlevel 0 !2007-02-12 Mon >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.debug 0 !2007-02-11 Sun >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.ignore_zeros False !2007-02-10 Sat >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.dereference False !2007-02-09 Fri >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.posix True >>> tarfile.posix Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'posix' !2007-02-08 Thu >>> import tarfile >>> tf = tarfile.open("hoge.tar", "a") >>> tf.gettarinfo("hoge4") >>> tf.addfile(tf.gettarinfo("hoge4")) >>> tf.getnames() ['hoge1', 'hoge2', 'hoge3', 'hoge4'] >>> tf.close() >>> tf = tarfile.open("hoge.tar") >>> tf.getnames() ['hoge1', 'hoge2', 'hoge3', 'hoge4'] >>> tf.list() -rw-r--r-- nnakamur/users 4 2007-02-20 12:09:58 hoge1 -rw-r--r-- nnakamur/users 4 2007-02-20 12:10:02 hoge2 -rw-r--r-- nnakamur/users 0 2007-02-20 12:10:24 hoge3 -rw-r--r-- nnakamur/users 4 2007-02-21 12:56:31 hoge4 link to hoge4 なぜかリンクに !2007-02-07 Wed >>> import tarfile >>> tf = tarfile.open("hoge.tar", "a") >>> tf.gettarinfo("hoge1") >>> tf.gettarinfo("hogehoge") >>> tf.gettarinfo("hogehogehoge") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/tarfile.py", line 1085, in gettarinfo statres = os.lstat(name) OSError: [Errno 2] No such file or directory: 'hogehogehoge' ファイルがないとダメなのか !2007-02-06 Tue >>> import tarfile >>> tf = tarfile.open("hoge.tar", "a") >>> ti = tf.getmember("hoge1") >>> tf.getnames() ['hoge1', 'hoge2'] >>> tf.addfile(ti) >>> tf.close() >>> tf = tarfile.open("hoge.tar") >>> tf.getnames() ['hoge1', 'hoge2', 'hoge1'] 追加した hoge1 の中身はぶっこわれていた。 そもそも同じ名前のはフィルがリストにあって良いの? !2007-02-05 Mon >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.getnames() ['hoge1', 'hoge2'] >>> tf.next() 起動し直し >>> import tarfile >>> tf = tarfile.open("hoge.tar") >>> tf.next() >>> tf.getnames() ['hoge1', 'hoge2'] >>> tf.next() ふーむ !2007-02-04 Sun >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz", "w:gz") >>> tf.add("hoge1") >>> tf.add("hoge2") >>> tf.getnames() ['hoge1', 'hoge2'] >>> tf.close() >>> tf = tarfile.open("hoge.tar.gz") >>> tf.getnames() ['hoge1', 'hoge2'] >>> import os >>> os.rename("hoge.tar.gz", "hoge.tar") >>> tf = tarfile.open("hoge.tar") >>> tf.getnames() ['hoge1', 'hoge2'] 'r:gz' にはしなくても大丈夫(自動判別)なのか? !2007-02-03 Sat >>> import tarfile >>> tf = tarfile.open("hoge.tar", "w") >>> tf.add("hoge1") >>> tf.add("hoge2") >>> tf.getnames() ['hoge1', 'hoge2'] >>> tf.close() >>> tf = tarfile.open("hoge.tar") >>> tf.getnames() ['hoge1', 'hoge2'] ファイル名を tar.gz にしても勝手に tar.gz にはなってくれないようだ !2007-02-02 Fri >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> f = tf.extractfile("hoge1") >>> f >>> f.readlines() ['123\n'] >>> f.readlines() [] >>> f = tf.extractfile("hoge1") >>> f.read() '123\n' >>> f.read() '' !2007-02-01 Thu >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.next() >>> tf.extract(tf.next()) >>> tf.extract(tf.next(), "tmp/") !2007-01-31 Wed >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.extract("hoge") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/tarfile.py", line 1307, in extract tarinfo = self.getmember(member) File "/usr/lib/python2.3/tarfile.py", line 1031, in getmember raise KeyError, "filename %r not found" % name KeyError: "filename 'hoge' not found" >>> tf.extract("hoge1") !2007-01-30 Tue >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.next() >>> tf.next() >>> tf.next() >>> tf.next() !2007-01-29 Mon >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.list() -rw-r--r-- nnakamur/users 0 2007-02-20 12:30:46 hoge1 -rw-r--r-- nnakamur/users 0 2007-02-20 12:30:47 hoge2 -rw-r--r-- nnakamur/users 0 2007-02-20 12:30:49 hoge3 !2007-01-28 Sun >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.getnames() ['hoge1', 'hoge2', 'hoge3'] !2007-01-27 Sat >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.getmembers() [, , ] !2007-01-26 Fri >>> import tarfile >>> tf = tarfile.open("hoge.tar.gz") >>> tf.getmember("hoge1") >>> tf.getmember("hoge2") >>> tf.getmember("hoge3") >>> tf.getmember("hoge4") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/tarfile.py", line 1031, in getmember raise KeyError, "filename %r not found" % name KeyError: "filename 'hoge4' not found" !2007-01-25 Thu >>> import tarfile >>> tarfile.is_tarfile("hoge.tar.gz") True >>> tarfile.is_tarfile(".emacs") False なんで tar でなく、tarfile なんだろう? zipfile だから?でも、gzip は gzipfile じゃないぞ !2007-01-24 Wed Unicode でファイルから読む # coding: euc-jp import re, fileinput for line in fileinput.input(): uline = unicode(line, 'utf-8') m = re.match(u"あ", uline) if m != None: print uline.encode('euc_jp'), で、 $ python2.4 foo.py foo_u8.txt あ !2007-01-23 Tue Unicode でファイルから読む # coding: euc-jp import fileinput for line in fileinput.input(): uline = unicode(line, 'utf-8') print uline.encode('euc_jp'), で、 $ python2.4 foo.py foo_u8.txt あ い !2007-01-22 Mon Unicode でファイルから読む # coding: euc-jp import fileinput for line in fileinput.input(): uline = unicode(line) print uline.encode('euc_jp'), で、 $ python2.4 foo.py foo_u8.txt Traceback (most recent call last): File "foo.py", line 5, in ? uline = unicode(line) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) むむむ !2007-01-21 Sun Unicode でファイルから読む # coding: euc-jp import fileinput for line in fileinput.input(): print line.encode('euc_jp'), で、 $ python2.4 foo.py foo_u8.txt Traceback (most recent call last): File "foo.py", line 5, in ? print line.encode('euc_jp'), UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) !2007-01-20 Sat Unicode でファイルから読む # coding: euc-jp import fileinput for line in fileinput.input(): print line, Unicode で出力される !2007-01-19 Fri EUC のファイルを読む # coding: euc-jp import re, fileinput for line in fileinput.input(): uline = unicode(line, "euc_jp") m = re.match(u"あ", uline) if m != None: print uline.encode('euc_jp'), で、 $ python2.4 foo.py foo あ !2007-01-18 Thu EUC でファイルから読む # coding: euc-jp import fileinput for line in fileinput.input(): print line.encode('euc_jp') で、 $ python2.4 foo.py foo Traceback (most recent call last): File "foo.py", line 5, in ? print line.encode('euc_jp') UnicodeDecodeError: 'ascii' codec can't decode byte 0xa4 in position 0: ordinal not in range(128) Unicode でないものを EUC にしようとするから? !2007-01-17 Wed EUC でファイルから読む import fileinput for line in fileinput.input(): print line, 何もしない場合は素通り !2007-01-16 Tue # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr.replace(u"は", u"が").encode('euc_jp') で、 $ python2.4 foo.py これがUnicode文字列です guess する機能は(標準では)入っていないのだろうか? !2007-01-15 Mon # coding: euc-jp ustr = u"これはUnicode文字列です" str = ustr.replace("Unicode", "EUC").encode('euc_jp') print str で、 $ python2.4 foo.py これはEUC文字列です !2007-01-14 Sun # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr.encode('iso-2022-jp') で、 $ python2.4 foo.py これはUnicode文字列です !2007-01-13 Sat # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr.encode('shift_jis') で、 $ python2.4 foo.py これはUnicode文字列です !2007-01-12 Fri # coding: euc-jp ustr = u"これはUnicode文字列です" for x in ustr: print x.encode('euc_jp') で、 $ python2.4 foo.py こ れ は U n i c o d e 文 字 列 で す !2007-01-11 Thu # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr[1].encode('euc_jp') で、 $ python2.4 foo.py れ !2007-01-10 Wed ほぼ、まんま # coding: euc-jp import re print re.findall(u"[あ-ん]+", u"あめんぼ赤いなあいうえお") for x in re.findall(u"[あ-ん]+", u"あめんぼ赤いなあいうえお"): print x.encode('euc_jp') で、 [u'\u3042\u3081\u3093\u307c', u'\u3044\u306a\u3042\u3044\u3046\u3048\u304a'] あめんぼ いなあいうえお >>> # coding: euc-jp ... >>> import re >>> print re.findall(u"[あ-ん]+", u"あめんぼ赤いなあいうえお") [u'\u3042\u3081\u3093\u307c', u'\u3044\u306a\u3042\u3044\u3046\u3048\u304a'] >>> for x in re.findall(u"[あ-ん]+", u"あめんぼ赤いなあいうえお"): ... print x.encode('euc_jp') ... あめんぼ いなあいうえお !2007-01-09 Tue # coding: euc-jp ustr = unicode("これはUnicode文字列です") print ustr.encode('euc_jp') で、 Traceback (most recent call last): File "foo.py", line 2, in ? ustr = unicode("これはUnicode文字列です") UnicodeDecodeError: 'ascii' codec can't decode byte 0xa4 in position 0: ordinal not in range(128) デフォルトエンコーディングが ascii だから エンコーディングの指定は省略できないみたい # coding: euc-jp ustr = unicode("これはUnicode文字列です", 'euc_jp') print ustr.encode('euc_jp') で、 これはUnicode文字列です !2007-01-08 Mon >>> import sys >>> sys.getdefaultencoding() 'ascii' >>> sys.setdefaultencoding("euc_jp") Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'setdefaultencoding' sys.setdefaultencoding はスクリプト内では実行できないようだ。 /usr/lib/python2.4/site.py を編集しろって??? /usr/lib/python2.4/site-packages/sitecustomize.py を使うのか??? !2007-01-07 Sun >>> print len('あいうえお') 10 >>> print len(u'あいうえお') 5 !2007-01-06 Sat # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr.encode('euc_jp') で、 これはUnicode文字列です !2007-01-05 Fri # coding: euc-jp ustr = u"これはUnicode文字列です" print ustr で、 $ python2.4 foo.py これはUnicode文字列です なぜ EUC 端末で表示できるのだ? 本当に UNICODE になっている??? $ python2.4 foo.py > foo Traceback (most recent call last): File "foo.py", line 3, in ? print ustr UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) リダイレクトだとなぜかエラー発生 !2007-01-04 Thu 以降、「日本語の扱い」では Python 2.4.1 を使う Emacs 使用者向けに # -*- coding: euc-jp -*- # ほげ ↑と書いただけで、↓と書けば認識されるようだ # coding: euc-jp # ほげ !2007-01-03 Wed # -*- coding: euc-jp -*- # ほげ で、Python 2.3 だと $ python foo.py File "foo.py", line 1 SyntaxError: 'unknown encoding: euc-jp' おそらく JapaneseCodesc を入れれば Python 2.3 でも怒られないのだろう Python 2.4 だと $ python2.4 foo.py ファイルのコードを SJIS にしておくと、 $ python2.4 foo.py File "foo.py", line 2 SyntaxError: unknown decode error ファイルのコードが JIS だと何も言われない !2007-01-02 Tue http://www.python.jp/Zope/articles/japanese/Python4Japanese-2 を参考に EUC を含んでいると # ほげ で、 $ python foo.py sys:1: DeprecationWarning: Non-ASCII character '\xa4' in file foo.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details * SJIS だと怒られる * JIS だと怒られない !2007-01-01 Mon まんま? from optparse import OptionParser def vararg_callback(option, opt_str, value, parser): assert value is None done = 0 value = [] rargs = parser.rargs while rargs: arg = rargs[0] if ((arg[:2] == "--" and len(arg) > 2) or (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")): break else: value.append(arg) del rargs[0] setattr(parser.values, option.dest, value) parser = OptionParser() parser.add_option("-c", "--callback", action="callback", callback=vararg_callback) (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -c foo Traceback (most recent call last): ... File "foo.py", line 18, in vararg_callback setattr(parser.values, option.dest, value) TypeError: attribute name must be string マニュアルの「callback=varargs」は、「callback=vararg_callback」の間違い? (原文もそうなっているけど) スタブと書いてあるからなんかをかませということか??? !2006-12-31 Sun まんま from optparse import OptionParser def store_value(option, opt_str, value, parser): setattr(parser.values, option.dest, value) parser = OptionParser() parser.add_option("--foo", action="callback", callback=store_value, type="int", nargs=3, dest="foo") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py --foo 1 2 3 (, []) !2006-12-30 Sat まんま from optparse import OptionParser from optparse import OptionValueError def is_moon_full(): return True def check_moon(option, opt_str, value, parser): if is_moon_full(): raise OptionValueError("%s option invalid when moon is full" % opt_str) setattr(parser.values, option.dest, 1) parser = OptionParser() parser.add_option("--foo", action="callback", callback=check_moon, dest="foo") (options, args) = parser.parse_args() で、 $ python foo.py --foo usage: foo.py [options] foo.py: error: --foo option invalid when moon is full !2006-12-29 Fri まんま from optparse import OptionParser from optparse import OptionValueError def check_order(option, opt_str, value, parser): if parser.values.b: raise OptionValueError("can't use %s after -b" % opt_str) setattr(parser.values, option.dest, 1) parser = OptionParser() parser.add_option("-a", action="callback", callback=check_order, dest='a') parser.add_option("-b", action="store_true", dest="b") parser.add_option("-c", action="callback", callback=check_order, dest='c') (options, args) = parser.parse_args() で、 $ python foo.py -a -b $ python foo.py -b -a usage: foo.py [options] foo.py: error: can't use -a after -b !2006-12-28 Thu まんま from optparse import OptionParser from optparse import OptionValueError def check_order(option, opt_str, value, parser): if parser.values.b: raise OptionValueError("can't use -a after -b") parser.values.a = 1 parser = OptionParser() parser.add_option("-a", action="callback", callback=check_order) parser.add_option("-b", action="store_true", dest="b") (options, args) = parser.parse_args() で、 $ python foo.py -a $ python foo.py -a -b $ python foo.py -b -a usage: foo.py [options] foo.py: error: can't use -a after -b 原文 record the fact that "-a" is seen, but blow up if it comes after "-b" in the command-line. が、 この例では、"-a" を発見して、その後で "-b" がコマンドライン中に現れた場合にはエラーになります。 となっていたので、bug 報告しておいた !2006-12-27 Wed かなり、まんま from optparse import OptionParser def record_foo_seen(option, opt_str, value, parser): parser.saw_foo = True parser = OptionParser() parser.add_option("--foo", action="callback", callback=record_foo_seen) (options, args) = parser.parse_args() print parser.saw_foo で、 $ python foo.py Traceback (most recent call last): File "foo.py", line 9, in ? print parser.saw_foo AttributeError: OptionParser instance has no attribute 'saw_foo' $ python foo.py --foo True アトリビュートがあるかどうかはどう書けば良かったっけ? !2006-12-26 Tue from optparse import OptionParser def my_callback(option, opt, value, parser): print (option, opt, value, parser) print parser.largs print parser.rargs parser = OptionParser() parser.add_option("-a", action="store_true") parser.add_option("-b", action="store_true") parser.add_option("-c", action="callback", callback=my_callback) (options, args) = parser.parse_args() で、 $ python foo.py -a -b -c (, '-c', None, ) [] [] $ python foo.py -a -c -b (, '-c', None, ) [] ['-b'] $ python foo.py -c -a -b (, '-c', None, ) [] ['-a', '-b'] !2006-12-25 Mon from optparse import OptionParser def my_callback(option, opt, value, parser): print (option, opt, value, parser) parser = OptionParser() parser.add_option("-c", action="callback", callback=my_callback, type="int") (options, args) = parser.parse_args() で、 $ python foo.py -c 1 (, '-c', 1, ) !2006-12-24 Sun from optparse import OptionParser def my_callback(option, opt, value, parser, *args, **kwargs): print (option, opt, value, parser, args, kwargs) parser = OptionParser() parser.add_option("-c", action="callback", callback=my_callback, callback_kwargs={'foo' : 1, 'bar' : 2}) (options, args) = parser.parse_args() で、 $ python foo.py -c (, '-c', None, , (), {'foo': 1, 'bar': 2}) * これで良いのか??? * 「キーワード引数からなるタプル」ってなんだっけ? !2006-12-23 Sat from optparse import OptionParser def my_callback(option, opt, value, parser, args): print (option, opt, value, parser, args) parser = OptionParser() parser.add_option("-c", action="callback", callback=my_callback, callback_args=(1,2,3)) (options, args) = parser.parse_args() で、 $ python foo.py -c (, '-c', None, , (1, 2, 3)) !2006-12-22 Fri from optparse import OptionParser def my_callback(option, opt, value, parser): print (option, opt, value, parser) parser = OptionParser() parser.add_option("-c", action="callback", callback=my_callback) (options, args) = parser.parse_args() で、 $ python foo.py -c (, '-c', None, ) !2006-12-21 Thu from optparse import OptionParser def my_callback(option, opt, value, parser): pass parser = OptionParser() parser.add_option("-c", action="callback", callback=my_callback) (options, args) = parser.parse_args() !2006-12-20 Wed まんま from optparse import OptionParser parser = OptionParser(conflict_handler="resolve") parser.add_option("-n", "--dry-run", help="do no harm") parser.add_option("-n", "--noisy", help="be noisy") (options, args) = parser.parse_args() で、 $ python foo.py --help usage: foo.py [options] options: -h, --help show this help message and exit --dry-run=DRY_RUN do no harm -nNOISY, --noisy=NOISY be noisy !2006-12-19 Tue from optparse import OptionParser parser = OptionParser() parser.add_option("-a", "--all") parser.add_option("-a", "--all") で、 Traceback (most recent call last): File "foo.py", line 5, in ? parser.add_option("-a", "--all") File "/usr/lib/python2.3/optparse.py", line 828, in add_option self._check_conflict(option) File "/usr/lib/python2.3/optparse.py", line 803, in _check_conflict option) optparse.OptionConflictError: option -a/--all: conflicting option string(s): -a, --all !2006-12-18 Mon from optparse import OptionParser parser = OptionParser() parser.add_option("-a", "--all") print parser.get_option("-a") parser.remove_option("-a") print parser.get_option("-a") parser.add_option("-a", "--all") parser.remove_option("--all") print parser.get_option("-a") parser.remove_option("-c") で、 -a/--all None None Traceback (most recent call last): File "foo.py", line 14, in ? parser.remove_option("-c") File "/usr/lib/python2.3/optparse.py", line 864, in remove_option raise ValueError("no such option %r" % opt_str) ValueError: no such option '-c' !2006-12-17 Sun from optparse import OptionParser parser = OptionParser() parser.add_option("-a", "--all") print parser.get_option("-a") print parser.get_option("-b") で、 -a/--all None !2006-12-16 Sat from optparse import OptionParser parser = OptionParser() parser.add_option("-a") print parser.get_option("-a") print parser.get_option("-b") で、 -a None !2006-12-15 Fri count でデフォルト値を指定するにはどうやれば? from optparse import OptionParser parser = OptionParser() parser.add_option("-a") print parser.has_option("-a") print parser.has_option("-b") で、 True False !2006-12-14 Thu from optparse import OptionParser parser = OptionParser() parser.add_option("-a", action="store_const", const=0, dest="var") parser.add_option("-b", action="store_const", const=1, dest="var") parser.add_option("-c", action="store_const", const=2, dest="var") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py (, []) $ python foo.py -a (, []) $ python foo.py -b (, []) $ python foo.py -c (, []) $ python foo.py -a -b -c (, []) $ python foo.py -c -b -a (, []) !2006-12-13 Wed from optparse import OptionParser parser = OptionParser() parser.add_option("-a", nargs=3) (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -a usage: foo.py [options] foo.py: error: -a option requires 3 values $ python foo.py -a 1 2 3 (, []) !2006-12-12 Tue from optparse import OptionParser parser = OptionParser() parser.add_option("-a") parser.add_option("-b", action="store") parser.add_option("-c", action="store_const") parser.add_option("-d", action="store_true") parser.add_option("-e", action="store_false") parser.add_option("-f", action="append") parser.add_option("-g", action="count") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -a foo (, []) $ python foo.py -b foo (, []) $ python foo.py -c (, []) $ python foo.py -d (, []) $ python foo.py -e (, []) $ python foo.py -f foo bar (, ['bar']) $ python foo.py -f foo -f bar (, []) $ python foo.py -a foo -a bar (, []) $ python foo.py -g (, []) $ python foo.py -g -g (, []) !2006-12-11 Mon そもそも、何個引数を書いても良いのかな? from optparse import OptionParser parser = OptionParser() parser.add_option("-q", "--quiet", "--quiet2", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -q (, []) $ python foo.py --quiet (, []) $ python foo.py --quiet2 (, []) !2006-12-10 Sun 長いオプション、短いオプションの順に書いてみたら? from optparse import OptionParser parser = OptionParser() parser.add_option("--quiet", "-q", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -q (, []) 単に座りが悪いだけか〜 !2006-12-09 Sat まんま import optparse option_list = [ optparse.make_option("-f", "--filename", action="store", type="string", dest="filename"), optparse.make_option("-q", "--quiet", action="store_false", dest="verbose"), ] parser = optparse.OptionParser(option_list=option_list) (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py (, []) !2006-12-08 Fri まんま from optparse import OptionParser def main(): usage = "usage: %prog [options] arg" parser = OptionParser(usage) parser.add_option("-f", "--file", dest="filename", help="read data from FILENAME") parser.add_option("-v", "--verbose", action="store_true", dest="verbose") parser.add_option("-q", "--quiet", action="store_false", dest="verbose") (options, args) = parser.parse_args() if len(args) != 1: parser.error("incorrect number of arguments") if options.verbose: print "reading %s..." % options.filename if __name__ == "__main__": main() で、 $ python foo.py usage: foo.py [options] arg foo.py: error: incorrect number of arguments $ python foo.py foo $ python foo.py -v foo reading None... うーん、引数の数のチェックくらいオプションモジュールにあっても良いのかも? オプションでないから機能としては別か? !2006-12-07 Thu from optparse import OptionParser parser = OptionParser() parser.add_option("-a", action="store_true") parser.add_option("-b", action="store_true") (options, args) = parser.parse_args() if options.a and options.b: parser.error("options -a and -b are mutually exclusive") で、 $ python foo.py -a $ python foo.py -b $ python foo.py -a -b usage: foo.py [options] foo.py: error: options -a and -b are mutually exclusive !2006-12-06 Wed from optparse import OptionParser parser = OptionParser() parser.add_option("-n", type="int", dest="num") (options, args) = parser.parse_args(["-nfoo"]) print (options, args) で、 $ python foo.py usage: foo.py [options] foo.py: error: option -n: invalid integer value: 'foo' !2006-12-05 Tue from optparse import OptionParser parser = OptionParser(usage="%prog [-q]", version="%prog 1.0") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="be vewwy quiet (I'm hunting wabbits)") (options, args) = parser.parse_args() で、 $ python foo.py --version foo.py 1.0 !2006-12-04 Mon from optparse import OptionParser usage = "usage: %prog %prog [options] arg1 arg2" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=True, help="make lots of noise [default]") #(options, args) = parser.parse_args() parser.print_help() で、 $ python foo.py usage: foo.py foo.py [options] arg1 arg2 options: -h, --help show this help message and exit -v, --verbose make lots of noise [default] 複数でも展開されるようだ !2006-12-03 Sun from optparse import OptionParser usage = "usage: %prog [options] arg1 arg2" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=True, help="make lots of noise [default]") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="be vewwy quiet (I'm hunting wabbits)") parser.add_option("-f", "--filename", metavar="FILE", help="write output to FILE"), parser.add_option("-m", "--mode", default="intermediate", help="interaction mode: novice, intermediate, " "or expert [default: %default]") #(options, args) = parser.parse_args() parser.print_help() で、 $ python foo.py usage: foo.py [options] arg1 arg2 options: -h, --help show this help message and exit -v, --verbose make lots of noise [default] -q, --quiet be vewwy quiet (I'm hunting wabbits) -fFILE, --filename=FILE write output to FILE -mMODE, --mode=MODE interaction mode: novice, intermediate, or expert [default: %default] !2006-12-02 Sat まんま from optparse import OptionParser usage = "usage: %prog [options] arg1 arg2" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=True, help="make lots of noise [default]") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="be vewwy quiet (I'm hunting wabbits)") parser.add_option("-f", "--filename", metavar="FILE", help="write output to FILE"), parser.add_option("-m", "--mode", default="intermediate", help="interaction mode: novice, intermediate, " "or expert [default: %default]") (options, args) = parser.parse_args() で、 $ python foo.py -h usage: foo.py [options] arg1 arg2 options: -h, --help show this help message and exit -v, --verbose make lots of noise [default] -q, --quiet be vewwy quiet (I'm hunting wabbits) -fFILE, --filename=FILE write output to FILE -mMODE, --mode=MODE interaction mode: novice, intermediate, or expert [default: %default] $ python ~/foo.py -h usage: foo.py [options] arg1 arg2 ... * なんで、「-f FILE」とかスペースが入らないんだろう?どっちでも良いけど。 * %default が展開されていないような? * Python 2.3.5 では、%default は展開されないようだ。Python 2.4.1 だと展開されていた。 !2006-12-01 Fri from optparse import OptionParser parser = OptionParser() parser.set_defaults(verbose=True) parser.add_option("-q", action="store_false", dest="verbose", default=True) parser.add_option("-v", action="store_true", dest="verbose", default=False) (options, args) = parser.parse_args() print (options, args) で、 (, []) 後優先でどんどん上書きされてしまうようだ。 って、そのようにマニュアルに書いてあった !2006-11-30 Thu from optparse import OptionParser parser = OptionParser() parser.set_defaults(verbose=True) parser.add_option("-q", action="store_false", dest="verbose") parser.add_option("-v", action="store_true", dest="verbose") (options, args) = parser.parse_args() print (options, args) で、 (, []) from optparse import OptionParser parser = OptionParser() parser.add_option("-q", action="store_false", dest="verbose") parser.add_option("-v", action="store_true", dest="verbose") parser.set_defaults(verbose=True) (options, args) = parser.parse_args() print (options, args) で、 (, []) !2006-11-29 Wed from optparse import OptionParser parser = OptionParser() parser.add_option("-v", action="store_true", dest="verbose", default=False) parser.add_option("-q", action="store_false", dest="verbose", default=True) (options, args) = parser.parse_args() print (options, args) で、 (, []) 逆に、 from optparse import OptionParser parser = OptionParser() parser.add_option("-q", action="store_false", dest="verbose", default=True) parser.add_option("-v", action="store_true", dest="verbose", default=False) (options, args) = parser.parse_args() print (options, args) で、 (, []) !2006-11-28 Tue from optparse import OptionParser parser = OptionParser() parser.add_option("-v", action="store_true", dest="verbose") parser.add_option("-q", action="store_false", dest="verbose") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py (, []) $ python foo.py -v (, []) $ python foo.py -q (, []) $ python foo.py -v -q (, []) $ python foo.py -q -v (, []) !2006-11-27 Mon from optparse import OptionParser parser = OptionParser() parser.add_option("-n", type="float", dest="num") (options, args) = parser.parse_args(["-n", "1"]) print (options, args) で、 (, []) !2006-11-26 Sun まんま from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="filename") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) 引数を少なく from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) さらに引数を少なく from optparse import OptionParser parser = OptionParser() parser.add_option("-f") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) 引数に「-」が含まれると、 from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file-a-b-c") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) ハッシュのキーになるだけなのに、なぜ「-」を「_」に 変換する必要があるのだろうか? ハッシュのキーになるだけではないのかな? 引数にへんてこりんなものが含まれると、 from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file-?") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) !2006-11-25 Sat まんま from optparse import OptionParser parser = OptionParser() parser.add_option("-n", type="int", dest="num") (options, args) = parser.parse_args(["-n42"]) print (options, args) で、 (, []) !2006-11-24 Fri まんま from optparse import OptionParser parser = OptionParser() parser.add_option("-n", type="int", dest="num") (options, args) = parser.parse_args(["-n", "1"]) print (options, args) で、 (, []) !2006-11-23 Thu まんま from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", action="store", type="string", dest="filename") (options, args) = parser.parse_args(["-f", "foo.txt"]) print (options, args) で、 (, []) !2006-11-22 Wed まんま(コードは 2006-11-20 と同じ) from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() print (options, args) で、 $ python foo.py -qf hoge (, []) !2006-11-21 Tue sys.argv をのぞく import sys from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() print (options, args) print sys.argv で、 $ python foo.py (, []) ['foo.py'] $ python foo.py -q (, []) ['foo.py', '-q'] $ python foo.py -q -f hoge (, []) ['foo.py', '-q', '-f', 'hoge'] !2006-11-20 Mon まんま from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() print (options, args) で、 (, []) $ python foo.py -f hoge (, []) $ python foo.py -q (, []) $ python foo.py hoge (, ['hoge']) $ python foo.py -h usage: foo.py [options] options: -h, --help show this help message and exit -fFILE, --file=FILE write report to FILE -q, --quiet don't print status messages to stdout $ python foo.py -a usage: foo.py [options] foo.py: error: no such option: -a !2006-11-19 Sun >>> s = set(['foo', 'bar']) >>> s.clear() >>> s set([]) !2006-11-18 Sat >>> s = set(['foo', 'bar']) >>> s.pop() 'foo' >>> s set(['bar']) >>> s.pop() 'bar' >>> s set([]) >>> s.pop() Traceback (most recent call last): File "", line 1, in ? KeyError: 'pop from an empty set' !2006-11-17 Fri >>> s = set(['foo', 'bar']) >>> s.discard('') >>> s set(['foo', 'bar']) >>> s.discard('foo') >>> s set(['bar']) >>> s.discard('foo') >>> s set(['bar']) !2006-11-16 Thu >>> s = set(['foo', 'bar']) >>> s.remove('foo') >>> s set(['bar']) >>> s.remove('foo') Traceback (most recent call last): File "", line 1, in ? KeyError: 'foo' !2006-11-15 Wed >>> s = set(['foo', 'bar']) >>> s.add(['hoge']) Traceback (most recent call last): File "", line 1, in ? TypeError: list objects are unhashable >>> s.add(set(['hoge'])) Traceback (most recent call last): File "", line 1, in ? TypeError: set objects are unhashable >>> s.add('hoge') >>> s set(['foo', 'bar', 'hoge']) !2006-11-14 Tue >>> s = set(['foo', 'bar']) >>> s.symmetric_difference_update(['foo']) >>> s set(['bar']) >>> s ^= set(['foo']) >>> s set(['foo', 'bar']) !2006-11-13 Mon >>> s = set(['foo', 'bar']) >>> s.difference_update(['foo']) >>> s set(['bar']) >>> s = set(['foo', 'bar']) >>> s -= set(['foo']) >>> s set(['bar']) !2006-11-12 Sun >>> s = set(['foo', 'bar']) >>> s.intersection_update(['foo']) >>> s set(['foo']) >>> s = set(['foo', 'bar']) >>> s &= set(['foo']) >>> s set(['foo']) !2006-11-11 Sat >>> s = set(['foo', 'bar']) >>> s.update(['foo']) >>> s set(['foo', 'bar']) >>> s.update(['baz']) >>> s set(['baz', 'foo', 'bar']) >>> s |= set(['hoge']) >>> s set(['baz', 'foo', 'bar', 'hoge']) !2006-11-10 Fri >>> frozenset('ab') | set('bc') frozenset(['a', 'c', 'b']) >>> set('bc') | frozenset('ab') set(['a', 'c', 'b']) !2006-11-09 Thu list.sort() メソッドの結果は不確定のsetsのリストとなります。 は、 the output of the list.sort() method is undefined for lists of sets. の訳 言いたいことから考えると、 「set のリストを list.sort() メソッドに渡した結果は、 定義できない(未定義、そもそも渡せない)」 「set のリストに対しては、list.sort() メソッドの結果は未定義」 という意味の気がするのだが。 >>> a = ['c', 'b', 'a'] >>> list.sort(a) >>> a ['a', 'b', 'c'] >>> s = set(['foo', 'bar']) >>> list.sort(s) Traceback (most recent call last): File "", line 1, in ? TypeError: descriptor 'sort' requires a 'list' object but received a 'set' >>> sl = [set(['foo', 'bar']), set(['baz']), set([])] >>> list.sort(sl) >>> sl [set([]), set(['foo', 'bar']), set(['baz'])] 渡すことはできてしまうなあ〜。やっぱり未定義という意味か? !2006-11-08 Wed >>> set('abc') == frozenset('abc') True >>> set('abc') == frozenset('cba') True !2006-11-07 Tue >>> import sets >>> set(['foo', 'bar']) == sets.Set(['foo', 'bar']) False あっそう >>> set(['foo', 'bar']).issubset(sets.Set(['foo', 'bar'])) True >>> set(['foo', 'bar']).issuperset(sets.Set(['foo', 'bar'])) True >>> sets.Set(['foo', 'bar']).issubset(set(['foo', 'bar'])) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.4/sets.py", line 309, in issubset self._binary_sanity_check(other) File "/usr/lib/python2.4/sets.py", line 343, in _binary_sanity_check raise TypeError, "Binary operation only permitted between sets" TypeError: Binary operation only permitted between sets ? !2006-11-06 Mon >>> s = set(['foo', 'bar']) >>> s <= set(['foo']) False >>> s <= set(['foo', 'bar', 'baz']) True >>> s >= set(['foo']) True >>> s | set(['hoge']) set(['foo', 'bar', 'hoge']) >>> s & set([]) set([]) >>> s & set(['foo']) set(['foo']) >>> s - set(['foo']) set(['bar']) >>> s ^ set(['foo']) set(['bar']) >>> s ^ set([]) set(['foo', 'bar']) >>> s == set(['bar', 'foo']) True >>> s == ['bar', 'foo'] False sets と同じ !2006-11-05 Sun >>> frozenset(['foo', 'bar']) frozenset(['foo', 'bar']) >>> frozenset(['foo', 'bar']).union(['hoge']) frozenset(['foo', 'bar', 'hoge']) >>> hash(set(['foo', 'bar'])) Traceback (most recent call last): File "", line 1, in ? TypeError: set objects are unhashable >>> hash(frozenset(['foo', 'bar'])) -1150997543 !2006-11-04 Sat >>> s = set(['foo', 'bar']) >>> s.copy() set(['foo', 'bar']) >>> s2 = s.copy() >>> s2.union('hoge') set(['bar', 'g', 'h', 'o', 'e', 'foo']) おっと、間違った >>> s = set(['foo', 'bar']) >>> s2 = s.copy() >>> s2.union(['hoge']) set(['foo', 'bar', 'hoge']) >>> s set(['foo', 'bar']) >>> s2 set(['foo', 'bar']) あっ、中身は変わっていないのか >>> s2.add('hoge') >>> s set(['foo', 'bar']) >>> s2 set(['foo', 'bar', 'hoge']) sets と同じ !2006-11-03 Fri >>> s = set(['foo', 'bar']) >>> s.symmetric_difference(['foo']) set(['bar']) >>> s.symmetric_difference([]) set(['foo', 'bar']) >>> s ^ set(['foo']) set(['bar']) >>> s ^ set([]) set(['foo', 'bar']) sets と同じ !2006-11-02 Thu >>> s = set(['foo', 'bar']) >>> s.difference([]) set(['foo', 'bar']) >>> s.difference(['foo']) set(['bar']) >>> s.difference(['foo', 'bar', 'baz']) set([]) >>> s - set([]) set(['foo', 'bar']) >>> s - set(['']) set(['foo', 'bar']) >>> s - set(['foo']) set(['bar']) >>> s - set(['foo', 'bar', 'baz']) set([]) sets と同じ !2006-11-01 Wed >>> s = set(['foo', 'bar']) >>> s.intersection(['foo']) set(['foo']) >>> s.intersection(['']) set([]) >>> s & set(['foo']) set(['foo']) >>> s & set(['']) set([]) sets と同じ !2006-10-31 Tue >>> s = set(['foo', 'bar']) >>> s.union(set(['hoge'])) set(['foo', 'bar', 'hoge']) >>> s.union(set(['foo'])) set(['foo', 'bar']) >>> s.union(['hoge']) set(['foo', 'bar', 'hoge']) >>> s | set(['hoge']) set(['foo', 'bar', 'hoge']) >>> s | set(['foo']) set(['foo', 'bar']) >>> s | ['hoge'] Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for |: 'set' and 'list' sets と同じ !2006-10-30 Mon >>> s = set(['foo', 'bar']) >>> s.issuperset(set(['foo'])) True >>> s.issuperset(set(['foo', 'bar'])) True >>> s.issuperset(set(['foo', 'bar', 'baz'])) False >>> s >= set(['foo']) True >>> s >= set(['foo', 'bar']) True >>> s >= set(['foo', 'bar', 'baz']) False sets と同じ !2006-10-29 Sun >>> s = set(['foo', 'bar']) >>> s.issubset(s) True >>> s.issubset(set(['foo'])) False >>> s.issubset(set(['foo', 'bar'])) True >>> s <= s True >>> s <= set(['foo']) False >>> s <= set(['foo', 'bar']) True sets と同じ !2006-10-28 Sat >>> 'foo' not in s False >>> 'hoge' not in s True sets と同じ !2006-10-27 Fri >>> 'foo' in set(['foo', 'bar']) True >>> 'baz' in set(['foo', 'bar']) False sets と同じ !2006-10-26 Thu >>> len(set(['foo', 'bar'])) 2 sets と同じ !2006-10-25 Wed python 2.4 が入っていたので、組み込み set を使ってみる $ python Python 2.3.5 (#2, Oct 16 2006, 19:19:48) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> set(['foo', 'bar']) Traceback (most recent call last): File "", line 1, in ? NameError: name 'set' is not defined $ python2.4 Python 2.4.1 (#2, Oct 18 2006, 20:58:01) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> set(['foo', 'bar']) set(['foo', 'bar']) >>> set(('foo', 'bar')) set(['foo', 'bar']) >>> set(('foo', 'bar', 'baz')) set(['baz', 'foo', 'bar']) set なのにマニュアルで sets となっているのは、 なんかまぎらわしいなあ〜。 複数形の s じゃないの?日本語訳の場合 set で良いとか??? !2006-10-24 Tue 演算子のオーバーロード >>> class Foo: ... def __repr__(self): ... print "call __repr__" ... def __str__(self): ... print "call __str__" ... >>> Foo() call __repr__ Traceback (most recent call last): File "", line 1, in ? TypeError: __repr__ returned non-string (type NoneType) そうすか これでどうだ! >>> class Foo: ... def __repr__(self): ... "call __repr__" ... def __str__(self): ... "call __str__" ... >>> Foo() Traceback (most recent call last): File "", line 1, in ? TypeError: __repr__ returned non-string (type NoneType) ううう、間違えた >>> class Foo: ... def __repr__(self): ... return "call __repr__" ... def __str__(self): ... return "call __str__" ... >>> Foo() call __repr__ >>> str(Foo()) 'call __str__' >>> print Foo() call __str__ まだ「オブジェクト指向な機能」も色々ありそうだが、とりあえず切り上げよう !2006-10-23 Mon 演算子のオーバーロード >>> class Foo: ... def __add__(self, other): ... print "call __add__" ... def __radd__(self, other): ... print "call __radd__" ... >>> Foo() + Foo() call __add__ >>> Foo() + 1 call __add__ >>> 1 + Foo() call __radd__ !2006-10-22 Sun ファイナライザ >>> class Foo: ... def __del__(self): ... print "deleting..." ... >>> def foo(): ... Foo() ... >>> foo() deleting... !2006-10-21 Sat 継承、循環? again >>> class Foo: ... def foo1(self): ... pass ... >>> dir(Foo) ['__doc__', '__module__', 'foo1'] >>> class Bar(Foo): ... def bar(self): ... pass ... >>> dir(Bar) ['__doc__', '__module__', 'bar', 'foo1'] >>> class Foo(Bar): ... def foo2(self): ... pass ... >>> dir(Foo) ['__doc__', '__module__', 'bar', 'foo1', 'foo2'] ふむ >>> class Foo: ... def foo1(self): ... pass ... >>> dir(Foo) ['__doc__', '__module__', 'foo1'] >>> class Foo: ... def foo2(self): ... pass ... >>> dir(Foo) ['__doc__', '__module__', 'foo2'] 継承していると何か変わってくるのか? と、思ったが、foo1 は、Bar から引き継いだものか !2006-10-20 Fri 継承、循環? >>> class Foo: ... def foo1(self): ... pass ... >>> class Bar(Foo): ... def bar(self): ... pass ... >>> class Foo(Bar): ... def foo2(self): ... pass ... >>> Foo().foo1() >>> Foo().foo2() >>> Bar().bar() >>> Bar().foo1() >>> Bar().foo2() Traceback (most recent call last): File "", line 1, in ? AttributeError: Bar instance has no attribute 'foo2' ?(→次の日に疑問解消) !2006-10-19 Thu 継承、循環? >>> class Foo: ... pass ... >>> class Bar(Foo): ... pass ... >>> class Foo(Bar): ... pass ... >>> Foo() <__main__.Foo instance at 0x402208ac> >>> Bar() <__main__.Bar instance at 0x4022072c> うむ? !2006-10-18 Wed 継承したときの自クラス内のメソッドの呼び出し >>> class Foo: ... def foo(self): ... print "foo" ... >>> class Bar(Foo): ... def bar(self): ... self.foo() ... >>> Bar().bar() foo まあ、自然か !2006-10-17 Tue メソッドの正体 これってやったっけ? >>> class Foo: ... def foo(self): ... print "foo" ... >>> Foo.foo(Foo()) foo !2006-10-16 Mon 多重継承と親メソッド >>> class A: ... def foo(self): ... print "A" ... >>> class B: ... def foo(self): ... print "B" ... >>> class Foo(A, B): ... def bar(self): ... A.foo(self) ... B.foo(self) ... >>> Foo().bar() A B 多重継承 影響ないから意味ないか !2006-10-15 Sun 多重継承 >>> class A: ... def foo(self): ... print "A" ... >>> class B: ... def foo(self): ... print "B" ... >>> class Foo(A, B): ... pass ... >>> Foo().foo() A ふーん !2006-10-14 Sat 継承。親のメソッドを呼ぶ >>> class Foo: ... def foo(self): ... print "foo in Foo" ... >>> class Bar(Foo): ... def foo(self): ... print "foo in Bar" ... def bar(self): ... Foo.foo(self) ... >>> Foo().foo() foo in Foo >>> Bar().foo() foo in Bar >>> Bar().bar() foo in Foo !2006-10-13 Fri 継承。_ のついたもの >>> class Foo: ... _x = 1 ... __y = 2 ... >>> class Bar(Foo): ... pass ... >>> Foo._x 1 >>> Foo.__y Traceback (most recent call last): File "", line 1, in ? AttributeError: class Foo has no attribute '__y' >>> Bar._x 1 >>> Bar.__y Traceback (most recent call last): File "", line 1, in ? AttributeError: class Bar has no attribute '__y' >>> dir(Bar) ['_Foo__y', '__doc__', '__module__', '_x'] >>> Bar._Foo__y 2 !2006-10-12 Thu オーバーライド >>> class Foo: ... def foo(self): ... print "foo in Foo" ... >>> class Bar(Foo): ... def foo(self): ... print "foo in Bar" ... >>> Foo().foo() foo in Foo >>> Bar().foo() foo in Bar !2006-10-11 Wed 継承。クラスメソッド >>> class Foo: ... def foo(cls): ... print "foo" ... foo = classmethod(foo) ... def bar(): ... print "bar" ... bar = staticmethod(bar) ... >>> class Bar(Foo): ... pass ... >>> Foo.foo() foo >>> Foo.bar() bar >>> Bar.foo() foo >>> Bar.bar() bar >>> Foo.foo = lambda : sys.stdout.write("FOO\n") >>> Foo.foo() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method () must be called with Foo instance as first argument (got nothing instead) >>> Bar.foo() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method () must be called with Bar instance as first argument (got nothing instead) !2006-10-10 Tue クラスと関数で同じ名前を使うと? >>> class Foo: ... pass ... >>> def Foo(): ... print "Foo" ... >>> Foo() Foo 衝突。変数と関数名も衝突するので、まあこんなものか。 逆順で定義 >>> def Foo(): ... print "Foo" ... >>> class Foo: ... pass ... >>> Foo() <__main__.Foo instance at 0x4022070c> !2006-10-09 Mon 変なものを継承してみる >>> class Foo("hoge"): ... pass ... Traceback (most recent call last): File "", line 1, in ? TypeError: str() takes at most 1 argument (3 given) どういう意味のエラー? !2006-10-08 Sun 変なものを継承してみる >>> def foo(): ... print "foo" ... >>> class Foo(foo): ... pass ... Traceback (most recent call last): File "", line 1, in ? TypeError: function() argument 1 must be code, not str どういう意味のエラー? !2006-10-07 Sat 継承。再度スーパークラスを作り直し >>> class Foo: ... x = 1 ... >>> class Bar(Foo): ... pass ... >>> Foo.x 1 >>> Bar.x 1 >>> class Foo: ... pass ... >>> Foo.x Traceback (most recent call last): File "", line 1, in ? AttributeError: class Foo has no attribute 'x' >>> Bar.x 1 !2006-10-06 Fri 継承。あとでメソッドを付け加えたクラスを作成 >>> class Foo: ... pass ... >>> class Bar(Foo): ... pass ... >>> Bar().foo() Traceback (most recent call last): File "", line 1, in ? AttributeError: Bar instance has no attribute 'foo' >>> class Foo: ... def foo(self): ... print "foo" ... >>> Bar().foo() Traceback (most recent call last): File "", line 1, in ? AttributeError: Bar instance has no attribute 'foo' !2006-10-05 Thu 継承 >>> class Foo: ... x = 1 ... >>> class Bar(Foo): ... pass ... >>> Foo.x 1 >>> Bar.x 1 >>> Foo.x = 2 >>> Foo.x 2 >>> Bar.x 2 !2006-10-04 Wed 継承 >>> class Foo: ... def foo(self): ... print "foo" ... >>> class Bar(Foo): ... pass ... >>> Foo().foo() foo >>> Bar().foo() foo !2006-10-03 Tue クラス名を小文字にしてみる >>> class foo: ... def foo(self): ... print "foo" ... >>> foo() <__main__.foo instance at 0x4022068c> >>> foo().foo() foo !2006-10-02 Mon 可視性 >>> class Foo: ... _x = 1 ... __y = 2 ... >>> Foo._x 1 >>> Foo.__y Traceback (most recent call last): File "", line 1, in ? AttributeError: class Foo has no attribute '__y' !2006-10-01 Sun メソッドの可視性 >>> class Foo: ... def __foo__(self): ... print "foo" ... >>> Foo().__foo__() foo あれ?見えちゃうの? !2006-09-30 Sat 可視性 >>> class Foo: ... def __init__(self): ... self.x = 1 ... self._y = 2 ... >>> Foo().x 1 >>> Foo()._y 2 あれ?見えちゃうぞ。__ だと、一応見えないようになるらしい >>> class Foo: ... def __init__(self): ... self.x = 1 ... self._y = 2 ... self.__z = 3 ... >>> Foo().x 1 >>> Foo()._y 2 >>> Foo().__z Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute '__z' >>> dir(Foo()) ['_Foo__z', '__doc__', '__init__', '__module__', '_y', 'x'] >>> Foo()._Foo__z 3 !2006-09-29 Fri クラスメソッド? >>> class Foo: ... def foo(cls): ... print "foo" ... foo = classmethod(foo) ... def bar(): ... print "bar" ... bar = staticmethod(bar) ... >>> Foo.foo() foo >>> Foo.bar() bar >>> Foo().foo() foo >>> Foo().bar() bar Perl っぽく無節操に呼べそうな気もしたのになあ〜 !2006-09-28 Thu 自クラス内のメソッドの呼び出し >>> class Foo: ... def foo(self): ... bar() ... def bar(): ... print "bar" ... >>> Foo().foo() Traceback (most recent call last): File "", line 1, in ? File "", line 3, in foo NameError: global name 'bar' is not defined >>> class Foo: ... def foo(self): ... bar(self) ... def bar(self): ... print "bar" ... >>> Foo().foo() Traceback (most recent call last): File "", line 1, in ? File "", line 3, in foo NameError: global name 'bar' is not defined >>> class Foo: ... def foo(self): ... self.bar() ... def bar(self): ... print "bar" ... >>> Foo().foo() bar うっ、そうだったのか メソッドも変数と同じと考えれば、不思議じゃないか >>> class Foo: ... def foo(self): ... print self.foo ... >>> Foo().foo() > !2006-09-27 Wed メソッドの追加 >>> class Foo: ... def foo(self): ... print "foo" ... >>> Foo().foo() foo >>> class Foo: ... def bar(self): ... print "bar" ... >>> Foo().foo() Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute 'foo' >>> Foo().bar() bar 少なくとも Ruby っぽくは、できないようだ !2006-09-26 Tue >>> Foo = 1 >>> class Foo: ... pass ... >>> Foo >>> Foo() <__main__.Foo instance at 0x4022082c> ふーん、Ruby はエラーになるけど !2006-09-25 Mon トップレベルの変数 >>> x = 1 >>> import __main__ >>> __main__.x 1 >>> dir(__main__) ['__builtins__', '__doc__', '__main__', '__name__', 'x'] !2006-09-24 Sun def の中で、class >>> def foo(): ... class Foo: ... pass ... >>> Foo Traceback (most recent call last): File "", line 1, in ? NameError: name 'Foo' is not defined >>> foo() >>> Foo Traceback (most recent call last): File "", line 1, in ? NameError: name 'Foo' is not defined どうやって活用? !2006-09-23 Sat もしかして、クラス変数のように使えるってこと? >>> class Foo: ... x = 1 ... def up(self): ... Foo.x += 1 ... >>> Foo.x 1 >>> Foo().up() >>> Foo.x 2 >>> Foo().up() >>> Foo.x 3 インスタンスを作らずメソッド呼べないんだっけ? !2006-09-22 Fri class とメソッドの間に書いた変数は? >>> class Foo: ... x = 1 ... def __init__(self): ... print x ... >>> Foo() Traceback (most recent call last): File "", line 1, in ? File "", line 4, in __init__ NameError: global name 'x' is not defined >>> class Foo: ... x = 1 ... def __init__(self): ... print Foo.x ... >>> Foo() 1 <__main__.Foo instance at 0x402206ec> >>> class Foo: ... x = 1 ... >>> Foo.x 1 !2006-09-21 Thu 特異メソッドのようなこと??? lambda 使って >>> import sys >>> class Foo: ... pass ... >>> f1 = Foo() >>> f2 = Foo() >>> f1.foo = lambda : sys.stdout.write("foo\n") >>> f1.foo() foo !2006-09-20 Wed 特異メソッドのようなこと??? >>> class Foo: ... pass ... >>> f1 = Foo() >>> f2 = Foo() >>> def foo(): ... print "foo" ... >>> f1.foo = foo >>> f1.foo() foo >>> f2.foo() Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute 'foo' !2006-09-19 Tue クラス名 again >>> class Foo: ... print Foo ... pass ... Traceback (most recent call last): File "", line 1, in ? File "", line 2, in Foo NameError: name 'Foo' is not defined >>> class Foo: ... pass ... >>> class Foo: ... print Foo ... __main__.Foo >>> Foo() <__main__.Foo instance at 0x4022082c> >>> class Foo: ... global Foo ... print Foo ... Traceback (most recent call last): File "", line 1, in ? File "", line 3, in Foo NameError: global name 'Foo' is not defined ふむ。さっぱり分からない… !2006-09-18 Mon スーパークラスを書き忘れてみる >>> class Foo(): File "", line 1 class Foo(): ^ SyntaxError: invalid syntax !2006-09-17 Sun 組み込み型の継承 >>> class Foo(int): ... def __init__(self, x): ... self = x ... >>> f = Foo(1) >>> f 1 >>> type(1) どうも継承している気がしないのだが、 どうすれば… !2006-09-16 Sat 組み込み型の継承 >>> class Foo: ... pass ... >>> dir(Foo) ['__doc__', '__module__'] >>> class Foo(int): ... pass ... >>> dir(Foo) ['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__dict__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__module__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__str__', '__sub__', '__truediv__', '__weakref__', '__xor__'] !2006-09-15 Fri 組み込み型の継承 >>> class Foo: ... pass ... >>> Foo() <__main__.Foo instance at 0x4022060c> >>> class Foo(int): ... pass ... >>> Foo() 0 >>> class Foo(str): ... pass ... >>> Foo() '' !2006-09-14 Thu __main__ って? >>> class Foo: ... pass ... >>> __main__.Foo() Traceback (most recent call last): File "", line 1, in ? NameError: name '__main__' is not defined >>> import __main__ >>> __main__.Foo() <__main__.Foo instance at 0x4022066c> トップからの名前の指定というのは、こうやるのが自然なのか??? !2006-09-13 Wed クラス名 >>> class Foo: ... def __init__(self): ... print Foo ... >>> Foo() __main__.Foo <__main__.Foo instance at 0x4022068c> !2006-09-12 Tue ネスト >>> class Foo: ... class Bar: ... pass ... pass ... >>> Foo() <__main__.Foo instance at 0x4022066c> >>> Bar() Traceback (most recent call last): File "", line 1, in ? NameError: name 'Bar' is not defined >>> Foo.Bar() <__main__.Bar instance at 0x4022096c> * ネストできるの??? * どういう意味になっているんだろうか? !2006-09-11 Mon self >>> class Foo: ... def __init__(self): ... print self ... >>> Foo() <__main__.Foo instance at 0x4022068c> <__main__.Foo instance at 0x4022068c> !2006-09-10 Sun クラシック? >>> class Foo: ... pass ... >>> type(Foo) >>> type(Foo()) >>> object >>> class Foo(object): ... pass ... >>> type(Foo) >>> type(Foo()) !2006-09-09 Sat self 省略可能? >>> class Foo: ... def __init__(self): ... pass ... def foo(): ... return "foo" ... >>> Foo().foo() Traceback (most recent call last): File "", line 1, in ? TypeError: foo() takes no arguments (1 given) >>> class Foo: ... def foo(self): ... return "foo" ... >>> Foo().foo() 'foo' self は必要らしい !2006-09-08 Fri 昨日のリベンジ >>> class Foo: ... def __init__(self, x): ... self.x = x ... def x(self): ... return self.x ... >>> f = Foo(1) >>> f.x 1 >>> f.x() Traceback (most recent call last): File "", line 1, in ? TypeError: 'int' object is not callable >>> Foo.x >>> Foo.x() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method x() must be called with Foo instance as first argument (got nothing instead) あれ? >>> class Foo: ... def __init__(self, x): ... self.x = x ... def get_x(self): ... return self.x ... >>> f = Foo(1) >>> f <__main__.Foo instance at 0x4022068c> >>> f.x 1 >>> f.get_x() 1 >>> Foo.get_x(f) 1 インスタンス名とメソッド名は同じじゃダメなのか??? 「TypeError: 'int' object is not callable」は、「1()」をやろうとしているのかな? >>> 1() Traceback (most recent call last): File "", line 1, in ? TypeError: 'int' object is not callable !2006-09-07 Thu >>> class Foo: ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def x(): ... return x ... def y(): ... return y ... >>> f = Foo(1, 2) >>> f.x 1 >>> f.x() Traceback (most recent call last): File "", line 1, in ? TypeError: 'int' object is not callable >>> Foo.x >>> Foo.x() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method x() must be called with Foo instance as first argument (got nothing instead) * def の定義のとき括弧省略できるんだっけと迷ったダメさ加減 * 間違いまくりの記述だった…。明日リベンジ !2006-09-06 Wed >>> class Foo: ... def __init__(self): ... self.__init__() ... >>> Foo() ... File "", line 3, in __init__ File "", line 3, in __init__ RuntimeError: maximum recursion depth exceeded !2006-09-05 Tue まずは、クラス >>> class Foo: ... File "", line 2 ^ IndentationError: expected an indented block >>> class Foo: ... pass ... >>> Foo >>> Foo() <__main__.Foo instance at 0x40223eec> !2006-09-04 Mon >>> m = mhlib.Message(mhlib.Folder(mhlib.MH(), "inbox"), 1) >>> m.openmessage(1) Traceback (most recent call last): File "", line 1, in ? AttributeError: Message instance has no attribute 'openmessage' >>> dir(m) ['__contains__', '__delitem__', '__doc__', '__getitem__', '__init__', '__len__', '__module__', '__repr__', '__setitem__', '__str__', 'dict', 'encodingheader', 'folder', 'fp', 'get', 'getaddr', 'getaddrlist', 'getallmatchingheaders', 'getbody', 'getbodyparts', 'getbodytext', 'getdate', 'getdate_tz', 'getencoding', 'getfirstmatchingheader', 'getheader', 'getheaders', 'getheadertext', 'getmaintype', 'getparam', 'getparamnames', 'getplist', 'getrawheader', 'getsubtype', 'gettype', 'has_key', 'headers', 'iscomment', 'isheader', 'islast', 'items', 'keys', 'maintype', 'number', 'parseplist', 'parsetype', 'plist', 'plisttext', 'readheaders', 'rewindbody', 'seekable', 'setdefault', 'startofbody', 'startofheaders', 'status', 'subtype', 'type', 'typeheader', 'unixfrom', 'values'] ? !2006-09-03 Sun movemessage とばし。ton って何だ? tofolder of number ?それじゃ逆か >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.copymessage(9035, mhlib.Folder(mhlib.MH(), "trash"), 512) trash フォルダの 512 番にコピーされていた !2006-09-02 Sat removemessages とばし。 >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.refilemessages([9036], 'trash') Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/mhlib.py", line 492, in refilemessages ton = tofolder.getlast() + 1 AttributeError: 'str' object has no attribute 'getlast' >>> mhlib.Folder(mhlib.MH(), "trash").refilemessages([512], mhlib.Folder(mhlib.MH(), "inbox")) !2006-09-01 Fri >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.putsequences({'cur': [10000000]}) >>> f.putsequences({'inbox': [9037]}) ? !2006-08-31 Thu >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getsequences() {'cur': [10000000]} ? !2006-08-30 Wed >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.setlast(9038) >>> f.getlast() 9038 !2006-08-29 Tue parsesequence 分からず。 >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getlast() 9037 !2006-08-28 Mon >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getcurrent() Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/mhlib.py", line 336, in getcurrent raise Error, "no cur message" mhlib.Error: no cur message >>> f.setcurrent(1) >>> f.getcurrent() 1 >>> f.setcurrent(10000000) >>> f.getcurrent() 10000000 !2006-08-27 Sun >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.listmessages() ... 7973, 7974] !2006-08-26 Sat >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getmessagefilename(1) '/home/nori/Mail/inbox/1' !2006-08-25 Fri >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getsequencesfilename() '/home/nori/Mail/inbox/.mh_sequences' そんなファイルはないみたいだが !2006-08-24 Thu >>> import mhlib >>> f = mhlib.Folder(mhlib.MH(), "inbox") >>> f.getfullname() '/home/nori/Mail/inbox' !2006-08-23 Wed >>> import mhlib >>> mhlib.Folder(mhlib.MH(), "inbox") Folder(MH('/home/nori/Mail', '/home/nori/.mh_profile'), 'inbox') >>> f = mhlib.Folder(mhlib.MH(), "inbox") !2006-08-22 Tue >>> import mhlib >>> mh = mhlib.MH() >>> mh.openfolder("inbox") Folder(MH('/home/nori/Mail', '/home/nori/.mh_profile'), 'inbox') !2006-08-21 Mon >>> import mhlib >>> mh = mhlib.MH() >>> mh.makefolder("hoge") >>> mh.deletefolder("hoge") !2006-08-20 Sun >>> import mhlib >>> mh = mhlib.MH() >>> mh.listallsubfolders("inbox") [] >>> mh.listallsubfolders("attach") [] !2006-08-19 Sat >>> import mhlib >>> mh = mhlib.MH() >>> mh.listsubfolders("inbox") [] >>> mh.listsubfolders("draft") [] >>> mh.listsubfolders("attach") ['attach/16', 'attach/19', 'attach/2', 'attach/20'] !2006-08-18 Fri >>> import mhlib >>> mh = mhlib.MH() >>> mh.listallfolders() ['attach', 'backup', 'draft', 'inbox', 'inbox30', 'inbox31', 'inbox32', 'inbox33', 'postq', 'queue', 'trash'] listfolders() と何が違う? !2006-08-17 Thu >>> import mhlib >>> mh = mhlib.MH() >>> mh.listfolders() ['attach', 'backup', 'draft', 'inbox', 'inbox30', 'inbox31', 'inbox32', 'inbox33', 'postq', 'queue', 'trash'] !2006-08-16 Wed >>> import mhlib >>> mh = mhlib.MH() >>> mh.setcontext("draft") >>> mh.getcontext() 'draft' !2006-08-15 Tue >>> import mhlib >>> mh = mhlib.MH() >>> mh.getcontext() 'inbox' !2006-08-14 Mon >>> import mhlib >>> mh = mhlib.MH() >>> mh.getpath() '/home/nori/Mail' !2006-08-13 Sun >>> import mhlib >>> mh = mhlib.MH() >>> mh.error("foo") MH error: foo >>> mh.error("%s %d", "foo", 1) MH error: foo 1 !2006-08-12 Sat >>> import csv >>> s = csv.Sniffer() >>> s.has_header("1,2,3") True >>> s.has_header("123") True >>> s.has_header("1 2 3") True >>> s.sniff("1,2,3") >>> s.sniff("1\t2\t3") >>> s.sniff("1,2,3").delimiter ',' >>> s.sniff("1\t2\t3").delimiter '\t' >>> s.sniff("1,2\t3") >>> s.sniff("1,2\t3").delimiter ',' >>> s.sniff("1\t2,3").delimiter ',' !2006-08-11 Fri >>> import csv >>> f = file("foo.csv", "w") >>> dw = csv.DictWriter(f, ["name", "value"]) >>> dw.writerow({"name" : 1, "value" : 2}) >>> dw.writerow({"name" : 10, "value" : 20}) >>> f.close() >>> reader = csv.DictReader(file("foo.csv", "r"), ["name", "value"]) >>> for row in reader: ... print row ... {'name': '1', 'value': '2'} {'name': '10', 'value': '20'} !2006-08-10 Thu >>> import csv >>> csv.excel.delimiter ',' >>> csv.excel.doublequote True >>> csv.excel.escapechar >>> csv.excel.lineterminator '\r\n' >>> csv.excel.quotechar '"' >>> csv.excel.quoting 0 >>> csv.excel.skipinitialspace False !2006-08-09 Wed >>> import csv >>> class excel_space(csv.excel): ... delimiter = ' ' ... >>> csv.register_dialect("excel-space", excel_space) >>> csv.list_dialects() ['excel-tab', 'excel', 'excel-space'] !2006-08-08 Tue >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f, 'excel-tab') >>> writer.writerow([1, 2, 3]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "r")) >>> for row in reader: ... print row ... ['1\t2\t3'] >>> reader = csv.reader(file("foo.csv", "r"), 'excel-tab') >>> for row in reader: ... print row ... ['1', '2', '3'] !2006-08-07 Mon >>> import csv >>> csv.get_dialect('excel') >>> csv.get_dialect('excel-tab') >>> dir(csv.get_dialect('excel')) ['__doc__', '__init__', '__module__', '_name', '_valid', '_validate', 'delimiter', 'doublequote', 'escapechar', 'lineterminator', 'quotechar', 'quoting', 'skipinitialspace'] !2006-08-06 Sun >>> import csv >>> csv.list_dialects() ['excel-tab', 'excel'] !2006-08-05 Sat >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerow(["foo,bar"]) >>> f.close() >>> f = open("foo.csv") >>> f.readlines() ['"foo,bar"\r\n'] >>> f.close() !2006-08-04 Fri >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerows([[1,2,3], [4,5]]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "r")) >>> for row in reader: ... print row ... ['1', '2', '3'] ['4', '5'] !2006-08-03 Thu >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerows([[0x10, 0x20], [0x30, 0x40]]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "rb")) >>> for row in reader: ... print row ... ['16', '32'] ['48', '64'] >>> str(0x10) '16' !2006-08-02 Wed >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerows([[1+1j, 2+2j], [3+3j, 4+4j]]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "rb")) >>> for row in reader: ... print row ... ['(1+1j)', '(2+2j)'] ['(3+3j)', '(4+4j)'] !2006-08-01 Tue >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerows([["foo bar",2], [4,"hoge hoge"]]) >>> f.close() で、foo.csv は、 foo bar,2 4,hoge hoge 空白がある場合にも "" で囲わないんだ〜と思ったら、 ruby の csv モジュールも囲っていなかった。 !2006-07-31 Mon >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerows([[1,2,3], [4,5,6]]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "rb")) >>> for row in reader: ... print row ... ['1', '2', '3'] ['4', '5', '6'] !2006-07-30 Sun >>> import csv >>> f = file("foo.csv", "w") >>> writer = csv.writer(f) >>> writer.writerow([1,2,3]) >>> writer.writerow([4,5,6]) >>> f.close() >>> reader = csv.reader(file("foo.csv", "rb")) >>> for row in reader: ... print row ... ['1', '2', '3'] ['4', '5', '6'] 配列としていっぺんに読み込む方法はないのだろうか? !2006-07-29 Sat >>> import csv >>> csv.QUOTE_ALL 1 >>> csv.QUOTE_MINIMAL 0 >>> csv.QUOTE_NONNUMERIC 2 >>> csv.QUOTE_NONE 3 !2006-07-28 Fri >>> import sys >>> sys.winver Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'winver' !2006-07-27 Thu >>> import sys >>> sys.warnoptions [] !2006-07-26 Wed >>> import sys >>> sys.version '2.3.5 (#2, Sep 4 2005, 22:01:42) \n[GCC 3.3.5 (Debian 1:3.3.5-13)]' >>> sys.api_version 1012 >>> sys.version_info (2, 3, 5, 'final', 0) !2006-07-25 Tue >>> import sys >>> sys.tracebacklimit Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'tracebacklimit' あれ? 2.3.5 では未実装??? !2006-07-24 Mon settrace(), settscdump() とばし。 >>> import sys >>> sys.stdin ', mode 'r' at 0x401e0020> >>> sys.stdout ', mode 'w' at 0x401e0060> >>> sys.stderr ', mode 'w' at 0x401e00a0> >>> sys.__stdin__ ', mode 'r' at 0x401e0020> >>> sys.__stdout__ ', mode 'w' at 0x401e0060> >>> sys.__stderr__ ', mode 'w' at 0x401e00a0> !2006-07-23 Sun setdefaultencoding(), setdlopenflags(), setprofile() とばし >>> import sys >>> sys.getrecursionlimit() 1000 >>> def fact(n): ... if n == 0: ... return 1 ... else: ... return n * fact(n-1) ... >>> fact(10) 3628800 >>> sys.setrecursionlimit(10) >>> fact(8) 40320 >>> fact(9) Traceback (most recent call last): File "", line 1, in ? File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact File "", line 5, in fact RuntimeError: maximum recursion depth exceeded >>> sys.setrecursionlimit(20) >>> fact(10) 3628800 !2006-07-22 Sat >>> import sys >>> sys.getcheckinterval() 100 >>> sys.setcheckinterval(1000) >>> sys.getcheckinterval() 1000 !2006-07-21 Fri >>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' !2006-07-20 Thu >>> import sys >>> sys.prefix '/usr' !2006-07-19 Wed >>> import sys >>> sys.platform 'linux2' !2006-07-18 Tue >>> import sys >>> sys.path ['', '/usr/lib/python23.zip', '/usr/lib/python2.3', '/usr/lib/python2.3/plat-linux2', '/usr/lib/python2.3/lib-tk', '/usr/lib/python2.3/lib-dynload', '/usr/local/lib/python2.3/site-packages', '/usr/lib/python2.3/site-packages', '/usr/lib/python2.3/site-packages/PIL'] !2006-07-17 Mon >>> import sys >>> sys.modules {'copy_reg': , '__main__': , 'site': , '__builtin__': , 'encodings': , 'encodings.encodings': None, 'posixpath': , 'encodings.codecs': None, 'os.path': , '_codecs': , 'encodings.exceptions': None, 'stat': , 'zipimport': , 'warnings': , 'encodings.types': None, 'UserDict': , 'sys': , 'codecs': , 'readline': , 'types': , 'signal': , 'linecache': , 'posix': , 'encodings.aliases': , 'exceptions': , 'os': } !2006-07-16 Sun >>> import sys >>> sys.maxunicode 1114111 !2006-07-15 Sat >>> import sys >>> sys.maxint 2147483647 !2006-07-14 Fri >>> import sys >>> sys.last_type Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'last_type' >>> sys.last_value >>> sys.last_type >>> sys.last_traceback !2006-07-13 Thu >>> import sys >>> sys.getwindowsversion() Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'getwindowsversion' >>> sys.hexversion() Traceback (most recent call last): File "", line 1, in ? TypeError: 'int' object is not callable >>> sys.hexversion 33752560 !2006-07-12 Wed >>> import sys >>> sys._getframe() !2006-07-11 Tue >>> import sys >>> sys.getrecursionlimit() 1000 !2006-07-10 Mon >>> import sys >>> sys.getrefcount(x) Traceback (most recent call last): File "", line 1, in ? NameError: name 'x' is not defined >>> x = "foo" >>> sys.getrefcount(x) 2 >>> a = [x, x] >>> sys.getrefcount(x) 4 >>> a = [] >>> sys.getrefcount(x) 2 >>> a = [x, x, x] >>> sys.getrefcount(x) 5 !2006-07-09 Sun >>> import sys >>> sys.getfilesystemencoding() !2006-07-08 Sat >>> import sys >>> sys.getdlopenflags() 2 !2006-07-07 Fri >>> import sys >>> sys.getdefaultencoding() 'ascii' !2006-07-06 Thu >>> import sys >>> sys.getcheckinterval() 100 !2006-07-05 Wed >>> import sys >>> sys.exit(0) >>> import sys >>> sys.exit("foo") foo !2006-07-04 Tue >>> import sys >>> sys.executable '/usr/bin/python' !2006-07-03 Mon >>> import sys >>> sys.exec_prefix '/usr' !2006-07-02 Sun >>> import sys >>> sys.exc_clear() !2006-07-01 Sat >>> import sys >>> sys.exc_info() (None, None, None) !2006-06-30 Fri displayhook, excepthook とばし。 >>> import sys >>> sys.__displayhook__ >>> sys.__excepthook__ !2006-06-29 Thu >>> import sys >>> sys.copyright 'Copyright (c) 2001-2005 Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.' !2006-06-28 Wed >>> import sys >>> sys.builtin_module_names ('__builtin__', '__main__', '_codecs', '_sre', '_symtable', 'errno', 'exceptions', 'gc', 'imp', 'marshal', 'posix', 'signal', 'sys', 'thread', 'xxsubtype', 'zipimport') !2006-06-27 Tue >>> import sys >>> sys.byteorder 'little' !2006-06-26 Mon >>> import sys >>> sys.argv [''] !2006-06-25 Sun >>> import urllib >>> urllib.url2pathname(urllib.pathname2url("~foo")) '~foo' URLopener, FancyURLopener をすぐ使うとおもえないので、とばし !2006-06-24 Sat >>> import urllib >>> urllib.pathname2url("/home/foo") '/home/foo' >>> urllib.pathname2url("~foo") '%7Efoo' >>> urllib.pathname2url("~foo/bar/baz") '%7Efoo/bar/baz' >>> urllib.pathname2url("~foo\bar\baz") '%7Efoo%08ar%08az' >>> urllib.pathname2url("~foo\\bar\\baz") '%7Efoo%5Cbar%5Cbaz' UNIX 上でやっても確認しにくいってことか? !2006-06-23 Fri >>> import urllib >>> urllib.urlencode({"file" : "foo"}) 'file=foo' >>> urllib.urlencode({"file" : "foo", "key" : "bar"}) 'key=bar&file=foo' >>> urllib.urlencode({"file" : "foo", "key" : "bar +"}) 'key=bar+%2B&file=foo' >>> urllib.urlencode({"file" : "foo", "key" : "bar "}) 'key=bar++&file=foo' >>> urllib.urlencode((("file", "foo"), ("key", "bar"))) 'file=foo&key=bar' >>> urllib.urlencode((("file", "foo"),)) 'file=foo' >>> urllib.urlencode((("file", "foo"))) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/urllib.py", line 1192, in urlencode raise TypeError TypeError: not a valid non-string sequence or mapping object 第2引数の機能 不明 !2006-06-22 Thu >>> import urllib >>> urllib.quote_plus("~ +%aaa") '%7E+%2B%25aaa' >>> urllib.quote("~ +%aaa") '%7E%20%2B%25aaa' !2006-06-21 Wed >>> import urllib >>> urllib.quote("~ +%aaa") '%7E%20%2B%25aaa' >>> urllib.quote("~ +%aaa", "~ ") '~ %2B%25aaa' !2006-06-20 Tue >>> import urllib >>> urllib.urlretrieve("http://www.ruby-lang.org/") ('/tmp/tmp0jUERw', ) >>> urllib.urlretrieve("http://www.ruby-lang.org/") ('/tmp/tmp3qbjGh', ) >>> urllib.urlcleanup() >>> urllib.urlretrieve("http://www.ruby-lang.org/") ('/tmp/tmphDR_So', ) 機能しているのか良く分からない !2006-06-19 Mon >>> import urllib >>> urllib.urlretrieve("http://www.ruby-lang.org/") ('/tmp/tmpzNb5T1', ) >>> urllib.urlretrieve("http://www.ruby-lang.org/", "foo") ('foo', ) !2006-06-18 Sun >>> import urllib >>> uo = urllib.urlopen("http://www.ruby-lang.org/") >>> uo.info() >>> import mimetools >>> uo.info().__methods__ Traceback (most recent call last): File "", line 1, in ? AttributeError: HTTPMessage instance has no attribute '__methods__' >>> uo.info().getplist() ['charset=iso-8859-1'] >>> uo.info().getencoding() '7bit' >>> uo.info().gettype() 'text/html' >>> uo.info().getmaintype() 'text' >>> uo.info().getsubtype() 'html' !2006-06-17 Sat >>> import urllib >>> uo = urllib.urlopen("http://www.ruby-lang.org/") >>> uo.geturl() 'http://www.ruby-lang.org/en/' !2006-06-16 Fri >>> import urllib >>> uo = urllib.urlopen("http://www.ruby-lang.org/") >>> uo.info() !2006-06-15 Thu >>> import urllib >>> no = urllib.urlopen("http://www.ruby-lang.org/") >>> no > >>> no.close() >>> no !2006-06-14 Wed >>> import urllib >>> no = urllib.urlopen("http://www.ruby-lang.org/") >>> no.fileno() 3 何の値? !2006-06-13 Tue >>> import urllib >>> no = urllib.urlopen("http://www.ruby-lang.org/") >>> no.readlines() ['>> import urllib >>> no = urllib.urlopen("http://www.ruby-lang.org/") >>> no.readline() '\n' !2006-06-11 Sun >>> import urllib >>> urllib.urlopen("http://www.ruby-lang.org/") > >>> no = urllib.urlopen("http://www.ruby-lang.org/") >>> no.read() '>> import shlex >>> lex = shlex.shlex() >>> lex.read_token() a_b_c 'a_b_c' >>> lex.read_token() a-b-c 'a' >>> >>> lex.read_token() 'b' >>> lex.read_token() 'c' >>> lex.read_token() 1+2 '1' >>> lex.read_token() '2' >>> lex.read_token() "foo bar" '"foo bar"' >>> lex.read_token() "foo \"bar\"" '"foo \\"' >>> lex.read_token() 'bar' >>> lex.read_token() '""' >>> lex.read_token() a -b 1 -c 'a' >>> lex.read_token() '-' >>> lex.read_token() 'b' >>> lex.read_token() '1' >>> lex.read_token() '-' >>> lex.read_token() 'c' いまいち良く分からないなあ〜。 本当にシェルっぽいプログラムを書くときに簡単になるのだろうか? !2006-06-09 Fri *source* とばし >>> import shlex >>> lex = shlex.shlex() >>> lex.error_leader > >>> lex.error_leader("foo") '"foo", line 1: ' >>> lex.error_leader > >>> lex.error_leader("foo", 2) '"foo", line 2: ' >>> lex.error_leader("foo", 2) '"foo", line 2: ' !2006-06-08 Thu >>> import shlex >>> lex = shlex.shlex() >>> lex.eof '' !2006-06-07 Wed >>> import shlex >>> lex = shlex.shlex() >>> lex.token '' >>> lex.get_token() a 'a' >>> lex.token '' >>> lex.push_token("a") >>> lex.token '' >>> lex.get_token() 'a' ふにゃ? !2006-06-06 Tue >>> import shlex >>> lex = shlex.shlex() >>> lex.lineno 1 >>> lex.lineno 1 >>> lex.get_token() a 'a' >>> lex.lineno 2 >>> lex.get_token() a b c 'a' >>> lex.lineno 2 >>> lex.get_token() 'b' >>> lex.lineno 2 >>> lex.get_token() 'c' >>> lex.lineno 3 !2006-06-05 Mon >>> import shlex >>> lex = shlex.shlex() >>> lex.debug 0 >>> lex.debug = 1 >>> lex.get_token() a b shlex: token='a' 'a' >>> lex.get_token() shlex: token='b' 'b' !2006-06-04 Sun >>> import shlex >>> lex = shlex.shlex() >>> lex.source !2006-06-03 Sat >>> import shlex >>> lex = shlex.shlex() >>> lex.instream ', mode 'r' at 0x401e0020> !2006-06-02 Fri >>> import shlex >>> lex = shlex.shlex() >>> lex.infile !2006-06-01 Thu >>> import shlex >>> lex = shlex.shlex() >>> lex.whitespace_split False !2006-05-31 Wed >>> import shlex >>> lex = shlex.shlex() >>> lex.escapedquotes '"' !2006-05-30 Tue >>> import shlex >>> lex = shlex.shlex() >>> lex.quotes '\'"' !2006-05-29 Mon >>> import shlex >>> lex = shlex.shlex() >>> lex.escape '\\' !2006-05-28 Sun >>> import shlex >>> lex = shlex.shlex() >>> lex.whitespace ' \t\r\n' !2006-05-27 Sat >>> import shlex >>> lex = shlex.shlex() >>> lex.wordchars 'abcdfeghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' !2006-05-26 Fri >>> import shlex >>> lex = shlex.shlex() >>> lex.commenters '#' !2006-05-25 Thu >>> import shlex >>> lex = shlex.shlex() >>> lex.read_token() a 'a' >>> lex.push_token("a b c") >>> lex.read_token() a 'a' >>> lex.get_token() 'a b c' >>> lex.get_token() a 'a' !2006-05-24 Wed >>> import shlex >>> lex = shlex.shlex() >>> lex.push_token("a b c") >>> lex.get_token() 'a b c' !2006-05-23 Tue >>> import shlex >>> lex = shlex.shlex() >>> lex.get_token() a 'a' >>> lex.get_token() a b c 'a' >>> lex.get_token() 'b' >>> lex.get_token() 'c' >>> lex.get_token() a 'a' !2006-05-22 Mon >>> import shlex >>> lex = shlex.shlex() >>> lex.eof '' >>> lex = shlex.shlex(sys.stdin, "*sys.stdin*", True) >>> lex.eof !2006-05-21 Sun >>> import shlex >>> lex = shlex.shlex() >>> lex.infile >>> lex.read_token() a 'a' >>> import sys >>> lex = shlex.shlex(sys.stdin, "*sys.stdin*") >>> lex.infile '*sys.stdin*' !2006-05-20 Sat >>> import shlex >>> shlex.split("foo bar baz") ['foo', 'bar', 'baz'] >>> shlex.split(" foo bar baz ") ['foo', 'bar', 'baz'] >>> " foo bar baz ".split() ['foo', 'bar', 'baz'] >>> shlex.split("./foo -a bar -t barz") ['./foo', '-a', 'bar', '-t', 'barz'] >>> shlex.split("# foo bar baz ") ['#', 'foo', 'bar', 'baz'] >>> shlex.split("# foo bar baz ", False) ['#', 'foo', 'bar', 'baz'] >>> shlex.split("# foo bar baz ", True) [] 第2引数に対する挙動はこれであっているのだろうか? 訳の間違いではないみたいなんだけど !2006-05-19 Fri http://python.matrix.jp/tips/container/dict.html >>> fname = 'test.log' >>> date = '2005-09-29' >>> "file:%(fname)s(%(date)s)" % vars() 'file:test.log(2005-09-29)' >>> "file:%(fname)s...%(fname)s" % vars() 'file:test.log...test.log' >>> "Detected %(b)d count(s) for %(a)s." % {'a': 'hoge', 'b':123} 'Detected 123 count(s) for hoge.' !2006-05-18 Thu http://python.matrix.jp/tips/container/dict.html >>> dir() ['__builtins__', '__doc__', '__name__', 'dic'] >>> dir({'hoge': 123, 'moge': 456}) ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] !2006-05-17 Wed http://python.matrix.jp/tips/container/dict.html >>> dict(zip(['hoge', 'moge'],[123, 456])) {'moge': 456, 'hoge': 123} zip って使いこなしていないなあ〜 !2006-05-16 Tue http://python.matrix.jp/tips/container/dict.html >>> vars() {'__builtins__': , '__name__': '__main__', '__doc__': None} >>> locals() {'__builtins__': , '__name__': '__main__', '__doc__': None} >>> globals() {'__builtins__': , '__name__': '__main__', '__doc__': None} >>> dic = {} >>> vars() {'__builtins__': , '__name__': '__main__', '__doc__': None, 'dic': {}} >>> locals() {'__builtins__': , '__name__': '__main__', '__doc__': None, 'dic': {}} >>> globals() {'__builtins__': , '__name__': '__main__', '__doc__': None, 'dic': {}} !2006-05-15 Mon http://python.matrix.jp/tips/container/list.html Python 2.3.5 ではダメ(ジェネレータは) Python 2.4.1 (#2, May 5 2005, 11:32:06) [GCC 3.3.5 (Debian 1:3.3.5-12)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> range(3) [0, 1, 2] >>> reversed([1,2,3]) >>> for i in reversed([1,2,3]): ... print i ... 3 2 1 >>> for i in sorted([1,2,3], reverse=True): ... print i ... 3 2 1 >>> for i in sorted([3,2,1]): ... print i ... 1 2 3 !2006-05-14 Sun >>> import platform >>> platform.libc_ver() ('glibc', '2.3') なぜ、微妙に略す〜 !2006-05-13 Sat >>> import platform >>> platform.dist() ('', '', '') !2006-05-12 Fri >>> import platform >>> platform.uname() ('Linux', 'valuestar', '2.4.31-0vl1.12.1', '#1 Sat May 13 00:23:28 JST 2006', 'i686', '') !2006-05-11 Thu >>> import platform >>> platform.version() '#1 Sat May 13 00:23:28 JST 2006' !2006-05-10 Wed >>> import platform >>> platform.system_alias(platform.system(), platform.release(), platform.version()) ('Linux', '2.4.31-0vl1.12.1', '#1 Sat May 13 00:23:28 JST 2006') タプルで返しただけ??? !2006-05-09 Tue >>> import platform >>> platform.system() 'Linux' !2006-05-08 Mon >>> import platform >>> platform.release() '2.4.31-0vl1.12.1' !2006-05-07 Sun >>> import platform >>> platform.python_version_tuple() ['2', '3', '4'] !2006-05-06 Sat >>> import platform >>> platform.python_version() '2.3.4' !2006-05-05 Fri >>> import platform >>> platform.python_compiler() 'GCC 3.3.2 20031218 (Vine Linux 3.3.2-0vl8)' !2006-05-04 Thu >>> import platform >>> platform.python_build() (1, 'Sep 28 2005 13:29:57') !2006-05-03 Wed >>> import platform >>> platform.processor() '' !2006-05-02 Tue >>> import platform >>> platform.platform() 'Linux-2.4.31-0vl1.12.1-i686-with-glibc2.3' >>> platform.platform(True) 'Linux-2.4.31-0vl1.12.1-i686-with-glibc2.3' !2006-05-01 Mon >>> import platform >>> platform.node() 'machine name' !2006-04-30 Sun >>> import platform >>> platform.machine() 'i686' !2006-04-29 Sat >>> import platform >>> platform.architecture() ('32bit', 'ELF') !2006-04-28 Fri # Ruby >> ["foo", "bar", "1", "2"].grep(/\d+/) => ["1", "2"] # Python >>> def ary_grep(ary, pattern): ... ret = [] ... for x in ary: ... m = re.search(pattern, x) ... if m: ... ret.append(x) ... return ret ... >>> ary_grep(["foo", "bar", "1", "2"], "\d+") ['1', '2'] String#count, String#delete, String#squeeze, String#tr も 正規表現っぽい(tr(1)) のが書けるけど、とばし。 !2006-04-27 Thu # Ruby >> "foo foo foo".sub(/foo/, "bar") => "bar foo foo" >> "foo foo foo".sub(/\s+/, ":") => "foo:foo foo" # Python >>> import re >>> re.sub("foo", "bar", "foo foo foo", 1) 'bar foo foo' >>> re.sub("\s+", ":", "foo foo foo", 1) 'foo:foo foo' !2006-04-26 Wed # Ruby >> '1-10,20'.split(/([-,])/) => ["1", "-", "10", ",", "20"] >> '1-10,20'.split(/(-)|(,)/) => ["1", "-", "10", ",", "20"] >> "a,b,c,,,".split(/,/) => ["a", "b", "c"] >> "a,b,c,,,".split(/,/, 0) => ["a", "b", "c"] >> "a,b,c,,,".split(/,/, 3) => ["a", "b", "c,,,"] >> "a,b,c,,,".split(/,/, 6) => ["a", "b", "c", "", "", ""] >> "a,b,c,,,".split(/,/, -1) => ["a", "b", "c", "", "", ""] >> "a,b,c,,,".split(/,/, 100) => ["a", "b", "c", "", "", ""] # Python >>> import re >>> re.split("([-,])", "1-10,20") ['1', '-', '10', ',', '20'] >>> re.split("(-)|(,)", "1-10,20") ['1', '-', None, '10', None, ',', '20'] >>> re.split(",", "a,b,c,,,") ['a', 'b', 'c', '', '', ''] >>> re.split(",", "a,b,c,,,", 0) ['a', 'b', 'c', '', '', ''] >>> re.split(",", "a,b,c,,,", 3) ['a', 'b', 'c', ',,'] >>> re.split(",", "a,b,c,,,", 2) ['a', 'b', 'c,,,'] >>> re.split(",", "a,b,c,,,", 6) ['a', 'b', 'c', '', '', ''] >>> re.split(",", "a,b,c,,,", -1) ['a,b,c,,,'] >>> re.split(",", "a,b,c,,,", 100) ['a', 'b', 'c', '', '', ''] !2006-04-25 Tue # Ruby >> " a \t b \n c".split(/\s+/) => ["", "a", "b", "c"] >> " a \t b \n c".split => ["a", "b", "c"] >> " a \t b \n c".split(' ') => ["a", "b", "c"] >> 'hi there'.split(/ */) => ["h", "i", "t", "h", "e", "r", "e"] >> 'hi there'.split(//) => ["h", "i", " ", "t", "h", "e", "r", "e"] # Python >>> import re >>> re.split("\s+", " a \t b \n c") ['', 'a', 'b', 'c'] >>> re.split(" ", " a \t b \n c") ['', '', '', 'a', '\t', '', 'b', '\n', '', 'c'] >>> re.split(" *", "hi there") ['hi', 'there'] >>> re.split("", "hi there") ['hi there'] >>> re.split(".", "hi there") ['', '', '', '', '', '', '', '', ''] >>> re.split("(.)", "hi there") ['', 'h', '', 'i', '', ' ', '', 't', '', 'h', '', 'e', '', 'r', '', 'e', ''] うむー、良く分からない… !2006-04-24 Mon # Ruby >> s = "foo bar"; s.slice!(/(\S+)\s+(\S+)/, 0) => "foo bar" >> s => "" >> s = "foo bar"; s.slice!(/(\S+)\s+(\S+)/, 1) => "foo" >> s => " bar" >> s = "foo bar"; s.slice!(/(\S+)\s+(\S+)/, 2) => "bar" >> s => "foo " >> s = "foo bar"; s.slice!(/(\S+)\s+(\S+)/, 3) => nil >> s => "foo bar" # Python >>> import re >>> def string_slice(str, pattern, nth = 0): ... m = re.search(pattern, str) ... if m: ... return str[0:m.start(nth)] + str[m.end(nth):] ... else: ... return str ... >>> string_slice("foo bar", "(\S+)\s+(\S+)") '' >>> string_slice("foo bar", "(\S+)\s+(\S+)", 0) '' >>> string_slice("foo bar", "(\S+)\s+(\S+)", 1) ' bar' >>> string_slice("foo bar", "(\S+)\s+(\S+)", 2) 'foo ' >>> string_slice("foo bar", "(\S+)\s+(\S+)", 3) Traceback (most recent call last): File "", line 1, in ? File "", line 4, in string_slice IndexError: no such group !2006-04-23 Sun # Ruby >> s = "foo bar"; s.slice!(/\S+/) => "foo" >> s => " bar" # Python >>> import re >>> def string_slice(str, pattern): ... return re.sub(pattern, "", str, 1) ... >>> string_slice("foo bar", "\S+") ' bar' !2006-04-22 Sat # Ruby >> "foobarbazfoobarbaz".scan(/ba./) {|s| p s} "bar" "baz" "bar" "baz" => "foobarbazfoobarbaz" >> "foobarbazfoobarbaz".scan(/(ba)(.)/) {|s| p s} ["ba", "r"] ["ba", "z"] ["ba", "r"] ["ba", "z"] => "foobarbazfoobarbaz" # Python >>> for m in re.finditer("ba.", "foobarbazfoobarbaz"): ... print m.group() ... bar baz bar baz >>> for m in re.finditer("(ba)(.)", "foobarbazfoobarbaz"): ... print m.groups() ... ('ba', 'r') ('ba', 'z') ('ba', 'r') ('ba', 'z') !2006-04-21 Fri # Ruby >> "foobar".scan(/./) => ["f", "o", "o", "b", "a", "r"] >> "foobarbazfoobarbaz".scan(/ba./) => ["bar", "baz", "bar", "baz"] >> "foobar".scan(/(.)/) => [["f"], ["o"], ["o"], ["b"], ["a"], ["r"]] >> "foobarbazfoobarbaz".scan(/(ba)(.)/) => [["ba", "r"], ["ba", "z"], ["ba", "r"], ["ba", "z"]] # Python >>> import re >>> re.findall(".", "foobar") ['f', 'o', 'o', 'b', 'a', 'r'] >>> re.findall("ba.", "foobarbazfoobarbaz") ['bar', 'baz', 'bar', 'baz'] >>> re.findall("(.)", "foobar") ['f', 'o', 'o', 'b', 'a', 'r'] ? >>> re.findall("(ba)(.)", "foobarbazfoobarbaz") [('ba', 'r'), ('ba', 'z'), ('ba', 'r'), ('ba', 'z')] マニュアルだと this will be a list of tuples if the pattern has more than one group. これは、もしパターンにグループが 1つ以上あれば、タプルのリストとなります。 ということで、間違っていますね !2006-04-20 Thu # Ruby >> "regexpindex".rindex(/e.*x/) => 9 >> "regexpindex".rindex(/e.*x/, 2) => 1 >> "regexpindex".rindex(/e.*x/, 3) => 3 >> "regexpindex".rindex(/e.*x/, 8) => 3 >> "regexpindex".rindex(/e.*x/, 9) => 9 # Python >>> def string_rindex(str, pattern, pos = -1): ... if pos == -1: ... start = len(str) ... else: ... start = pos ... for i in xrange(start, -1, -1): ... m = re.compile(pattern).search(str, i) ... if m: ... if m.start() <= start: ... return m.start() ... return None ... >>> string_rindex("regexpindex", "e.*x") 9 >>> string_rindex("regexpindex", "e.*x", 2) 1 >>> string_rindex("regexpindex", "e.*x", 3) 3 >>> string_rindex("regexpindex", "e.*x", 8) 3 >>> string_rindex("regexpindex", "e.*x", 9) 9 仕様を理解できていないので、かなり怪しい… !2006-04-19 Wed # Ruby >> "regexpindex".index(/e.*x/) => 1 >> "regexpindex".index(/e.*x/, 2) => 3 >> "regexpindex".index(/e.*xx/) => nil # Python >>> import re >>> def string_index(str, pattern, pos = 0): ... if pos == 0: ... m = re.search(pattern, str) ... if m: ... return m.start() ... else: ... return None ... else: ... m = re.search(pattern, str[pos:]) ... if m: ... return pos + m.start() ... else: ... return None ... >>> string_index("regexpindex", "e.*x") 1 >>> string_index("regexpindex", "e.*x", 2) 3 >>> string_index("regexpindex", "e.*xx") 正規表現オブジェクトだと、引数に開始位置と終了位置が指定できるようだ >>> re.compile("e.*x").search("regexpindex") <_sre.SRE_Match object at 0x4021cf70> >>> re.compile("e.*x").search("regexpindex").start() 1 >>> re.compile("e.*x").search("regexpindex", 2).start() 3 >>> def string_index(str, pattern, pos = 0): ... m = re.compile(pattern).search(str, pos) ... if m: ... return m.start() ... else: ... return None ... >>> string_index("regexpindex", "e.*x") 1 >>> string_index("regexpindex", "e.*x", 2) 3 >>> string_index("regexpindex", "e.*xx") !2006-04-18 Tue # Ruby >> 'abcabc'.gsub(/b/, '(\&)') => "a(b)ca(b)c" >> 'abcabc'.gsub(/b/) {|s| s.upcase } => "aBcaBc" >> 'abcabc'.gsub(/b/) { $&.upcase } => "aBcaBc" >> 'abbbxabx'.gsub(/a(b+)/, '\1') => "bbbxbx" # Python >>> import re >>> re.sub("b", lambda m: "(%s)" % m.group(0), "abcabc") 'a(b)ca(b)c' >>> re.sub("b", lambda m: m.group(0).upper(), "abcabc") 'aBcaBc' >>> re.sub("a(b+)", r'\1', "abbbxabx") 'bbbxbx' !2006-04-17 Mon # Ruby >> "foo foo foo".gsub(/foo/, "bar") => "bar bar bar" >> "foo foo foo".gsub(/\s+/, ":") => "foo:foo:foo" # Python >>> import re >>> re.sub("foo", "bar", "foo foo foo") 'bar bar bar' >>> re.sub("\s+", ":", "foo foo foo") 'foo:foo:foo' !2006-04-16 Sun # Ruby >> s = "foo bar"; s[/(\S+)\s+(\S+)/, 0] = "FOO" => "FOO" >> s => "FOO" >> s = "foo bar"; s[/(\S+)\s+(\S+)/, 1] = "FOO" => "FOO" >> s => "FOO bar" >> s = "foo bar"; s[/(\S+)\s+(\S+)/, 2] = "FOO" => "FOO" >> s => "foo FOO" >> s = "foo bar"; s[/(\S+)\s+(\S+)/, 3] = "FOO" IndexError: index 3 out of regexp # Python >>> import re >>> def string_aset(str, pattern, val, nth = 0): ... m = re.search(pattern, str) ... if m: ... return str[0:m.start(nth)] + val + str[m.end(nth):] ... else: ... return str ... >>> string_aset("foo bar", "\S+", "FOO") 'FOO bar' >>> string_aset("foo bar", "(\S+)\s+(\S+)", "FOO", 0) 'FOO' >>> string_aset("foo bar", "(\S+)\s+(\S+)", "FOO", 1) 'FOO bar' >>> string_aset("foo bar", "(\S+)\s+(\S+)", "FOO", 2) 'foo FOO' >>> string_aset("foo bar", "(\S+)\s+(\S+)", "FOO", 3) Traceback (most recent call last): File "", line 1, in ? File "", line 4, in string_aset IndexError: no such group !2006-04-15 Sat # Ruby >> "foo bar"[/\S+/] = "FOO" => "FOO" >> s = "foo bar"; s[/\S+/] = "FOO" => "FOO" >> s => "FOO bar" # Python >>> import re >>> def string_aset(str, pattern, val): ... return re.sub(pattern, val, str, 1) ... >>> s = "foo bar" >>> string_aset(s, "\S+", "FOO") 'FOO bar' >>> string_aset(s, "\d+", "FOO") 'foo bar' 文字列はイミュータブルなので、これでしょうがない !2006-04-14 Fri # Ruby >> "foo bar"[/\S+/] => "foo" >> "foo bar"[/\d+/] => nil >> "foo bar"[/(\S+)\s+(\S+)/, 0] => "foo bar" >> "foo bar"[/(\S+)\s+(\S+)/, 1] => "foo" >> "foo bar"[/(\S+)\s+(\S+)/, 2] => "bar" >> "foo bar"[/(\S+)\s+(\S+)/, 3] => nil # Python >>> import re >>> def string_aref(str, pattern, nth = 0): ... m = re.search(pattern, str) ... if m: ... return m.group(nth) ... else: ... return None ... >>> string_aref("foo bar", "\S+") 'foo' >>> string_aref("foo bar", "\d+") >>> string_aref("foo bar", "(\S+)\s+(\S+)", 0) 'foo bar' >>> string_aref("foo bar", "(\S+)\s+(\S+)", 1) 'foo' >>> string_aref("foo bar", "(\S+)\s+(\S+)", 2) 'bar' >>> string_aref("foo bar", "(\S+)\s+(\S+)", 3) Traceback (most recent call last): File "", line 1, in ? File "", line 4, in string_aref IndexError: no such group !2006-04-13 Thu # Ruby >> "foo" =~ /[a-z]/ => 0 >> "FOO" =~ /[a-z]/ => nil >> "FOO" =~ /[a-z]/i => 0 # Python >>> import re >>> re.search(r"[a-z]", "foo") <_sre.SRE_Match object at 0x4021cf70> >>> re.search(r"[a-z]", "FOO") >>> re.search(r"[a-z]", "FOO", re.IGNORECASE) <_sre.SRE_Match object at 0x402230c8> !2006-04-12 Wed # Ruby >> "foo foo" =~ /(\S+)\s+\1/ => 0 >> "foo bar" =~ /(\S+)\s+\1/ => nil # Python >>> import re >>> "\1" '\x01' >>> "\\1" '\\1' >>> '\1' '\x01' >>> '\\1' '\\1' >>> r'\1' '\\1' >>> re.search("(\S+)\s+\\1", "foo foo") <_sre.SRE_Match object at 0x402107e0> >>> re.search("(\S+)\s+\\1", "foo bar") !2006-04-11 Tue # Ruby >> "foo bar" =~ /(\S+)\s+(\S+)/ => 0 >> [$1, $2] => ["foo", "bar"] >> /(\S+)\s+(\S+)/.match("foo bar") => # >> m = /(\S+)\s+(\S+)/.match("foo bar") => # >> m.size => 3 >> m.to_a => ["foo bar", "foo", "bar"] >> [m[0], m[1], m[2]] => ["foo bar", "foo", "bar"] # Python >>> import re >>> re.search("(\S+)\s+(\S+)", "foo bar") <_sre.SRE_Match object at 0x402240f8> >>> m = re.search("(\S+)\s+(\S+)", "foo bar") >>> m.group() 'foo bar' >>> m.group(0) 'foo bar' >>> m.group(1) 'foo' >>> m.group(2) 'bar' >>> m.group(0, 1, 2) ('foo bar', 'foo', 'bar') >>> m.groups() ('foo', 'bar') >>> m.lastindex 2 !2006-04-10 Mon # Ruby >> "foo" =~ /\S+/ => 0 >> "foo" =~ /\s+/ => nil >> " foo" =~ /\S+/ => 1 >> " foo" =~ /\s+/ => 0 # Python >>> import re >>> "\S" '\\S' >>> '\S' '\\S' >>> "\\S" '\\S' >>> '\\S' '\\S' >>> r"\S" '\\S' >>> '\w' '\\w' >>> re.match('\S+', "foo") <_sre.SRE_Match object at 0x4021cf70> >>> re.match('\S+', "foo").start() 0 >>> re.match('\s+', "foo") * match を使ってしまったが、match ではダメだった。 * match は文字列先頭からパタンに一致するか見る >>> re.match('\S+', " foo") >>> re.search('\S+', " foo") <_sre.SRE_Match object at 0x4021cf70> >>> re.search('\S+', " foo").start() 1 >>> re.search('\s+', " foo") <_sre.SRE_Match object at 0x4021cf70> >>> re.search('\s+', " foo").start() 0 !2006-04-09 Sun # Ruby >> Dir.new("tmp") => # # Python >>> open('tmp') Traceback (most recent call last): File "", line 1, in ? IOError: [Errno 21] Is a directory インスタンスという概念がないのかも??? !2006-04-08 Sat # Ruby >> Dir.getwd => "/home/nnakamur" >> Dir.pwd => "/home/nnakamur" # Python >>> import os >>> os.getcwd() '/home/nnakamur' !2006-04-07 Fri # Ruby >> Dir.foreach('tmp') {|x| puts x} . .. ... # Python >>> import os >>> def dir_foreach(path, func): ... for x in os.listdir(path): ... func(x) ... >>> dir_foreach('tmp', lambda x: print x) File "", line 1 dir_foreach('tmp', lambda x: print x) ^ SyntaxError: invalid syntax >>> def puts(s): ... print s ... >>> dir_foreach('tmp', puts) bar foo ... print は lambda の中に書けない(2006-08-30 Wed) !2006-04-06 Thu # Ruby >> Dir.entries('..') => [".", "..", "lost+found", "nnakamur", "local"] # Python >>> import os >>> os.listdir('..') ['lost+found', 'nnakamur', 'local'] !2006-04-05 Wed # Ruby >> Dir.mkdir("bar") => 0 >> Dir.delete("bar") => 0 >> Dir.delete("bar") Errno::ENOENT: No such file or directory - bar # Python >>> import os >>> os.mkdir("bar") >>> os.rmdir("bar") >>> os.rmdir("bar") Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory: 'bar' !2006-04-04 Tue # Ruby Dir.chroot(path) # Python os.chroot(path) !2006-04-03 Mon # Ruby >> Dir.pwd => "/home/nnakamur" >> Dir.chdir('..') => 0 >> Dir.pwd => "/home" # Python >>> import os >>> os.getcwd() '/home/nnakamur' >>> os.chdir('..') >>> os.getcwd() '/home' !2006-04-02 Sun # Ruby >> Dir['z*'] => ["z1.rb", "z.rb", "z.py", "z2.rb", "zz.c", "zz.py", "zzz.scm", "zzz.scm~"] >> Dir.glob('z*') => ["z1.rb", "z.rb", "z.py", "z2.rb", "zz.c", "zz.py", "zzz.scm", "zzz.scm~"] # Python >>> import glob >>> glob.glob('z*') ['z1.rb', 'z.rb', 'z.py', 'z2.rb', 'zz.c', 'zz.py', 'zzz.scm', 'zzz.scm~'] !2006-04-01 Sat # Ruby >> File::SEPARATOR => "/" >> File::Separator => "/" # Python >>> import os >>> import os.path >>> os.sep '/' >>> os.path.sep '/' !2006-03-31 Fri # Ruby >> File::PATH_SEPARATOR => ":" # Python >>> import os >>> import os.path >>> os.pathsep ':' >>> os.path.pathsep ':' !2006-03-30 Thu # Ruby >> File::ALT_SEPARATOR => nil # Python >>> import os >>> os.altsep >>> import os.path >>> os.path.altsep !2006-03-29 Wed # Ruby File.truncate(path, length) File#truncate(length) # Python f = open(path) f.truncate(length) !2006-03-28 Tue # Ruby >> File.open(".emacs").lstat => # >> File.open(".emacs").stat => # # Python >>> import os >>> os.lstat(".emacs") (33188, 34236L, 2072L, 1, 1000, 100, 7294L, 1147165476, 1141974608, 1141974608) !2006-03-27 Mon # Ruby >> File.open("foo").path => "foo" # Python >>> f = open("foo") >>> f.name 'foo' !2006-03-26 Sun Python に flock ってあるの? fcntl にあるみたいなのだが、「Unixプラットフォームで利用できます。」 という一文が…。 ちょっと検索したが、ポータビリティの高い方法は 良く分からなかった。 !2006-03-25 Sat # Ruby File.chown(owner, group[, filename[, ...]]) File#chown(owner, group) # Python os.chown(path, uid, gid) !2006-03-24 Fri File.chmod と同じ # Ruby >> File.new('foo').chmod(0666) => 0 # Python >>> import os >>> os.chmod('foo', 0666) !2006-03-23 Thu # Ruby >> File.new(".emacs").atime => Wed Mar 22 10:00:18 JST 2006 >> File.new(".emacs").ctime => Fri Mar 10 16:10:08 JST 2006 >> File.new(".emacs").mtime => Fri Mar 10 16:10:08 JST 2006 # Python >>> import os.path >>> os.path.getatime(".emacs") 1142989218 >>> os.path.getctime(".emacs") 1141974608 >>> os.path.getmtime(".emacs") 1141974608 !2006-03-22 Wed File.writable_real? とばし。 # Ruby >> File.zero?("bar") => true >> File.zero?("hoge") => false # Python >>> def file_zerop(file): ... import os.path ... if os.path.exists(file) and os.path.getsize(file) == 0: ... return True ... else: ... return False ... >>> file_zerop("bar") True >>> file_zerop("hoge") False !2006-03-21 Tue # Ruby >> File.writable?(".emacs") => true >> File.writable?("/") => false # Python >>> import os >>> os.access(".emacs", os.W_OK) True >>> os.access("/", os.W_OK) False !2006-03-20 Mon File.socket?, File.sticky? 不明。 # Ruby >> File.symlink?("foo") => false >> File.symlink?("bar") => true # Python >>> import os.path >>> os.path.islink("foo") False >>> os.path.islink("bar") True !2006-03-19 Sun # Ruby >> File.size?(".emacs") => 863 >> File.size?("hoge") => nil # Python >>> import os.path >>> os.path.getsize(".emacs") 863L >>> os.path.getsize("hoge") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/posixpath.py", line 142, in getsize return os.stat(filename).st_size OSError: [Errno 2] No such file or directory: 'hoge' !2006-03-18 Sat File.readable_real? とばし。 File.setgid?, File.setuid?, # Ruby >> File.size(".emacs") => 863 # Python >>> import os.path >>> os.path.getsize(".emacs") 863L !2006-03-17 Fri File.grpowned?(path), File.owned?(path), File.identical?, File.pipe? 不明。 # Ruby >> File.readable?(".emacs") => true >> File.readable?("/root") => false # Python >>> import os >>> os.access(".emacs", os.R_OK) True >>> os.access("/root", os.R_OK) False !2006-03-16 Thu * bar -> foo のリンク * baz -> hoge のリンク # Ruby >> File.file?(".emacs") => true >> File.file?("tmp") => false >> File.file?("hoge") => false >> File.file?("bar") => true >> File.file?("baz") => false # Python >>> import os.path >> File.file?(".emacs") => true >> File.file?("tmp") => false >> File.file?("hoge") => false >> File.file?("bar") => true >>> os.path.isfile("baz") False !2006-03-15 Wed File.executable_real? とばし。 # Ruby >> File.exist?(".emacs") => true >> File.exist?("hoge") => false # Python >>> import os.path >>> os.path.exists(".emacs") True >>> os.path.exists("hoge") False !2006-03-14 Tue # Ruby >> File.executable?("/usr/bin/ruby") => true >> File.executable?("tmp") => true >> File.executable?(".emacs") => false # Python >>> import os >>> os.access("/usr/bin/ruby", os.X_OK) True >>> os.access("tmp", os.X_OK) True >>> os.access(".emacs", os.X_OK) False !2006-03-13 Mon # Ruby >> File.directory?("tmp") => true >> File.directory?(".emacs") => false # Python >>> import os.path >>> os.path.isdir("tmp") True >>> os.path.isdir(".emacs") False !2006-03-12 Sun # Ruby >> File.blockdev?("/dev/hda1") => true >> File.blockdev?("/dev/mouse") => false # Python >>> import os >>> import stat >>> os.stat("/dev/hda1").st_dev 773L >>> stat.S_ISBLK(os.stat("/dev/hda1").st_dev) False >>> stat.S_ISBLK(os.stat("/dev/mouse").st_dev) False >>> stat.S_ISBLK(os.stat("/dev/mouse")[stat.ST_DEV]) False File.blockdev?(path), File.chardev?(path) 相当不明。 stat.S_ISBLK(os.stat(path).st_dev) で良さそうだが、ダメみたい? !2006-03-11 Sat # Ruby >> File.stat("foo") => # >> File.utime(Time.now, Time.now, "foo") => 1 >> File.stat("foo") => # # Python >>> import os >>> os.stat("foo") (33188, 226267L, 776L, 1, 501, 100, 0L, 1144667707, 1144667707, 1144667707) >>> import time >>> time.localtime(1144667707) (2006, 4, 10, 20, 15, 7, 0, 100, 0) >>> os.utime("foo", None) >>> os.stat("foo") (33188, 226267L, 776L, 1, 501, 100, 0L, 1144667905, 1144667905, 1144667905) >>> time.localtime(1144667905) (2006, 4, 10, 20, 18, 25, 0, 100, 0) >>> os.utime("foo", (1144667707, 1144667707)) >>> os.stat("foo") (33188, 226267L, 776L, 1, 501, 100, 0L, 1144667707, 1144667707, 1144667971) !2006-03-10 Fri # Ruby >> File.umask() => 18 >> File.umask(0x022) => 18 >> File.umask() => 34 >> File.umask(18) => 34 >> File.umask() => 18 >> File.umask() => 18 # Python >>> import os >>> os.umask(0x022) 18 >>> os.umask(0x002) 34 >>> os.umask(0x022) 2 >>> os.umask(0x002) 34 !2006-03-09 Thu # Ruby >> File.truncate("foo", 3) => 0 # Python >>> f = open("foo") >>> f.truncate(3) Traceback (most recent call last): File "", line 1, in ? IOError: [Errno 13] Permission denied >>> f = open("foo", "w") >>> f.truncate(3) >>> f.close() 確かに小さくはなったが、中身が何か変 >>> f = open("foo", "r+") >>> f.truncate(3) >>> f.close() こうやったら、中身が破壊されず、小さくなった。ふーむ。 !2006-03-08 Wed # Ruby >> File.symlink("foo", "bar") => 0 # Python >>> import os >>> os.symlink("foo", "bar") !2006-03-07 Tue # Ruby >> File.stat(".emacs") => # # Python >>> import os >>> os.stat(".emacs") (33188, 34236L, 2072L, 1, 1000, 100, 7294L, 1142989218, 1141974608, 1141974608) >>> import time >>> time.localtime(1141974608) (2006, 3, 10, 16, 10, 8, 4, 69, 0) !2006-03-06 Mon # Ruby >> File.split("dir/file.ext") => ["dir", "file.ext"] >> File.split("file.ext") => [".", "file.ext"] >> File.split("foo/bar/") => ["foo", "bar"] >> File.split("foo//bar") => ["foo", "bar"] # Python >>> import os.path >>> os.path.split("dir/file.ext") ('dir', 'file.ext') >>> os.path.split("file.ext") ('', 'file.ext') >>> os.path.split("foo/bar/") ('foo/bar', '') >>> os.path.split("foo//bar") ('foo', 'bar') !2006-03-05 Sun # Ruby >> File.rename("bar", "baz") => 0 >> File.rename("baz", "tmp") Errno::EISDIR: Is a directory - baz or tmp >> File.rename("baz", "tmp/baz") => 0 # Python >>> import os >>> os.rename("bar", "baz") >>> os.rename("baz", "tmp/") Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 21] Is a directory >>> os.rename("baz", "tmp/baz") !2006-03-04 Sat $ ln -s foo bar $ ln -s bar baz しておいて、 # Ruby >> File.readlink("bar") => "foo" >> File.readlink("baz") => "bar" # Python >>> import os >>> os.readlink("bar") 'foo' >>> os.readlink("baz") 'bar' >>> import os.path >>> os.path.abspath("bar") '/home/nnakamur/bar' >>> os.path.normpath("bar") 'bar' >>> os.path.realpath("bar") '/home/nnakamur/foo' !2006-03-03 Fri # Ruby >> File.open(".emacs") {|f| f.gets; f.gets} => ";; set path\n" >> open(".emacs") {|f| f.gets; f.gets} => ";; set path\n" >> File.open("foo", "w") {|f| f.print "foo"} => nil >> File.open("foo") {|f| f.gets } => "foo" # Python >>> f = open('.emacs') >>> f.readline() '\n' >>> f.readline() ';; set path\n' >>> f = open('foo', 'w') >>> f.write("foo") >>> f = open('foo') >>> f.readline() 'foo' !2006-03-02 Thu # Ruby >> File.link("foo", "bar") => 0 >> p File.stat("foo") # => nil >> p File.stat("bar") # => nil # Python >>> import os >>> os.link('foo', 'bar') >>> os.stat('foo') (33188, 34945L, 2072L, 2, 1000, 100, 0L, 1142564401, 1142564401, 1142564451) >>> os.stat('bar') (33188, 34945L, 2072L, 2, 1000, 100, 0L, 1142564401, 1142564401, 1142564451) >>> import os.path >>> os.path.samefile('foo', 'bar') True >>> os.path.samestat(os.stat('foo'), os.stat('bar')) True !2006-03-01 Wed # Ruby >> File.join("/home", "foo", "bar") => "/home/foo/bar" >> File.join('/home', 'foo') => "/home/foo" >> File.join('/home/', 'foo') => "/home/foo" >> File.join('/home/', '/foo') => "/home//foo" >> File.expand_path(File.join('/home/', '/foo')) => "/home/foo" >> File.join('/home/', '../foo') => "/home/../foo" >> File.join('/home', '../foo') => "/home/../foo" >> File.join('.', 'foo') => "./foo" # Python >>> import os.path >>> os.path.join("/home", "foo", "bar") '/home/foo/bar' >>> os.path.join('/home', 'foo') '/home/foo' >>> os.path.join('/home/', 'foo') '/home/foo' >>> os.path.join('/home/', '/foo') '/foo' >>> os.path.join('/home/', '../foo') '/home/../foo' >>> os.path.join('/home', '../foo') '/home/../foo' >>> os.path.join('.', 'foo') './foo' !2006-02-28 Tue # Ruby >> File.ftype(".emacs") => "file" >> File.ftype("bar") => "link" >> File.ftype("tmp") => "directory" # Python >>> import os.path >>> def file_ftype(filename): ... if os.path.islink(filename): ... return "link" ... elif os.path.isfile(filename): ... return "file" ... elif os.path.isdir(filename): ... return "directory" ... >>> file_ftype(".emacs") 'file' >>> file_ftype("bar") 'link' >>> file_ftype("tmp") 'directory' !2006-02-27 Mon # Ruby >> %w(foo foobar bar).each {|f| p File.fnmatch("foo*", f)} true true false => ["foo", "foobar", "bar"] # Python >>> import fnmatch >>> fnmatch.fnmatch("foo", "foo*") True >>> fnmatch.fnmatch("foobar", "foo*") True >>> fnmatch.fnmatch("bar", "foo*") False オペレーティングシステムが大文字、小文字を区別しない場合、 比較を行う前に、両方のパラメタを全て大文字、または全て小文字に揃えます。 うーん、逆のような? !2006-02-26 Sun # Ruby >> File.extname("foo/foo.txt") => ".txt" >> File.extname("foo/foo.tar.gz") => ".gz" >> File.extname("foo/bar") => "" >> File.extname("foo/.bar") => "" >> File.extname("foo.txt/bar") => "" >> File.extname(".foo") => "" >> File.extname("a.foo") => ".foo" # Python >>> import os.path >>> os.path.splitext("foo/foo.txt")[1] '.txt' >>> os.path.splitext("foo/foo.tar.gz")[1] '.gz' >>> os.path.splitext("foo/bar")[1] '' >>> os.path.splitext("foo/.bar")[1] '.bar' >>> os.path.splitext("foo.txt/bar")[1] '' >>> os.path.splitext(".foo")[1] '.foo' >>> os.path.splitext("a.foo")[1] '.foo' >>> def file_extname(path): ... split = os.path.splitext(path) ... if split[0] == "" or split[0][-1] == "/": ... return "" ... else: ... return split[1] ... >>> file_extname("foo/foo.txt") '.txt' >>> file_extname("foo/foo.tar.gz") '.gz' >>> file_extname("foo/bar") '' >>> file_extname("foo/.bar") '' >>> file_extname("foo.txt/bar") '' >>> file_extname(".foo") '' >>> file_extname("a.foo") '.foo' !2006-02-25 Sat # Ruby >> File.expand_path('..') => "/home" >> File.expand_path('..', "/tmp") => "/" >> File.expand_path('~') => "/home/nnakamur" >> File.expand_path('~/bar') => "/home/nnakamur/bar" >> File.expand_path('~root') => "/root" >> File.expand_path("..", "tmp/tmp") => "/home/nnakamur/tmp" # Python >>> import os.path >>> os.path.realpath("..") '/home' >>> os.path.realpath("/tmp/..") '/' >>> os.path.realpath("~") '/home/nnakamur/~' >>> os.path.realpath("~/bar") '/home/nnakamur/~/bar' >>> os.path.realpath("~root") '/home/nnakamur/~root' >>> os.path.normpath("~") '~' >>> os.path.expanduser("~") '/home/nnakamur' >>> os.path.expanduser("~/bar") '/home/nnakamur/bar' >>> os.path.expanduser("~root") '/root' >>> def expand_path(path, default_dir=""): ... d = os.path.expanduser(os.path.expandvars(default_dir)) ... p = os.path.expanduser(os.path.expandvars(path)) ... if default_dir == "": ... return os.path.realpath(p) ... else: ... return os.path.realpath(d + "/" + p) ... >>> expand_path("..") '/home' >>> expand_path("..", "/tmp") '/' >>> expand_path("..", "/tmp/") '/' >>> expand_path("~") '/home/nnakamur' >>> expand_path("~/bar") '/home/nnakamur/foo' >>> expand_path("~/var") '/home/nnakamur/var' >>> expand_path("~root") '/root' >>> expand_path("$HOME/var") '/home/nnakamur/var' >>> expand_path("..", "tmp/tmp") '/home/nnakamur/tmp' * それっぽい???(分かっているだけでも微妙に違うけど…) * os.path.realpath() でなくて、os.path.abspath を使えば良いのか? * os.path.join をうまく使った方が良い??? !2006-02-24 Fri # Ruby >> File.dirname("dir/file.ext") => "dir" >> File.dirname("file.ext") => "." >> File.dirname("foo/bar/") => "foo" >> File.dirname("foo//bar") => "foo" # Python >>> import os.path >>> os.path.dirname("dir/file.ext") 'dir' >>> os.path.dirname("file.ext") '' >>> os.path.dirname("foo/bar/") 'foo/bar' >>> os.path.dirname("foo//bar") 'foo' !2006-02-23 Thu # Ruby >> File.delete('foo') => 1 # Python >>> import os >>> os.remove('foo') どちらも、ディレクトリは消せない !2006-02-22 Wed 実行はスキップ # Ruby File.chown(owner, group[, filename[, ...]]) # Python os.chown(path, uid, gid) !2006-02-21 Tue # Ruby >> File.chmod(0666, 'foo') => 1 # Python >>> import os >>> os.chmod('foo', 0666) !2006-02-20 Mon # Ruby >> File.basename('/home/foo') => "foo" >> File.basename('/home/foo/') => "foo" >> File.basename("ruby/ruby.c") => "ruby.c" >> File.basename("ruby/ruby.c", ".c") => "ruby" >> File.basename("ruby/ruby.c", ".*") => "ruby" >> File.basename("ruby/ruby.exe", ".*") => "ruby" # Python >>> import os.path >>> os.path.basename('/home/foo/') '' >>> os.path.basename('/home/foo') 'foo' >>> os.path.basename('ruby/ruby.c') 'ruby.c' !2006-02-19 Sun # Ruby >> File.atime(".emacs") => Mon Feb 27 09:04:57 JST 2006 >> File.ctime(".emacs") => Mon Feb 06 09:29:36 JST 2006 >> File.mtime(".emacs") => Mon Feb 06 09:29:36 JST 2006 # Python >>> import os.path >>> os.path.getctime(".emacs") 1139185776 >>> import time >>> time.localtime(os.path.getctime(".emacs")) (2006, 2, 6, 9, 29, 36, 0, 37, 0) >>> time.asctime(time.localtime(os.path.getctime(".emacs"))) 'Mon Feb 6 09:29:36 2006' >>> time.asctime(time.localtime(os.path.getatime(".emacs"))) 'Mon Feb 27 09:04:57 2006' >>> time.asctime(time.localtime(os.path.getmtime(".emacs"))) 'Mon Feb 6 09:29:36 2006' もっと簡単にできそうな気はする。 そもそも Ruby も本当は Time オブジェクトを返しているだけなので、 文字列が返ってくるわけではないよなぁ…。 !2006-02-18 Sat # Ruby >> h = {1=>"a", 2=>"b", 3=>"c"} => {1=>"a", 2=>"b", 3=>"c"} >> h.values_at(1,3,4) => ["a", "c", nil] # Python >>> def dict_values_at(d, l): ... ret_list = [] ... for x in l: ... if d.has_key(x): ... ret_list.append(d[x]) ... else: ... ret_list.append(None) ... return ret_list ... >>> h = {1 : "a", 2 : "b", 3 : "c"} >>> dict_values_at(h, [1,3,4]) ['a', 'c', None] >>> def dict_values_at(d, *args): ... ret_list = [] ... for x in args: ... if d.has_key(x): ... ret_list.append(d[x]) ... else: ... ret_list.append(None) ... return ret_list ... >>> dict_values_at(h, 1,3,4) ['a', 'c', None] !2006-02-17 Fri # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.values => [1, 2] # Python >>> {"foo" : 1, "bar" : 2}.values() [1, 2] !2006-02-16 Thu # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.to_a => [["foo", 1], ["bar", 2]] # Python >>> {"foo" : 1, "bar" : 2}.items() [('foo', 1), ('bar', 2)] !2006-02-15 Wed # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.shift => ["foo", 1] >> h => {"bar"=>2} # Python >>> h = {"foo" : 1, "bar" : 2} >>> h.popitem() ('foo', 1) >>> h {'bar': 2} >>> h.popitem() ('bar', 2) >>> h {} >>> h.popitem() Traceback (most recent call last): File "", line 1, in ? KeyError: 'popitem(): dictionary is empty' !2006-02-14 Tue # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.replace({"foo" => 10, "baz" => 20}) => {"baz"=>20, "foo"=>10} >> h => {"baz"=>20, "foo"=>10} # Python >>> def dict_replace(d1, d2): ... d1.clear() ... d1.update(d2) ... return d1 ... >>> h = {"foo" : 1, "bar" : 2} >>> dict_replace(h, {"foo" : 10, "baz" : 20}) {'foo': 10, 'baz': 20} >>> h {'foo': 10, 'baz': 20} !2006-02-13 Mon # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.merge({"baz" => 3}) => {"baz"=>3, "foo"=>1, "bar"=>2} >> h => {"foo"=>1, "bar"=>2} >> h.merge({"bar" => 3}) => {"foo"=>1, "bar"=>3} >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.merge!({"baz" => 3}) => {"baz"=>3, "foo"=>1, "bar"=>2} >> h => {"baz"=>3, "foo"=>1, "bar"=>2} >> h.merge!({"bar" => 3}) => {"baz"=>3, "foo"=>1, "bar"=>3} >> h => {"baz"=>3, "foo"=>1, "bar"=>3} # Python >>> h = {"foo" : 1, "bar" : 2} >>> h.update({"baz" : 3}) >>> h {'baz': 3, 'foo': 1, 'bar': 2} >>> h.update({"bar" : 3}) >>> h {'baz': 3, 'foo': 1, 'bar': 3} !2006-02-12 Sun # Ruby >> {"foo" => 1, "bar" => 2}.length => 2 >> {"foo" => 1, "bar" => 2}.size => 2 # Python >>> len({"foo" : 1, "bar" : 2}) 2 !2006-02-11 Sat # Ruby >> {"foo" => 1, "bar" => 2}.keys => ["foo", "bar"] # Python >>> {"foo" : 1, "bar" : 2}.keys() ['foo', 'bar'] !2006-02-10 Fri # Ruby >> { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }.invert => {0=>"a", 100=>"n", 200=>"d", 300=>"y"} # Python >>> def dict_invert(d): ... ret_d = {} ... for k in d.keys(): ... ret_d[d[k]] = k ... return ret_d ... >>> dict_invert({ "n" : 100, "m" : 100, "y" : 300, "d" : 200, "a" : 0 }) {0: 'a', 100: 'n', 300: 'y', 200: 'd'} !2006-02-09 Thu # Ruby >> {"foo" => 1, "bar" => 2}.index(1) => "foo" >> {"foo" => 1, "bar" => 2}.index(10) => nil # Python >>> def dict_index(d, val): ... for k in d.keys(): ... if d[k] == val: ... return k ... return None ... >>> dict_index({"foo" : 1, "bar" : 2}, 1) 'foo' >>> dict_index({"foo" : 1, "bar" : 2}, 10) !2006-02-08 Wed # Ruby >> {"foo" => 1, "bar" => 2}.has_value?(1) => true >> {"foo" => 1, "bar" => 2}.has_value?(10) => false # Python >>> 1 in {"foo" : 1, "bar" : 2}.values() True >>> 10 in {"foo" : 1, "bar" : 2}.values() False 直接的なメソッドは見当たらなかった !2006-02-07 Tue # Ruby >> {"foo" => 1, "bar" => 2}.has_key?("foo") => true >> {"foo" => 1, "bar" => 2}.has_key?("hoge") => false # Python >>> {"foo" : 1, "bar" : 2}.has_key("foo") True >>> {"foo" : 1, "bar" : 2}.has_key("hoge") False !2006-02-06 Mon # Ruby >> {"foo" => 1, "bar" => 2}.fetch("foo") => 1 >> {"foo" => 1, "bar" => 2}.fetch("hoge") IndexError: key not found # Python >>> {"foo" : 1, "bar" : 2}["foo"] 1 >>> {"foo" : 1, "bar" : 2}["hoge"] Traceback (most recent call last): File "", line 1, in ? KeyError: 'hoge' !2006-02-05 Sun # Ruby >> {}.empty? => true # Python >>> h = {"foo" : 1} >>> del h["foo"] >>> h == {} True !2006-02-04 Sat # Ruby >> {"foo" => 1, "bar" => 2}.each_value {|v| p v} 1 2 => {"foo"=>1, "bar"=>2} # Python >>> for x in {"foo" : 1, "bar" : 2}.itervalues(): ... print x ... 1 2 !2006-02-03 Fri # Ruby >> {"foo" => 1, "bar" => 2}.each_key {|k| p k} "foo" "bar" => {"foo"=>1, "bar"=>2} # Python >>> for x in {"foo" : 1, "bar" : 2}.iterkeys(): ... print x ... foo bar !2006-02-02 Thu # Ruby >> {"foo" => 1, "bar" => 2}.each {|k,v| p [k,v]} ["foo", 1] ["bar", 2] => {"foo"=>1, "bar"=>2} # Python >>> for x in {"foo" : 1, "bar" : 2}.iteritems(): ... print x[0], x[1] ... foo 1 bar 2 !2006-02-01 Wed # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.delete_if {|k,v| v % 2 == 0} => {"foo"=>1} >> h => {"foo"=>1} # Python >>> def dict_delete_if(d, func): ... for x in d.iteritems(): ... if func(x): ... del d[x[0]] ... >>> h = {"foo" : 1, "bar" : 2} >>> dict_delete_if(h, lambda x: x[1] % 2 == 0) Traceback (most recent call last): File "", line 1, in ? File "", line 2, in dict_delete_if RuntimeError: dictionary changed size during iteration >>> def dict_delete_if(d, func): ... for x in d.keys(): ... if func(x, d[x]): ... del d[x] ... >>> h = {"foo" : 1, "bar" : 2} >>> def func(k, v): ... return v % 2 == 0 ... >>> dict_delete_if(h, func) >>> h {'foo': 1} Ruby の場合、途中で要素を削除しても怒られないみたい !2006-01-31 Tue 一休み、一休み >>> for x in {"foo" : 1, "bar" : 2}: ... print x ... foo bar >>> for x in {"foo" : 1, "bar" : 2}.iteritems(): ... print x ... ('foo', 1) ('bar', 2) >>> for x in {"foo" : 1, "bar" : 2}.iterkeys(): ... print x ... foo bar >>> for x in {"foo" : 1, "bar" : 2}.itervalues(): ... print x ... 1 2 !2006-01-30 Mon # Ruby >> {"foo" => 1, "bar" => 2}.reject {|k,v| v % 2 == 0} => {"foo"=>1} # Python >>> def dict_reject(d, func): ... ret_d = {} ... for x in d.iteritems(): ... if not func(x): ... ret_d[x[0]] = x[1] ... return ret_d ... >>> dict_reject({"foo" : 1, "bar" : 2}, lambda x: x[1] % 2 == 0) {'foo': 1} !2006-01-29 Sun # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.delete("foo") => 1 >> h.delete("foo") => nil >> h => {"bar"=>2} # Python >>> h = {"foo" : 1, "bar" : 2} >>> del h["foo"] >>> del h["foo"] Traceback (most recent call last): File "", line 1, in ? KeyError: 'foo' >>> h {'bar': 2} !2006-01-28 Sat # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h2 = h.dup => {"foo"=>1, "bar"=>2} >> h2["foo"] = 10 => 10 >> h => {"foo"=>1, "bar"=>2} >> h2 => {"foo"=>10, "bar"=>2} # Python >>> h = {"foo" : 1, "bar" : 2} >>> h2 = h.copy() >>> h2["foo"] = 10 >>> h {'foo': 1, 'bar': 2} >>> h2 {'foo': 10, 'bar': 2} !2006-01-27 Fri # Ruby >> h = {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} >> h.clear => {} >> h => {} # Python >>> h = {"foo" : 1, "bar" : 2} >>> h.clear() >>> h {} !2006-01-26 Thu # Ruby >> h = {} => {} >> h["foo"] = 1 => 1 >> h => {"foo"=>1} # Python >>> h = {} >>> h["foo"] = 1 >>> h {'foo': 1} !2006-01-25 Wed # Ruby >> {"foo" => 1, "bar" => 2}["foo"] => 1 >> {"foo" => 1, "bar" => 2}["hoge"] => nil # Python >>> {"foo" : 1, "bar" : 2}["foo"] 1 >>> {"foo" : 1, "bar" : 2}["hoge"] Traceback (most recent call last): File "", line 1, in ? KeyError: 'hoge' !2006-01-24 Tue # Ruby >> h = {} => {} >> h[0] => nil >> h = Hash.new(0) => {} >> h[0] => 0 # Python >>> def dict_get_with_default(d, key, default): ... if d.has_key(key): ... return d[key] ... else: ... return default ... >>> dict_get_with_default({"foo" : 1}, "foo", "z") 1 >>> dict_get_with_default({"foo" : 1}, "bar", "z") 'z' もっと良い方法はないのだろうか? !2006-01-23 Mon # Ruby >> h = Hash.new => {} >> alist = [[1,["a"]], [2,["b"]], [3,["c"]]] => [[1, ["a"]], [2, ["b"]], [3, ["c"]]] >> alist.each {|k,v| h[k] = v } => [[1, ["a"]], [2, ["b"]], [3, ["c"]]] >> h => {1=>["a"], 2=>["b"], 3=>["c"]} # Python >>> alist = [(1, ["a"]), (2, ["b"]), (3, ["c"])] >>> dict(alist) {1: ['a'], 2: ['b'], 3: ['c']} >>> def array_pair_to_hash(ary): ... d = {} ... for x in ary: ... d[x[0]] = x[1] ... return d ... >>> array_pair_to_hash([(1, ["a"]), (2, ["b"]), (3, ["c"])]) {1: ['a'], 2: ['b'], 3: ['c']} !2006-01-22 Sun 2005-12-24 に作った array_flatten と 2006-01-21 の array_to_hash を使って # Ruby >> alist = [[1,"a"], [2,"b"], [3,"c"]] => [[1, "a"], [2, "b"], [3, "c"]] >> Hash[*alist.flatten] => {1=>"a", 2=>"b", 3=>"c"} # Python >>> def array_flatten(ary): ... ret_ary = [] ... for x in ary: ... if type(x) == type([]): ... ret_ary.extend(array_flatten(x)) ... else: ... ret_ary.append(x) ... return ret_ary ... >>> def array_to_hash(ary): ... d = {} ... length = len(ary) ... if length % 2 != 0: ... raise ValueError, "odd number of arguments for dict" ... else: ... i = 0 ... while i < length: ... d[ary[i]] = ary[i+1] ... i += 2 ... return d ... >>> alist = [[1,"a"], [2,"b"], [3,"c"]] >>> array_to_hash(array_flatten(alist)) {1: 'a', 2: 'b', 3: 'c'} >>> alist = [[1,["a"]], [2,["b"]], [3,["c"]]] >>> array_to_hash(array_flatten(alist)) {1: 'a', 2: 'b', 3: 'c'} あっ、確かに flatten だとそうなるか >>> array_flatten(alist) [1, 'a', 2, 'b', 3, 'c'] !2006-01-21 Sat # Ruby >> ary = [1,"a", 2,"b", 3,"c"] => [1, "a", 2, "b", 3, "c"] >> Hash[*ary] => {1=>"a", 2=>"b", 3=>"c"} # Python >>> def array_to_hash(ary): ... d = {} ... length = len(ary) ... if length % 2 != 0: ... raise ValueError, "odd number of arguments for dict" ... else: ... i = 0 ... while i < length: ... d[ary[i]] = ary[i+1] ... i += 2 ... return d ... >>> array_to_hash([1,"a", 2,"b", 3,"c"]) {1: 'a', 2: 'b', 3: 'c'} >>> array_to_hash([1,"a", 2,"b", 3,"c", 4]) Traceback (most recent call last): File "", line 1, in ? File "", line 5, in array_to_hash ValueError: odd number of arguments for dict ふと、なぜ、for を使わず while を使ったんだっけ〜と思った。 C っぽい for はないけど、一応 range で書けるはずだよな。 !2006-01-20 Fri # Ruby >> {"foo" => 1, "bar" => 2} => {"foo"=>1, "bar"=>2} # Python >>> {"foo" : 1, "bar" : 2} {'foo': 1, 'bar': 2} 配列からハッシュを作る関数はあるのだろうか? こういうのはできるようだ。 >>> dict([("foo", 1), ("bar", 2)]) {'foo': 1, 'bar': 2} !2006-01-19 Thu 軟弱なので、sort_by とばし…。 # Ruby >> [1,2,3].zip([4,5,6], [7,8,9]) => [[1, 4, 7], [2, 5, 8], [3, 6, 9]] >> [1,2].zip([:a,:b,:c], [:A,:B,:C,:D]) => [[1, :a, :A], [2, :b, :B]] >> (1..5).zip([:a,:b,:c], [:A,:B,:C,:D]) => [[1, :a, :A], [2, :b, :B], [3, :c, :C], [4, nil, :D], [5, nil, nil]] # Python >>> def array_zip(ary, *args): ... length = len(ary) ... ret_ary = [] ... i = 0 ... for x in ary: ... a = [x] ... for xx in args: ... if i < len(xx): ... a.append(xx[i]) ... else: ... a.append(None) ... ret_ary.append(a) ... i += 1 ... return ret_ary ... >>> array_zip([1,2,3], [4,5,6], [7,8,9]) [[1, 4, 7], [2, 5, 8], [3, 6, 9]] >>> array_zip([1,2], ["a", "b", "c"], ["A", "B", "C", "D"]) [[1, 'a', 'A'], [2, 'b', 'B']] >>> array_zip([1,2,3,4,5], ["a", "b", "c"], ["A", "B", "C", "D"]) [[1, 'a', 'A'], [2, 'b', 'B'], [3, 'c', 'C'], [4, None, 'D'], [5, None, None]] !2006-01-18 Wed # Ruby >> [1, 2, 3, 4, 5].reject {|x| x % 2 == 0} => [1, 3, 5] # Python >>> def array_reject(ary, func): ... ret_ary = [] ... for x in ary: ... if not func(x): ... ret_ary.append(x) ... return ret_ary ... >>> array_reject([1, 2, 3, 4, 5], lambda x: x % 2 == 0) [1, 3, 5] !2006-01-17 Tue min とばし # Ruby >> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0].partition { |i| i % 3 == 0 } => [[9, 6, 3, 0], [10, 8, 7, 5, 4, 2, 1]] # Python >>> def array_partition(ary, func): ... ary_true = [] ... ary_false = [] ... for x in ary: ... if func(x): ... ary_true.append(x) ... else: ... ary_false.append(x) ... return ary_true, ary_false ... >>> array_partition([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], lambda x: x % 3 == 0) ([9, 6, 3, 0], [10, 8, 7, 5, 4, 2, 1]) !2006-01-16 Mon もう一度! >>> def array_max(ary, func): ... if len(ary) == 0: ... raise ValueError, "min() or max() arg is an empty sequence" ... elif len(ary) == 1: ... return ary[0] ... else: ... max_val = ary[0] ... prev_x = ary[0] ... for x in ary: ... if func(x, prev_x) > 0: ... max_val = x ... prev_x = x ... return max_val ... >>> def func(a, b): ... return cmp(b, a) ... >>> array_max([3, 1, 5], func) 1 >>> array_max([], func) Traceback (most recent call last): File "", line 1, in ? File "", line 3, in array_max ValueError: min() or max() arg is an empty sequence >>> array_max([1], func) 1 !2006-01-15 Sun # Ruby >> [3, 1, 5].max {|a, b| b <=> a} => 1 # Python >>> def array_max(array, func): ... a = array[:] ... a.sort(func) ... return a.pop() ... >>> def func(a, b): ... return cmp(b, a) ... >>> array_max([3, 5, 1], func) 1 手抜きすぎ。効率悪すぎ… !2006-01-14 Sat grep とばし # Ruby >> [1,2,3,4,5].inject(0) {|result, item| result + item } => 15 # Python >>> def array_inject(ary, init, func): ... val = init ... for x in ary: ... val = func(val, x) ... return val ... >>> def add(result, item): ... return result + item ... >>> array_inject([1, 2, 3, 4, 5], 0, add) 15 !2006-01-13 Fri # Ruby >> [1, 2, 3, 1, 2, 3].find_all {|x| x == 1} => [1, 1] >> [1, 2, 3, 1, 2, 3].find_all {|x| x > 1} => [2, 3, 2, 3] # Python >>> def array_find_all(ary, func): ... return filter(lambda x: func(x), ary) ... >>> array_find_all([1, 2, 3, 1, 2, 3], lambda x: x == 1) [1, 1] >>> array_find_all([1, 2, 3, 1, 2, 3], lambda x: x > 1) [2, 3, 2, 3] !2006-01-12 Thu # Ruby >> [1, 2, 3, 1, 2, 3].find {|x| x == 1} => 1 >> [1, 2, 3, 1, 2, 3].find {|x| x > 1} => 2 # Python >>> def array_find(ary, func): ... return filter(lambda x: func(x), ary).pop(0) ... >>> array_find([1, 2, 3, 1, 2, 3], lambda x: x == 1) 1 >>> array_find([1, 2, 3, 1, 2, 3], lambda x: x > 1) 2 >>> def array_find(ary, func): ... for x in ary: ... if func(x): ... return x ... >>> array_find([1, 2, 3, 1, 2, 3], lambda x: x == 1) 1 >>> array_find([1, 2, 3, 1, 2, 3], lambda x: x > 1) 2 !2006-01-11 Wed # Ruby >> [10, 20, 30].each_with_index {|x, i| p [x, i]} [10, 0] [20, 1] [30, 2] => [10, 20, 30] # Python >>> def array_each_with_index(ary, func): ... i = 0 ... for x in ary: ... func(x, i) ... i += 1 ... >>> array_each_with_index([10, 20, 30], lambda x, i: print x, i) File "", line 1 array_each_with_index([10, 20, 30], lambda x, i: print x, i) ^ SyntaxError: invalid syntax >>> array_each_with_index([10, 20, 30], foo) 10 0 20 1 30 2 うーむ、lambda ってどこにでも書けるものではないのか??? print は lambda の中に書けない(2006-08-30 Wed) >>> import sys >>> array_each_with_index([10, 20, 30], lambda x, i: sys.stdout.write('%s %d\n' % (x, i))) 10 0 20 1 30 2 !2006-01-10 Tue # Ruby >> [1,2,3].any? {|v| v > 0} => true >> [1,2,3].any? {|v| v < 0} => false >> [1,2,3,0].any? {|v| v > 0} => true >> [1,2,3,0].any? {|v| v < 0} => false # Python >>> def array_anyp(ary, func): ... return filter(lambda x: func(x), ary) != [] ... >>> array_anyp([1, 2, 3], lambda x: x > 0) True >>> array_anyp([1, 2, 3], lambda x: x < 0) False >>> array_anyp([1, 2, 3, 0], lambda x: x > 0) True >>> array_anyp([1, 2, 3, 0], lambda x: x < 0) False 自分でグルグルまわして検査した方が良さそうだけど !2006-01-09 Tue # Ruby >> [1,2,3].all? {|v| v > 0} => true >> [1,2,3].all? {|v| v < 0} => false >> [1,2,3,0].all? {|v| v > 0} => false # Python >>> def array_allp(ary, func): ... return len(filter(lambda x: not func(x), ary)) == 0 ... >>> array_allp([1, 2, 3], lambda x: x > 0) True >>> array_allp([1, 2, 3], lambda x: x < 0) False >>> array_allp([1, 2, 3, 0], lambda x: x > 0) False !2006-01-08 Sun # Ruby >> [1, 2, 3, 4, 5].values_at(0, 2, 4) => [1, 3, 5] >> [1, 2, 3, 4, 5].values_at(0, 2, 4, 10) => [1, 3, 5, nil] >> [1, 2, 3, 4, 5].values_at(-1) => [5] >> [1, 2, 3, 4, 5].values_at(-2) => [4] # Python >>> def array_values_at(ary, *args): ... length = len(ary) ... ret_ary = [] ... for i in args: ... if i < length: ... ret_ary.append(ary[i]) ... else: ... ret_ary.append(None) ... return ret_ary ... >>> array_values_at([1, 2, 3, 4, 5], 0, 2, 4) [1, 3, 5] >>> array_values_at([1, 2, 3, 4, 5], 0, 2, 4, 10) [1, 3, 5, None] >>> array_values_at([1, 2, 3, 4, 5], -1) [5] >>> array_values_at([1, 2, 3, 4, 5], -2) [4] !2006-01-07 Sat # Ruby >> [1, 2, 3].unshift 0 => [0, 1, 2, 3] >> [1, 2, 3].unshift [0] => [[0], 1, 2, 3] # Python >>> a = [1, 2, 3] >>> array_unshift(a, 0) [0, 1, 2, 3] >>> a [0, 1, 2, 3] >>> a = [1, 2, 3] >>> array_unshift(a, [0]) [[0], 1, 2, 3] >>> a [[0], 1, 2, 3] !2006-01-06 Fri # Ruby >> [1, 1, 1].uniq => [1] >> [1, 2, 3, 1, 2].uniq => [1, 2, 3] # Python >>> def array_uniq(ary): ... length = len(ary) ... h = {} ... i = 0 ... while i < length: ... if h.has_key(ary[i]): ... del(ary[i]) ... length -= 1 ... else: ... h[ary[i]] = True ... i += 1 ... return ary ... >>> array_uniq([1, 1, 1]) [1] >>> array_uniq([1, 2, 3, 1, 2]) [1, 2, 3] !2006-01-05 Thu # Ruby >> [1, 2, 3].to_s => "123" >> ["1", "2", "3"].to_s => "123" >> [1, 2, 3].join => "123" # Python >>> import string >>> string.join([1, 2, 3], "") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/string.py", line 135, in join return sep.join(words) TypeError: sequence item 0: expected string, int found >>> string.join(["1", "2", "3"], "") '123' >>> def array_to_s(ary): ... return string.join(map(lambda x: str(x), ary), "") ... >>> array_to_s([1, 2, 3]) '123' >>> array_to_s([]) '' >>> array_to_s(["1", "2", "3"]) '123' !2006-01-04 Wed # Ruby >> [10, 2, 3, 1].sort => [1, 2, 3, 10] >> ["10", "2", "3", "1"].sort => ["1", "10", "2", "3"] >> [10, 2, 3, 1].sort {|a, b| b <=> a} => [10, 3, 2, 1] # Python >>> a = [10, 2, 3, 1] >>> a.sort() >>> a [1, 2, 3, 10] >>> a = ["10", "2", "3", "1"] >>> a.sort() >>> a ['1', '10', '2', '3'] >>> a = [10, 2, 3, 1] >>> a.sort(lambda a, b: cmp(b, a)) >>> a [10, 3, 2, 1] !2006-01-03 Tue # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.shift => 1 >> a => [2, 3] >> a = [] => [] >> a.shift => nil >> a => [] # Python >>> a = [1, 2, 3] >>> a.pop(0) 1 >>> a [2, 3] >>> a = [] >>> a.pop(0) Traceback (most recent call last): File "", line 1, in ? IndexError: pop from empty list !2006-01-02 Mon rindex 別実装 # Python >>> def array_rindex(ary, val): ... for i in xrange(len(ary) - 1, -1, -1): ... if ary[i] == val: ... return i ... return None ... >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 1) 4 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 4) 3 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 0) >>> def array_rindex(ary, val): ... for i in xrange(len(ary) - 1, -1, -1): ... if ary[i] == val: ... return i ... raise ValueError ... >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 1) 4 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 4) 3 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 0) Traceback (most recent call last): File "", line 1, in ? File "", line 5, in array_rindex ValueError !2006-01-01 Sun # Ruby >> [1, 2, 3, 4, 1, 2, 3].rindex(0) => nil >> [1, 2, 3, 4, 1, 2, 3].rindex(1) => 4 >> [1, 2, 3, 4, 1, 2, 3].rindex(4) => 3 # Python >>> def array_rindex(ary, val): ... new_ary = ary[:] ... new_ary.reverse() ... return len(ary) - new_ary.index(val) - 1 ... >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 1) 4 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 4) 3 >>> array_rindex([1, 2, 3, 4, 1, 2, 3], 0) Traceback (most recent call last): File "", line 1, in ? File "", line 4, in array_rindex ValueError: list.index(x): x not in list >>> try: ... array_rindex([1, 2, 3, 4, 1, 2, 3], 0) ... except ValueError: ... pass ... >>> try: ... array_rindex([1, 2, 3, 4, 1, 2, 3], 0) ... except ValueError: ... print "foo" ... foo !2005-12-31 Sat # Ruby >> [1, 2, 3].reverse => [3, 2, 1] # Python >>> a = [1, 2, 3] >>> a.reverse() >>> a [3, 2, 1] !2005-12-30 Fri # Ruby >> [[15,1], [25,2], [35,3]].rassoc(2) => [25, 2] # Python >>> def array_rassoc(ary, val): ... for x in ary: ... if x[1] == val: ... return x ... return None ... >>> array_rassoc([[15,1], [25,2], [35,3]], 2) [25, 2] !2005-12-29 Thu # Ruby >> [1, 2, 3].push(1) => [1, 2, 3, 1] >> [1, 2, 3].push(1, 2) => [1, 2, 3, 1, 2] >> [1, 2, 3].push([1, 2]) => [1, 2, 3, [1, 2]] # Python >>> a = [1, 2, 3]; a.append(1); print a [1, 2, 3, 1] >>> a = [1, 2, 3]; a.append(1, 2); print a Traceback (most recent call last): File "", line 1, in ? TypeError: append() takes exactly one argument (2 given) >>> a = [1, 2, 3]; a.append([1, 2]); print a [1, 2, 3, [1, 2]] !2005-12-28 Wed # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.pop => 3 >> a => [1, 2] >> a.pop => 2 >> a => [1] >> a.pop => 1 >> a => [] >> a.pop => nil # Python >>> a = [1, 2, 3] >>> a.pop() 3 >>> a [1, 2] >>> a.pop() 2 >>> a [1] >>> a.pop() 1 >>> a [] >>> a.pop() Traceback (most recent call last): File "", line 1, in ? IndexError: pop from empty list !2005-12-27 Tue # Ruby >> [1, 2, 3, nil].nitems => 3 # Python >>> len(filter(lambda x: x != None, [1, 2, 3, None])) 3 !2005-12-26 Mon # Ruby >> [1, 2, 3].insert(0, 10) => [10, 1, 2, 3] >> [1, 2, 3].insert(-1, 20) => [1, 2, 3, 20] >> [1, 2, 3].insert(0, [1]) => [[1], 1, 2, 3] # Python >>> a = [1, 2, 3] >>> a.insert(0, 10) >>> a [10, 1, 2, 3] >>> a = [1, 2, 3] >>> a.insert(-1, 20) >>> a [1, 2, 20, 3] >>> a = [1, 2, 3] >>> a.insert(0, [1]) >>> a [[1], 1, 2, 3] !2005-12-25 Sun # Ruby >> [1, 2, 3, 1, 2, 3].index(2) => 1 >> [1, 2, 3, 1, 2, 3].index(4) => nil # Python >>> [1, 2, 3, 1, 2, 3].index(2) 1 >>> [1, 2, 3, 1, 2, 3].index(4) Traceback (most recent call last): File "", line 1, in ? ValueError: list.index(x): x not in list !2005-12-24 Sat # Ruby >> p [1, [2, 3, [4], 5]].flatten [1, 2, 3, 4, 5] => nil # Python >>> def array_flatten(ary): ... ret_ary = [] ... for x in ary: ... if type(x) == type([]): ... ret_ary.extend(array_flatten(x)) ... else: ... ret_ary.append(x) ... return ret_ary ... >>> array_flatten([1, [2, 3, [4], 5]]) [1, 2, 3, 4, 5] !2005-12-23 Fri # Ruby >> [1,2,3].first => 1 >> [].first => nil >> [1].first() => 1 >> [1,2,3].first(0) => [] >> [1,2,3].first(1) => [1] >> [1,2,3].first(2) => [1, 2] >> [1,2,3].first(3) => [1, 2, 3] >> [1,2,3].first(4) => [1, 2, 3] >> [1,2,3].first(-1) ArgumentError: negative array size (or size too big) # Python >>> def array_first(ary, i = None): ... if i == None: ... if len(ary) == 0: ... return None ... else: ... return ary[0] ... else: ... return ary[0:i] ... >>> array_first([1,2,3]) 1 >>> array_first([]) >>> array_first([1]) 1 >>> array_first([1,2,3], 0) [] >>> array_first([1,2,3], 1) [1] >>> array_first([1,2,3], 2) [1, 2] >>> array_first([1,2,3], 3) [1, 2, 3] >>> array_first([1,2,3], 4) [1, 2, 3] >>> array_first([1,2,3], 5) [1, 2, 3] >>> array_first([1,2,3], -1) [1, 2] !2005-12-22 Thu # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.fill(10) => [10, 10, 10] >> a => [10, 10, 10] # Python >>> def array_fill(ary, val): ... for i in xrange(0, len(ary)): ... ary[i] = val ... >>> a = [1, 2, 3] >>> array_fill(a, 10) >>> a [10, 10, 10] 本当に同じ挙動かは分からない !2005-12-21 Wed # Ruby >> a = [1, 2, 3, 4, 5] => [1, 2, 3, 4, 5] >> a.delete_if {|x| x % 2 == 0} => [1, 3, 5] >> a => [1, 3, 5] # Python >>> a = [1, 2, 3, 4, 5] >>> filter(lambda x: x % 2 != 0, a) [1, 3, 5] これじゃ、find_all だけど… >>> def array_delete_if(ary, func): ... length = len(ary) ... i = 0 ... while i < length: ... if func(ary[i]): ... del(ary[i]) ... length -= 1 ... else: ... i += 1 ... >>> a = [1, 2, 3, 4, 5] >>> array_delete_if(a, lambda x: x % 2 == 0) >>> a [1, 3, 5] >>> a = [1, 2, 3, 4, 5] >>> array_delete_if(a, lambda x: x > 10) >>> a [1, 2, 3, 4, 5] !2005-12-20 Tue # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.delete_at(1) => 2 >> a => [1, 3] >> a.delete_at(1) => 3 >> a => [1] >> a.delete_at(1) => nil # Python >>> a = [1, 2, 3] >>> del a[1] >>> a [1, 3] >>> del a[1] >>> a [1] >>> del a[1] Traceback (most recent call last): File "", line 1, in ? IndexError: list assignment index out of range !2005-12-19 Mon # Ruby >> a = [1, 2, 3, 1, 2, 3] => [1, 2, 3, 1, 2, 3] >> a.delete(2) => 2 >> a => [1, 3, 1, 3] >> a.delete(2) => nil # Python >>> a = [1, 2, 3, 1, 2, 3] >>> a.remove(2) >>> a [1, 3, 1, 2, 3] >>> a.remove(2) >>> a [1, 3, 1, 3] >>> a.remove(2) Traceback (most recent call last): File "", line 1, in ? ValueError: list.remove(x): x not in list む?複数を一気に削除するメソッドはないのか??? >>> def array_delete(ary, x): ... while ary.count(x) > 0: ... ary.remove(x) ... >>> a = [1, 2, 3, 1, 2, 3] >>> array_delete(a, 2) >>> a [1, 3, 1, 3] >>> array_delete(a, 2) !2005-12-18 Sun # Ruby >> [1, 2, 3].concat([4, 5, 6]) => [1, 2, 3, 4, 5, 6] # Python >>> a = [1, 2, 3] >>> a.append([4, 5, 6]) >>> a [1, 2, 3, [4, 5, 6]] >>> a = [1, 2, 3] >>> a += [4, 5, 6] >>> a [1, 2, 3, 4, 5, 6] >>> a = [1, 2, 3] >>> a.extend([4, 5, 6]) >>> a [1, 2, 3, 4, 5, 6] !2005-12-17 Sat # Ruby >> [1, nil, 2, nil, 3].compact => [1, 2, 3] # Python >>> def array_compact(ary): ... ret_array = [] ... for x in ary: ... if x != None: ... ret_array.append(x) ... return ret_array ... >>> array_compact([1, None, 2, None, 3]) [1, 2, 3] >>> filter(lambda x: x != None, [1, None, 2, None, 3]) [1, 2, 3] >>> [x for x in [1, None, 2, None, 3] if x != None] [1, 2, 3] !2005-12-16 Fri # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.map {|x| x * 2} => [2, 4, 6] # Python >>> a = [1, 2, 3] >>> map(lambda x: x * 2, a) [2, 4, 6] >>> a [1, 2, 3] >>> [x * 2 for x in a] [2, 4, 6] map! に相当するものはないのか??? !2005-12-15 Thu # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.id (irb):73: warning: Object#id will be deprecated; use Object#object_id => 538454226 >> a.object_id => 538454226 >> a.dup.object_id => 538441356 # Python >>> a = [1, 2, 3] >>> b = a[:] >>> b[0] = 0 >>> a [1, 2, 3] >>> b [0, 2, 3] !2005-12-14 Wed # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a.clear => [] >> a => [] # Python >>> a = [1, 2, 3] >>> a = [] >>> a [] !2005-12-13 Tue # Ruby >> [[1, 2], [1, 3]].assoc(1) => [1, 2] >> [[1, 2], [1, 3]].assoc(0) => nil # Python >>> def array_assoc(ary, key): ... for x in ary: ... if x[0] == key: ... return x ... return None ... >>> array_assoc([[1, 2], [1, 3]], 1) [1, 2] >>> array_assoc([[1, 2], [1, 3]], 0) >>> print array_assoc([[1, 2], [1, 3]], 0) None ハッシュ用? !2005-12-12 Mon # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a << 4 => [1, 2, 3, 4] >> a => [1, 2, 3, 4] # Python >>> a = [1, 2, 3] >>> a.append(4) >>> a [1, 2, 3, 4] !2005-12-11 Sun # Ruby >> [1, 2, 3] | [1, 3, 5] => [1, 2, 3, 5] # Python >>> [1, 2, 3] or [1, 3, 5] [1, 2, 3] まあ、多分ないってことで。 !2005-12-10 Sat # Ruby >> [1, 2, 3] & [1] => [1] # Python >>> [1, 2, 3] and [1] [1] >>> [1, 2, 3] and [1, 10] [1, 10] >>> [1, 2, 3] & [1] Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for &: 'list' and 'list' >>> def array_and(ary1, ary2): ... ret_array = [] ... for x in ary2: ... if x in ary1: ... ret_array.append(x) ... return ret_array ... >>> array_and([1, 2, 3], [1]) [1] >>> array_and([1, 2, 3], [1, 10]) [1] >>> array_and([1, 2, 3], []) [] 全然意味が違った… !2005-12-09 Fri # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a[0...1] = [11, 12] => [11, 12] >> a => [11, 12, 2, 3] # Python >>> a = [1, 2, 3] >>> a[0:1] = [11, 12] >>> a [11, 12, 2, 3] !2005-12-08 Thu # Ruby >> [1, 2, 3][0...0] => [] >> [1, 2, 3][0...1] => [1] >> [1, 2, 3][0...2] => [1, 2] >> [1, 2, 3][0...3] => [1, 2, 3] >> [1, 2, 3][0...4] => [1, 2, 3] >> [1, 2, 3][0...-1] => [1, 2] >> [1, 2, 3][0...-2] => [1] >> [1, 2, 3][0...-3] => [] >> [1, 2, 3][0...-4] => [] # Python >>> [1, 2, 3][0:0] [] >>> [1, 2, 3][0:1] [1] >>> [1, 2, 3][0:2] [1, 2] >>> [1, 2, 3][0:3] [1, 2, 3] >>> [1, 2, 3][0:4] [1, 2, 3] >>> [1, 2, 3][0:-1] [1, 2] >>> [1, 2, 3][0:-2] [1] >>> [1, 2, 3][0:-3] [] >>> [1, 2, 3][0:-4] [] !2005-12-07 Wed # Ruby >> a = [1, 2, 3] => [1, 2, 3] >> a[0] = 0 => 0 >> a => [0, 2, 3] # Python >>> a = [1, 2, 3] >>> a[0] = 0 >>> a [0, 2, 3] !2005-12-06 Tue # Ruby >> [1, 2, 3][0] => 1 >> [1, 2, 3][4] => nil >> [1, 2, 3][-1] => 3 >> [1, 2, 3][-4] => nil >> [1, 2, 3].fetch(4) IndexError: index 4 out of array >> [1, 2, 3].fetch(-4) IndexError: index -1 out of array # Python >>> [1, 2, 3][0] 1 >>> [1, 2, 3][4] Traceback (most recent call last): File "", line 1, in ? IndexError: list index out of range >>> [1, 2, 3][-1] 3 >>> [1, 2, 3][-4] Traceback (most recent call last): File "", line 1, in ? IndexError: list index out of range !2005-12-05 Mon # Ruby >> [1, 2, 3] <=> [1, 2, 3] => 0 # Python >>> [1, 3, 3] <=> [1, 2] File "", line 1 [1, 3, 3] <=> [1, 2] ^ SyntaxError: invalid syntax >>> cmp([1, 2, 3], [1, 2, 3]) 0 >>> cmp([1, 3, 3], [1, 2]) 1 !2005-12-04 Sun # Ruby >> [1, 2, 3] > [1, 2, 3] NoMethodError: undefined method `>' for [1, 2, 3]:Array # Python >>> [1, 2, 3] > [1, 2, 3] False >>> [1, 2, 3] > [1, 2, 2] True !2005-12-03 Sat # Ruby >> [1, 2, 3] == [1, 2, 3] => true >> [1, 2, 3] != [1, 2, 3] => false >> [[1, 2, 3], [4, 5, 6]] == [[1, 2, 3], [4, 5, 6]] => true # Python >>> [1, 2, 3] == [1, 2, 3] True >>> [1, 2, 3] != [1, 2, 3] False >>> [[1, 2, 3], [4, 5, 6]] == [[1, 2, 3], [4, 5, 6]] True !2005-12-02 Fri # Ruby >> [1, 2, 3].max => 3 >> [1, 2, 3].min => 1 # Python >>> max([1, 2, 3]) 3 >>> min([1, 2, 3]) 1 !2005-12-01 Thu # Ruby >> [1, 2, 3].length => 3 # Python >>> len([1, 2, 3]) 3 !2005-11-30 Wed # Ruby >> [].empty? => true >> [1, 2, 3].empty? => false # Python >>> [] == [] True >>> [] == [1, 2, 3] False !2005-11-29 Tue # Ruby >> [1, 2, 3].include?(1) => true >> [1, 2, 3].include?(4) => false # Python >>> 1 in [1, 2, 3] True >>> 4 in [1, 2, 3] False !2005-11-28 Mon # Ruby >> [1, 2, 3] - [4, 5, 6] => [1, 2, 3] >> [1, 2, 3] - [1, 1] => [2, 3] # Python >>> [1, 2, 3] - [4, 5, 6] Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for -: 'list' and 'list' !2005-11-27 Sun # Ruby >> [1, 2, 3] * 2 => [1, 2, 3, 1, 2, 3] >> 2 * [1, 2, 3] TypeError: Array can't be coerced into Fixnum # Python >>> [1, 2, 3] * 2 [1, 2, 3, 1, 2, 3] >>> 2 * [1, 2, 3] [1, 2, 3, 1, 2, 3] !2005-11-26 Sat # Ruby >> [1, 2, 3] + [4, 5, 6] => [1, 2, 3, 4, 5, 6] # Python >>> [1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] !2005-11-25 Fri # Ruby >> [1, 2, 3] => [1, 2, 3] # Python >>> [1, 2, 3] [1, 2, 3] !2005-11-24 Thu ふと、モジュール関数を追加するのは、 単に辞書に入れれば良い気がしてきたので試してみた。 >>> import string >>> def string_to_a(str): # 2005-11-22 ... new_ary = [] ... for x in str: ... new_ary = new_ary + [x] ... return new_ary ... >>> string.__dict__['to_a'] = string_to_a >>> string.to_a("abc") ['a', 'b', 'c'] "abc".strip() といった感じで呼び出すには、 どこに何を付け加えたら良いんだろうか? !2005-11-23 Wed # Ruby >> "abc".reverse => "cba" # Python # 2005-11-22 の string_to_a(str) を使って、 >>> import string >>> def string_reverse(str): ... a = string_to_a(str) ... a.reverse() ... return string.join(a, "") ... >>> string_reverse("abc") 'cba' >>> string_reverse("") '' !2005-11-22 Tue リストに reverse() はあるのに、 直接文字列には適用できないようだ。 >>> [1, 2, 3].reverse() >>> a = [1, 2, 3] >>> a.reverse() >>> a [3, 2, 1] 良く考えると、String#to_a がない??? >>> def string_to_a(str): ... new_ary = [] ... for x in str: ... new_ary = new_ary + [x] ... return new_ary ... >>> string_to_a("abc") ['a', 'b', 'c'] >>> string_to_a("") [] どうやら Ruby の String#to_a は、こんな機能ではないみたい… list() なぞという関数があった… >>> list("abc") ['a', 'b', 'c'] !2005-11-21 Mon String#chomp の別解を考えついてしまった。 >>> def string_chomp(str): ... length = len(str) ... ... if length == 0: ... return str ... elif str[length-1] == '\r': ... return str.rstrip('\r') ... elif str[length-2:] == '\r\n': ... return str.rstrip('\r\n') ... else: ... return str.rstrip('\n') ... >>> string_chomp("abc\ndef\n") 'abc\ndef' >>> string_chomp("abcr\rdef\r") 'abcr\rdef' >>> string_chomp("abcr\r\ndef\r\n") 'abcr\r\ndef' >>> string_chomp("abcr\n\rdef\n\r") 'abcr\n\rdef\n' >>> string_chomp("") '' >>> string_chomp("a") 'a' >>> string_chomp("\n") '' >>> string_chomp("\r") '' >>> string_chomp("\r\n") '' >>> string_chomp("\n\r") '\n' !2005-11-20 Sun 新事実、発覚! >>> "abc".split("") Traceback (most recent call last): File "", line 1, in ? ValueError: empty separator バラバラにするにはどうすりゃ? !2005-11-19 Sat String#succ に相当するものはなさそう。 あると便利なこともあるけど。 軟弱なので、実装はしない…。 Perl 由来かと勘違いしていたが、 Perl の場合は文字列を数値に変換して計算するだけか。 $ perl -e 'print "1" + 1, "\n";' 2 $ perl -e 'print "10" + 1, "\n";' 11 $ perl -e 'print "A" + 1, "\n";' 1 $ perl -e 'print "Z" + 1, "\n";' 1 !2005-11-18 Fri # Ruby >> "abc".insert(0, "AAA") => "AAAabc" >> "abc".insert(1, "AAA") => "aAAAbc" >> "abc".insert(2, "AAA") => "abAAAc" >> "abc".insert(3, "AAA") => "abcAAA" >> "abc".insert(4, "AAA") IndexError: index 4 out of string from (irb):12:in `insert' from (irb):12 >> "abc".insert(-1, "AAA") => "abcAAA" >> "abc".insert(-2, "AAA") => "abAAAc" >> "abc".insert(-3, "AAA") => "aAAAbc" >> "abc".insert(-4, "AAA") => "AAAabc" >> "abc".insert(-5, "AAA") IndexError: index -4 out of string # Python >>> def string_insert(str, n, ins_str): ... return str[:n] + ins_str + str[n:] ... >>> string_insert("abc", 0, "AAA") 'AAAabc' >>> string_insert("abc", 1, "AAA") 'aAAAbc' >>> string_insert("abc", 2, "AAA") 'abAAAc' >>> string_insert("abc", 3, "AAA") 'abcAAA' >>> string_insert("abc", 4, "AAA") 'abcAAA' >>> string_insert("abc", -1, "AAA") 'abAAAc' >>> string_insert("abc", -2, "AAA") 'aAAAbc' >>> string_insert("abc", -3, "AAA") 'AAAabc' >>> string_insert("abc", -4, "AAA") 'AAAabc' 敗北… !2005-11-17 Thu # Ruby >> "abc".insert(1, "AAA") => "aAAAbc" # Python >>> "abc"[0:1] + "AAA" + "abc"[1:] 'aAAAbc' >>> "abc"[:1] + "AAA" + "abc"[1:] 'aAAAbc' 一般的に書き起こす気力がない… !2005-11-16 Wed # Ruby >> "abc".include?("a") => true >> "abc".include?("A") => false >> "abc".include?("ab") => true >> "abc".include?(97) => true # Python >>> "a" in "abc" True >>> "A" in "abc" False >>> "ab" in "abc" True !2005-11-15 Tue # Ruby >> "abc".each_byte {|x| p x} 97 98 99 >> "abc".each_byte {|x| p x.chr} "a" "b" "c" # Python for x in "abc": ... print x ... a b c !2005-11-14 Mon # Ruby >> "abc\ndef\n".each {|x| p x } "abc\n" "def\n" # Python # 2005-11-12 の string_chomp(s) を使って、 >>> for x in string_chomp("abc\ndef\n").split("\n"): ... print x ... abc def Python の最新機能を使えば、もっと別の書き方もありそう(?) !2005-11-13 Sun # Ruby puts "abc\r\n\f\x00\b10\\\"".dump' # => "abc\r\n\f\000\01010\\\"" # Python >>> repr("abc\r\n\f\x00\b10\\\"") '\'abc\\r\\n\\x0c\\x00\\x0810\\\\"\'' >>> print repr("abc\r\n\f\x00\b10\\\"") 'abc\r\n\x0c\x00\x0810\\"' 似ているのかなあ??? !2005-11-12 Sat # Ruby p "abc\ndef\n".chomp # => "abc\ndef" p "abcr\rdef\r".chomp # => "abcr\rdef" p "abcr\r\ndef\r\n".chomp # => "abcr\r\ndef" p "abcr\n\rdef\n\r".chomp # => "abcr\n\rdef\n" # Python >>> def string_chomp(s): ... length = len(s) ... ... if length == 0: ... return s ... elif s[length-1] == '\n': ... if (length > 1) and (s[length-2] == '\r'): ... return s[0:length-2] ... else: ... return s[0:length-1] ... elif s[length-1] == '\r': ... return s[0:length-1] ... else: ... return s ... >>> string_chomp("abc\ndef\n") 'abc\ndef' >>> string_chomp("abcr\rdef\r") 'abcr\rdef' >>> string_chomp("abcr\r\ndef\r\n") 'abcr\r\ndef' >>> string_chomp("abcr\n\rdef\n\r") 'abcr\n\rdef\n' >>> string_chomp("") '' >>> string_chomp("a") 'a' >>> string_chomp("\n") '' >>> string_chomp("\r") '' >>> string_chomp("\r\n") '' >>> string_chomp("\n\r") '\n' !2005-11-11 Fri # Ruby p 'a' <=> 'A' # => 1 p 'a'.casecmp('A') # => 0 # Python >>> def string_cmp(s1, s2): ... if s1 > s2: ... return 1 ... elif s1 < s2: ... return -1 ... else: ... return 0 ... >>> string_cmp("a", "A") 1 >>> string_cmp("A", "a") -1 >>> string_cmp("A", "A") 0 >>> def string_casecmp(s1, s2): ... if s1.lower() > s2.lower(): ... return 1 ... elif s1.lower() < s2.lower(): ... return -1 ... else: ... return 0 ... >>> string_casecmp("a", "A") 0 >>> string_casecmp("a", "b") -1 >>> string_casecmp("b", "a") 1 モジュール関数を追加するにはどうやったら良いんだろう? cmp を使えば良かった…(2006-01-12 Thu) >>> cmp("a", "A") 1 >>> cmp("A", "a") -1 >>> cmp("A", "A") 0 !2005-11-10 Thu # Ruby p "%d %s" % [1, "foo"] # => "1 foo" # Python >>> print "%d %s" % (1, "foo") 1 foo ちょっと似ている !2005-11-09 Wed # Ruby p "abc".gsub(/a/, "A") # => "Abc" p "abc".gsub(/ab/, "AB") # => "ABc" p "abc abc".gsub(/ab/, "AB") # => "ABc ABc" # Python >>> import string >>> string.replace("abc", "a", "A") 'Abc' >>> string.replace("abc", "ba", "BA") 'abc' >>> string.replace("abc", "ab", "AB") 'ABc' >>> string.replace("abc abc", "ab", "AB") 'ABc ABc' !2005-11-08 Tue # Ruby irb(main):001:0> class String irb(main):002:1> def zfill(width) irb(main):003:2> len = self.length irb(main):004:2> "0" * ((len < width) ? (width - len) : 0) + self irb(main):005:2> end irb(main):006:1> end => nil irb(main):007:0> "a".zfill(10) => "000000000a" irb(main):008:0> "1".zfill(10) => "0000000001" irb(main):009:0> "1.2".zfill(10) => "00000001.2" irb(main):010:0> "aaa".zfill(10) => "0000000aaa" irb(main):011:0> "aaa".zfill(1) => "aaa" irb(main):012:0> "aaa".zfill(2) => "aaa" irb(main):013:0> "aaa".zfill(3) => "aaa" irb(main):014:0> "aaa".zfill(4) => "0aaa" # Python >>> import string >>> string.zfill("a", 10) '000000000a' >>> string.zfill("1", 10) '0000000001' >>> string.zfill(1, 10) '0000000001' >>> string.zfill(1.2, 10) '00000001.2' >>> string.zfill('aaa', 1) 'aaa' !2005-11-07 Mon # Ruby p "a".ljust(10) # => "a " p "a".rjust(10) # => " a" p "a".center(10) # => " a " p "a".center(11) # => " a " p "ab".center(10) # => " ab " p "ab".center(11) # => " ab " # Python >>> import string >>> string.ljust("a", 10) 'a ' >>> string.rjust("a", 10) ' a' >>> string.center("a", 10) ' a ' >>> string.center("a", 11) ' a ' >>> string.center("ab", 10) ' ab ' >>> string.center("ab", 11) ' ab ' あっ、やっぱり微妙に違うんだ。 !2005-11-06 Sun # Ruby p "abc".tr('abc', 'ABC').delete('a') # => "ABC" p "abc".delete('a').tr('abc', 'ABC') # => "BC" p "abc".delete('a').tr('a-c', 'A-C') # => "BC" p "abc".delete('A').tr('abc', 'ABC') # => "ABC" p "abc".delete('a') # => "bc" # Python >>> import string >>> string.translate("abc", string.maketrans("abc", "ABC")) 'ABC' >>> string.translate("abc", string.maketrans("abc", "ABC"), "a") 'BC' >>> string.translate("abc", string.maketrans("abc", "ABC"), "A") 'ABC' >>> string.translate("abc", string.maketrans("", ""), "a") 'bc' tr と delete を混ぜたようなものか? !2005-11-05 Sat # Ruby p ['a', 'b', 'c'].join # => "abc" p ['a', 'b', 'c'].join(":") # => "a:b:c" # Python >>> import string >>> string.join(['a', 'b', 'c']) 'a b c' >>> string.join(['a', 'b', 'c'], ":") 'a:b:c' >>> string.join('a', 'b', 'c') Traceback (most recent call last): File "", line 1, in ? TypeError: join() takes at most 2 arguments (3 given) >>> string.join(('a', 'b', 'c')) 'a b c' !2005-11-04 Fri Ruby に expandtabs() に相当するものはなさそう。 C Magazine 2002 年 10 月号に関係しそうなコードが載っていた。 !2005-11-03 Thu # Ruby p "abc def ghi".split.map {|x| x.capitalize}.join(" ") # => "Abc Def Ghi" p "abc def ghi".split.map {|x| x.capitalize}.join(" ") # => "Abc Def Ghi" # Python >>> import string >>> string.capwords("abc def ghi") 'Abc Def Ghi' >>> string.capwords("abc def ghi") 'Abc Def Ghi' なぜ、こんなのがデフォルトで用意されているかは不明 !2005-11-02 Wed モジュールで定義される定数 ascii_letters, ascii_lowercase, ascii_uppercase ... あたりは Ruby には、なさそうな気がする。 * 何に使うんだ? * どう使うんだ? * 正規表現で十分? * ここから Python 2.3.5 がデフォルト(たまには、Python 2.3.4 になるかも???) * ここから ruby-1.8.2 がデフォルト !2005-11-01 Tue # Ruby p "a b c".split # => ["a", "b", "c"] p "a b c".split # => ["a", "b", "c"] p " a b c ".split # => ["a", "b", "c"] p "a:b:c".split(":") # => ["a", "b", "c"] p ":a:b:c:".split(":") # => ["", "a", "b", "c"] p "a::b::c".split(":") # => ["a", "", "b", "", "c"] p "a::b::c".split(/:/) # => ["a", "", "b", "", "c"] p "a::b::c".split(/:+/)# => ["a", "b", "c"] # Python >>> "a b c".split() ['a', 'b', 'c'] >>> "a b c".split() ['a', 'b', 'c'] >>> " a b c ".split() ['a', 'b', 'c'] >>> "a:b:c".split(":") ['a', 'b', 'c'] >>> "a::b::c".split(":") ['a', '', 'b', '', 'c'] >>> ":a:b:c:".split(":") ['', 'a', 'b', 'c', ''] 微妙に違うなあ !2005-10-31 Mon # Ruby p " abc ".lstrip # => "abc " p " abc ".rstrip # => " abc" p " abc ".strip # => "abc" p "\t\r\n\f\v\0".strip # => "" lstrip, rstrip は 1.7.x からだそうな。 # Python >>> " abc ".lstrip() 'abc ' >>> " abc ".rstrip() ' abc' >>> " abc ".strip() 'abc' >>> "\t\r\n\f\v\0".strip() '\x00' !2005-10-30 Sun # Ruby p "abc abc".index("a", 1) # => 4 p "abc abc".rindex("a", 1) # => 0 # Python >>> "abc abc".index("a", 1) 4 >>> "abc abc".rindex("a", 1) 4 >>> "abc abc".rindex("a", 0) 4 >>> "abc abc".find("a", 1, 2) -1 >>> "abc abc".find("a", 1, 3) -1 >>> "abc abc".find("a", 1, 4) -1 >>> "abc abc".find("a", 1, 5) 4 引数の意味 かなり違う。 Python より Ruby の方が妥当かなあ。 部分文字列を対象にしたいなら str[?:?].find() ってやれば良いだけだし。 もしかして、この仕様は Python の文字列が immutable ということに関係する??? !2005-10-29 Sat # Ruby p "abc abc".rindex("a") # => 4 p "abc abc".rindex("d") # => nil # Python >>> "abc abc".rfind("a") 4 >>> "abc abc".rfind("d") -1 >>> "abc abc".rindex("a") 4 >>> "abc abc".rindex("d") Traceback (most recent call last): File "", line 1, in ? ValueError: substring not found !2005-10-28 Fri # Ruby p "abc".index("a") # => 0 p "abc".index("b") # => 1 p "abc".index("d") # => nil # Python >>> "abc".find("a") 0 >>> "abc".find("d") -1 >>> "abc".index("a") 0 >>> "abc".index("d") Traceback (most recent call last): File "", line 1, in ? ValueError: substring not found !2005-10-27 Thu # Ruby "abcDEF".swapcase # => "ABCdef" # Python >>> "abcDEF".swapcase() 'ABCdef' !2005-10-26 Wed # Ruby p "ABC".downcase # => "abc" # Python >>> string.lower("ABC") 'abc' >>> "ABC".lower() 'abc' !2005-10-25 Tue # Ruby p "abc".upcase # => "ABC" # Python >>> import string >>> string.upper("abc") 'ABC' >>> "abc".upper() 'ABC' Python は C の tolower, toupper あたりからで、 Ruby は *case で統一したのか??? EmacsLisp も *case みたい。 !2005-10-24 Mon # Ruby p "abc".capitalize # => "Abc" # Python >>> import string >>> string.capitalize("abc") 'Abc' >>> "abc".capitalize() 'Abc' !2005-10-23 Sun # Ruby p "1.0".to_f # => 1.0 p "1".to_f # => 1.0 p "a".to_f # => 0.0 p 1.0.to_f # => 1.0 p 1.to_f # => 1.0 # Python >>> float("1.0") 1.0 >>> float("1") 1.0 >>> float("a") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for float(): a >>> float(1.0) 1.0 >>> float(1) 1.0 !2005-10-22 Sat # Ruby p "1".to_i # => 1 p "1.0".to_i # => 1 p "a".to_i # => 0 p 1.to_i # => 1 p 1.0.to_i # => 1 # Python >>> int("1") 1 >>> int("1.0") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): 1.0 >>> int("a") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): a >>> int(1) 1 >>> int(1.0) 1 例外を出さない int() はないのだろうか? !2005-10-21 Fri # Ruby p "abc abc abc".count("a") # => 3 p "abc abc abc".count("") # => 0 p "abc abc abc".count("abc") # => 9 p "abc abc abc".scan(/abc/).size # => 3 # Python >>> import string >>> string.count("abc abc abc", "a") 3 >>> string.count("abc abc abc", "") 12 >>> string.count("abc abc abc", "abc") 3 似て非なるもの、というか、全く別物だった…。 Python の方が私の直観に合うな。 !2005-10-20 Thu # Ruby p "".empty? # => true # Python >>> "" == "" True "".empty? と "" == "" は、同じ文字数か(スペースのいれ方によって変わるけど…) !2005-10-19 Wed # Ruby p "abcd" > "abc" # => true p "abc" >= "abc" # => true # Python >>> "abcd" > "abc" True >>> "abcd" >= "abc" True !2005-10-18 Tue # Ruby p "abc" == "abc" # => true p "abc" != "abc" # => false # Python >>> "abc" == "abc" True >>> "abc" != "abc" False !2005-10-17 Mon # Ruby p "abc"[0,1] # => "a" p "abc"[0,2] # => "ab" p "abc"[1,2] # => "bc" p "abc"[1,0] # => "" p "abc"[1,-1] # => nil p "abc"[1,1] # => "b" p "abc"[2,1] # => "c" p "abc"[0..0] # => "a" p "abc"[0..1] # => "ab" p "abc"[1..1] # => "b" p "abc"[1..2] # => "bc" p "abc"[1..0] # => "" p "abc"[0...0] # => "" p "abc"[0...1] # => "a" p "abc"[1...1] # => "" p "abc"[1...2] # => "b" p "abc"[1...0] # => nil # Python >>> "abc"[0:0] '' >>> "abc"[0:1] 'a' >>> "abc"[1:1] '' >>> "abc"[1:2] 'b' >>> "abc"[1:0] '' !2005-10-16 Sun # Ruby p "abc"[1] # => 98 p "abc"[0] # => 97 p "abc"[-1] # => 99 p "abc"[3] # => p "abc"[-4] # => nil p "abc"[0..0] # => "a" p "abc"[1..1] # => "b" p "abc"[0].chr # => "a" # Python >>> "abc"[0] 'a' >>> "abc"[1] 'b' >>> "abc"[-1] 'c' >>> "abc"[3] Traceback (most recent call last): File "", line 1, in ? IndexError: string index out of range >>> "abc"[-4] Traceback (most recent call last): File "", line 1, in ? IndexError: string index out of range !2005-10-15 Sat # Ruby p "hoge" * 3 # => "hogehogehoge" # Python >>> "hoge" * 3 'hogehogehoge' !2005-10-14 Fri # Ruby p "foo" + "bar" # => "foobar" # Python >>> "foo" + "bar" 'foobar' !2005-10-13 Thu # Ruby p "foo".length # => 3 p "foo".size # => 3 # Python >>> len("foo") 3 !2005-10-12 Wed # Ruby irb(main):001:0> s = "foo irb(main):002:0" bar irb(main):003:0" " "foo\nbar\n" # Python >>> s = "foo File "", line 1 s = "foo ^ SyntaxError: EOL while scanning single-quoted string >>> s = "foo\ ... bar" >>> s 'foobar' !2005-10-11 Tue # Ruby s = "foo" s = 'foo' s = <>> s = "foo" >>> s = 'foo' >>> s = """foo""" !2005-10-10 Mon # Ruby p Math.exp(1) # => 2.71828182845905 # Python >>> import math >>> math.exp(1) 2.7182818284590451 !2005-10-09 Sun # Ruby p Math.log10(10) # => 1.0 # Python >>> import math >>> math.log10(10) 1.0 !2005-10-08 Sat # Ruby p Math.log(Math::E) # => 1.0 # Python >>> import math >>> math.log(math.e) 1.0 !2005-10-07 Fri # Ruby p Math.sqrt(2) # => 1.4142135623731 # Python >>> import math >>> math.sqrt(2) 1.4142135623730951 !2005-10-06 Thu # Ruby p Math::E # => 2.71828182845905 p Math::PI # => 3.14159265358979 # Python >>> import math >>> math.pi 3.1415926535897931 >>> math.e 2.7182818284590451 !2005-10-05 Wed # Ruby p 1.5.round # => 2 p -1.5.round # => -2 # Python >>> round(1.5) 2.0 >>> round(-1.5) -2.0 ceil, truncate, floor はないんだろうか? truncate は int() と同じかな? !2005-10-04 Tue # Ruby p 10.to_s(2) # => "1010" p 10.to_s(8) # => "12" p 10.to_s(16) # => "a" p 35.to_s(36) # => "z" # Python >>> oct(10) '012' >>> hex(10) '0xa' 微妙に違うなあ。2, 36 進数ないし。 !2005-10-03 Mon # Ruby p 1.to_s # => "1" # Python >>> str(1) '1' !2005-10-02 Sun # Ruby 1.upto(2.5) {|x| p x} 1 2 # Python >>> for x in range(1, 2.5): ... print x ... __main__:1: DeprecationWarning: integer argument expected, got float 1 !2005-10-01 Sat # Ruby 2.downto(1) {|x| p x} 2 1 # Python >>> for x in range(2, 0, -1): ... print x ... 2 1 含む、含まないは、制御できないのかな !2005-09-30 Fri # Ruby 16.hex # => NoMethodError: undefined method `hex' for 16:Fixnum "10".hex # => 16 # Python >>> hex(16) '0x10' >>> hex(-1) __main__:1: FutureWarning: hex()/oct() of negative int will return a signed string in Python 2.4 and up '0xffffffff' 全然別ものだった !2005-09-29 Thu # Ruby p 1 <=> 0 # => 1 p 1 <=> 1 # => 0 p 0 <=> 1 # => -1 # Python >>> cmp(1, 0) 1 >>> cmp(1, 1) 0 >>> cmp(0, 1) -1 !2005-09-28 Wed # Ruby p 65.chr # => "A" p 256.chr # => RangeError: 256 out of char range # Python >>> chr(65) 'A' >>> chr(256) Traceback (most recent call last): File "", line 1, in ? ValueError: chr() arg not in range(256) あてずっぽでやったら成功! !2005-09-27 Tue # Ruby 1/0 # => ZeroDivisionError: divided by 0 # Python >>> 1/0 Traceback (most recent call last): File "", line 1, in ? ZeroDivisionError: integer division or modulo by zero !2005-09-26 Mon # Ruby p 3[0] # => 1 p 3[1] # => 1 p 3[2] # => 0 # Python >>> 3 & (1<<0) 1 >>> 3 & (1<<1) 2 >>> 3 & (1<<2) 0 Python にはなさそう。Ruby に、こんなのあったの知らなかったし(忘れていたし) !2005-09-25 Sun # Ruby 1.class # => Fixnum p 1.integer? # => true p 1.float? # => NameError: undefined method `float?' for 1:Fixnum p 1.0.float? # => NameError: undefined method `float?' for 1.0:Float integer? はあっても、float? はないと。 # Python >>> type(1) >>> type(1) == type(0) True >>> import types >>> type(1) == types.IntType True >>> type(1.0) == types.IntType False >>> type(1.0) == types.FloatType True import types が面倒なときは、type(0) あたりと比較しても 簡単で良さそうな気もするけど、ダメか? !2005-09-24 Sat # Ruby p 10.divmod(3) # => [3, 1] p -10.divmod(3) # => [-4, 2] # Python >>> divmod(10, 3) (3, 1) >>> divmod(-10, 3) (-4, 2) そっくり !2005-09-23 Fri # Ruby p 1.to_f # => 1.0 p 1.2.to_f # => 1.2 # Python >>> float(1) 1.0 >>> float("1") 1.0 >>> float("1.2") 1.2 !2005-09-22 Thu # Ruby p 1.5.to_i # => 1 p "1".to_i # => 1 p "1.5".to_i # => 1 p "a".to_i # => 0 # Python >>> int(1.5) 1 >>> int("1") 1 >>> int("1.5") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): 1.5 >>> int("a") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for int(): a !2005-09-21 Wed # Ruby p -1.abs # => 1 p Math.abs(-1) # => NameError: undefined method `abs' for Math:Module # Python >>> abs(-1) 1 !2005-09-20 Tue p 1.zero? # => false p 0.zero? # => true p 0.nonzero? # => nil p 1.nonzero? # => 1 p 1.0.nonzero? # => 1.0 zero? に相当するものは見あたらなさそう。 Ruby の場合、 p !0 # => false だから、存在するんだろう >>> not 0 True >>> not 1 False !2005-09-19 Mon # Ruby p true == 1 # => false p true == 0 # => false p 1 & true # => TypeError: no implicit conversion from boolean p true & 1 # => true p 1 && true # => true p true && 1 # => 1 p true && 1 # => 1 # Python >>> 1 is True False >>> 0 is False False >>> 0 is True False >>> True == 1 True >>> True == 0 False >>> 1 & True 1 >>> True & 1 1 !2005-09-18 Sun うーん、もともと「ライブラリリファレンス」から始めたのかな? 苦し紛れに Ruby と比較してみる。 # Ruby p true.type # => TrueClass p false.type # => FalseClass p nil.type # => NilClass p !true # => false p true && true # => true p true & true # => true p true and true # => true p true ^ true # => false p true ^ false # => true # Python >>> True True >>> False False >>> import types >>> type(True) >>> type(False) >>> !True File "", line 1 !True ^ SyntaxError: invalid syntax >>> not True False >>> True & True True >>> True && True File "", line 1 True && True ^ SyntaxError: invalid syntax >>> True and True True >>> True ^ True False >>> True ^ False True >>> bool(1) True >>> bool(0) False ! はないのか? && もないのか? !2005-09-17 Sat >>> str1 = "foo" >>> str2 = str1 >>> id(str1) 1075613792 >>> id(str2) 1075613792 >>> str3 = str1 + '' >>> id(str3) 1075613792 >>> id(str1 + 'a') 1075605440 >>> str3 = str1[:] >>> id(str3) 1075613792 >>> id("foo") 1075613792 >>> id('f' + 'o' + 'o') 1075614368 >>> 'fooa'[0:-1] 'foo' >>> id('fooa'[0:-1]) 1075605376 >>> list1 = [1, 2, 3] >>> list2 = list1 >>> id(list1) 1075605420 >>> id(list2) 1075605420 >>> list3 = list1[:] >>> id(list3) 1075605452 >>> list1[0] = 10 リストはミュータブルだけど、文字列はイミュータブルだから コピーする必要さえないのか??? !2005-09-16 Fri 2005-08-26, 2005-08-30 のファイルを処理する。 だいたいこんなのを雛型にすれば良いか。 import sys, string, re, fileinput def dict_add(x, key, value): if x.has_key(key): x[key] += value else: x[key] = value sum = {} for line in fileinput.input(): m = re.match("^(\S+)\s+(\d+)", line) if m == None: sys.stderr.write("Format Error!! %s in line: %d" % (line, fileinput.lineno())) continue name, price = m.groups() dict_add(sum, name, string.atoi(price)) for k, v in sum.items(): print "%-10s: %d" % (k, v) * 改行を削除する方法不明 !2005-09-15 Thu string.foo("abc") が常に "abc".foo() にできるわけではないことに気がついた >>> import string >>> string.upper("abc") 'ABC' >>> "abc".upper() 'ABC' >>> "1".atoi() Traceback (most recent call last): File "", line 1, in ? AttributeError: 'str' object has no attribute 'atoi' >>> string.atoi("1") 1 !2005-09-14 Wed 2005-08-26, 2005-08-30 のファイルを処理する。 気まぐれに each_with_index (エラーになる入力はないとする) import sys, re, fileinput def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in fileinput.input(): name, price = re.match("(\S+)\s+(\d+)", line).groups() dict_add(sum, name, int(price)) for i, k in enumerate(sum.keys()): print "%2d %-10s: %d" % (i, k, sum[k]) !2005-09-13 Tue 2005-08-26, 2005-08-30 のファイルを処理する。 エラー処理を追加してみる。 import sys, re, fileinput def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in fileinput.input(): m = re.match("^(\S+)\s+(\d+)", line) if m == None: sys.stderr.write("Format Error!! %s in line: %d\n" % (line, fileinput.lineno())) continue name, price = m.groups() dict_add(sum, name, int(price)) for (k, v) in sum.items(): print "%-10s: %d" % (k, v) * stderr に出すのは write しかないんだっけ?(print >> sys.stderr, "foo" という書き方があるようだ) * chomp, chop に相当するのは何だったっけ? * next じゃないんだね。C とかと同じで continue !2005-09-12 Mon 2005-08-26, 2005-08-30 のファイルを処理する。 string.split を使わないで。 import sys, re, fileinput def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in fileinput.input(): name, price = re.match("(\S+)\s+(\d+)", line).groups() dict_add(sum, name, int(price)) for (k, v) in sum.items(): print "%-10s: %d" % (k, v) まだ、エラーは考えていない !2005-09-11 Sun fileinput で遊ぶ。 import fileinput for line in fileinput.input(): print "%s %d %d %d %d" % (fileinput.filename(), fileinput.filelineno(), fileinput.lineno(), fileinput.isfirstline(), fileinput.isstdin()) といってもこのくらい。 !2005-09-10 Sat 2005-08-26, 2005-08-30 のファイルを処理する。 表示の際、ソートしないのならこうも書けるようだ。 import sys, string, fileinput def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in fileinput.input(): name, price = string.split(line)[0:2] dict_add(sum, name, int(price)) for (k, v) in sum.items(): print "%-10s: %d" % (k, v) * (k, v) のカッコは不要だったようだ * iteritems() でも(表面上)同じ動作をするようだ * iteritems() と items() の違いは何? !2005-09-09 Fri 2005-08-26, 2005-08-30 のファイルを処理する。 fileinput というのがあるようなので使ってみる。 import sys, string, fileinput def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in fileinput.input(): name, price = string.split(line)[0:2] dict_add(sum, name, int(price)) keys = sum.keys() keys.sort(lambda a, b : cmp(b, a)) for x in keys: print "%-10s: %d" % (x, sum[x]) 標準入力も引数のファイルしていも、よきにはからってくれるようだ。 こりゃ便利じゃない? ruby だと ARGF で良いのか。 sum = Hash.new(0) while line = ARGF.gets name, price = line.split sum[name] += price.to_i end sum.keys.sort.each {|x| printf "%-10s %d\n", x, sum[x] } !2005-09-08 Thu ファイル(複数可)を入力として、 2005-08-26, 2005-08-30 のファイルを処理する。 ファイルの指定がない場合は、標準入力から読み込む。 import sys, string def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value def proc_file(file): for line in file: name, price = string.split(line)[0:2] dict_add(sum, name, int(price)) sum = {} if len(sys.argv) == 1: proc_file(sys.stdin) else: for file in sys.argv[1:]: proc_file(open(file, 'r')) keys = sum.keys() keys.sort(lambda a, b : cmp(b, a)) for x in keys: print "%-10s: %d" % (x, sum[x]) !2005-09-07 Wed ファイル(複数可)を入力として、 2005-08-26, 2005-08-30 のファイルを処理する。 import sys, string def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for file in sys.argv[1:]: for line in open(file, 'r'): name, price = string.split(line)[0:2] dict_add(sum, name, int(price)) keys = sum.keys() keys.sort(lambda a, b : cmp(b, a)) for x in keys: print "%-10s: %d" % (x, sum[x]) !2005-09-06 Tue ファイル(複数可)を入力としてみる。 まずは、単に出力するだけ。 import sys for file in sys.argv[1:]: for line in open(file, 'r'): print line, !2005-09-05 Mon 2005-08-30 のファイルを入力として、 ちょっと書き直してみる あれ?↓なことに気がついてしまった >>> import string >>> "foo bar baz".split(" ") ['foo', 'bar', '', 'baz'] >>> string.split("foo bar baz") ['foo', 'bar', 'baz'] おまけに、多重代入はタプルっぽくしなくて良いようだ。がぴょーん。 ということで、 import sys, string def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in sys.stdin: name, price = string.split(line)[0:2] dict_add(sum, name, int(price)) keys = sum.keys() keys.sort(lambda a, b : cmp(b, a)) for x in keys: print "%-10s: %d" % (x, sum[x]) !2005-09-04 Sun 2005-08-30 のファイルを入力として、 ちょっと書き直してみる そういえば、キーで sort ってすることよくあるな。 ということでソートしてみる。 import sys, re def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} for line in sys.stdin: (name, price) = re.compile("\s+").split(line)[0:2] dict_add(sum, name, int(price)) keys = sum.keys() keys.sort() for x in keys: print "%-10s: %d" % (x, sum[x]) 破壊的でない sort ってないのかなあ? python 2.4 だと sorted() というのができたらしい。 keys.sort(lambda a, b : cmp(b, a)) とすると、降順になるようだ。 !2005-09-03 Sat 2005-08-30 のファイルを入力として、 ちょっと書き直してみる いちいちキーが既に存在するときと、存在しないときで区別するのが面倒だ。 なんか良い方法があるのかも知れないけど、今のところ分からないので、 関数化してみる。 import sys, re def dict_add(x, key, value): try: x[key] += value except KeyError: x[key] = value sum = {} num = {} for line in sys.stdin: (name, price) = re.compile("\s+").split(line)[0:2] dict_add(sum, name, int(price)) dict_add(num, name, 1) for x in sum.keys(): print "%-10s: %d" % (x, sum[x]) for x in num.keys(): print "%-10s: %d" % (x, num[x]) !2005-09-02 Fri 2005-08-30 のファイルを入力として、 ちょっと書き直してみる CookBook を見ていたら、2.2 以降だと、readlines を省略できるらしい。 CookBook って 第 2 版が出ていたようだ。 CookBook もさっさと読んでみないとな。 import sys, re sum = {} for line in sys.stdin: (name, price) = re.compile("\s+").split(line)[0:2] try: sum[name] += int(price) except KeyError: sum[name] = int(price) for x in sum.keys(): print "%-10s: %d" % (x, sum[x]) かなり すっきりしてきた。 !2005-09-01 Thu 2005-08-30 のファイルを入力として、 ちょっと書き直してみる import sys, re sum = {} for line in sys.stdin.readlines(): (name, price) = re.compile("\s+").split(line)[0:2] try: sum[name] += int(price) except KeyError: sum[name] = int(price) for x in sum.keys(): print "%-10s: %d" % (x, sum[x]) * readlines は効率悪いのかな? * 代入文が式でない(?)のが痛いなあ * xrange があるように、xreadlines があるようだ !2005-08-31 Wed 2005-08-30 のファイルを入力として、 ちょっと書き直してみる import sys, re sum = {} while 1: line = sys.stdin.readline() if not line: break list = re.compile("\s+").split(line) (name, price) = list[0:2] try: sum[name] += int(price) except KeyError: sum[name] = int(price) for x in sum.keys(): print "%-10s: %d" % (x, sum[x]) !2005-08-30 Tue 入力ファイルを以下に変更 orange 100 apple 200 banana 300 orange 300 それぞれの合計でも出してみる。 import sys, re r = re.compile("\s+") sum = {} while 1: line = sys.stdin.readline() if not line: break list = r.split(line) name = list[0] price = list[1] if sum.has_key(name): sum[name] += int(price) else: sum[name] = int(price) for x in sum.keys(): print "%-10s: %d" % (x, sum[x]) * python も初期化が必要なんだったっけ? * 多重代入ってあったよな。 * デフォルト値というのは設定できたかな? * int って何度も使ってしまっているけど、何か間違いな気がする * string.atoi は、浮動小数点ダメだし、string.atof しかないのかな?(Ruby も #to_i, #to_f くらいしかなかったかな?) !2005-08-29 Mon 2005-08-26 のファイルを入力として、 そろろろ合計でも出してみる? import sys, re r = re.compile("\s+") sum = 0 while 1: line = sys.stdin.readline() if not line: break list = r.split(line) sum += int(list[1]) print "sum: %d" % sum !2005-08-28 Sun 2005-08-26 のファイルを入力として、 import sys num = 0 while 1: line = sys.stdin.readline() if not line: break num += 1 print "line: %d\n" % num, ++ ってなかったか。 !2005-08-27 Sat 2005-08-26 のファイルを入力として、 ちょっと加工してみた。 import sys, re r = re.compile("\s+") while 1: line = sys.stdin.readline() if not line: break list = r.split(line) print "%s:%s\n" % (list[0], list[1]), "a b c".split(" ") といった感じだと、 複数スペースがあるとダメっぽいので、re を使用。 print の最後に , を書くのが気持ち悪いなあ…。 !2005-08-26 Fri 以下のようなファイルで練習してみよう。 orange 100 apple 200 banana 300 これを読み込んで料理する。 ただ、読み込んで出力するだけ。 import sys while 1: line = sys.stdin.readline() if not line: break print line, !2005-08-25 Thu >>> id(1) 135416336 >>> id("foo") 1075613760 >>> id("foo") 1075613888 >>> id("foo") 1075613920 >>> s = "foo" >>> id(s) 1075613728 >>> id(s) 1075613728 !2005-08-24 Wed >>> 11/4 2 >>> 11//4 2 >>> 11/4.0 2.75 >>> 11//4.0 2.0 !2005-08-23 Tue まんま >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! !2005-08-22 Mon まんま >>> 11/4 2 >>> from __future__ import division >>> 11/4 2.75 >>> import __future__ >>> __future__.division _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) !2005-08-21 Sun まんま >>> 0.1 0.10000000000000001 >>> str(0.1) '0.1' >>> print str(0.1) 0.1 >>> round(0.1, 1) 0.10000000000000001 !2005-08-20 Sat まんま >>> def average(values): ... return sum(values, 0.0) / len(values) ... >>> import unittest >>> class TestStatisticalFunctions(unittest.TestCase): ... def test_average(self): ... self.assertEqual(average([20, 30, 70]), 40.0) ... self.assertEqual(round(average([1, 5, 7]), 1), 4.3) ... self.assertRaises(ZeroDivisionError, average, []) ... self.assertRaises(TypeError, average, 20, 30, 70) ... >>> unittest.main() . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK >>> def average(values): ... return sum(values, 0.0) / len(values) ... >>> import unittest >>> class TestStatisticalFunctions(unittest.TestCase): ... def test_average(self): ... self.assertEqual(average([20, 30, 70]), 30.0) ... >>> unittest.main() F ====================================================================== FAIL: test_average (__main__.TestStatisticalFunctions) ---------------------------------------------------------------------- Traceback (most recent call last): File "", line 3, in test_average File "/usr/local/Python-2.3.4/lib/python2.3/unittest.py", line 302, in failUnlessEqual raise self.failureException, \ AssertionError: 40.0 != 30.0 ---------------------------------------------------------------------- Ran 1 test in 0.019s FAILED (failures=1) !2005-08-19 Fri ほぼ、まんま >>> def average(values): ... """Computes the arithmetic mean of a list of numbers. ... ... >>> print average([20, 30, 70]) ... 40.0 ... """ ... return sum(values, 0.0) / len(values) ... >>> import doctest >>> doctest.testmod() (0, 1) >>> def average(values): ... """Computes the arithmetic mean of a list of numbers. ... ... >>> print average([20, 30, 70]) ... 30.0 ... """ ... return sum(values, 0.0) / len(values) ... >>> doctest.testmod() ***************************************************************** Failure in example: print average([20, 30, 70]) from line #2 of __main__.average Expected: 30.0 Got: 40.0 ***************************************************************** 1 items had failures: 1 of 1 in __main__.average ***Test Failed*** 1 failures. *** Tester.merge: '__main__.average' in both testers; summing outcomes. *** Tester.merge: '__main__' in both testers; summing outcomes. (1, 1) なかなか面白い機構。ユニットテストと何が違うんだろう? この方式ですむなら、ユニットテストよりお手軽??? !2005-08-18 Thu ほぼ、まんま >>> from timeit import Timer >>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit() 3.7625100612640381 >>> Timer('a,b = b,a', 'a=1; b=2').timeit() 4.2504699230194092 >>> Timer('str += "a"', 'str = ""').timeit(10000) 0.23065519332885742 >>> Timer('str += "a"', 'str = ""').timeit(10000) 0.21817517280578613 >>> Timer('str += "ab"', 'str = ""').timeit(10000) 0.85792994499206543 >>> Timer('str += "abc"', 'str = ""').timeit(10000) 1.2878799438476562 >>> Timer('str += "abcd"', 'str = ""').timeit(10000) 1.7107079029083252 !2005-08-17 Wed まんま >>> import zlib >>> s = 'witch which has which witches wrist watch' >>> len(s) 41 >>> t = zlib.compress(s) >>> len(t) 37 >>> zlib.decompress(t) 'witch which has which witches wrist watch' >>> zlib.crc32(t) -1438085031 !2005-08-16 Tue smtplib とばし(使うの失敗…)。 まんま >>> from datetime import date >>> now = date.today() >>> now datetime.date(2005, 8, 24) >>> now.strftime("%m-%d-%y or %d%b %Y is a %A on the %d day of %B") '08-24-05 or 24Aug 2005 is a Wednesday on the 24 day of August' >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days 14999 !2005-08-15 Mon まんま >>> import urllib2 >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): ... if 'EST' in line: ... print line ... >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): ... if 'EDT' in line: ... print line ...
Aug. 15, 08:16:14 AM EDT !2005-08-14 Sun まんま >>> import random >>> random.choice(['apple', 'pear', 'banana']) 'pear' >>> random.sample(xrange(100), 10) [37, 98, 93, 8, 74, 24, 45, 64, 59, 56] >>> random.random() 0.36141947556239495 >>> random.randrange(6) 0 !2005-08-13 Sat まんま >>> import math >>> math.cos(math.pi / 4.0) 0.70710678118654757 >>> math.log(1024, 2) 10.0 !2005-08-12 Fri まんま >>> import re >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') 'cat in the hat' >>> 'tea for too'.replace('too', 'two') 'tea for two' !2005-08-11 Thu まんま >>> import sys >>> sys.stderr.write('Warning, log file not found starting a new one') Warning, log file not found starting a new one>>> !2005-08-10 Wed まんま >>> import sys >>> print sys.argv [''] !2005-08-09 Tue まんま >>> import glob >>> glob.glob('*.py') [] !2005-08-08 Mon まんま >>> import shutil >>> shutil.copyfile('foo', 'bar') >>> shutil.move('bar', 'boo') !2005-08-07 Sun まんま >>> import os >>> dir(os) ['EX_CANTCREAT', 'EX_CONFIG', ... 'write'] >>> help(os) !2005-08-06 Sat まんま >>> import os >>> os.system('time 0:02') sh: line 1: 0:02: command not found real 0m0.002s user 0m0.000s sys 0m0.000s 32512 >>> os.getcwd() '/home/nori' >>> os.chdir('/server/accesslogs') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory: '/server/accesslogs' >>> os.chdir('/etc') !2005-08-05 Fri まんま >>> def reverse(data): ... for index in range(len(data)-1, -1, -1): ... yield data[index] ... >>> for char in reverse('golf'): ... print char ... f l o g !2005-08-04 Thu まんま >>> class Reverse: ... "Iterator for looping over a sequence backwards" ... def __init__(self, data): ... self.data = data ... self.index = len(data) ... def __iter__(self): ... return self ... def next(self): ... if self.index == 0: ... raise StopIteration ... self.index = self.index - 1 ... return self.data[self.index] ... >>> for char in Reverse('spam'): ... print char ... m a p s !2005-08-03 Wed まんま >>> s = 'abc' >>> it = iter(s) >>> it >>> it.next() 'a' >>> it.next() 'b' >>> it.next() 'c' >>> it.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2005-08-02 Tue まんま >>> for element in [1, 2, 3]: ... print element ... 1 2 3 >>> for element in (1, 2, 3): ... print element ... 1 2 3 >>> for key in {'one':1, 'two':2}: ... print key ... two one >>> for char in "123": ... print char ... 1 2 3 >>> for line in open("foo"): ... print line ... a b c !2005-08-01 Mon まんま >>> class B: ... pass ... >>> class C(B): ... pass ... >>> class D(C): ... pass ... >>> for c in [B, C, D]: ... try: ... raise c() ... except D: ... print "D" ... except C: ... print "C" ... except B: ... print "B" ... B C D !2005-07-31 Sun まんま >>> class Employee: ... pass ... >>> john = Employee() >>> john.name = 'John Doe' >>> john.dept = 'computer lab' >>> john.salary = 1000 >>> john <__main__.Employee instance at 0x401c6fec> >>> john.__dict__ {'salary': 1000, 'dept': 'computer lab', 'name': 'John Doe'} ↓何のことじゃ? インスタンスメソッドオブジェクトにもまた、属性があります: m.im_self は メソッドの属しているインスタンスオブジェクトで、 m.im_func はメソッドに 対応する関数オブジェクトです。 !2005-07-30 Sat >>> class Foo: ... __x = 1 ... >>> f = Foo() >>> Bar = Foo >>> b = Bar() >>> Bar.__dict__ {'__module__': '__main__', '_Foo__x': 1, '__doc__': None} >>> b._Bar__x Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute '_Bar__x' >>> b._Foo__x 1 !2005-07-29 Fri >>> class Foo: ... __x = 1 ... >>> f = Foo() >>> f.__dict__ {} >>> Foo.__dict__ {'__module__': '__main__', '_Foo__x': 1, '__doc__': None} !2005-07-28 Thu >>> class Foo: ... _x = 1 ... >>> f = Foo() >>> f._x 1 >>> class Foo: ... _Foo__x = 1 ... __x = 10 ... >>> f = Foo() >>> f._Foo__x 10 >>> class Foo: ... _Foo__x = 1 ... __x = 10 ... def foo(self): ... print _Foo__x ... print __x ... >>> f = Foo() >>> f.foo() Traceback (most recent call last): File "", line 1, in ? File "", line 5, in foo NameError: global name '_Foo__x' is not defined !2005-07-27 Wed >>> class Foo: ... def foo(self): ... print "foo" ... def __bar(self): ... print "bar" ... >>> f = Foo() >>> f.foo() foo >>> f.__bar() Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute '__bar' >>> f._Foo__bar() bar !2005-07-26 Tue メソッドの参照は以下のようにしてい解決されます 「い」が不要そう >>> class Foo: ... x = 1 ... __y = 10 ... >>> f = Foo() >>> f.x 1 >>> f.__y Traceback (most recent call last): File "", line 1, in ? AttributeError: Foo instance has no attribute '__y' >>> f._Foo__y 10 !2005-07-25 Mon まんま >>> class Bag: ... def __init__(self): ... self.data = [] ... def add(self, x): ... self.data.append(x) ... def addtwice(self, x): ... self.add(x) ... self.add(x) ... >>> x = Bag() >>> x.add(1) >>> x.addtwice(10) >>> x.data [1, 10, 10] !2005-07-24 Sun 結構、まんま >>> def f1(self, x, y): ... return min(x, x+y) ... >>> class C: ... f = f1 ... def g(self): ... return 'hello world' ... h = g ... >>> C.f(1,2) Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method f1() must be called with C instance as first argument (got int instance instead) >>> c = C() >>> c.f(1,2) 1 >>> c.g() 'hello world' >>> c.h() 'hello world' >>> C.h() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method g() must be called with C instance as first argument (got nothing instead) >>> C.h(c) 'hello world' >>> C.f(c,1,2) 1 !2005-07-23 Sat 結構、まんま >>> class MyClass: ... "A simple example class" ... i = 12345 ... def f(self): ... return 'hello world' ... >>> x = MyClass() >>> x.f() 'hello world' >>> xf = x.f >>> xf() 'hello world' >>> MyClass.f(x) 'hello world' >>> MyClass.f(1) Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method f() must be called with MyClass instance as first argument (got int instance instead) >>> x <__main__.MyClass instance at 0x401c6f8c> !2005-07-22 Fri 結構、まんま >>> class MyClass: ... "" ... >>> x = MyClass() >>> x.counter = 1 >>> while x.counter < 10: ... x.counter = x.counter * 2 ... >>> print x.counter 16 >>> del x.counter >>> print x.counter Traceback (most recent call last): File "", line 1, in ? AttributeError: MyClass instance has no attribute 'counter' !2005-07-21 Thu まんま >>> class Complex: ... def __init__(self, realpart, imagpart): ... self.r = realpart ... self.i = imagpart ... >>> x = Complex(3.0, -4.5) >>> x.r, x.i (3.0, -4.5) !2005-07-20 Wed まんま >>> class MyClass: ... "A simple example class" ... i = 12345 ... def f(self): ... return 'hello world' ... >>> MyClass.i 12345 >>> MyClass.f >>> MyClass.__doc__ 'A simple example class' !2005-07-19 Tue まんま >>> try: ... raise KeyboardInterrupt ... finally: ... print 'Goodbye, world!' ... Goodbye, world! Traceback (most recent call last): File "", line 2, in ? KeyboardInterrupt !2005-07-18 Mon まんま >>> class MyError(Exception): ... def __init__(self, value): ... self.value = value ... def __str__(self): ... return repr(self.value) ... >>> try: ... raise MyError(2*2) ... except MyError, e: ... print 'My exception occurred, value:', e.value ... My exception occurred, value: 4 !2005-07-17 Sun まんま >>> try: ... raise NameError, 'HiThere' ... except NameError: ... print 'An exception flew by!' ... raise ... An exception flew by! Traceback (most recent call last): File "", line 2, in ? NameError: HiThere !2005-07-16 Sat まんま >>> raise NameError, 'HiThere' Traceback (most recent call last): File "", line 1, in ? NameError: HiThere !2005-07-15 Fri まんま >>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError, detail: ... print 'Handling run-time error:', detail ... Handling run-time error: integer division or modulo by zero !2005-07-14 Thu まんま >>> try: ... raise Exception('spam', 'eggs') ... except Exception, inst: ... print type(inst) ... print inst.args ... print inst ... x, y = inst ... print 'x =', x ... print 'y =', y ... ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs !2005-07-13 Wed まんま import sys for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close() で、 $ python foo.py aaa cannot open aaa $ python foo.py foo.py foo.py has 11 lines !2005-07-12 Tue まんま >>> import sys >>> try: ... f = open('myfile.txt') ... s = f.readline() ... i = int(s.strip()) ... except IOError, (errno, strerror): ... print "I/O error(%s): %s" % (errno, strerror) ... except ValueError: ... print "Could not convert data to an integer." ... except: ... print "Unexpected error:", sys.exc_info()[0] ... raise ... I/O error(2): No such file or directory !2005-07-11 Mon まんま >>> while True: ... try: ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: ... print "Oops! That was no valid number. Try again..." ... Please enter a number: Traceback (most recent call last): File "", line 3, in ? KeyboardInterrupt >>> while True: ... try: ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: ... print "Oops! That was no valid number. Try again..." ... Please enter a number: a Oops! That was no valid number. Try again... Please enter a number: 1 !2005-07-10 Sun >>> import pickle >>> f = open('foo', 'w') >>> pickle.dump([1,2,3], f) >>> f.close() >>> f = open('foo', 'r') >>> f.readlines() ['(lp0\n', 'I1\n', 'aI2\n', 'aI3\n', 'a.'] >>> f.close() >>> f = open('foo', 'r') >>> x = pickle.load(f) >>> x [1, 2, 3] !2005-07-09 Sat まんま >>> f = open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) >>> f.read(1) '5' >>> f.seek(-3, 2) >>> f.read(1) 'd' すなわち 参照店としてファイルの先頭を使います。 「店」違っとります !2005-07-08 Fri けっこう、まんま >>> f = open('foo', 'w') >>> f.write('This is a test\n') >>> value = ('the answer', 42) >>> s = str(value) >>> f.write(s) >>> f.close() >>> f = open('foo', 'r') >>> f.readlines() ['This is a test\n', "('the answer', 42)"] !2005-07-07 Thu けっこう、まんま >>> f = open('foo', 'r') >>> f.read() 'a\nb\nc' >>> f.read() '' >>> f.read() '' >>> f = open('foo', 'r') >>> f.readline() 'a\n' >>> f.readline() 'b\n' >>> f.readline() 'c' >>> f.readline() '' >>> f.readline() '' >>> f = open('foo', 'r') >>> f.readlines() ['a\n', 'b\n', 'c'] >>> f.readlines() [] !2005-07-06 Wed まんま >>> f = open('/tmp/workfile', 'w') >>> print f !2005-07-05 Tue まんま >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table Jack: 4098; Sjoerd: 4127; Dcab: 8637678 !2005-07-04 Mon まんま >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for name, phone in table.items(): ... print '%-10s ==> %10d' % (name, phone) ... Dcab ==> 7678 Jack ==> 4098 Sjoerd ==> 4127 !2005-07-03 Sun まんま >>> import math >>> print 'The value of PI is approximately %5.3f.' % math.pi The value of PI is approximately 3.142. !2005-07-02 Sat ほぼ、まんま >>> '12'.zfill(5) '00012' >>> '-3.14'.zfill(7) '-003.14' >>> '3.14159265359'.zfill(5) '3.14159265359' >>> 'foo'.zfill(5) '00foo' !2005-07-01 Fri >>> repr(1).rjust(2) ' 1' >>> repr(1).ljust(2) '1 ' >>> repr(1).center(10) ' 1 ' !2005-06-30 Thu まんま >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 !2005-06-29 Wed まんま >>> for x in range(1, 11): ... print repr(x).rjust(2), repr(x*x).rjust(3), ... print repr(x*x*x).rjust(4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 !2005-06-28 Tue まんま >>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hello, world.'" >>> str(0.1) '0.1' >>> repr(0.1) '0.10000000000000001' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' >>> print s The value of x is 32.5, and y is 40000... >>> hello = 'hello, world\n' >>> hellos = repr(hello) >>> print hellos 'hello, world\n' >>> repr((x, y, ('spam', 'eggs'))) "(32.5, 40000, ('spam', 'eggs'))" >>> `x, y, ('spam', 'eggs')` "(32.5, 40000, ('spam', 'eggs'))" !2005-06-27 Mon まんま。2005-06-22 の fibo.py を使用 >>> a = [1, 2, 3, 4, 5] >>> import fibo, sys >>> fib = fibo.fib >>> dir() ['__builtins__', '__doc__', '__name__', 'a', 'fib', 'fibo', 'sys'] >>> import __builtin__ >>> dir(__builtin__) ['ArithmeticError', 'AssertionError', ... 'zip'] !2005-06-26 Sun まんま。2005-06-22 の fibo.py を使用 >>> import fibo, sys >>> dir(fibo) ['__builtins__', '__doc__', '__file__', '__name__', 'fib', 'fib2'] >>> dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 'version_info', 'warnoptions'] !2005-06-25 Sat >>> import sys >>> sys.path ['', '/usr/local/Python-2.3.4/lib/python23.zip', '/usr/local/Python-2.3.4/lib/python2.3', '/usr/local/Python-2.3.4/lib/python2.3/plat-linux2', '/usr/local/Python-2.3.4/lib/python2.3/lib-tk', '/usr/local/Python-2.3.4/lib/python2.3/lib-dynload', '/usr/local/Python-2.3.4/lib/python2.3/site-packages'] !2005-06-24 Fri まんま >>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' >>> sys.ps1 = 'C> ' C> print 'Yuck!' Yuck! !2005-06-23 Thu 昨日の fibo.py を使用 まんま >>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 >>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 import に ファイル名(モジュール名)が来たり、 関数名が来たりするから、ずーと混乱したままなのかなあ? * モジュールを import * 関数をモジュールから import と冷静に考えれば、なんら混乱すべきところはないか。 !2005-06-22 Wed まんま $ cat fibo.py def fib(n): # nまで加算されるフィボナッチ級数を印字 a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): # nまで加算されるフィボナッチ級数を返す result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result >>> import fibo >>> fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo' >>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 !2005-06-21 Tue まんま >>> (1, 2, 3) < (1, 2, 4) True >>> [1, 2, 3] < [1, 2, 4] True >>> 'ABC' < 'C' < 'Pascal' < 'Python' True >>> (1, 2, 3, 4) < (1, 2, 4) True >>> (1, 2) < (1, 2, -1) True >>> (1, 2, 3) == (1.0, 2.0, 3.0) True >>> (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) True >>> [1, 2, 3] < (1, 2, 3) True >>> [1, 2, 3] == (1, 2, 3) False !2005-06-20 Mon まんま >>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim' !2005-06-19 Sun まんま >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print 'What is your %s? It is %s.' % (q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue. !2005-06-18 Sat まんま >>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe Python にもあったのか。前から? !2005-06-17 Fri まんま >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.iteritems(): ... print k, v ... gallahad the pure robin the brave !2005-06-16 Thu まんま >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127} >>> vec = [2, 4, 6] >>> dict([(x, x**2) for x in vec]) {2: 4, 4: 16, 6: 36} !2005-06-15 Wed まんま >>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'sape': 4139, 'jack': 4098, 'guido': 4127} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'jack': 4098, 'irv': 4127, 'guido': 4127} >>> tel.keys() ['jack', 'irv', 'guido'] >>> tel.has_key('guido') True >>> tel.has_key('foo') False >>> tel['foo'] Traceback (most recent call last): File "", line 1, in ? KeyError: 'foo' !2005-06-14 Tue まんま >>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) >>> empty = () >>> singleton = 'hello', >>> len(empty) 0 >>> len(singleton) 1 >>> singleton ('hello',) >>> x, y, z = t >>> x 12345 >>> y 54321 >>> z 'hello!' !2005-06-13 Mon まんま >>> a = [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.599999999999994, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.599999999999994, 1234.5] >>> del a >>> a Traceback (most recent call last): File "", line 1, in ? NameError: name 'a' is not defined !2005-06-12 Sun まんま >>> freshfruit = [' banana', ' loganberry ', 'passion fruit '] >>> [weapon.strip() for weapon in freshfruit] ['banana', 'loganberry', 'passion fruit'] >>> vec = [2, 4, 6] >>> [3*x for x in vec] [6, 12, 18] >>> [3*x for x in vec if x > 3] [12, 18] >>> [3*x for x in vec if x < 2] [] >>> [[x,x**2] for x in vec] [[2, 4], [4, 16], [6, 36]] >>> [x, x**2 for x in vec] File "", line 1 [x, x**2 for x in vec] ^ SyntaxError: invalid syntax >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3] >>> [vec1[i]*vec2[i] for i in range(len(vec1))] [8, 12, -54] >>> [str(round(355/113.0, i)) for i in range(1, 6)] ['3.1', '3.14', '3.142', '3.1416', '3.14159'] >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3] >>> [vec1[i]*vec2[i] for i in range(len(vec1))] [8, 12, -54] >>> [str(round(355/113.0, i)) for i in range(1, 6)] ['3.1', '3.14', '3.142', '3.1416', '3.14159'] 使い慣れれば、便利そう !2005-06-11 Sat まんま >>> def sum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> sum(range(1, 11)) 55 >>> sum([]) 0 もとから sum があるらしい。 >>> sum(range(1, 11)) 55 >>> sum([]) 0 あっ、本当だ !2005-06-10 Fri まんま >>> def add(x,y): return x+y ... >>> reduce(add, range(1, 11)) 55 !2005-06-09 Thu まんま >>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] >>> seq = range(8) >>> def add(x, y): return x+y ... >>> map(add, seq, seq) [0, 2, 4, 6, 8, 10, 12, 14] !2005-06-08 Wed まんま >>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] おっ、これは便利そうだね >>> filter(lambda x: x % 2 != 0 and x % 3 != 0, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] !2005-06-07 Tue まんま >>> queue = ["Eric", "John", "Michael"] >>> queue.append("Terry") >>> queue.append("Graham") >>> queue.pop(0) 'Eric' >>> queue.pop(0) 'John' >>> queue ['Michael', 'Terry', 'Graham'] pop(0) とは !2005-06-06 Mon まんま >>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4] !2005-06-05 Sun まんま >>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.599999999999994, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.599999999999994, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.599999999999994] >>> a.sort() >>> a [-1, 1, 66.599999999999994, 333, 333, 1234.5] !2005-06-04 Sat まんま >>> def my_function(): ... """Do nothing, but document it. ... ... No, really, it doesn't do anything. ... """ ... pass ... >>> print my_function.__doc__ Do nothing, but document it. No, really, it doesn't do anything. えっ 最初の行は大文字で始まり、ピリオドで終わっていなければなりません。 知らなかった… >>> def my_function(): ... """do nothing, but document it.""" ... >>> print my_function.__doc__ do nothing, but document it. 推奨というだけか? !2005-06-03 Fri まんま >>> def make_incrementor(n): ... return lambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 43 !2005-06-02 Thu 「任意引数リスト」昨日の例で出てるな。とばし。 ほぼ、まんま >>> range(3, 6) [3, 4, 5] >>> args = [3, 6] >>> range(*args) [3, 4, 5] >>> *args File "", line 1 *args ^ SyntaxError: invalid syntax !2005-06-01 Wed まんま >>> def function(a): ... pass ... >>> function(0, a=0) Traceback (most recent call last): File "", line 1, in ? TypeError: function() got multiple values for keyword argument 'a' >>> def cheeseshop(kind, *arguments, **keywords): ... print "-- Do you have any", kind, '?' ... print "-- I'm sorry, we're all out of", kind ... for arg in arguments: print arg ... print '-'*40 ... keys = keywords.keys() ... keys.sort() ... for kw in keys: print kw, ':', keywords[kw] ... >>> cheeseshop('Limburger', "It's very runny, sir.", ... "It's really very, VERY runny, sir.", ... client='John Cleese', ... shopkeeper='Michael Palin', ... sketch='Cheese Shop Sketch') -- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch !2005-05-31 Tue まんま >>> def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): ... print "-- This parrot wouldn't", action, ... print "if you put", voltage, "Volts through it." ... print "-- Lovely plumage, the", type ... print "-- It's", state, "!" ... >>> parrot(1000) -- This parrot wouldn't voom if you put 1000 Volts through it. -- Lovely plumage, the Norwegian Blue -- It's a stiff ! >>> parrot(action = 'VOOOOOM', voltage = 1000000) -- This parrot wouldn't VOOOOOM if you put 1000000 Volts through it. -- Lovely plumage, the Norwegian Blue -- It's a stiff ! >>> parrot('a thousand', state = 'pushing up the daisies') -- This parrot wouldn't voom if you put a thousand Volts through it. -- Lovely plumage, the Norwegian Blue -- It's pushing up the daisies ! >>> parrot('a million', 'bereft of life', 'jump') -- This parrot wouldn't jump if you put a million Volts through it. -- Lovely plumage, the Norwegian Blue -- It's bereft of life ! >>> parrot() Traceback (most recent call last): File "", line 1, in ? TypeError: parrot() takes at least 1 argument (0 given) >>> parrot(voltage=5.0, 'dead') SyntaxError: non-keyword arg after keyword arg >>> parrot(110, voltage=220) Traceback (most recent call last): File "", line 1, in ? TypeError: parrot() got multiple values for keyword argument 'voltage' >>> parrot(actor='John Cleese') Traceback (most recent call last): File "", line 1, in ? TypeError: parrot() got an unexpected keyword argument 'actor' !2005-05-30 Mon まんま >>> def f(a, L=[]): ... L.append(a) ... return L ... >>> print f(1) [1] >>> print f(2) [1, 2] >>> print f(3) [1, 2, 3] >>> def f(a, L=None): ... if L is None: ... L = [] ... L.append(a) ... return L ... >>> print f(1) [1] >>> print f(2) [2] >>> print f(3) [3] チュートリアルで、こんな細かいことまでちゃんと書いてあるんだ。素晴らしい! !2005-05-29 Sun まんま >>> i = 5 >>> def f(arg=i): ... print arg ... >>> i = 6 >>> f() 5 !2005-05-28 Sat まんま >>> def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): ... while True: ... ok = raw_input(prompt) ... if ok in ('y', 'ye', 'yes'): return True ... if ok in ('n', 'no', 'nop', 'nope'): return False ... retries = retries - 1 ... if retries < 0: raise IOError, 'refusenik user' ... print complaint ... >>> ask_ok('Do you really want to quit?') Do you really want to quit?n False >>> ask_ok('OK to overwrite the file?', 2) OK to overwrite the file? Yes or no, please! OK to overwrite the file? Yes or no, please! OK to overwrite the file? Traceback (most recent call last): File "", line 1, in ? File "", line 7, in ask_ok IOError: refusenik user そういえば、raw_input と input って何が違うんだろう? !2005-05-27 Fri まんま >>> def fib2(n): ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = 0, 1 ... while b < n: ... result.append(b) ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) >>> f100 [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] !2005-05-26 Thu まんま >>> def fib(n): ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 ... while b < n: ... print b, ... a, b = b, a+b ... >>> fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 自分が書くコードにドキュメンテーション 文字列を入れるのはよい習慣です。 書く癖をつけるようにしてください。 チュートリアルで、ちゃんとしつけをするということか。 >>> fib >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89 >>> print fib(0) None !2005-05-25 Wed まんま >>> while True: ... pass ... Traceback (most recent call last): File "", line 1, in ? KeyboardInterrupt !2005-05-24 Tue まんま >>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, 'equals', x, '*', n/x ... break ... else: ... print n, 'is a prime number' ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3 !2005-05-23 Mon まんま >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): ... print i, a[i] ... 0 Mary 1 had 2 a 3 little 4 lamb !2005-05-22 Sun まんま >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range(5, 10) [5, 6, 7, 8, 9] >>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70] !2005-05-21 Sat まんま a = ['cat', 'window', 'defenestrate'] >>> for x in a[:]: ... if len(x) > 6: a.insert(0, x) ... >>> a ['defenestrate', 'cat', 'window', 'defenestrate'] こうすると、 >>> a = ['cat', 'window', 'defenestrate'] >>> for x in a: ... if len(x) > 6: a.insert(0, x) ... 戻ってこない…。確かに安全じゃない !2005-05-20 Fri まんま >>> a = ['cat', 'window', 'defenestrate'] >>> for x in a: ... print x, len(x) ... cat 3 window 6 defenestrate 12 !2005-05-19 Thu まんま >>> x = int(raw_input("Please enter an integer: ")) Please enter an integer: 1 >>> if x < 0: ... x = 0 ... print 'Negative changed to zero' ... elif x == 0: ... print 'Zero' ... elif x == 1: ... print 'Single' ... else: ... print 'More' ... Single !2005-05-18 Wed まんま >>> i = 256*256 >>> print 'The value of i is', i The value of i is 65536 !2005-05-17 Tue まんま >>> a, b = 0, 1 >>> while b < 10: ... print b ... a, b = b, a+b ... 1 1 2 3 5 8 !2005-05-16 Mon まんま >>> q = [2, 3] >>> p = [1, q, 4] >>> len(p) 3 >>> p[1] [2, 3] >>> p[1][0] 2 >>> p[1].append('xtra') >>> p [1, [2, 3, 'xtra'], 4] >>> q [2, 3, 'xtra'] !2005-05-15 Sun まんま >>> a = ['spam', 'eggs', 100, 1234] >>> a ['spam', 'eggs', 100, 1234] >>> a[0] 'spam' >>> a[3] 1234 >>> a[-2] 100 >>> a[1:-1] ['eggs', 100] >>> a[:2] + ['bacon', 2*2] ['spam', 'eggs', 'bacon', 4] >>> 3*a[:3] + ['Boe!'] ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!'] >>> a ['spam', 'eggs', 100, 1234] >>> a[2] = a[2] + 23 >>> a ['spam', 'eggs', 123, 1234] >>> a[0:2] = [1, 12] >>> a [1, 12, 123, 1234] >>> a[0:2] = [] >>> a [123, 1234] >>> a[1:1] = ['bletch', 'xyzzy'] >>> a [123, 'bletch', 'xyzzy', 1234] >>> a[:0] = a >>> a [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234] >>> len(a) 8 !2005-05-14 Sat まんま >>> u"abc" u'abc' >>> u"あいう" u'\xa4\xa2\xa4\xa4\xa4\xa6' >>> str(u"あいう") Traceback (most recent call last): File "", line 1, in ? UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128) >>> u"あいう".encode('utf-8') '\xc2\xa4\xc2\xa2\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa6' >>> unicode('\xc2\x82\xc2\xa0\xc2\x82\xc2\xa2\xc2\x82\xc2\xa4', 'utf-8') u'\x82\xa0\x82\xa2\x82\xa4' !2005-05-13 Fri まんま >>> u'Hello World !' u'Hello World !' >>> u'Hello\u0020World !' u'Hello World !' >>> ur'Hello\u0020World !' u'Hello World !' >>> ur'Hello\\u0020World !' u'Hello\\\\u0020World !' !2005-05-12 Thu まんま >>> s = 'supercalifragilisticexpialidocious' >>> len(s) 34 !2005-05-11 Wed まんま >>> word = 'Help' + 'A' >>> word[0] = 'x' Traceback (most recent call last): File "", line 1, in ? TypeError: object doesn't support item assignment >>> word[:1] = 'Splat' Traceback (most recent call last): File "", line 1, in ? TypeError: object doesn't support slice assignment >>> 'x' + word[1:] 'xelpA' >>> 'Splat' + word[4] 'SplatA' >>> word[:2] + word[2:] 'HelpA' >>> word[:3] + word[3:] 'HelpA' >>> word[1:100] 'elpA' >>> word[10:] '' >>> word[2:1] '' >>> word[-1] 'A' >>> word[-2] 'p' >>> word[-2:] 'pA' >>> word[:-2] 'Hel' >>> word[-0] 'H' >>> word[-100:] 'HelpA' >>> word[-10] Traceback (most recent call last): File "", line 1, in ? IndexError: string index out of range !2005-05-10 Tue まんま >>> word = 'Help' + 'A' >>> word[4] 'A' >>> word[0:2] 'He' >>> word[2:4] 'lp' >>> word[:2] 'He' >>> word[2:] 'lpA' !2005-05-09 Mon まんま >>> 'str' 'ing' 'string' >>> 'str'.strip() + 'ing' 'string' >>> 'str'.strip() 'ing' File "", line 1 'str'.strip() 'ing' ^ SyntaxError: invalid syntax へ〜、できるんだ。python らしくないけど !2005-05-08 Sun まんま >>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '' !2005-05-07 Sat まんま >>> print """ ... Usage: thingy [OPTIONS] ... -h Display this usage message ... -H hostname Hostname to connect to ... """ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to !2005-05-06 Fri まんま >>> hello = r"This is a rather long string containing\n\ ... several lines of text much as you would do in C." >>> print hello This is a rather long string containing\n\ several lines of text much as you would do in C. !2005-05-05 Thu まんま >>> hello = "This is a rather long string containing\n\ ... several lines of text just as you would do in C.\n\ ... Note that whitespace at the beginning of the line is\ ... significant." >>> print hello This is a rather long string containing several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant. !2005-05-04 Wed まんま >>> 'spam eggs' 'spam eggs' >>> 'doesn\'t' "doesn't" >>> "doesn't" "doesn't" >>> '"Yes," he said.' '"Yes," he said.' >>> "\"Yes,\" he said." '"Yes," he said.' >>> '"Isn\'t," she said.' '"Isn\'t," she said.' !2005-05-03 Tue まんま >>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round(_, 2) 113.06 ふーん、_ !2005-05-02 Mon まんま >>> a=3.0+4.0j >>> float(a) Traceback (most recent call last): File "", line 1, in ? TypeError: can't convert complex to float; use abs(z) >>> a.real 3.0 >>> a.imag 4.0 >>> abs(a) 5.0 !2005-05-01 Sun まんま >>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5 !2005-04-30 Sat まんま >>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) (-1+0j) >>> 3+1j*3 (3+3j) >>> (3+1j)*3 (9+3j) >>> (1+2j)/(1+1j) (1.5+0.5j) !2005-04-29 Fri $ python -c "import sys; print sys.argv[0]" -c >>> import sys >>> print sys.argv[0] !2005-04-28 Thu 気分を変えて、チュートリアルを読もう $ python -c "print 'foo'" foo !2005-04-27 Wed bar ディレクトリは、空。 foo ディレクトリは、foo/hoge hoge あり。 >>> import filecmp >>> dc = filecmp.dircmp("foo", "bar") >>> dc.report_partial_closure() diff foo bar Only in foo : ['foo', 'hoge'] >>> dc.report_full_closure() diff foo bar Only in foo : ['foo', 'hoge'] どういう動作するの? !2005-04-26 Tue foo ディレクトリに CVS ディレクトリを作ってみた >>> import filecmp >>> dc = filecmp.dircmp("foo", "bar") >>> dc.report() diff foo bar >>> dc = filecmp.dircmp("foo", "bar", []) >>> dc.report() diff foo bar Only in foo : ['CVS'] !2005-04-25 Mon foo と bar ディレクトリを作って、foo ディレクトリに hoge ファイルを touch >>> import filecmp >>> dc = filecmp.dircmp("foo", "bar") >>> dc.report() diff foo bar Only in foo : ['hoge'] bar にも hoge (内容違う)を作ってみた >>> dc = filecmp.dircmp("foo", "bar") >>> dc.report() diff foo bar Differing files : ['hoge'] dircmp を new したときの状態を見るようだ bar の hoge を foo の hoge と同じにしてみた >>> dc = filecmp.dircmp("foo", "bar") >>> dc.report() diff foo bar Identical files : ['hoge'] !2005-04-24 Sun >>> import filecmp >>> filecmp.cmpfiles('tmp', 'tmp', []) ([], [], []) 動作不明 !2005-04-23 Sat >>> import filecmp >>> filecmp.cmp('.emacs', '.emacs') True ファイルが同じだと中身の比較はやらないよう >>> filecmp.cmp('.emacs', '.emacs~') False !2005-04-22 Fri >>> import pydoc >>> dir(pydoc) ['Doc', 'ErrorDuringImport', 'HTMLDoc', 'HTMLRepr', 'Helper', 'ModuleScanner', 'Repr', 'Scanner', 'TextDoc', 'TextRepr', '__author__', '__builtin__', '__builtins__', '__credits__', '__date__', '__doc__', '__file__', '__name__', '__version__', '_is_some_method', '_split_list', 'allmethods', 'apropos', 'classname', 'cli', 'cram', 'describe', 'doc', 'expandtabs', 'find', 'getdoc', 'getpager', 'gui', 'help', 'html', 'imp', 'importfile', 'inspect', 'isdata', 'ispackage', 'ispath', 'join', 'locate', 'lower', 'os', 'pager', 'pathdirs', 'pipepager', 'plain', 'plainpager', 're', 'replace', 'resolve', 'rfind', 'rstrip', 'safeimport', 'serve', 'split', 'splitdoc', 'strip', 'stripid', 'synopsis', 'sys', 'tempfilepager', 'text', 'ttypager', 'types', 'visiblename', 'writedoc', 'writedocs'] >>> pydoc.help Welcome to Python 2.3! This is the online help utility. If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://www.python.org/doc/tut/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type "quit". To get a list of available modules, keywords, or topics, type "modules", "keywords", or "topics". Each module also comes with a one-line summary of what it does; to list the modules whose summaries contain a given word such as "spam", type "modules spam". help> sys Help on built-in module sys: NAME sys FILE ... help> quit You are now leaving help and returning to the Python interpreter. If you want to ask for help on a particular object directly from the interpreter, you can type "help(object)". Executing "help('string')" has the same effect as typing a particular string at the help> prompt. >>> 詳細は分からないが、何か便利そうではある !2005-04-21 Thu >>> import __future__ >>> __future__ >>> dir(__future__) ['CO_FUTURE_DIVISION', 'CO_GENERATOR_ALLOWED', 'CO_NESTED', '_Feature', '__all__', '__builtins__', '__doc__', '__file__', '__name__', 'all_feature_names', 'division', 'generators', 'nested_scopes'] >>> __future__.CO_FUTURE_DIVISION 8192 >>> __future__.CO_GENERATOR_ALLOWED 4096 >>> __future__.CO_NESTED 16 >>> __future__._Feature >>> __future__.__all__ ['all_feature_names', 'nested_scopes', 'generators', 'division'] >>> __future__.all_feature_names ['nested_scopes', 'generators', 'division'] >>> __future__.nested_scopes _Feature((2, 1, 0, 'beta', 1), (2, 2, 0, 'alpha', 0), 16) >>> __future__.generators _Feature((2, 2, 0, 'alpha', 1), (2, 3, 0, 'final', 0), 4096) >>> __future__.division _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) 「_Feature クラスのインスタンス」ってどうやって作るんだっけ? !2005-04-20 Wed >>> __name__ '__main__' >>> __main__ Traceback (most recent call last): File "", line 1, in ? NameError: name '__main__' is not defined >>> import __main__ >>> __main__ >>> dir(__main__) ['__builtins__', '__doc__', '__main__', '__name__'] if __name__ == "__main__": との関連が良く分からない… !2005-04-19 Tue >>> __builtin__ Traceback (most recent call last): File "", line 1, in ? NameError: name '__builtin__' is not defined >>> import __builtin__ >>> __builtin__ >>> __builtin__.abs(-1) 1 Jython (とか)用??? !2005-04-18 Mon まんま >>> import dl, time >>> a=dl.open('/lib/libc.so.6') >>> a.call('time'), time.time() (1114592127, 1114592127.8314941) !2005-04-17 Sun まんま >>> import difflib >>> text1 = ''' 1. Beautiful is better than ugly. ... 2. Explicit is better than implicit. ... 3. Simple is better than complex. ... 4. Complex is better than complicated. ... '''.splitlines(1) >>> len(text1) 4 >>> text1[0][-1] '\n' >>> text2 = ''' 1. Beautiful is better than ugly. ... 3. Simple is better than complex. ... 4. Complicated is better than complex. ... 5. Flat is better than nested. ... '''.splitlines(1) >>> d = difflib.Differ() >>> result = list(d.compare(text1, text2)) >>> from pprint import pprint >>> pprint(result) [' 1. Beautiful is better than ugly.\n', '- 2. Explicit is better than implicit.\n', '- 3. Simple is better than complex.\n', '+ 3. Simple is better than complex.\n', '? ++\n', '- 4. Complex is better than complicated.\n', '? ^ ---- ^\n', '+ 4. Complicated is better than complex.\n', '? ++++ ^ ^\n', '+ 5. Flat is better than nested.\n'] >>> import sys >>> sys.stdout.writelines(result) 1. Beautiful is better than ugly. - 2. Explicit is better than implicit. - 3. Simple is better than complex. + 3. Simple is better than complex. ? ++ - 4. Complex is better than complicated. ? ^ ---- ^ + 4. Complicated is better than complex. ? ++++ ^ ^ + 5. Flat is better than nested. !2005-04-16 Sat まんま >>> import difflib >>> s = difflib.SequenceMatcher(lambda x: x == " ", ... "private Thread currentThread;", ... "private volatile Thread currentThread;") >>> print round(s.ratio(), 3) 0.866 >>> for block in s.get_matching_blocks(): ... print "a[%d] and b[%d] match for %d elements" % block ... a[0] and b[0] match for 8 elements a[8] and b[17] match for 6 elements a[14] and b[23] match for 15 elements a[29] and b[38] match for 0 elements >>> for opcode in s.get_opcodes(): ... print "%6s a[%d:%d] b[%d:%d]" % opcode ... equal a[0:8] b[0:8] insert a[8:8] b[8:17] equal a[8:14] b[17:23] equal a[14:29] b[23:38] なぜか元の英語が残ったまま。消し忘れ? !2005-04-15 Fri まんま >>> import difflib >>> s = difflib.SequenceMatcher(None, "abcd", "bcde") >>> s.ratio() 0.75 >>> s.quick_ratio() 0.75 >>> s.real_quick_ratio() 1.0 !2005-04-14 Thu >>> import difflib >>> s = difflib.SequenceMatcher(None, "aaa", "aaabbb") >>> s.quick_ratio() 0.66666666666666663 !2005-04-13 Wed >>> import difflib >>> s = difflib.SequenceMatcher(None, "aaa", "aaa") >>> s.ratio() 1.0 >>> s = difflib.SequenceMatcher(None, "aaa", "aaabbb") >>> s.ratio() 0.66666666666666663 >>> s = difflib.SequenceMatcher(None, "aaa", "bbb") >>> s.ratio() 0.0 !2005-04-12 Tue >>> import difflib >>> a = "qabxcd" >>> b = "abycdf" >>> s = difflib.SequenceMatcher(None, a, b) >>> i = s.get_grouped_opcodes(7) >>> i.next() [('delete', 0, 1, 0, 0), ('equal', 1, 3, 0, 2), ('replace', 3, 4, 2, 3), ('equal', 4, 6, 3, 5), ('insert', 6, 6, 5, 6)] >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2005-04-11 Mon まんま >>> import difflib >>> a = "qabxcd" >>> b = "abycdf" >>> s = difflib.SequenceMatcher(None, a, b) >>> for tag, i1, i2, j1, j2 in s.get_opcodes(): ... print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" % ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2])) ... delete a[0:1] (q) b[0:0] () equal a[1:3] (ab) b[0:2] (ab) replace a[3:4] (x) b[2:3] (y) equal a[4:6] (cd) b[3:5] (cd) insert a[6:6] () b[5:6] (f) !2005-04-10 Sun まんま >>> import difflib >>> s = difflib.SequenceMatcher(None, "abxcd", "abcd") >>> s.get_matching_blocks() [(0, 0, 2), (3, 2, 2), (5, 4, 0)] !2005-04-09 Sat >>> import difflib >>> s = difflib.SequenceMatcher(None, " abcd", "abcd abcd") >>> s.find_longest_match(0, 4, 0, 9) (0, 4, 4) !2005-04-08 Fri まんま >>> import difflib >>> s = difflib.SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) (1, 0, 4) !2005-04-07 Thu >>> import difflib >>> s = difflib.SequenceMatcher() >>> s.set_seq1(" abcd") >>> s.set_seq2("abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) (0, 4, 5) !2005-04-06 Wed >>> import difflib >>> s = difflib.SequenceMatcher() >>> s.set_seqs(" abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) (0, 4, 5) !2005-04-05 Tue >>> import difflib >>> difflib.IS_CHARACTER_JUNK("") True >>> difflib.IS_CHARACTER_JUNK(" ") True >>> difflib.IS_CHARACTER_JUNK("\n") False >>> difflib.IS_CHARACTER_JUNK("\t") True >>> difflib.IS_CHARACTER_JUNK("\t\f") False >>> difflib.IS_CHARACTER_JUNK("\f") False !2005-04-04 Mon >>> import difflib >>> difflib.IS_LINE_JUNK(" ") True >>> difflib.IS_LINE_JUNK("a") False >>> difflib.IS_LINE_JUNK("#") True >>> difflib.IS_LINE_JUNK("//") False !2005-04-03 Sun >>> import difflib >>> i = difflib.unified_diff("aaa", "aaab") >>> i.next() '--- \n' >>> i.next() '+++ \n' >>> i.next() '@@ -1,3 +1,4 @@\n' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() '+b' >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2005-04-02 Sat まんま >>> import difflib >>> diff = difflib.ndiff('one\ntwo\nthree\n'.splitlines(1), ... 'ore\ntree\nemu\n'.splitlines(1)) >>> diff = list(diff) >>> print ''.join(difflib.restore(diff, 1)), one two three >>> print ''.join(difflib.restore(diff, 2)), ore tree emu !2005-04-01 Fri まんま >>> import difflib >>> diff = difflib.ndiff('one\ntwo\nthree\n'.splitlines(1), 'ore\ntree\nemu\n'.splitlines(1)) >>> print ''.join(diff), - one ? ^ + ore ? ^ - two - three ? - + tree + emu !2005-03-31 Thu 途中まで、まんま >>> import difflib >>> difflib.get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy']) ['apple', 'ape'] >>> import keyword >>> difflib.get_close_matches('wheel', keyword.kwlist) ['while'] >>> difflib.get_close_matches('apple', keyword.kwlist) [] >>> difflib.get_close_matches('accept', keyword.kwlist) ['except'] >>> difflib.get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'], 1) ['apple'] >>> difflib.get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'], 2) ['apple', 'ape'] !2005-03-30 Wed >>> import difflib >>> i = difflib.context_diff("aaa", "aaa\nbbb") >>> i.next() '*** \n' >>> i.next() '--- \n' >>> i.next() '***************\n' >>> i.next() '*** 1,3 ****\n' >>> i.next() '--- 1,7 ----\n' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() '+ \n' >>> i.next() '+ b' >>> i.next() '+ b' >>> i.next() '+ b' >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2005-03-29 Tue >>> import difflib >>> difflib.context_diff("aaa", "aaa") >>> i = difflib.context_diff("aaa", "aaa") >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i = difflib.context_diff("aaa", "aaab") >>> i.next() '*** \n' >>> i.next() '--- \n' >>> i.next() '***************\n' >>> i.next() '*** 1,3 ****\n' >>> i.next() '--- 1,4 ----\n' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() ' a' >>> i.next() '+ b' >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2005-03-28 Mon >>> import zlib >>> zlib.decompressobj().unused_data '' >>> zlib.decompressobj().unconsumed_tail '' >>> zlib.decompressobj().decompress('x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E') 'foo' >>> zlib.decompressobj().unused_data '' >>> zlib.decompressobj().unconsumed_tail '' >>> zlib.decompressobj().flush() セグメンテーション違反です はにゃ? !2005-03-27 Sun >>> import zlib >>> zlib.compressobj().compress("foo") 'x\x9c' >>> zlib.compressobj().flush() 'x\x9c\x03\x00\x00\x00\x00\x01' >>> zlib.compressobj().flush() 'x\x9c\x03\x00\x00\x00\x00\x01' !2005-03-26 Sat >>> import zlib >>> zlib.decompressobj() !2005-03-25 Fri >>> import zlib >>> zlib.decompress('x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E') 'foo' >>> zlib.decompress('x\x00\x9cK\xcb\xcf\x07\x00\x02\x82\x01E') Traceback (most recent call last): File "", line 1, in ? zlib.error: Error -3 while decompressing data: incorrect header check !2005-03-24 Thu >>> import zlib >>> zlib.crc32("foo") -1938594527 !2005-03-23 Wed >>> import zlib >>> zlib.compressobj() 何に使うんだ? >>> zlib.compressobj().compress("foo") 'x\x9c' >>> zlib.compressobj(9).compress("foo") 'x\xda' >>> zlib.compressobj().compress("foo") 'x\x9c' ? !2005-03-22 Tue >>> import zlib >>> zlib.compress("foo") 'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' !2005-03-21 Mon >>> import zlib >>> zlib.adler32("foo") 42074437 !2005-03-20 Sun >>> import getpass >>> getpass.getpass() Password: '' >>> getpass.getpass() Password: 'aaa' >>> getpass.getpass('Please Input:') Please Input: '' >>> getpass.getuser() 'nnakamur' !2005-03-19 Sat フラグメント指定子ってなんだ? >>> import urlparse >>> urlparse.urldefrag('http://www.cwi.nl/%7Eguido/Python.html') ('http://www.cwi.nl/%7Eguido/Python.html', '') !2005-03-18 Fri まんま >>> import urlparse >>> urlparse.urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html') 'http://www.cwi.nl/%7Eguido/FAQ.html' ぶっちゃけ、この関数は マニュアルで、「ぶっちゃけ」ないで (^_^; !2005-03-17 Thu >>> import urlparse >>> urlparse.urlunsplit(urlparse.urlsplit('http://www.cwi.nl:80/%7Eguido/Python.html')) 'http://www.cwi.nl:80/%7Eguido/Python.html' !2005-03-16 Wed >>> import urlparse >>> urlparse.urlsplit('http://www.cwi.nl:80/%7Eguido/Python.html') ('http', 'www.cwi.nl:80', '/%7Eguido/Python.html', '', '') >>> urlparse.urlsplit('http://jp.rubyist.net/magazine/?0005') ('http', 'jp.rubyist.net', '/magazine/', '0005', '') >>> urlparse.urlsplit('http://raa.ruby-lang.org/owner.rhtml?id=1381') ('http', 'raa.ruby-lang.org', '/owner.rhtml', 'id=1381', '') !2005-03-15 Tue >>> import urlparse >>> urlparse.urlunparse(('http', 'www.foo.org', '')) ... def urlunparse((scheme, netloc, url, params, query, fragment)): ValueError: unpack tuple of wrong size >>> urlparse.urlunparse(('http', 'www.foo.org', '', '', '', '')) 'http://www.foo.org' !2005-03-14 Mon >>> import urlparse >>> urlparse.urlparse('http://www.cwi.nl:80/%7Eguido/Python.html') ('http', 'www.cwi.nl:80', '/%7Eguido/Python.html', '', '', '') >>> urlparse.urlparse('http://jp.rubyist.net/magazine/?0005') ('http', 'jp.rubyist.net', '/magazine/', '', '0005', '') >>> urlparse.urlparse('http://raa.ruby-lang.org/owner.rhtml?id=1381') ('http', 'raa.ruby-lang.org', '/owner.rhtml', '', 'id=1381', '') >>> urlparse.urlparse('http://www.foo.org/?bar=1?boo=2') ('http', 'www.foo.org', '/', '', 'bar=1?boo=2', '') >>> urlparse.urlparse('http://www.foo.org/?bar=1&boo=2') ('http', 'www.foo.org', '/', '', 'bar=1&boo=2', '') !2005-03-13 Sun >>> import fnmatch >>> fnmatch.fnmatch('.emacs', ".em*") True >>> fnmatch.fnmatch('.emacs', ".EM*") False >>> fnmatch.filter(['.emacs', 'foo', '.emacs~'], ".ema*") ['.emacs', '.emacs~'] >>> fnmatch.fnmatch('~/.emacs', ".em*") False >>> fnmatch.fnmatch('~/.emacs', "~/.em*") True >>> fnmatch.fnmatch('~/.emacs', "$HOME/.em*") False !2005-03-12 Sat >>> import glob >>> glob.glob('.emacs*') ['.emacs', '.emacs~'] >>> glob.glob('~/.emacs*') [] >>> glob.glob(os.path.expandvars('~/.emacs*')) [] >>> glob.glob(os.path.expanduser('~/.emacs*')) ['/home/nnakamur/.emacs', '/home/nnakamur/.emacs~'] os.path.expantion() なんてないと怒られたぞ !2005-03-11 Fri >>> import getopt >>> args = '-a -b -cfoo a1 -d bar a2 a3'.split() >>> optlist, args = getopt.getopt(args, 'abc:d:') >>> optlist [('-a', ''), ('-b', ''), ('-c', 'foo')] >>> args ['a1', '-d', 'bar', 'a2', 'a3'] >>> optlist, args = getopt.gnu_getopt(args, 'abc:d:') >>> optlist [('-d', 'bar')] >>> args ['a1', 'a2', 'a3'] !2005-03-10 Thu >>> import getopt >>> args = '-a -b -cfoo -d bar a1 a2'.split() >>> optlist, args = getopt.getopt(args, 'abc:') ... getopt.GetoptError: option -d not recognized !2005-03-09 Wed まんま >>> import getopt >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' >>> args = s.split() >>> optlist, args = getopt.getopt(args, 'x', [ ... 'condition=', 'output-file=', 'testing']) >>> optlist [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] >>> args ['a1', 'a2'] !2005-03-08 Tue まんま >>> import getopt >>> args = '-a -b -cfoo -d bar a1 a2'.split() >>> optlist, args = getopt.getopt(args, 'abc:d:') >>> optlist [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] >>> args ['a1', 'a2'] !2005-03-07 Mon >>> import os >>> os.curdir '.' >>> os.pardir '..' >>> os.sep '/' >>> os.altsep >>> print os.altsep None >>> os.extsep '.' >>> os.pathsep ':' >>> os.defpath ':/bin:/usr/bin' >>> os.linesep '\n' !2005-03-06 Sun >>> import os >>> os.confstr('Unix95') Traceback (most recent call last): File "", line 1, in ? ValueError: unrecognized configuration name >>> os.confstr_names {'CS_XBS5_LP64_OFF64_CFLAGS': 1108, 'CS_LFS64_CFLAGS': 1004, 'CS_XBS5_LPBIG_OFFBIG_LIBS': 1114, 'CS_XBS5_ILP32_OFFBIG_LINTFLAGS': 1107, 'CS_XBS5_ILP32_OFF32_LIBS': 1102, 'CS_XBS5_ILP32_OFF32_LINTFLAGS': 1103, 'CS_LFS64_LIBS': 1006, 'CS_XBS5_ILP32_OFF32_CFLAGS': 1100, 'CS_XBS5_I ... ? !2005-03-05 Sat 「6.1.5 プロセス管理」だいたいとばし >>> import os >>> os.times() (0.17999999999999999, 0.070000000000000007, 0.0, 0.0, 12685.469999999999) !2005-03-04 Fri >>> import os >>> os.abort() Abort !2005-03-03 Thu >>> import os >>> os.walk('tmp/tmp') >>> w = os.walk('tmp/tmp') >>> w.next() ('tmp/tmp', [], ['HelloWorld.class', 'HelloWorld.html', 'HelloWorld.java', 'ShowUnicode.class', 'ShowUnicode.html', 'ShowUnicode.java', 'ShowUnicodeFrame.class', 'HelloWorld.java~', 'DateTest.java', 'ColorFrame.java', 'DateTest.java~', 'ColorFrame.class']) >>> w.next() Traceback (most recent call last): File "", line 1, in ? StopIteration os.path にも walk あったよね !2005-03-02 Wed >>> import os >>> import os.path >>> import time >>> time.gmtime(os.path.getatime('foo')) (2005, 3, 6, 12, 35, 36, 6, 65, 0) >>> os.utime('foo', None) >>> time.gmtime(os.path.getatime('foo')) (2005, 3, 6, 12, 37, 7, 6, 65, 0) >>> os.utime('foo', (1110112600, 1110112600)) >>> time.gmtime(os.path.getatime('foo')) (2005, 3, 6, 12, 36, 40, 6, 65, 0) !2005-03-01 Tue >>> import os >>> os.unlink('foo') >>> os.unlink('foo') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory: 'foo' !2005-02-28 Mon >>> import os >>> os.TMP_MAX 238328 !2005-02-27 Sun >>> import os >>> os.tmpnam() __main__:1: RuntimeWarning: tmpnam is a potential security risk to your program '/tmp/filedAjwpo' tempnam() と tmpnam() の(引数以外の)違い不明 !2005-02-26 Sat >>> import os >>> os.tempnam() __main__:1: RuntimeWarning: tempnam is a potential security risk to your program '/tmp/fileC5BwSf' >>> os.tempnam() '/tmp/fileQniubV' >>> os.tempnam('.') './fileBo3m5U' >>> os.tempnam('.', 'boo') './boonnVaLW' なぜ name でなく nam ? !2005-02-25 Fri statvfs() とばし >>> import os >>> os.symlink('.emacs', 'fff') !2005-02-24 Thu stat は既に使っているようなのでとばし >>> import os >>> os.stat('.emacs') (33188, 2236L, 2086L, 1, 501, 100, 183L, 1104655852, 978075702, 1109493469) >>> os.stat_float_times() False >>> os.stat('.emacs') (33188, 2236L, 2086L, 1, 501, 100, 183L, 1104655852, 978075702, 1109493469) >>> os.stat_float_times(True) >>> os.stat('.emacs') (33188, 2236L, 2086L, 1, 501, 100, 183L, 1104655852, 978075702, 1109493469) >>> os.stat_float_times() True む? !2005-02-23 Wed >>> import os >>> os.makedirs('f/f') >>> os.rmdir('f/f') >>> os.rmdir('f') >>> os.makedirs('f/f') >>> os.rmdir('f') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 39] Directory not empty: 'f' 再帰的には消せない !2005-02-22 Tue >>> import os >>> os.renames('bar', 'foo') 全然、再帰させていないけど… !2005-02-21 Mon >>> import os >>> os.rename('foo', 'bar') >>> os.rename('foo', 'bar') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory !2005-02-20 Sun >>> import os >>> os.makedirs('f/f') >>> os.removedirs('f/f') !2005-02-19 Sat $ touch foo >>> import os >>> os.remove('foo') >>> os.remove('foo') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory: 'foo' >>> os.mkdir('foo') >>> os.remove('foo') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 21] Is a directory: 'foo' !2005-02-18 Fri >>> import os >>> os.readlink('/usr/bin/vi') '/etc/alternatives/vi' !2005-02-17 Thu >>> import os >>> os.pathconf_names {'PC_MAX_INPUT': 2, 'PC_VDISABLE': 8, 'PC_SYNC_IO': 9, 'PC_SOCK_MAXBUF': 12, 'PC_NAME_MAX': 3, 'PC_MAX_CANON': 1, 'PC_PRIO_IO': 11, 'PC_CHOWN_RESTRICTED': 6, 'PC_ASYNC_IO': 10, 'PC_NO_TRUNC': 7, 'PC_FILESIZEBITS': 13, 'PC_LINK_MAX': 0, 'PC_PIPE_BUF': 5, 'PC_PATH_MAX': 4} >>> os.pathconf('foo', 'PC_CHOWN_RESTRICTED') 1 ? !2005-02-16 Wed >>> import os >>> os.mkdir('f/f') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 2] No such file or directory: 'f/f' >>> os.makedirs('f/f') !2005-02-15 Tue mkfifo, mknod, major, minor, makedev とばし >>> import os >>> os.mkdir('f') >>> os.mkdir('f') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 17] File exists: 'f' !2005-02-14 Mon >>> import os >>> os.lstat('foo') (33188, 35495L, 2072L, 1, 1000, 100, 0L, 1108004742, 1108004742, 1108004742) >>> os.lstat('bar') (41471, 35491L, 2072L, 1, 1000, 100, 3L, 1108350567, 1107746037, 1107746037) >>> os.stat('bar') (33188, 35495L, 2072L, 1, 1000, 100, 0L, 1108004742, 1108004742, 1108004742) !2005-02-13 Sun >>> import os >>> os.listdir('..') ['lost+found', 'nori', 'ftp', 'samba', 'httpd-vine2.0', 'httpd'] !2005-02-12 Sat >>> import os >>> os.link('foo', 'bar') >>> os.path.islink('foo') False >>> os.path.islink('bar') False >>> os.stat('foo') (32784, 2294L, 2086L, 2, 501, 100, 0L, 1108299950, 1108299950, 1108300199) >>> os.stat('bar') (32784, 2294L, 2086L, 2, 501, 100, 0L, 1108299950, 1108299950, 1108300199) !2005-02-11 Fri >>> import os >>> os.stat('foo') (33188, 2294L, 2086L, 1, 501, 100, 0L, 1108299950, 1108299950, 1108299950) >>> import stat >>> os.chmod('foo', stat.S_IWGRP) >>> os.stat('foo') (32784, 2294L, 2086L, 1, 501, 100, 0L, 1108299950, 1108299950, 1108300071) ちゃんと変わったか不明… !2005-02-10 Thu >>> import os >>> os.chroot('..') Traceback (most recent call last): File "", line 1, in ? OSError: [Errno 1] Operation not permitted: '..' !2005-02-09 Wed >>> import os >>> os.access('foo', F_OK) Traceback (most recent call last): File "", line 1, in ? NameError: name 'F_OK' is not defined >>> os.access('foo', os.F_OK) True !2005-02-08 Tue >>> import os >>> os.uname() ('Linux', 'nakamura', '2.2.19', '#1 Sat Oct 20 18:09:49 EST 2001', 'i686') !2005-02-07 Mon set*() とばし。 >>> import os >>> os.umask(0x022) 18 >>> os.umask(0x002) 34 >>> os.umask(0x022) 2 >>> print "%x" % 18 12 >>> print "%x" % 34 22 !2005-02-06 Sun >>> import os >>> os.putenv('HOGE', 'foo') >>> os.getenv('HOGE') >>> os.system('echo $HOGE') foo 0 !2005-02-05 Sat >>> import os >>> os.getenv('home') >>> os.getenv('HOME') '/home/nori' >>> os.getenv('HOGE', 'foo') 'foo' !2005-02-04 Fri >>> import os >>> os.getegid() 100 >>> os.geteuid() 1000 >>> os.getgid() 100 >>> os.getgroups() [100, 25] >>> os.getlogin() 'nnakamur' >>> os.getpgrp() 4226 >>> os.getpid() 4226 >>> os.getppid() 2677 >>> os.getuid() 1000 !2005-02-03 Thu >>> import os >>> os.ctermid() '/dev/tty' !2005-02-02 Wed >>> import os >>> os.getcwd() '/home/nnakamur' >>> os.chdir('..') >>> os.getcwd() '/home' !2005-02-01 Tue >>> import os >>> os.name 'posix' >>> os.environ {'WSDIR': '/usr/local/ws', 'LOGNAME': ... !2005-01-31 Mon >>> import os.path >>> os.path.supports_unicode_filenames False !2005-01-30 Sun >>> import os.path >>> def foo(arg, dirname, names): ... print arg, dirname, names ... >>> os.path.walk('tmp', foo, 1) 1 tmp ['poe', '.....', '......'] ... !2005-01-29 Sat >>> import os.path >>> os.path.splitext('/home/') ('/home/', '') >>> os.path.splitext('foo.c') ('foo', '.c') >>> os.path.splitext('foo.c.bar') ('foo.c', '.bar') >>> os.path.splitext('foo.') ('foo', '.') !2005-01-28 Fri >>> import os.path >>> os.path.splitdrive('/home/') ('', '/home/') !2005-01-27 Thu >>> import os.path >>> os.path.split('/home/foo') ('/home', 'foo') >>> os.path.split('/home/foo/bar') ('/home/foo', 'bar') >>> os.path.split('/home/foo/bar/') ('/home/foo/bar', '') !2005-01-26 Wed >>> import os.path >>> stat('foo') Traceback (most recent call last): File "", line 1, in ? NameError: name 'stat' is not defined >>> import os >>> s1 = os.stat('foo') >>> s2 = os.stat('foo') >>> os.path.samestat(s1, s2) True !2005-01-25 Tue >>> import os.path >>> f1 = open('foo') >>> f2 = open('foo') >>> os.path.sameopenfile(f1, f2) Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.3.4/lib/python2.3/posixpath.py", line 220, in sameopenfile s1 = os.fstat(fp1) TypeError: an integer is required 何を与えれば良いんだ? !2005-01-24 Mon foo -> bar としておいて、 >>> import os.path >>> os.path.samefile('foo', 'bar') Traceback (most recent call last): touch bar して >>> os.path.samefile('foo', 'bar') True !2005-01-23 Sun >>> import os.path >>> os.path.realpath('.') '/home/nori' >>> os.path.realpath('..') '/home' >>> os.path.realpath('~') '/home/nori/~' !2005-01-22 Sat >>> import os.path >>> os.path.normpath('/home/../foo') '/foo' ? >>> os.path.normpath('/home/./foo') '/home/foo' >>> os.path.normpath('/home/.//foo') '/home/foo' >>> os.path.normpath('./foo') 'foo' !2005-01-21 Fri >>> import os.path >>> os.path.normcase('foo') 'foo' >>> os.path.normcase('foo bar') 'foo bar' >>> os.path.normcase('foo/bar') 'foo/bar' >>> os.path.normcase('foo\ bar') 'foo\\ bar' !2005-01-20 Thu >>> import os.path >>> os.path.join('/home', 'foo') '/home/foo' >>> os.path.join('/home/', 'foo') '/home/foo' >>> os.path.join('/home/', '/foo') '/foo' >>> os.path.join('/home/', '../foo') '/home/../foo' >>> os.path.join('/home', '../foo') '/home/../foo' >>> os.path.join('.', 'foo') './foo' !2005-01-19 Wed >>> import os.path >>> os.path.ismount('/') True >>> os.path.ismount('/usr') True >>> os.path.ismount('/usr/') True >>> os.path.ismount('/usr/local') False >>> os.path.ismount('.emacs') False !2005-01-18 Tue >>> import os.path >>> os.path.islink('.emacs') False >>> os.path.islink('.xsession') True !2005-01-17 Mon >>> import os.path >>> os.path.isdir('tmp') True >>> os.path.isdir('.emacs') False !2005-01-16 Sun >>> import os.path >>> os.path.isfile('./tmp') False >>> os.path.isfile('.emacs') True !2005-01-15 Sat >>> import os.path >>> os.path.isabs('/home') True >>> os.path.isabs('tmp') False >>> os.path.isabs('./tmp') False !2005-01-14 Fri >>> import os.path >>> os.path.getsize('/home') 4096L !2005-01-13 Thu >>> import os.path >>> os.path.getctime('/home/') 958450830 >>> import time >>> time.localtime(os.path.getctime('/home/')) (2000, 5, 16, 13, 20, 30, 1, 137, 0) !2005-01-12 Wed >>> import os.path >>> os.path.getmtime('/home/') 958450830 >>> import time >>> time.gmtime(os.path.getmtime('/home/')) (2000, 5, 16, 4, 20, 30, 1, 137, 0) !2005-01-11 Tue >>> import os.path >>> os.path.getatime('/home/') 1096420577 >>> import time >>> time.gmtime(os.path.getatime('/home/')) (2004, 9, 29, 1, 16, 17, 2, 273, 0) !2005-01-10 Mon >>> import os.path >>> os.path.expandvars('~') '~' >>> os.path.expandvars('$HOME') '/home/nori' !2005-01-09 Sun >>> import os.path >>> os.path.expanduser('/home/foo') '/home/foo' >>> os.path.expanduser('~') '/home/nori' >>> os.path.expanduser('~/') '/home/nori/' >>> os.path.expanduser('~nori') '/home/nori' !2005-01-08 Sat >>> import os.path >>> os.path.exists('/home') True >>> os.path.exists('/home/foo') False !2005-01-07 Fri >>> import os.path >>> os.path.dirname('/home/foo') '/home' >>> os.path.dirname('/home/foo/') '/home/foo' !2005-01-06 Thu >>> import os.path >>> os.path.commonprefix(['/home/foo', '/home/bar']) '/home/' >>> os.path.commonprefix(['/home/foo/a', '/home/foo/b', '/home/bar']) '/home/' >>> os.path.commonprefix(['/home/foo/a', '/home/foo/b']) '/home/foo/' !2005-01-05 Wed >>> import os.path >>> os.path.basename('/home/foo') 'foo' >>> os.path.basename('/home/foo/') '' いまいち使いにくくならないか? !2005-01-04 Tue >>> import os.path >>> os.path.abspath("") '/home/nnakamur' >>> os.path.abspath(".") '/home/nnakamur' >>> os.path.abspath("..") '/home' >>> os.path.abspath("~") '/home/nnakamur/~' ? >>> os.path.abspath("~/..") '/home/nnakamur' ? !2005-01-03 Mon >>> import fileinput >>> f = fileinput.FileInput(['foo']) >>> f.readline() 'a\n' !2005-01-02 Sun >>> import fileinput >>> f = fileinput.FileInput(['foo']) >>> f.next() 'a\n' !2005-01-01 Sat >>> import fileinput >>> f = fileinput.input(['foo']) >>> f.readline() 'a\n' !2004-12-31 Fri >>> import fileinput >>> f = fileinput.input(['foo']) >>> f.close() !2004-12-30 Thu >>> import fileinput >>> f = fileinput.input(['foo', 'zzz']) >>> f.nextfile() >>> f.next() 'a\n' >>> f.filename() 'foo' >>> f.nextfile() >>> f.filename() 'foo' >>> f.next() '\n' >>> f.filename() 'zzz' >>> f.lineno() 2 >>> f.filelineno() 1 !2004-12-29 Wed >>> import fileinput >>> f = fileinput.input(['foo']) >>> f.isstdin() False !2004-12-28 Tue >>> import fileinput >>> f = fileinput.input(['foo']) >>> f.isfirstline() False >>> f.next() 'a\n' >>> f.isfirstline() True !2004-12-27 Mon >>> import fileinput >>> f = fileinput.input(['foo', 'zzz']) >>> f.filename() >>> f.next() 'a\n' >>> f.filename() 'foo' >>> f.lineno() 1 >>> f.filelineno() 1 >>> f.next() 'b\n' >>> f.next() 'c\n' >>> f.next() '\n' >>> f.filename() 'zzz' >>> f.lineno() 4 >>> f.filelineno() 1 !2004-12-26 Sun >>> import fileinput >>> f = fileinput.input('foo') >>> f.next() 'a\n' !2004-12-25 Sat >>> import fileinput >>> f = fileinput.input(['foo']) >>> f.lineno() 0 >>> f.filename() >>> f.next() 'a\n' >>> f.filename() 'foo' !2004-12-24 Fri >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.clear() >>> s1 Set([]) !2004-12-23 Thu やっと復帰(2005-01-03 Mon) >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.pop() 'foo' >>> s1 Set(['bar']) !2004-12-22 Wed >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.discard('') >>> s1 Set(['foo', 'bar']) >>> s1.discard('foo') >>> s1 Set(['bar']) !2004-12-21 Tue >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.remove('') Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.3.4/lib/python2.3/sets.py", line 534, in remove del self._data[element] KeyError: '' >>> s1.remove('foo') >>> s1 Set(['bar']) !2004-12-20 Mon >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.add(['hoge']) Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.3.4/lib/python2.3/sets.py", line 521, in add self._data[element] = True TypeError: list objects are unhashable >>> s1.add(sets.Set(['hoge'])) >>> s1 Set(['foo', 'bar', ImmutableSet(['hoge'])]) あ、こうしなきゃダメなのか >>> s1 = sets.Set(['foo', 'bar']) >>> s1.add('hoge') >>> s1 Set(['foo', 'bar', 'hoge']) !2004-12-19 Sun >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.symmetric_difference_update(['foo']) >>> s1 Set(['bar']) >>> s1 ^= sets.Set(['foo']) >>> s1 Set(['foo', 'bar']) !2004-12-18 Sat >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.difference_update([]) >>> s1 Set(['foo', 'bar']) >>> s1.difference_update(['foo']) >>> s1 Set(['bar']) >>> s1 = sets.Set(['foo', 'bar']) >>> s1 -= sets.Set(['foo']) >>> s1 Set(['bar']) !2004-12-17 Fri >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.intersection_update([]) >>> s1 Set([]) >>> s1 = sets.Set(['foo', 'bar']) >>> s1.intersection_update(['foo']) >>> s1 Set(['foo']) >>> s1 = sets.Set(['foo', 'bar']) >>> s1 &= (sets.Set(['foo'])) >>> s1 Set(['foo']) !2004-12-16 Thu >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.union_update(['baz']) >>> s1 Set(['baz', 'foo', 'bar']) >>> s1 |= sets.Set(['hoge']) >>> s1 Set(['baz', 'foo', 'bar', 'hoge']) !2004-12-15 Wed >>> import sets >>> hash(sets.ImmutableSet(['foo', 'bar'])) 938951391 !2004-12-14 Tue >>> import sets >>> sets.Set(['foo', 'bar']) == sets.Set(['foo', 'bar']) True !2004-12-13 Mon 等価な演算ってそういう意味だったか >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1 <= ['foo'] Traceback (most recent call last): ... TypeError: Binary operation only permitted between sets >>> s1 <= sets.Set(['foo']) False >>> s1 <= sets.Set(['foo', 'bar', 'baz']) True >>> s1 >= sets.Set(['foo']) True >>> s1 | sets.Set(['hoge']) Set(['foo', 'bar', 'hoge']) >>> s1 & sets.Set([]) Set([]) >>> s1 & sets.Set(['foo']) Set(['foo']) >>> s1 - sets.Set(['foo']) Set(['bar']) >>> s1 - sets.Set([]) Set(['foo', 'bar']) >>> s1 ^ sets.Set(['foo']) Set(['bar']) >>> s1 ^ sets.Set([]) Set(['foo', 'bar']) !2004-12-12 Sun >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.copy() Set(['foo', 'bar']) !2004-12-11 Sat >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.symmetric_difference(['foo']) Set(['bar']) >>> s1.symmetric_difference([]) Set(['foo', 'bar']) !2004-12-10 Fri >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.difference([]) Set(['foo', 'bar']) >>> s1.difference(['foo']) Set(['bar']) !2004-12-09 Thu >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.intersection(['foo']) Set(['foo']) >>> s1.intersection(['']) Set([]) あれ?(たまたま間違えたが、)Set でなく単なる配列でも良いのか !2004-12-08 Wed >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.union(sets.Set(['hoge'])) Set(['foo', 'bar', 'hoge']) >>> s1.union(sets.Set(['foo'])) Set(['foo', 'bar']) !2004-12-07 Tue >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.issuperset(sets.Set(['foo'])) True >>> s1.issuperset(sets.Set(['foo', 'bar', 'baz'])) False !2004-12-06 Mon >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> s1.issubset(s1) True >>> s1.issubset(sets.Set(['foo'])) False >>> s1.issubset(sets.Set(['foo', 'bar', 'baz'])) True !2004-12-05 Sun >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> 'foo' not in s1 False >>> 'hoge' not in s1 True !2004-12-04 Sat >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> 'foo' in s1 True >>> 'hoge' in s1 False !2004-12-03 Fri まだ、2.4 は入れていないぞー >>> import sets >>> s1 = sets.Set(['foo', 'bar']) >>> len(s1) 2 !2004-12-02 Thu まんま >>> from sets import Set >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) >>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack']) >>> employees = engineers | programmers | managers >>> engineering_management = engineers & managers >>> fulltime_management = managers - engineers - programmers >>> engineers.add('Marvin') >>> engineers Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) >>> employees.issuperset(engineers) False >>> employees.union_update(engineers) >>> employees.issuperset(engineers) True >>> for group in [engineers, programmers, managers, employees]: ... group.discard('Susan') ... print group ... Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) Set(['Janice', 'Jack', 'Sam']) Set(['Jane', 'Zack', 'Jack']) Set(['Zack', 'Sam', 'Marvin', 'Jack', 'Jane', 'Janice', 'John']) !2004-12-01 Wed >>> import calendar >>> import time >>> calendar.timegm(time.localtime()) 1101903062 >>> time.gmtime(calendar.timegm(time.gmtime())) (2004, 12, 1, 3, 14, 12, 2, 336, 0) !2004-11-30 Tue >>> import calendar >>> calendar.calendar(2004) ' 2004\n\n January February March\nMo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su\n 1 2 3 4 1 1 2 .... !2004-11-29 Mon >>> import calendar >>> calendar.prcal(2004) 2004 January February March Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 1 2 3 4 1 1 2 3 4 5 6 7 .... !2004-11-28 Sun >>> import calendar >>> calendar.month(2004, 11) ' November 2004\nMo Tu We Th Fr Sa Su\n 1 2 3 4 5 6 7\n 8 9 10 11 12 13 14\n15 16 17 18 19 20 21\n22 23 24 25 26 27 28\n29 30\n' >>> calendar.month(2004, 11, 10) ' November 2004\n Monday Tuesday Wednesday Thursday Friday Saturday Sunday\n 1 2 3 4 5 6 7\n 8 9 10 11 12 13 14\n 15 16 17 18 19 20 21\n 22 23 24 25 26 27 28\n 29 30\n' >>> calendar.month(2004, 11, 10, 1) ' November 2004\n Monday Tuesday Wednesday Thursday Friday Saturday Sunday\n 1 2 3 4 5 6 7\n 8 9 10 11 12 13 14\n 15 16 17 18 19 20 21\n 22 23 24 25 26 27 28\n 29 30\n' >>> calendar.month(2004, 11, 4, 1) ' November 2004\nMon Tue Wed Thu Fri Sat Sun\n 1 2 3 4 5 6 7\n 8 9 10 11 12 13 14\n 15 16 17 18 19 20 21\n 22 23 24 25 26 27 28\n 29 30\n' !2004-11-27 Sat >>> import calendar >>> calendar.monthcalendar(2004, 11) [[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14], [15, 16, 17, 18, 19, 20, 21], [22, 23, 24, 25, 26, 27, 28], [29, 30, 0, 0, 0, 0, 0]] !2004-11-26 Fri >>> import calendar >>> calendar.monthrange(2004, 1) (3, 31) >>> calendar.monthrange(2004, 2) (6, 29) !2004-11-25 Thu >>> import calendar >>> calendar.weekday(2004, 11, 25) 3 >>> calendar.THURSDAY 3 !2004-11-24 Wed >>> import calendar >>> calendar.leapdays(2000, 2004) 1 >>> calendar.leapdays(2000, 2005) 2 !2004-11-23 Tue >>> import calendar >>> calendar.isleap(2004) True >>> calendar.isleap(2000) True !2004-11-22 Mon >>> import calendar >>> calendar.firstweekday() 0 >>> calendar.SUNDAY 6 >>> calendar.SATURDAY 5 >>> calendar.MONDAY 0 >>> calendar.setfirstweekday(calendar.SUNDAY) >>> calendar.firstweekday() 6 !2004-11-21 Sun >>> import time >>> time.time() 1101045944.498821 >>> time.timezone -32400 >>> time.tzname ('JST', 'JST') tzset() はとばし !2004-11-20 Sat >>> import time >>> time.struct_time >>> type(time.localtime()) !2004-11-19 Fri >>> import time >>> time.strptime('18-50', "%H-%M") (1900, 1, 1, 18, 50, 0, 0, 1, -1) >>> time.strptime(time.ctime()) (2004, 11, 19, 18, 53, 20, 4, 324, -1) !2004-11-18 Thu >>> import time >>> time.strftime("%H-%M") '18-50' !2004-11-17 Wed >>> import time >>> time.localtime(); time.sleep(10); time.localtime() (2004, 11, 17, 12, 9, 31, 2, 322, 0) (2004, 11, 17, 12, 9, 41, 2, 322, 0) !2004-11-16 Tue >>> import time >>> time.mktime(2004, 11, 16, 23, 5, 41, 6, 319, 0) Traceback (most recent call last): File "", line 1, in ? TypeError: mktime() takes exactly 1 argument (9 given) >>> time.mktime((2004, 11, 16, 23, 5, 41, 6, 319, 0)) 1100613941.0 >>> time.localtime(time.mktime((2004, 11, 16, 23, 5, 41, 6, 319, 0))) (2004, 11, 16, 23, 5, 41, 1, 321, 0) >>> time.asctime(time.localtime(time.mktime((2004, 11, 16, 23, 5, 41, 6, 319, 0)))) 'Tue Nov 16 23:05:41 2004' !2004-11-15 Mon >>> import time >>> time.ctime() 'Mon Nov 15 12:11:48 2004' >>> time.ctime(1) 'Thu Jan 1 09:00:01 1970' !2004-11-14 Sun >>> import time >>> time.clock() 1.24 !2004-11-13 Sat >>> import time >>> time.asctime(time.gmtime()) 'Sun Nov 14 14:08:20 2004' >>> time.asctime(time.localtime()) 'Sun Nov 14 23:08:28 2004' !2004-11-12 Fri >>> import time >>> time.accept2dyear 1 >>> time.altzone -32400 >>> time.daylight 0 !2004-11-11 Thu >>> import time >>> time.gmtime(0) (1970, 1, 1, 0, 0, 0, 3, 1, 0) >>> time.gmtime() (2004, 11, 14, 14, 5, 35, 6, 319, 0) >>> time.localtime() (2004, 11, 14, 23, 5, 41, 6, 319, 0) !2004-11-10 Wed >>> import datetime >>> t = datetime.time(19, 20, 1) >>> t.strftime("%h-%m-%s") 'Saturday-00--1' >>> t.strftime("%H-%M-%s") '19-20--1' >>> t.strftime("%H-%M-%S") '19-20-01' あとは、だいたい同じだしとばし !2004-11-09 Tue >>> import datetime >>> d1 = datetime.timedelta(1) >>> d2 = datetime.timedelta(2) >>> d2 - d1 datetime.timedelta(1) >>> d2 + d1 datetime.timedelta(3) >>> d2 * 2 datetime.timedelta(4) >>> d2 // 1 datetime.timedelta(2) >>> abs(-d2) datetime.timedelta(2) !2004-11-08 Mon かなりとばして、 >>> import datetime >>> d = datetime.datetime(2004, 11, 7) >>> d = datetime.datetime(2004, 11, 8) >>> d.dst() >>> d.tzname() >>> d.timetuple() (2004, 11, 8, 0, 0, 0, 0, 313, -1) >>> d.ctime() 'Mon Nov 8 00:00:00 2004' !2004-11-07 Sun >>> import datetime >>> d = datetime.datetime(2004, 11, 7) >>> date = datetime.date(2004, 11, 7) >>> d.combine(date, time) datetime.datetime(2004, 11, 7, 22, 54) >>> time = datetime.time(22, 54) !2004-11-06 Sat >>> import datetime >>> d = datetime.datetime(2004, 11, 6) >>> d.fromtimestamp(1.0) datetime.datetime(1970, 1, 1, 9, 0, 1) >>> d.utcfromtimestamp(1.0) datetime.datetime(1970, 1, 1, 0, 0, 1) >>> d.fromordinal(1) datetime.datetime(1, 1, 1, 0, 0) !2004-11-05 Fri >>> import datetime >>> d = datetime.datetime(2004, 11, 5) >>> d.now() datetime.datetime(2004, 11, 5, 17, 29, 52, 378897) >>> d.utcnow() datetime.datetime(2004, 11, 5, 8, 30, 16, 68454) !2004-11-04 Thu >>> import datetime >>> d = datetime.datetime(2004, 11, 4) >>> d.today() datetime.datetime(2004, 11, 4, 12, 8, 19, 482739) !2004-11-03 Wed >>> import datetime >>> d = datetime.date(2004, 11, 3) >>> d.strftime("%Y-%m-%d") '2004-11-03' >>> d.strftime("%y-%m-%d") '04-11-03' !2004-11-02 Tue >>> import datetime >>> d = datetime.date(2004, 11, 2) >>> d.ctime() 'Tue Nov 2 00:00:00 2004' !2004-11-01 Mon >>> import datetime >>> d = datetime.date(2004, 11, 1) >>> d.weekday() 0 >>> d.isoweekday() 1 >>> d.isocalendar() (2004, 45, 1) >>> d.isoformat() '2004-11-01' !2004-10-31 Sun >>> import datetime >>> d = datetime.date(2004, 10, 31) >>> d.timetuple() (2004, 10, 31, 0, 0, 0, 6, 305, -1) !2004-10-30 Sat >>> import datetime >>> d = datetime.date(2004, 10, 30) >>> d.replace(2004, 11, 31) Traceback (most recent call last): File "", line 1, in ? ValueError: day is out of range for month >>> d.replace(month = 11) datetime.date(2004, 11, 30) !2004-10-29 Fri >>> import datetime >>> d = datetime.date(2004, 10, 29) >>> d.fromordinal(1) datetime.date(1, 1, 1) !2004-10-28 Thu >>> import datetime >>> d = datetime.date(2004, 10, 28) >>> d.fromtimestamp("%Y") Traceback (most recent call last): File "", line 1, in ? TypeError: a float is required >>> d.fromtimestamp(1.0) datetime.date(1970, 1, 1) >>> d.fromtimestamp(2.0) datetime.date(1970, 1, 1) >>> d.fromtimestamp(1) datetime.date(1970, 1, 1) !2004-10-27 Wed >>> import datetime >>> d = datetime.date(2004, 10, 27) >>> d.min datetime.date(1, 1, 1) >>> d.max datetime.date(9999, 12, 31) >>> d.resolution datetime.timedelta(1) >>> d.year 2004 >>> d.month 10 >>> d.day 27 >>> d + 1 Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for +: 'datetime.date' and 'int' >>> d + datetime.timedelta(1) datetime.date(2004, 10, 28) >>> d + datetime.timedelta(5) datetime.date(2004, 11, 1) >>> datetime.date(2004, 10, 27) - datetime.date(2004, 10, 26) datetime.timedelta(1) >>> datetime.date(2004, 10, 27) < datetime.date(2004, 10, 26) False >>> datetime.date(2004, 10, 27) <= datetime.date(2004, 10, 26) False !2004-10-26 Tue >>> import datetime >>> datetime.MINYEAR 1 >>> datetime.MAXYEAR 9999 >>> datetime.date >>> d = datetime.date(2004, 10, 26) >>> d.today() datetime.date(2004, 10, 26) !2004-10-25 Mon >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.width = 10 >>> wrapper.fill("01234567890123456789") '0123456789\n0123456789' !2004-10-24 Sun >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.width = 10 >>> wrapper.break_long_words True >>> wrapper.wrap("booooooooooo boooo") ['booooooooo', 'oo boooo'] >>> wrapper.break_long_words = False >>> wrapper.wrap("booooooooooo boooo") ['booooooooooo', 'boooo'] !2004-10-23 Sat >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.width = 10 >>> wrapper.fix_sentence_endings False >>> wrapper.wrap("This is a pen. That is a pen.") ['This is a', 'pen. That', 'is a pen.'] >>> wrapper.wrap("booooooooooo boooo") ['booooooooo', 'oo boooo'] >>> wrapper.wrap("01234567 9012") ['01234567', '9012'] >>> wrapper.fix_sentence_endings = True >>> wrapper.wrap("This is a pen. That is a pen.") ['This is a', 'pen. That', 'is a pen.'] >>> wrapper.wrap("This is a pen. that is a pen.") ['This is a', 'pen. that', 'is a pen.'] >>> wrapper.wrap("01234567 9012") ['01234567', '9012'] !2004-10-22 Fri >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.subsequent_indent = "+" >>> wrapper.width = 10 >>> wrapper.wrap("01234567890123456789") ['0123456789', '+012345678', '+9'] !2004-10-21 Thu >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.replace_whitespace True ? >>> wrapper.initial_indent = "* " >>> wrapper.wrap("0123456789") ['* 0123456789'] !2004-10-20 Wed >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.expand_tabs True >>> wrapper.wrap("foo\tbar") ['foo bar'] >>> wrapper.expand_tabs = False >>> wrapper.wrap("foo\tbar") ['foo bar'] !2004-10-19 Tue >>> import textwrap >>> wrapper = textwrap.TextWrapper() >>> wrapper.width 70 >>> wrapper.width = 10 >>> wrapper.wrap("01234567890123456789") ['0123456789', '0123456789'] !2004-10-18 Mon >>> import textwrap >>> wrapper = textwrap.TextWrapper(initial_indent="* ") >>> wrapper.wrap("0123456789") ['* 0123456789'] !2004-10-17 Sun >>> import textwrap >>> textwrap.dedent(" foo ") 'foo ' !2004-10-16 Sat >>> import textwrap >>> textwrap.fill("01234567890123456789012345678901234567890123456789012345678901234567890123456789") '0123456789012345678901234567890123456789012345678901234567890123456789\n0123456789' >>> textwrap.fill("01234567890123456789012345678901234567890123456789012345678901234567890123456789", 10) '0123456789\n0123456789\n0123456789\n0123456789\n0123456789\n0123456789\n0123456789\n0123456789' !2004-10-15 Fri cunifvariate, expovariate, gammavariate, gauss, lognormvariate, normalvariate, vonmisesvariate, paretovariate, weibullvariate, class WichmannHill, whseed とばし >>> import textwrap >>> textwrap.wrap("01234567890123456789012345678901234567890123456789012345678901234567890123456789") ['0123456789012345678901234567890123456789012345678901234567890123456789', '0123456789'] >>> textwrap.wrap("01234567890123456789012345678901234567890123456789012345678901234567890123456789", 10) ['0123456789', '0123456789', '0123456789', '0123456789', '0123456789', '0123456789', '0123456789', '0123456789'] !2004-10-14 Thu >>> import random >>> random.betavariate(0, 0) Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.3.4/lib/python2.3/random.py", line 594, in betavariate y = self.gammavariate(alpha, 1.) File "/usr/local/Python-2.3.4/lib/python2.3/random.py", line 457, in gammavariate raise ValueError, 'gammavariate: alpha and beta must be > 0.0' ValueError: gammavariate: alpha and beta must be > 0.0 ? 引数の満たすべき条件は ... alpha > -1 および beta > -1 です。 >>> random.betavariate(1, 1) 0.66385291139060298 >>> random.betavariate(1, 1) 0.47900583490343746 !2004-10-13 Wed >>> import random >>> random.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2) [2, 9] >>> random.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2) [8, 3] >>> random.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2) [4, 2] !2004-10-12 Tue >>> import random >>> random.uniform(1, 3) 2.467250906717235 >>> random.uniform(1, 3) 2.8246111703321182 !2004-10-11 Mon >>> import random >>> ary = [0, 1, 2, 3] >>> random.shuffle(ary) >>> ary [2, 0, 1, 3] >>> random.shuffle(ary) >>> ary [3, 2, 0, 1] !2004-10-10 Sun >>> import random >>> random.choice([0, 1, 2, 3]) 3 >>> random.choice([0, 1, 2, 3]) 2 >>> random.choice([0, 1, 2, 3]) 0 !2004-10-09 Sat >>> import random >>> random.randint(1,3) 1 >>> random.randint(1,3) 3 >>> random.randint(1,3) 3 >>> random.randint(1,3) 2 >>> random.randint(-1,3) 2 >>> random.randint(-1,3) 3 >>> random.randint(-1,3) 1 >>> random.randint(-1,3) 2 >>> random.randint(-1,3) 3 >>> random.randint(-1,3) 2 >>> random.randint(-1,3) 0 !2004-10-08 Fri >>> import random >>> random.randrange(2) 1 >>> random.randrange(2) 1 >>> random.randrange(2) 1 >>> random.randrange(2) 0 >>> random.randrange(2,4) 3 >>> random.randrange(2,6,2) 4 >>> random.randrange(2,6,2) 2 >>> random.randrange(2,6,2) 2 >>> random.randrange(2,6,2) 4 !2004-10-07 Thu >>> import random >>> random.seed(1) >>> random.random() 0.13436424411240122 >>> random.random() 0.84743373693723267 >>> random.seed(1) >>> random.jumpahead(1) >>> random.random() 0.99510321786951772 ? !2004-10-06 Wed >>> import random >>> r = random.getstate() >>> random.random() 0.41713966217584852 >>> random.random() 0.78433685308126067 >>> random.setstate(r) >>> random.random() 0.41713966217584852 !2004-10-05 Tue >>> import random >>> random.random() 0.2753280849061811 >>> random.random() 0.9697830153421988 >>> random.seed(1) >>> random.random() 0.13436424411240122 >>> random.random() 0.84743373693723267 >>> random.seed(1) >>> random.random() 0.13436424411240122 >>> random.random() 0.84743373693723267 !2004-10-04 Mon sin, sinh, sqrt, tan, tanh いいや。 >>> import math >>> math.log(0) Traceback (most recent call last): File "", line 1, in ? OverflowError: math range error >>> math.log(0L) Traceback (most recent call last): File "", line 1, in ? ValueError: math domain error !2004-10-03 Sun Python 2.2.2 (#2, Nov 23 2002, 15:32:14) >>> import math >>> math.radians(180) Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'radians' Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import math >>> math.radians(180) 3.1415926535897931 !2004-10-02 Sat >>> import math >>> math.pow(2, 3) 8.0 !2004-10-01 Fri >>> import math >>> math.modf(1) (0.0, 1.0) >>> math.modf(1.2) (0.19999999999999996, 1.0) >>> math.modf(0.3) (0.29999999999999999, 0.0) !2004-09-30 Thu >>> import math >>> math.log(1) 0.0 >>> math.log(math.e) 1.0 >>> math.log(2, 2) 1.0 >>> math.log10(10) 1.0 >>> math.log10(100) 2.0 !2004-09-29 Wed >>> import math >>> math.ldexp(1, 1) 2.0 >>> math.ldexp(3, 1) 6.0 >>> math.ldexp(1, 2) 4.0 >>> math.ldexp(1, 3) 8.0 !2004-09-28 Tue >>> import math >>> math.hypot(1, 1) 1.4142135623730951 hypotenuse の略??? !2004-09-27 Mon >>> import math >>> math.frexp(1.0) (0.5, 1) >>> math.frexp(2.0) (0.5, 2) >>> math.frexp(4.0) (0.5, 3) >>> math.frexp(3.0) (0.75, 2) >>> math.frexp(8.0) (0.5, 4) !2004-09-26 Sun >>> import math >>> math.fmod(10, 3) 1.0 >>> math.fmod(-10, 3) -1.0 >>> 10 % 3 1 >>> -10 % 3 2 !2004-09-25 Sat >>> import math >>> math.floor(1.9) 1.0 >>> math.floor(-1.9) -2.0 !2004-09-24 Fri >>> import math >>> math.fabs(-1.0) 1.0 !2004-09-23 Thu >>> import math >>> math.exp(1) 2.7182818284590451 !2004-09-22 Wed Python 2.2.2 (#2, Nov 23 2002, 15:32:14) >>> import math >>> math.degrees(math.pi) Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute 'degrees' Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import math >>> math.degrees(math.pi) 180.0 !2004-09-21 Tue sin, cos, tan, atan2 とかどうでもいいや。 >>> import math >>> math.ceil(1.9) 2.0 >>> math.ceil(-1.9) -1.0 !2004-09-20 Mon >>> import math >>> math.asin(0) 0.0 >>> math.asin(1) 1.5707963267948966 >>> math.atan(0) 0.0 !2004-09-19 Sun >>> import math >>> math.acos(1) 0.0 >>> math.acos(0) 1.5707963267948966 !2004-09-18 Sat >>> import math >>> math.e 2.7182818284590451 !2004-09-17 Fri >>> import math >>> math.pi 3.1415926535897931 !2004-09-16 Thu >>> import re >>> m = re.compile("^a").search("ab") >>> m.string 'ab' !2004-09-15 Wed >>> import re >>> m = re.compile("^a").search("ab") >>> m.re <_sre.SRE_Pattern object at 0x401b8820> >>> m.re.pattern '^a' !2004-09-14 Tue >>> import re >>> r = re.compile("(?P\w)(?P\w)") >>> m = r.search("ab") >>> m.lastgroup 'bar' !2004-09-13 Mon >>> import re >>> m = re.compile("(\w)").search("ab") >>> m.lastindex 1 >>> m = re.compile("(\w?)(\w?)(\w?)").search("ab") >>> m.lastindex 3 >>> m.group(1) 'a' >>> m.group(2) 'b' >>> m.group(3) '' !2004-09-12 Sun >>> import re >>> m = re.compile("\w").search("ab", 1) >>> m.endpos 2 >>> m = re.compile("\w").search("abcde") >>> m.endpos 5 !2004-09-11 Sat >>> import re >>> m = re.compile("^a").search("ab", 0) >>> m.pos 0 >>> m = re.compile("\w").search("ab", 1) >>> m.pos 1 !2004-09-10 Fri >>> import re >>> r = re.compile("(\w)(\w)") >>> m = r.search("ab") >>> m.span() (0, 2) >>> m.span(1) (0, 1) >>> m.span(2) (1, 2) >>> m.span(3) Traceback (most recent call last): File "", line 1, in ? IndexError: no such group !2004-09-09 Thu >>> import re >>> r = re.compile("(?P\w)(?P\w)") >>> m = r.search("ab") >>> m.start(0) 0 >>> m.end(0) 2 >>> m.start() 0 >>> m.end() 2 >>> m.start(1) 0 >>> m.end(1) 1 >>> m.start(2) 1 >>> m.end(2) 2 !2004-09-08 Wed >>> import re >>> r = re.compile("(?P\w)(?P\w)") >>> m = r.search("ab") >>> m.groupdict() {'foo': 'a', 'bar': 'b'} >>> r = re.compile("(?P\w)(?P\w)(?P.?)") >>> m = r.search("ab") >>> m.groupdict() {'poo': '', 'foo': 'a', 'bar': 'b'} >>> m.groupdict('N') {'poo': '', 'foo': 'a', 'bar': 'b'} ? !2004-09-07 Tue >>> import re >>> r = re.compile("(?P\w)(?P\w)") >>> m = r.search("ab") >>> m.groups() ('a', 'b') >>> r = re.compile("(\w)(\w?)") >>> m = r.search("a") >>> m.groups() ('a', '') >>> m.groups('foo') ('a', '') ? >>> r = re.compile("(\w)(\w)?") >>> m = r.search("a") >>> m.groups() ('a', None) >>> m.groups('foo') ('a', 'foo') !2004-09-06 Mon >>> import re >>> r = re.compile("(?P\w)(?P\w)") >>> m = r.search("ab") >>> m.group('foo') 'a' >>> m.group(1) 'a' >>> m.group('bar') 'b' >>> m.group('poo') Traceback (most recent call last): File "", line 1, in ? IndexError: no such group !2004-09-05 Sun >>> import re >>> r = re.compile("\w+") >>> r.pattern '\\w+' !2004-09-04 Sat >>> import re >>> r = re.compile("(\w)(\w)") >>> r.groupindex {} >>> r = re.compile("(\w)\g<1>") >>> r.groupindex {} >>> r = re.compile("(?P\w)(?P\w)") >>> r.groupindex {'foo': 1, 'bar': 2} !2004-09-03 Fri findall, finditer, sub, subn はモジュール コンテンツとほぼ同じなのでとばし >>> import re >>> r = re.compile("\s+") >>> r.flags 0 >>> r = re.compile("foo", re.I) >>> r.flags 2 >>> r = re.compile("foo", re.M) >>> r.flags 8 !2004-09-02 Thu search とばし(もう不要だろう) >>> import re >>> r = re.compile("\s+") >>> r.split("foo bar baz") ['foo', 'bar', 'baz'] >>> r.split("foo bar baz", 1) ['foo', 'bar baz'] !2004-09-01 Wed >>> import re >>> r = re.compile("foo") >>> r.match("foo ") <_sre.SRE_Match object at 0x401c5598> >>> r.match("foo ", 1) >>> r = re.compile("foo") >>> r.match("foo ", 0, 4) <_sre.SRE_Match object at 0x401dbf70> >>> r.match("foo ", 0, 3) <_sre.SRE_Match object at 0x401c5598> >>> r.match("foo ", 0, 2) >>> r.match(" foo ", 1, 3) >>> r.match(" foo ", 1, 4) <_sre.SRE_Match object at 0x401dbf70> >>> r = re.compile("^foo") >>> r.match("bar\nfoo") >>> r.match("foo ", 0, 4) <_sre.SRE_Match object at 0x401dbf70> >>> r.match("foo ", 0, 3) <_sre.SRE_Match object at 0x401c5598> >>> r.match("foo ", 0, 2) >>> r.match(" foo ", 1, 3) >>> r.match(" foo ", 1, 4) これは、文字列のスライシングと 完全に同じ意味だというわけではありません... 全然、意味分からん!(けど、上の違いが出るってこと?) !2004-08-31 Tue >>> import re >>> re.sub("foo\sbar", "Poo", "foo bar") 'Poo' >>> re.sub(re.compile("foo"), "bar", "foo bar") 'bar bar' >>> re.sub(re.compile("foo"), "bar", "FOO BAR") 'FOO BAR' >>> re.sub(re.compile("foo", re.I), "bar", "FOO BAR") 'bar BAR' >>> re.sub("(?i)foo", "bar", "FOO BAR") 'bar BAR' >>> re.sub("(foo)", 'A\1', "foo bar") 'A\x01 bar' >>> re.sub("(foo)", r'A\1', "foo bar") 'Afoo bar' >>> re.sub("(foo)", "A\g<1>", "foo bar") 'Afoo bar' >>> re.sub("(foo) (\w+)", "A\g<1>", "foo bar") 'Afoo' >>> re.sub("(foo) (\w+)", "A\g<2>", "foo bar") 'Abar' >>> re.sub("\(foo\)", "foo", "foo bar") 'foo bar' >>> re.sub("\(foo\)", "foo", "(foo) bar") 'foo bar' >>> re.sub("foo", "A\g<0>A", "foo foo") 'AfooA AfooA' !2004-08-30 Mon >>> import re >>> re.escape("\t") '\\\t' !2004-08-29 Sun >>> import re >>> re.subn("foo", "bar", "foo bar") ('bar bar', 1) >>> re.subn("foo", "bar", "foo foo") ('bar bar', 2) !2004-08-28 Sat >>> import re >>> re.sub("foo", "bar", "foo bar") 'bar bar' >>> re.sub("foo", "bar", "foo foo foo", 2) 'bar bar foo' >>> def upper(x): ... return string.upper(x.group(0)) ... >>> re.sub("foo", upper, "foo bar") 'FOO bar' うーん、本当か? !2004-08-27 Fri >>> import re >>> i = re.finditer("\w", "abc") >>> i.next() <_sre.SRE_Match object at 0x401c5598> >>> i.next() <_sre.SRE_Match object at 0x401dbf70> >>> i.next() <_sre.SRE_Match object at 0x401c5598> >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i = re.finditer("\w", "abc") >>> m = i.next() >>> m.group(0) 'a' >>> m.group(1) Traceback (most recent call last): File "", line 1, in ? IndexError: no such group >>> i = re.finditer("(\d)\w(\w)", "1aA2bBc3") >>> m = i.next() >>> m.group(0) '1aA' >>> m.group(0)[0] '1' >>> m.group(0)[1] 'a' >>> m.group(0)[2] 'A' >>> m = i.next() >>> m.group(0) '2bB' >>> m.group(1) '2' >>> m.group(2) 'B' >>> m.group(3) Traceback (most recent call last): File "", line 1, in ? IndexError: no such group !2004-08-26 Thu >>> import re >>> re.findall("\w", "abc") # => ['a', 'b', 'c'] >>> re.findall("\d", "1a2bc3") # => ['1', '2', '3'] >>> re.findall("(\d)\w", "1a2bc3") # => ['1', '2'] >>> re.findall("(\d)\w(\w)", "1aA2bBc3") # => [('1', 'A'), ('2', 'B')] 他にマッチがなければ、 「他に」ってどういう意味? !2004-08-25 Wed >>> re.split("\s+", "foo bar baz") # => ['foo', 'bar', 'baz'] >>> re.split("(\s+)", "foo bar baz") # => ['foo', ' ', 'bar', ' ', 'baz'] >>> re.split("\s+", "foo bar baz", 1) # => ['foo', 'bar baz'] >>> "foo bar baz".split("\s+") # => ['foo bar baz'] >>> "foo bar baz".split(" ") # => ['foo', 'bar', 'baz'] String#split がないわけではないようだ。 けど、正規表現を使うには、re.split を使えってことかな? !2004-08-24 Tue >>> import re >>> re.search("a", "abc") <_sre.SRE_Match object at 0x401c5560> >>> re.search("a", "cba") <_sre.SRE_Match object at 0x401dbf38> >>> re.match("a", "abc") <_sre.SRE_Match object at 0x401c5560> >>> re.match("a", "cba") >>> re.search("a", "ABC") >>> re.search("a", "ABC", re.I) <_sre.SRE_Match object at 0x401de058> !2004-08-23 Mon >>> import re >>> re.compile("a b").search("ab") >>> re.compile("a b", re.VERBOSE).search("ab") <_sre.SRE_Match object at 0x401dd0c8> >>> re.compile("a#b").search("ac") >>> re.compile("a#b", re.VERBOSE).search("ac") <_sre.SRE_Match object at 0x401c5560> !2004-08-22 Sun >>> import re >>> re.compile(".").search("a") <_sre.SRE_Match object at 0x401c5560> >>> re.compile(".").search("\n") >>> re.compile(".", re.DOTALL).search("\n") <_sre.SRE_Match object at 0x401dd0c8> !2004-08-21 Sat >>> import re >>> re.compile("^a").search("ab") <_sre.SRE_Match object at 0x401dbf38> >>> re.compile("^a").search("ba") >>> re.compile("^a").search("b\na") >>> re.compile("^a", re.MULTILINE).search("b\na") <_sre.SRE_Match object at 0x401c5560> !2004-08-20 Fri >>> import re >>> re.compile("a").match("BA", 1) >>> re.compile("a", re.IGNORECASE).match("ba", 1) <_sre.SRE_Match object at 0x401dd058> >>> re.compile("a", re.IGNORECASE).match("BA", 1) <_sre.SRE_Match object at 0x401dd090> !2004-08-19 Thu シーケンス prog = re.compile(pat) result = prog.match(str) は、 result = re.match(pat, str) と同じ意味ですが、compile() を使うバージョンの方が、 その式を一つのプログラムで何回も使う時にはより効率的です。 え? Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import re >>> re.compile("a").match("ba", 1) <_sre.SRE_Match object at 0x401c5598> >>> re.match('a', 'ba', 1) >>> re.compile("a").match("ba") >>> re.compile("a").match("ab") <_sre.SRE_Match object at 0x401dbf70> >>> re.match('a', 'ab') <_sre.SRE_Match object at 0x401c5598> result = re.match(pat, str, flag) とは同じでない??? モジュール コンテンツ match( pattern, string[, flags]) 正規表現オブジェクト match( string[, pos[, endpos]]) ワナか! !2004-08-18 Wed Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import re >>> re.compile("a").match("ba", 1) <_sre.SRE_Match object at 0x401c5598> >>> m = re.compile("a").match("ba", 1) >>> m.group() 'a' >>> m = re.compile("^a").search("ba", 1) >>> m.group() Traceback (most recent call last): File "", line 1, in ? AttributeError: 'NoneType' object has no attribute 'group' >>> m >>> m is None True >>> m = re.compile("^a").search("\na", 1) >>> m >>> m = re.compile("^a", re.M).search("\na", 1) >>> m <_sre.SRE_Match object at 0x401c5598> >>> m.group() 'a' >>> m = re.compile("^a", re.M).search("ba", 1) >>> m !2004-08-17 Tue string 終了。ずーと string.foo() とやってきたけど、 Ruby 風にこんなんでも OK なんだよな。 Python 2.1.3 (#1, Sep 12 2002, 00:24:18) >>> "abc".upper() # => 'ABC' 昔のだとダメなんだけど、 いつから仕様が変わったんだっけ? こういう、ある意味しょうもないところの変更は、 混乱するからやめて欲しい(今の仕様の方が楽で良いけど)。 Python 1.5.2 (#0, Oct 20 2001, 16:30:45) [GCC 2.95.4 20011006 (Debian prerelease)] on linux2 >>> "abc".upper() Traceback (innermost last): File "", line 1, in ? AttributeError: 'string' object has no attribute 'upper' !2004-08-16 Mon >>> import string >>> string.replace("abc", "a", "A") # => 'Abc' >>> string.replace("abc abc", "a", "A") # => 'Abc Abc' >>> string.replace("abc abc", "a", "A", 1) # => 'Abc abc' !2004-08-15 Sun >>> import string >>> string.zfill("abc", 10) # => '0000000abc' >>> string.zfill("abc", 0) # => 'abc' >>> string.zfill("abc", -1) # => 'abc' >>> string.zfill(1, 10) # => '0000000001' >>> string.zfill(-1, 10) # => '-000000001' >>> string.zfill("0xffff", 10) # => '00000xffff' なぜ、引数が string でなくても大丈夫なんだろうか?(内部で変換しているだけなんだろうけど…) !2004-08-14 Sat >>> import string >>> string.ljust("abc", 10) # => 'abc ' >>> string.rjust("abc", 10) # => ' abc' >>> string.center("abc", 10) # => ' abc ' >>> string.center("abcdefghijklmno", 10) # => 'abcdefghijklmno' !2004-08-13 Fri >>> import string >>> string.upper("abc") # => 'ABC' !2004-08-12 Thu >>> import string >>> string.translate("abc", string.maketrans("a", "A")) # => 'Abc' >>> string.translate("abc", string.maketrans("a", "A"), "a") # => 'bc' >>> string.translate("abc", string.maketrans("a", "A"), "b") # => 'Ac' !2004-08-11 Wed >>> import string >>> string.swapcase("abc") # => 'ABC' >>> string.swapcase("ABC") # => 'abc' >>> string.swapcase("Abc") # => 'aBC' !2004-08-10 Tue Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import string >>> string.strip(" abc ") # => 'abc' >>> string.strip(" abc ", None) # => 'abc' >>> string.strip(" abc ", " a") # => 'bc' >>> string.strip(" abc ", " ") # => 'abc' >>> string.strip(" abc ", " b") # => 'abc' !2004-08-09 Mon Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import string >>> string.rstrip(" abc ", None) # => ' abc' >>> string.rstrip(" abc ", "a") # => ' abc ' >>> string.rstrip(" abc ", " a") # => ' abc' >>> string.rstrip(" abc ", " c") # => ' ab' >>> string.lstrip(" abc ", "a") # => ' abc ' >>> string.lstrip(" abc ", "a ") # => 'bc ' !2004-08-08 Sun >>> import string >>> string.rstrip(" abc ") # => ' abc' !2004-08-07 Sat Python 2.0 (#3, Feb 17 2001, 13:45:43) >>> import string >>> string.lstrip(" abc") # => 'abc' >>> string.lstrip(" abc", None) Traceback (most recent call last): File "", line 1, in ? TypeError: too many arguments; expected 1, got 2 2.2.3 以降のが入っていないや…。 !2004-08-06 Fri >>> import string >>> string.splitfields("a:b:c", ":") # => ['a', 'b', 'c'] 今は split に同じ。 !2004-08-05 Thu >>> import string >>> string.split("a:b:c", ":") # => ['a', 'b', 'c'] >>> string.split("a:b:c", ":", 1) # => ['a', 'b:c'] >>> string.split("a b c") # => ['a', 'b', 'c'] >>> string.split("a:b:c") # => ['a:b:c'] >>> string.split("a b c", None) # => ['a', 'b', 'c'] >>> string.split(" a b c ") # => ['a', 'b', 'c'] >>> string.split(":a:b:c:", ":") # => ['', 'a', 'b', 'c', ''] !2004-08-04 Wed >>> import string >>> string.maketrans("a", "A") '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017 \020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`Abc... >>> string.maketrans("ab", "AB") '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017 \020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABc... >>> string.maketrans("abc", "AB") Traceback (most recent call last): File "", line 1, in ? ValueError: maketrans arguments must have same length !2004-08-03 Tue >>> import string >>> string.lower("ABC") # => 'abc' !2004-08-02 Mon >>> import string >>> string.count("abcabc", "d") # => 0 >>> string.count("abcabc", "a") # => 2 >>> string.count("abcabc", "ab") # => 2 >>> string.count("abcabc", "ab", 2) # => 1 >>> string.count("abcabc", "ab", 2, 3) # => 0 !2004-08-01 Sun >>> import string >>> string.rindex("abcabc", "ab") # => 3 >>> string.rindex("abcabc", "d") Traceback (most recent call last): File "", line 1, in ? File "/usr/local/lib/python2.0/string.py", line 148, in rindex return s.rindex(*args) ValueError: substring not found in string.rindex !2004-07-31 Sat >>> import string >>> string.index("abc", "a") # => 0 >>> string.index("abc", "d") Traceback (most recent call last): File "", line 1, in ? File "/usr/local/lib/python2.0/string.py", line 139, in index return s.index(*args) ValueError: substring not found in string.index find との違いは例外を発生されるかどうかだけとさ !2004-07-30 Fri >>> import string >>> string.rfind("abcabc", "ab") # => 3 !2004-07-29 Thu >>> import string >>> string.find("abc", "a") # => 0 >>> string.find("abc", "ab") # => 0 >>> string.find("abc", "d") # => -1 >>> string.find("abcabc", "ab") # => 0 >>> string.find("abcabc", "ab", 3) # => 3 >>> string.find("abcabc", "ab", 3, 4) # => -1 !2004-07-28 Wed >>> import string >>> string.expandtabs("\t") # => ' ' >>> string.expandtabs(" \t") # => ' ' >>> string.expandtabs("\t", 3) # => ' ' !2004-07-27 Tue >>> import string >>> string.capitalize("abc def") # => 'Abc def' >>> string.capwords("abc") # => 'Abc' >>> string.capwords("abc def") # => 'Abc Def' >>> string.capwords("abc def") # => 'Abc Def' >>> string.capwords(" abc def ") # => 'Abc Def' !2004-07-26 Mon >>> import string >>> string.capitalize("abc") # => 'Abc' >>> string.capitalize("ABC") # => 'Abc' !2004-07-25 Sun >>> import string >>> string.atol("111111111111111") 111111111111111L >>> long("111111111111111") 111111111111111L typo リリース 2.0 以降で撤廃された仕様です。 組み込み関数 long() を使ういましょう。 撤廃だけど残っているという意味なのか? !2004-07-24 Sat >>> import string >>> string.atoi(1) Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.2.2/lib/python2.2/string.py", line 220, in atoi return _int(s, base) TypeError: int() can't convert non-string with explicit base >>> string.atoi("1") 1 >>> string.atoi("1.1") Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.2.2/lib/python2.2/string.py", line 220, in atoi return _int(s, base) ValueError: invalid literal for int(): 1.1 >>> string.atoi("111111111111111111") Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.2.2/lib/python2.2/string.py", line 220, in atoi return _int(s, base) ValueError: int() literal too large: 111111111111111111 >>> string.atoi("+") Traceback (most recent call last): File "", line 1, in ? File "/usr/local/Python-2.2.2/lib/python2.2/string.py", line 220, in atoi return _int(s, base) ValueError: invalid literal for int(): + >>> string.atoi("+1") 1 int() でもエラーの動作は同じよう !2004-07-23 Fri >>> import string >>> string.atof("1.2") # => 1.2 >>> float("1.2") # => 1.2 >>> string.atof("1.2.2") Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.1/string.py", line 199, in atof return _float(s) ValueError: invalid literal for float(): 1.2.2 >>> float("1.2.2") Traceback (most recent call last): File "", line 1, in ? ValueError: invalid literal for float(): 1.2.2 !2004-07-22 Thu Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> import string >>> string.ascii_lowercase # => 'abcdefghijklmnopqrstuvwxyz' >>> string.ascii_uppercase # => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits # => '0123456789' >>> string.hexdigits # -> '0123456789abcdefABCDEF' >>> string.letters # => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.lowercase # => 'abcdefghijklmnopqrstuvwxyz' >>> string.octdigits # => '01234567' >>> string.punctuation # => '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' >>> string.printable # => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c' >>> string.uppercase # => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.whitespace # => '\t\n\x0b\x0c\r ' !2004-07-21 Wed Python 2.1.3 (#1, Sep 12 2002, 00:24:18) >>> import string >>> string.ascii_letters Traceback (most recent call last): File "", line 1, in ? AttributeError: 'string' module has no attribute 'ascii_letters' Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> string.ascii_letters Traceback (most recent call last): File "", line 1, in ? NameError: name 'string' is not defined >>> import string >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' !2004-07-20 Tue 例外は例外によりスキップ >>> False # => False >>> True # => True >>> print False # => False >>> None >>> types.NoneType Traceback (most recent call last): File "", line 1, in ? NameError: name 'types' is not defined >>> import types >>> types.NoneType # => >>> NotImplemented # => NotImplemented >>> Ellipsis # => Ellipsis !2004-07-19 Mon Python 2.0 (#3, Feb 17 2001, 13:45:43) >>> import string >>> string.__methods__ Traceback (most recent call last): File "", line 1, in ? AttributeError: __methods__ >>> string.__members__ Traceback (most recent call last): File "", line 1, in ? AttributeError: __members__ !2004-07-18 Sun Python 2.2.2 (#2, Nov 23 2002, 15:32:14) >>> import string >>> string.__dict__ {'ascii_lowercase': 'abcdefghijklmnopqrstuvwxyz', ... >>> string.__methods__ Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute '__methods__' >>> dir(string) ['_StringTypes', ... >>> string.__members__ Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute '__members__' >>> string.__class__ >>> string.__bases__ Traceback (most recent call last): File "", line 1, in ? AttributeError: 'module' object has no attribute '__bases__' !2004-07-17 Sat >>> bool(1) # => 1 >>> print bool(1) # => 1 >>> print bool(True) # => 1 >>> print bool(False) # => 0 !2004-07-16 Fri >>> types Traceback (most recent call last): File "", line 1, in ? NameError: name 'types' is not defined >>> import types >>> types >>> types.__dict__ {'TypeType': , ... !2004-07-15 Thu >>> class C: ... def method(self): ... pass ... >>> c = C() >>> print c.method.im_self <__main__.C instance at 0x8120fac> >>> print c.method.im_func >>> print c <__main__.C instance at 0x8120fac> >>> print c.method >>> c.method.im_func(c.method.im_self) >>> c.method() !2004-07-14 Wed >>> def foo(): ... pass ... >>> print foo.func_code ", line 1> >>> print foo.func_globals {'__doc__': None, 'foo': , '__name__': '__main__', '__builtins__': } >>> print foo.__dict__ None >>> print foo.func_dict None !2004-07-13 Tue >>> f = open("foo", "r") >>> f.newlines >>> print f.newlines # => None >>> f.readline() # => 'abc' >>> print f.newlines # => None >>> f.close() >>> f = open("foo", "r") >>> print f.newlines # => None >>> f.readline() # => 'a\n' >>> print f.newlines # => None >>> print f.softspace# => 0 >>> f.close() seek とかやっていないけど、ファイルオブジェクトはこれで終りにしよう !2004-07-12 Mon Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> f = open("foo", "r") >>> f.encoding >>> print f.encoding # => None >>> f.name # => 'foo' !2004-07-11 Sun >>> f = open("foo", "r") >>> f.mode # => 'r' !2004-07-10 Sat >>> f = open("foo", "r") >>> f.closed() Traceback (most recent call last): File "", line 1, in ? TypeError: 'int' object is not callable >>> f.closed # => 0 >>> f.close() >>> f.closed # => 1 !2004-07-09 Fri >>> f = open("foo", "w") >>> f.write("a") >>> f.writelines(["b", "c"]) >>> f.close() >>> f = open("foo", "r") >>> f.readlines() # => ['abc'] !2004-07-08 Thu Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> f = open("foo", "r") >>> f.xreadlines() # => >>> i = f.xreadlines() >>> i.next() # => 'a\n' >>> i.next() # => 'b\n' !2004-07-07 Wed >>> f = open("foo", "r") >>> f.readlines() # => ['a\n', 'b\n', 'c\n'] !2004-07-06 Tue >>> f = open("foo", "r") >>> f.readline() # => 'a\n' >>> f.readline() # => 'b\n' >>> f.readline() # => 'c\n' >>> f.readline() # => '' >>> f.readline() # => '' !2004-07-05 Mon Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> f = open("foo", "r") >>> iter(f) # => >>> iter(f).next() # => 'a\n' >>> iter(f).next() # => 'b\n' >>> iter(f).next() # => 'c\n' >>> iter(f).next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2004-07-04 Sun >>> f = open("foo", "r") >>> f.tell() # => 0 !2004-07-03 Sat >>> f = open("foo", "r") >>> f.isatty() # => 0 >>> f.fileno() # => 3 ふに? !2004-07-02 Fri Python 2.1.3 (#1, Sep 12 2002, 00:24:18) >>> f = file("foo", "w") Traceback (most recent call last): File "", line 1, in ? NameError: name 'file' is not defined Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> f = file("foo", "w") >>> f.close() なんだとー。いつのまに… file() コンストラクタは Python 2.2 で新たに追加されました。 以前の関数名である open() は互換性のために残されており、 file() の別名となっています。 !2004-07-01 Thu >>> d = {"foo" : 1, "bar" : 2} >>> pairs = zip(d.values(), d.keys()) >>> pairs # => [(1, 'foo'), (2, 'bar')] マップ型終了(のつもり) !2004-06-30 Wed Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> d = {"foo" : 1, "bar" : 2} >>> i = d.iteritems() >>> i >>> i.next() # => ('foo', 1) >>> i.next() # => ('bar', 2) >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i = d.iterkeys() >>> i.next() # => 'foo' >>> i.next() # => 'bar' >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> i = d.itervalues() >>> i.next() # => 1 >>> i.next() # => 2 >>> i.next() Traceback (most recent call last): File "", line 1, in ? StopIteration !2004-06-29 Tue >>> d = {"foo" : 1, "bar" : 2} >>> d.popitem() # => ('foo', 1) >>> d.popitem() # => ('bar', 2) >>> d.popitem() Traceback (most recent call last): File "", line 1, in ? KeyError: popitem(): dictionary is empty !2004-06-28 Mon Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> d = {"foo" : 1, "bar" : 2} >>> d.pop("boo") Traceback (most recent call last): File "", line 1, in ? KeyError: 'boo' >>> d.pop("boo", 999) # => 999 >>> d.pop("foo") # => 1 >>> d # => {'bar': 2} !2004-06-27 Sun >>> d = {"foo" : 1, "bar" : 2} >>> d.setdefault("foo", 999) # => 1 >>> d # => {'foo': 1, 'bar': 2} >>> d.setdefault("boo", 999) # => 999 >>> d # => {'foo': 1, 'boo': 999, 'bar': 2} !2004-06-26 Sat >>> d = {"foo" : 1, "bar" : 2} >>> d.get("foo") # => 1 >>> d.get("boo", 999) # => 999 >>> d.get("poo") >>> print d.get("poo") # => None !2004-06-25 Fri Python 2.3.4 (#2, Jun 25 2004, 10:00:05) >>> d = {"foo" : 1, "bar" : 2} >>> d.fromkeys("boo", 10) # => {'b': 10, 'o': 10} >>> d # => {'foo': 1, 'bar': 2} >>> d.fromkeys(["boo", "qoo"], 10) # => {'qoo': 10, 'boo': 10} >>> d # => {'foo': 1, 'bar': 2} !2004-06-24 Thu >>> d = {"foo" : 1, "bar" : 2} >>> e = {"poo" : 1, "boo" : 2} >>> d.update(e) >>> d # => {'boo': 2, 'bar': 2, 'foo': 1, 'poo': 1} !2004-06-23 Wed >>> d = {"foo" : 1, "bar" : 2} >>> d.items() # => [('foo', 1), ('bar', 2)] >>> d.keys() # => ['foo', 'bar'] >>> d.values() # => [1, 2] !2004-06-22 Tue Python 2.1.3 (#1, Sep 12 2002, 00:24:18) >>> d = {"foo" : 1, "bar" : 2} >>> "foo" in d Traceback (most recent call last): File "", line 1, in ? TypeError: 'in' or 'not in' needs sequence right argument あれ? 2.2 以降じゃないとだめなそうな。 Python 2.2.2 (#2, Nov 23 2002, 15:32:14) >>> d = {"foo" : 1, "bar" : 2} >>> "foo" in d # => 1 >>> "foo" not in d # => 0 !2004-06-21 Mon >>> d = {"foo" : 1, "bar" : 2} >>> d.has_key("foo") # => 1 >>> d.has_key("hoge") # => 0 !2004-06-20 Sun >>> {"foo" : 1, "bar" : 2} # => {'foo': 1, 'bar': 2} >>> d = {"foo" : 1, "bar" : 2} >>> len(d) # => 2 >>> d["hoge"] Traceback (most recent call last): File "", line 1, in ? KeyError: hoge >>> d["foo"] # => 1 >>> d["hoge"] = 100 >>> d # => {'foo': 1, 'hoge': 100, 'bar': 2} >>> del d["hoge"] >>> d # => {'foo': 1, 'bar': 2} >>> d.clear() >>> d # => {} !2004-06-19 Sat マニュアルそのまんま >>> lists = [[]] * 3 >>> lists # => [[], [], []] >>> lists[0].append(3) >>> lists # => [[3], [3], [3]] >>> lists = [[] for i in range(3)] >>> lists[0].append(3) >>> lists[1].append(5) >>> lists[2].append(7) >>> lists # => [[3], [5], [7]] !2004-06-18 Fri xrange もシーケンス型 >>> 1 in xrange(1, 4) # => 1 >>> 8 in xrange(1, 4) # => 0 >>> 1 not in xrange(1, 4) # => 0 >>> 8 not in xrange(1, 4) # => 1 >>> xrange(1, 4) + xrange(5, 7) # => TypeError: cannot concatenate xrange objects >>> xrange(1, 4) * 2 # => (xrange(1, 4) * 2) >>> (xrange(1, 4) * 2)[5] # => 3 >>> 2 * xrange(1, 4) # => (xrange(1, 4) * 2) >>> xrange(1, 4)[0] # => 1 >>> xrange(1, 4)[1] # => 2 >>> xrange(1, 4)[-1] # => 3 >>> xrange(1, 4)[-2] # => 2 >>> xrange(1, 4)[0:0] # => xrange(0) >>> xrange(1, 4)[0:1] # => xrange(1, 2) >>> xrange(1, 4)[0:2] # => xrange(1, 3) >>> xrange(1, 4)[0:-1] # => xrange(1, 3) >>> xrange(1, 4)[0:-2] # => xrange(1, 2) >>> xrange(1, 4)[:] # => xrange(1, 4) >>> len(xrange(1, 4)) # => 3 >>> min(xrange(1, 4)) # => 1 >>> max(xrange(1, 4)) # => 3 >>> x = xrange(1, 4) >>> x[0] = 10 # => TypeError: object doesn't support item assignment !2004-06-17 Thu タプルもシーケンス型 >>> 1 in (1, 2, 3) # => 1 >>> 8 in (1, 2, 3) # => 0 >>> 1 not in (1, 2, 3) # => 0 >>> 8 not in (1, 2, 3) # => 1 >>> (1, 2, 3) + (4, 5, 6)# => (1, 2, 3, 4, 5, 6) >>> (1, 2, 3) * 2 # => (1, 2, 3, 1, 2, 3) >>> 2 * (1, 2, 3) # => (1, 2, 3, 1, 2, 3) >>> (1, 2, 3)[0] # => 1 >>> (1, 2, 3)[1] # => 2 >>> (1, 2, 3)[-1] # => 3 >>> (1, 2, 3)[-2] # => 2 >>> (1, 2, 3)[0:0] # => () >>> (1, 2, 3)[0:1] # => (1,) >>> (1, 2, 3)[0:2] # => (1, 2) >>> (1, 2, 3)[0:-1] # => (1, 2) >>> (1, 2, 3)[0:-2] # => (1,) >>> (1, 2, 3)[:] # => (1, 2, 3) >>> len((1, 2, 3)) # => 3 >>> min((1, 2, 3)) # => 1 >>> max((1, 2, 3)) # => 3 >>> t = (1, 2, 3) >>> t[0] = 10 # => TypeError: object doesn't support item assignment !2004-06-16 Wed 配列はもちろんシーケンス型 >>> 1 in [1, 2, 3] # => 1 >>> 8 in [1, 2, 3] # => 0 >>> 1 not in [1, 2, 3] # => 0 >>> 8 not in [1, 2, 3] # => 1 >>> [1, 2, 3] + [4, 5, 6]# => [1, 2, 3, 4, 5, 6] >>> [1, 2, 3] * 2 # => [1, 2, 3, 1, 2, 3] >>> 2 * [1, 2, 3] # => [1, 2, 3, 1, 2, 3] >>> [1, 2, 3][0] # => 1 >>> [1, 2, 3][1] # => 2 >>> [1, 2, 3][-1] # => 3 >>> [1, 2, 3][-2] # => 2 >>> [1, 2, 3][0:0] # => [] >>> [1, 2, 3][0:1] # => [1] >>> [1, 2, 3][0:2] # => [1, 2] >>> [1, 2, 3][0:-1] # => [1, 2] >>> [1, 2, 3][0:-2] # => [1] >>> [1, 2, 3][:] # => [1, 2, 3] >>> len([1, 2, 3]) # => 3 >>> min([1, 2, 3]) # => 1 >>> max([1, 2, 3]) # => 3 >>> list = [1, 2, 3] >>> list[0] = 10 >>> list # => [10, 2, 3] !2004-06-15 Tue 文字列はシーケンス型 >>> "f" in "foo" # => 1 >>> "a" in "foo" # => 0 >>> "f" not in "foo" # => 0 >>> "a" not in "foo" # => 1 >>> "foo" + "bar" # => 'foobar' >>> "foo" * 2 # => 'foofoo' >>> 2 * "foo" # => 'foofoo' >>> "abc"[0] # => 'a' >>> "abc"[1] # => 'b' >>> "abc"[-1] # => 'c' >>> "abc"[-2] # => 'b' >>> "abc"[0:0] # => '' >>> "abc"[0:1] # => 'a' >>> "abc"[0:2] # => 'ab' >>> "abc"[0:-1] # => 'ab' >>> "abc"[0:-2] # => 'a' >>> "abc"[:] # => 'abc' >>> len("abc") # => 3 >>> min("abc") # => 'a' >>> max("abc") # => 'c' >>> str = "abc" >>> str[0] = "a" # => TypeError: object doesn't support item assignment >>> str[0:1] = "a" # => TypeError: object doesn't support slice assignment >>> "abc"[0] = "a" # => TypeError: object doesn't support item assignment なんだ? s[i:j:k] s の i 番目から j 番目まで、k 毎のスライス !2004-06-14 Mon >>> r = xrange(1,10) >>> 0 in a # => 0 >>> 1 in a # => 1 >>> 10 in a # => 0 >>> 9 in a # => 1 >>> 10 not in a # => 1 >>> a.min() Traceback (most recent call last): File "", line 1, in ? AttributeError: min >>> min(a) # => 1 >>> max(a) # => 9 !2004-06-13 Sun >>> int(1) # => 1 >>> int("1") # => 1 >>> type(int(1)) # => >>> type(long(1)) # => >>> float(1) # => 1.0 >>> complex(1) # => (1+0j) >>> abs(-1) # => 1 >>> complex(1+1j).conjugate() # => (1-1j) >>> (1+1j).conjugate() # => (1-1j) >>> divmod(10,3) # => (3, 1) >>> pow(2,3) # => 8 >>> 2 ** 3 # => 8 >>> [1, 2] == [1.0, 2.0] # => 1 >>> [1, 2] is [1.0, 2.0] # => 0 !2004-06-12 Sat >>> 1 < 2 < 3 # => 1 >>> 2 < 1 < 3 # => 0 >>> 1 != 1 # => 0 >>> 1 <> 1 # => 0 != もあったのか。 != のほうが望ましい書き方です; <> は廃止すべき書き方です。 だそうな。 >>> "a" == "a" # => 1 >>> a1 = "a" >>> a2 = "a" >>> a1 == a2 # => 1 >>> "0" == 0 # => 0 >>> "0" > 0 # => 1 >>> "0" < 0 # => 0 >>> import types >>> 0 is types.IntType # => 0 >>> type(0) == types.IntType # => 1 勘違い >>> 0 is 0 # => 1 >>> 0 is not 0 # => 0 >>> a1 = [1,2,3] >>> a2 = [1,2,3] >>> a1 is a2 # => 0 !2004-06-11 Fri >>> 1 or 0 # => 1 >>> 1 and 0 # => 0 >>> not 1 # => 0 >>> not 1 == 1 # => 0 >>> 1 == not 1 # => SyntaxError: invalid syntax これらの演算子は、演算を行う上で必要がない限り、二つ目の引数を評価しません。 例が作れない…。 !2004-06-10 Thu # Python 2.0 >>> print None # => None >>> print False Traceback (most recent call last): File "", line 1, in ? NameError: There is no variable named 'False' >>> print 0 # => 0 >>> print 0L # => 0 >>> print 0.0 # => 0.0 >>> print 0.0j # => 0j >>> def is_false(arg): ... if arg: ... print "true" ... else: ... print "false" ... >>> is_false(None) # => false >>> is_false(0) # => false >>> is_false(0L) # => false >>> is_false(0.0) # => false >>> is_false(0.0j) # => false >>> is_false('') # => false >>> is_false(()) # => false >>> is_false([]) # => false >>> is_false(1) # => true