また人のブログを読んでたんですが。
うん、プログラムなんざ動けば良いのだ。
一つだけ問題があるとすれば、星田さん(でいいのかな?)はファイルを開いてるけど、閉じるのを忘れている(笑)。
開いたファイルは必ず閉じないとならないのだ。そう、openには必ずcloseが必要。この二つはコンビなのだ。
ただ、忘れちまうんだよな〜(笑)。確かにメンド臭い。
そういう僕みたいなものぐさな人の為に、Pythonはwithと言う機能を提供してる。withはブロックを伴い、withを抜けた時にファイル読み書きの場合は自動的にファイルを閉じてくれる。
>>> with open('workfile') as f:read_data = f.read()
これも多分、ANSI Common Lispから借りてきた機能だと思う。Pythonは関数型言語の発想に拠るところが凄く多いのだ。つまりC言語なんかにはこんな機能はない。
いずれにせよ、ファイルを開く時は、読み書きに関わらず、withを伴った方が安全だ。僕もcloseを忘れる事には自信がある(爆
さて、OPMLなるフォーマットは全く知らないが。面白そうなんで、僕だったらこう書く、と言うのを例示しておこう。どっちにせよ動けば良いのだ。
件のブログによると、使われてる無理ゲー社会なるテキストファイルは多分写真を読む限り、次のようなブツになってるんじゃないか。知らんけど。
無理ゲー社会
難解な世界を単純化する陰謀論が脳には必要
人は自尊心が傷つくことを何としても避ける
自尊心は社会での自分の存在価値の尺度
ファクトでなくてアイデンティティ
一夫一妻制は男の凶暴性(共同体のトラブル)を抑えるため
近代の場合は徴兵制など国力を高めるため
モテ非モテ問題はリベラルの結果
女は若さと美しさ男は金
平和が続けば不平等になるのはしょうがない
アメリカでは有効でも日本では普通の富裕税でないと
職業訓練などは特に女性に有効
失業者にもいろいろいる
共同所有自己申告税
保有ではなく使用する価値へ
お金はいつか分配ができるが評判は出来ない
豊かになればより非モテは悲惨になる
コンストラクタル理論
より遠くへ速くなめらかに流れるものが目的
物理にも意思があるという事
人間の脳は本質的に他社とコネクトするように作られている
脳をネットにつないで集合の一部として生きる未来
上級国民 = 自分らしく生きていける人々
下級国民 = 自分らしく生きて行くように圧力をかけられるが実現できない人々
多分一行目辺りにタイトルが入ってるような事をブログで書いてたんで、こういう形式なんじゃないか、と想像してる。
間違ってたらゴメン。
取り敢えず僕だったらこう書く、と言う例。
#! /usr/bin/env python3
table = {"head": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<opml version=\"1.0\">\n\
\t<head>\n\
\t\t<title>{}</title>\n\
\t\t<expansionState>0</expantionState>\n\
\t</head>\n\
\t<body>\n",
"outline": "\t\t<outline text = \"{}\"/>\n",
"tail": "\t\t</outline>\n\
\t</body>\n\
</opml>\n"}
def make_opml(name):
with open(name + ".txt", "r") as f:
return table["head"].format(name) + \
"".join([table["outline"].format(s.strip()) for s in f.readlines()])\
+ table["tail"]
if __name__ == "__main__":
print(make_opml(input("ファイル名をお願いします: ")), end = "")
まず一行目。#! /usr/bin/env python3だが、これは通称、Shebangと呼ばれる。このスクリプトがどこで起動されようとPythonインタプリタ本体を探し出してくれるオマジナイだ。Sharp(#)とbang(!)でSharp-bang、略してShebangだな。日本語だとシェバングとかシバンとか言われてる。
元々、UNIX/Linuxのスクリプトの流儀なのだが、最近のPythonは賢くて、Windowsでこれを記述しても見事Pythonの在り処を探してくれるようになってくれた(Python3じゃなくってPythonかもしれないが)。
二行目からはPythonの辞書型の登場だ。OPMLの仕様は良く分からんが、ザーッと調べた結果、最低でも3つのパートでなんとかなるんじゃねーの、と言う希望的観測で"head"と"outline"と"tail"の3つを設定してる。
>>> table["head"]
'<?xml version="1.0" encoding="UTF-8"?>\n<opml version="1.0">\n\t<head>\n\t\t<title>{}</title>\n\t\t<expansionState>0</expantionState>\n\t</head>\n\t<body>\n'
>>> table["outline"]
'\t\t<outline text = "{}"/>\n'
>>> table["tail"]
'\t\t</outline>\n\t</body>\n</opml>\n'
>>>
出力の見栄えを良くする為にタブ(\t)や改行(\n)を入れてるが本質的な問題ではない。
なお、例えばtable["outline"]の値等に於いて"{}"なんつーのが使われてるが、これは文字列に「ここに何か埋め込みます」と言うサインを表している。
それは次に説明しよう。
関数本体は次のような感じだ。
def make_opml(name):
with open(name + ".txt", "r") as f:
return table["head"].format(name) + \
"".join([table["outline"].format(s.strip()) for s in f.readlines()])\
+ table["tail"]
先にも書いた通り、nameで受け取ったファイルを開く為にwithを用いている。
そして、headとoutlineとtailを組み合わせた文字列を返している。
細かく見ていこう。
まずはheadのtable["head"].format(name)と言う部分。
さっき見た通り、table["head"]は次のような文字列を返す。
>>> table["head"]
'<?xml version="1.0" encoding="UTF-8"?>\n<opml version="1.0">\n\t<head>\n\t\t<title>{}</title>\n\t\t<expansionState>0</expantionState>\n\t</head>\n\t<body>\n'
>>>
ここでポイントは<title>{}</title>と言う部分。ここにテキストのタイトルが入る筈、つまり<title>無理ゲー社会</title>になって欲しい筈なのだが、要するにこの<title>〜</title>の間にはまずはnameを挟みたい筈なのだ。
この{}を穴埋めして欲しい時に使うのがformatメソッドである。
>>> table["head"].format("無理ゲー社会")
'<?xml version="1.0" encoding="UTF-8"?>\n<opml version="1.0">\n\t<head>\n\t\t<title>無理ゲー社会</title>\n\t\t<expansionState>0</expantionState>\n\t</head>\n\t<body>\n'
>>>
これでtitleタグの問題は解消される。
ハッキリ言うと、ここで使ってる主要テクニックはこれだけ、である。
そしてoutlineに対しても同じ事をやってるに過ぎない。
>>> table["outline"].format("女は若さと美しさ男は金")
'\t\t<outline text = "女は若さと美しさ男は金"/>\n'
>>>
使った文章例は世知辛いが(笑)、ホンマ、基本テクニックはこれだけ、なのである。
もちろん、元々のコードのように文字列を+を使って連結しても悪くはないが、メンド臭いだろう(笑)。formatはPython3の目玉機能と言って良く、バンバン使うべきだと思う(多分C#のそれに影響を受けて追加した機能だろう)。
あと、outlineに文章本体が順番にハマっていくので、そうなるとまたもやリスト内包表記の出番である。for文なんぞは使わず、ハナクソをほじってる間に書けるようにすべきPythonの強力な機構である。
もう一つのポイントはf.readlines()も返り値はリストだし、リスト内包表記もリストを返す。これらの要素である文字列を全部結合するにはどうすれば良いのか、と言う問題がある。
形式的には次のようなリストになってるわけだな。
["A", "B", "C", "D"]
この中身を全部結合して"ABCD"と言う文字列を作りたい。
この場合、ちょっとトリッキーなんだけど、次のように書く。
>>> "".join(["A", "B", "C", "D"])
'ABCD'
>>>
joinと言うメソッドを使うのだ。そうすればリスト内包表記で得られた文字列のリストを単一の文字列へと変換する事が出来る。
なお、ザーッとOPMLの仕様を見る限り、
<outline text = "hoge"></outline><outline text = "fuga"></outline><outline text = "piyo"></outline>
とする必要はなく、
<outline text = "hoge"/><outline text = "fuga"/><outline text = "piyo"/></outline>
で充分な筈だ・・・・・・間違ってたらゴメン(笑)。
なお、元々のコードで、
でエラーが出た原因として、次のように述懐してたが、
もしかしてだけど・・「’(シングルクォーテーション)」で囲うことにしてみたら行けたりする・・わけないか・・?
行けたよオイ! なんとな~・・もしかしてこういう時のために同じ役割なのに「’」と「”」の2つが用意されていたということ?役割カブった機能とか混乱するやろwアホス(^^) とか思っててごめんなさい。
とか書いてるけど、勘違い、である。
もちろん、シングルクオテーションで挟む、と言うのは正解なのだが、エラーが出た原因はクオテーションの数の帳尻が合ってないから、なのだ。
つまり、
datalist[l] = "<outline text="" + datalist[l] + "></outline>""
だと文字列の解釈がおかしくなってるのである。
要するに、上の書き方だと、
"<outline text=" -> ここで一つの文字列" + datalist[l] + " -> ここで一つの文字列></outline> -> ここは文字列じゃない"" -> 空文字列
になっちゃってて、これは意図するトコではないだろう。
元々のコードの写真を見れば分かると思うが、文字列部分とそうじゃないトコの色味がおかしい、のに気づくだろうか。
だからエラーが出たのである。
こういう場合は、もちろんシングルクオテーションで囲むのも正解だが、本来は次のように書くべきなのだ。
datalist[l] = "<outline text=\"" + datalist[l] + "></outline>"
そう、エスケープシーケンス("\")を使うのが正解なのだ。"と"で挟まれた文字列内で"と言う記号を使いたい場合、"だけ使うと上で見たようなおかしな結果になる。
そこで、「文字列中で"を使いたいんじゃ」って場合はエスケープシーケンスを使って「\"」と記述するのがC言語由来の正しいやり方なのである。
もちろん、そのメンド臭さを嫌ってシングルクオテーションとダブルクオテーションも同じ意味になってるのがPythonのPythonたる所以ではあるんだけどね。
いずれにせよ、エスケープシーケンスの「使い方」を学んでおいて損はないと思う。
さて、あとはここだけだ。
if __name__ == "__main__":
print(make_opml(input("ファイル名をお願いします: ")), end = "")
Pythonではシェバングと合わせ、スクリプトを「端末で動かすマトモなプログラムとしたい場合」、上のようなif __name__ == "__main__":を利用する。
これは見方を変えると、C言語に於けるmain関数のようなモノだ。
ここでグダグダ書くよりも、次のページでも参考にしたら良いだろう。
これで終わり、である。
動作結果は次のようになる。
ファイル名をお願いします: 無理ゲー社会
<?xml version="1.0" encoding="UTF-8"?>
<opml version="1.0">
<head>
<title>無理ゲー社会</title>
<expansionState>0</expantionState>
</head>
<body>
<outline text = "無理ゲー社会"/>
<outline text = "難解な世界を単純化する陰謀論が脳には必要"/>
<outline text = "人は自尊心が傷つくことを何としても避ける"/>
<outline text = "自尊心は社会での自分の存在価値の尺度"/>
<outline text = "ファクトでなくてアイデンティティ"/>
<outline text = "一夫一妻制は男の凶暴性(共同体のトラブル)を抑えるため"/>
<outline text = "近代の場合は徴兵制など国力を高めるため"/>
<outline text = "モテ非モテ問題はリベラルの結果"/>
<outline text = "女は若さと美しさ男は金"/>
<outline text = "平和が続けば不平等になるのはしょうがない"/>
<outline text = "アメリカでは有効でも日本では普通の富裕税でないと"/>
<outline text = "職業訓練などは特に女性に有効"/>
<outline text = "失業者にもいろいろいる"/>
<outline text = "共同所有自己申告税"/>
<outline text = "保有ではなく使用する価値へ"/>
<outline text = "お金はいつか分配ができるが評判は出来ない"/>
<outline text = "豊かになればより非モテは悲惨になる"/>
<outline text = "コンストラクタル理論"/>
<outline text = "より遠くへ速くなめらかに流れるものが目的"/>
<outline text = "物理にも意思があるという事"/>
<outline text = "人間の脳は本質的に他社とコネクトするように作られている"/>
<outline text = "脳をネットにつないで集合の一部として生きる未来"/>
<outline text = "上級国民 = 自分らしく生きていける人々"/>
<outline text = "下級国民 = 自分らしく生きて行くように圧力をかけられるが実現できない人々"/>
</outline>
</body>
</opml>
>>>
多分、こんなモンじゃないかな?
あとはファイルに書き出すだけ、である。