書いたエントリは、引っ込めれない。
上記のエントリに対して、id:bonlife氏よりコメントを頂きました。
ありがとうございます。(実は、僕ひそかに氏のブログの購読者だったりします。)
まさか、SOS団のカウンタよろしく、カウンタのほとんどを自分で
回しているようなブログにコメントが書かれるとは、思いもせず、
変な興奮状態に陥っています。
しかも、
期待してます。
と期待までして頂いた。
これはあれでしょうか?選択肢が、
1. ソースを読む
2. ソースを読む
3. ソースを読む
という状況なのでしょうか。
そうですか。はい、頑張ります!!
Pythonモジュールのソースを読もうとしたら、C言語のソースにぶち当たった
PythonのRandomモジュールのソースコードを読んでみようと思い立ち、
random.pyを開いたら、
import _random
と、_randomっていうモジュールが読み込まれていて、
これがRandomクラスの親クラスになっていた。
はて、_random.pyってあったっけ?と思い、ディレクトリ内を探したんだけど
見つからなくて、ネットで情報収集してみたら、これって_random.soっていう
共有ファイルらしい。で、この_random.soが、どのソースから作られているかも
調べたら、_randommodule.cというC言語で書かれたソースファイルが、
それらしい。
...読むか。
Perlクックブックのお題をPythonで解いてみた その16
レシピ2.6 乱数を生成する
#!/usr/bin/env python # -*- coding: utf-8 -*- import random # 25 <= n <= 75 の乱数を1つ生成する print random.randrange(25,75+1) print random.randint(25,75) # a から z までの文字から10個を無作為に抽出する str = "abcdefghijklmnopqrstuvwxyz" listStr = [ str[random.randrange(0,len(str))] for n in range(10)] print ''.join(listStr)
#!/usr/bin/env python # -*- coding: utf-8 -*- from random import Random # 25 <= n <= 75 の乱数を1つ生成する rand = Random() print rand.randrange(25,75+1) print rand.randint(25,75) # a から z までの文字から10個を無作為に抽出する str = "abcdefghijklmnopqrstuvwxyz" listStr = [ str[rand.randrange(0,len(str))] for n in range(10)] print ''.join(listStr)
さて、上の2つ、結果として同じ処理を行っている訳ですが、
ソースコードが、微妙に違います。
違う部分というのは、モジュールのインポート部分。
上の方のインポート部分が、
import random
なのに対して、下のものは
from random import Random
となってします。
これは、どちらもrandomモジュール内のRandomクラスをインポートしています。
randomモジュールには、Randomクラスの他にWichmannHillクラスと
SystemRandomクラスが定義されています。
下のソースは、この中のRandomクラスをインポートすることを、
プログラマが明示的に書いている形になります。
では、上のソースは、どのような仕組みになっているのかというと、
randomモジュールの最後の方で、実はRandomクラスを用いてインスタンスを
生成しているのです。
random.py Line 828
_inst = Random() seed = _inst.seed random = _inst.random uniform = _inst.uniform randint = _inst.randint choice = _inst.choice randrange = _inst.randrange sample = _inst.sample shuffle = _inst.shuffle normalvariate = _inst.normalvariate lognormvariate = _inst.lognormvariate expovariate = _inst.expovariate vonmisesvariate = _inst.vonmisesvariate gammavariate = _inst.gammavariate gauss = _inst.gauss betavariate = _inst.betavariate paretovariate = _inst.paretovariate weibullvariate = _inst.weibullvariate getstate = _inst.getstate setstate = _inst.setstate jumpahead = _inst.jumpahead getrandbits = _inst.getrandbits
この部分があるので、プログラマは、Randomクラスを明示的にインポートして
インスタンスを作ることなく、メソッドをしようすることが可能なのです。
(偉そうに書いているけど、これ、リファレンスにも書いてあるという事実)
ブログとか作ってみたいかと その3.1
データベースの修正
Blobテーブル
カテゴリ情報を追加しました。
class Blog(SQLObject): blog_name = UnicodeCol(length=32) description = UnicodeCol(length=128) user_id = ForeignKey('User') entries = MultipleJoin('Entry') Categories = MultipleJoin('Category')
Categoryテーブル
ブログIDを追加しました。
class Category(SQLObject): category_name = UnicodeCol(unique=True,length=16) entris = RelatedJoin('Entry') blog_id = ForeignKey('Blog')
ブログとか作ってみたいかと その3
データベースの設定
プロジェクトを作成したので、次に使用するデータベースの設定を行います。
tgBlogディレクトリ配下にある「dev.cfg」ファイルを
編集することによって設定が可能となります。
「dev.cfg」ファイルを開くと、以下のように書かれた箇所が見れます。
# DATABASE
# pick the form for your database
# sqlobject.dburi="postgres://username@hostname/databasename"
# sqlobject.dburi="mysql://username:password@hostname:port/databasename"
# sqlobject.dburi="sqlite:///file_name_and_path"# If you have sqlite, here's a simple default to get you started
# in development
sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
これをみると、PostgreSQL、MySQL、sqliteのうちいずれかが選択可能なようです。
また、デフォルトはsqliteであり、tgBlogディレクトリ配下に
devdata.sqliteという名前のファイルを作成するようになっています。
tgBlogでは、sqliteを用いて、またtgBlogディレクトリ配下に
データベース用のファイルを作成しようと考えているので、
特に設定を変更する必要もないのですが、ファイル名だけでも変更しておくことにします。
sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
をコメントアウトし
#sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
そして、
# sqlobject.dburi="sqlite:///file_name_and_path"
という部分のコメントをはずし、パスとファイル名を指定します。
sqlobject.dburi="sqlite:///home/hoge/python/tg/tgBlog/tgblog.db"
Modelの編集
データベースの設定が終わったので、
次にデータベース上の各情報が保存されているテーブルと
やりとりを行うためのModelの編集を行います。
「tgBlog/tgblog」ディレクトリ配下にあるmodel.pyを編集します。
model.pyを開くと以下のようにコードが書かれてます。
from datetime import datetime from turbogears.database import PackageHub from sqlobject import * from turbogears import identity hub = PackageHub('tgblog') __connection__ = hub # class YourDataClass(SQLObject): # pass ・ ・ ・
・・・以降には、認証用の「Visitクラス」、「VisitIdentityクラス」、
「Groupクラス」、「Userクラス」、「Permissionクラス」が定義されています。
では、今回扱うそれぞれの情報について、クラスを宣言していきます。
ブログ情報
class Blog(SQLObject): blog_name = UnicodeCol(length=32) description = UnicodeCol(length=128) user_id = ForeignKey('User') entries = MultipleJoin('Entry')
クラスは、SQLObjectを継承して作成します。
Blogクラスには、ブログの名前、ブログの説明、所有するユーザを表すID、そのBlogに登録されたエントリについての4つの情報を定義します。
エントリ情報
class Entry(SQLObject): title = UnicodeCol(length=64) body = UnicodeCol(length=2048) created = DateTimeCol(default=datetime.now) blog_id = ForeignKey('Blog') comments = MultipleJoin('Comment') categories = RelatedJoin('Category')
Entryクラスには、エントリのタイトル、本文、作成日、エントリが登録されるブログのID、コメント、カテゴリについて定義します。
Comment情報
class Comment(SQLObject): user_name = UnicodeCol(length=32) title = UnicodeCol(length=32) comment = UnicodeCol(length=256) created = DateTimeCol(default=datetime.now) entry_id = ForeignKey('Entry')
Commentクラスには、コメントの投稿主の名前、タイトル、コメント本文
作成日、どのエントリに対してのコメントなのかの情報について定義します。
Category情報
class Category(SQLObject): category_name = UnicodeCol(unique=True,length=16) entris = RelatedJoin('Entry')
Categoryクラスには、カテゴリ名と、各カテゴリが付いているエントリ情報に
ついて定義します。
テーブルの作成
クラスを定義したら、テーブルを作成します。
テーブルの作成は、tgBlogディレクトリで
以下のコマンドを入力することでできます。
$ tg-admin sql create
テーブルの作成が成功すると、以下のようなメッセージが出力されます。
Using database URI sqlite:///home/hoge/python/tg/tgBlog/tgblog.db
そして、
-rw-r--r-- 1 hoge hoge 23552 10月 27 23:10 tgblog.db
というファイルが作成されます。
テストデータの入力
テストデータを入力するために、コマンドシェルを立ち上げます。
シェルを立ち上げるためには、「tg-admin」コマンドを「shell」オプションを付けて実行します。
$ tg-admin shell
すると、シェルが立ち上がります。
Python 2.4.3 (#1, Oct 23 2006, 14:19:47) [GCC 4.1.1 20060525 (Red Hat 4.1.1-1)] on linux2 Type "help", "copyright", "credits" or "license" for more information. (CustomShell) >>>
ユーザ情報
User(user_name='hoge',email_address="hoge@hoge.com",display_name='hoge',password='hoge')
>>> u = User.get(1) >>> u >>> <User 1 user_name=u'hoge' email_address=u'hoge@hoge.com' display_name=u'hoge' password=u'hoge' created='datetime.datetime...)'>
ブログ情報
>>> Blog(blog_name='Test Blog',description='Test',user_id=1) <Blog 1 blog_name=u'Test Blog' description=u'Test' user_id=1>
>>> b = Blog.get(1) >>> b <Blog 1 blog_name=u'Test Blog' description=u'Test' user_id=1>
カテゴリ情報
>>> Category(category_name='test') <Category 1 category_name=u'test'>
>>> c = Category.get(1) >>> c <Category 1 category_name=u'test'>
エントリ情報
>>> Entry(title=u'test' body=u'test' created='datetime.datetime...)' blog_id=1) <Entry 1 title=u'test' body=u'test' created='datetime.datetime...)' blog_id=1>
>>> e = Entry.get(1) >>> e <Entry 1 title=u'test' body=u'test' created='datetime.datetime...)' blog_id=1>
カテゴリの追加
>>> e.addCategory(1)
>>> e.categories [<Category 1 category_name=u'test'>]
コメント情報
>>> Comment(user_name='test',title='title_comment',comment="comment test",entry_id=1) <Comment 1 user_name=u'test' title=u'title_comment' comment=u'comment test' created='datetime.datetime...)' entry_id=1>
>>> c = Comment.get(1) >>> c <Comment 1 user_name=u'test' title=u'title_comment' comment=u'comment test' created='datetime.datetime...)' entry_id=1>
Perlクックブックのお題をPythonで解いてみた その13
レシピ2.2 浮動小数点を丸める
#!/usr/bin/env python2.4 # -*- coding: utf-8 -*- # 小数点第2位で丸め込み fnum = 0.74 print "%.1f" % fnum fnum = 0.75 print "%.1f" % fnum
結果
$ ./recipe22.py 0.7 0.8
ブログとか作ってみたいかと その2
プロジェクトの作成
PythonやTurboGearsなど、開発に必要なものは
既にインストール済みなので、早速プロジェクトを生成する。
TurboGearsでプロジェクトを生成するには、
「tg-admin」コマンドを使用する。
$ tg-admin quickstart
Enter project name: tgBlog
Enter package name [tgblog]:
Do you need Identity (usernames/passwords) in this project? [no] yes
これで、ユーザ認証が可能なプロダクトが生成される。
以下のようなディレクトリができる。
drwxrwxr-x 4 hoge hoge 4096 10月 25 23:52 tgBlog
で、ディレクトリの中身をみると
-rw-rw-r-- 1 hoge hoge 122 10月 25 23:52 README.txt -rw-rw-r-- 1 hoge hoge 1909 10月 25 23:52 dev.cfg -rw-rw-r-- 1 hoge hoge 2589 10月 25 23:52 sample-prod.cfg -rw-rw-r-- 1 hoge hoge 2117 10月 25 23:52 setup.py -rw-rw-r-- 1 hoge hoge 1194 10月 25 23:52 setup.pyc -rwxrw-r-- 1 hoge hoge 797 10月 25 23:52 start-tgblog.py -rw-rw-r-- 1 hoge hoge 122 10月 25 23:52 test.cfg drwxrwxr-x 2 hoge hoge 4096 10月 25 23:52 tgBlog.egg-info drwxrwxr-x 7 hoge hoge 4096 10月 25 23:52 tgblog
Webアプリの雛型を立ち上げるには、以下のようにする。
$ ./start-tgblog.py
すると、びゃ〜と以下のようにログが出力され、
テスト用のサーバが立ち上がる。
2007-10-26 00:09:13,950 cherrypy.msg INFO CONFIG: Server parameters: 2007-10-26 00:09:13,951 cherrypy.msg INFO CONFIG: server.environment: development 2007-10-26 00:09:13,951 cherrypy.msg INFO CONFIG: server.log_to_screen: True 2007-10-26 00:09:13,951 cherrypy.msg INFO CONFIG: server.log_file: 2007-10-26 00:09:13,952 cherrypy.msg INFO CONFIG: server.log_tracebacks: True 2007-10-26 00:09:13,952 cherrypy.msg INFO CONFIG: server.log_request_headers: True 2007-10-26 00:09:13,952 cherrypy.msg INFO CONFIG: server.protocol_version: HTTP/1.0 2007-10-26 00:09:13,953 cherrypy.msg INFO CONFIG: server.socket_host: 2007-10-26 00:09:13,953 cherrypy.msg INFO CONFIG: server.socket_port: 8080 2007-10-26 00:09:13,954 cherrypy.msg INFO CONFIG: server.socket_file: 2007-10-26 00:09:13,954 cherrypy.msg INFO CONFIG: server.reverse_dns: False 2007-10-26 00:09:13,954 cherrypy.msg INFO CONFIG: server.socket_queue_size: 5 2007-10-26 00:09:13,955 cherrypy.msg INFO CONFIG: server.thread_pool: 10 2007-10-26 00:09:14,003 turbogears.visit INFO Visit Tracking starting 2007-10-26 00:09:14,036 turbogears.visit.sovisit INFO Succesfully loaded "tgblog.model.Visit" 2007-10-26 00:09:14,036 turbogears.visit INFO Visit filter initialised 2007-10-26 00:09:14,153 turbogears.identity INFO Identity starting 2007-10-26 00:09:14,195 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.User" 2007-10-26 00:09:14,196 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.Group" 2007-10-26 00:09:14,196 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.Permission" 2007-10-26 00:09:14,197 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.VisitIdentity" 2007-10-26 00:09:14,238 turbogears.identity INFO Identity visit plugin initialised 2007-10-26 00:09:14,242 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.User" 2007-10-26 00:09:14,242 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.Group" 2007-10-26 00:09:14,243 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.Permission" 2007-10-26 00:09:14,243 turbogears.identity.soprovider INFO Succesfully loaded "tgblog.model.VisitIdentity" 2007-10-26 00:09:14,446 cherrypy.msg INFO HTTP: Serving HTTP on http://localhost:8080/