みろりHP


緑色さんの多目的ブログ
みろりえいちぴー(旧)
引っ越し先 みろりHP: https://www.mrrhp.com
| カテゴリ:- |
スポンサーサイト

一定期間更新がないため広告を表示しています

| スポンサードリンク | - | - |
| カテゴリ:感想文 |
サガン『悲しみよ こんにちは』



親愛なるルームメイトが読んでいたので興味をひかれ、俺も読んでみた。ただ内容には惹かれるところが今回はあまりなかったので、サマリと簡単な感想だけ書く。



裕福なうちのお嬢さん、セシルは愛するやもめの父レイモン、その愛人エルザと海辺の別荘でバカンスを過ごす。三人とも似たような享楽的な性格なので楽しくやれるし、海辺ではシリルというグッドなボーイフレンドを見つけるし、サイコーのバカンスである。しかしそこへ父がふるい友人、アンヌを招待する。アンヌは超然としており規範を重んじる人物だ。セシルとは心底合わないタイプである。そんな人物と、父は再婚すると言い出す。アンヌは娘となるセシルに勉強をさせ、シリルと距離をおかせる。セシルは、このままでは自分が誘導され作り変えられてしまうと感じる。そしてこう思う、父とわたしの昔の生活を取り戻さなくてはと。セシルは父にフラれたエルザと、自分の恋人シリルを利用し陰謀を企てる。ふたりに恋人のふりをさせ、自分にフラれたことなど気にしていないエルザの様子を父に見せつければ、父はきっとふたたびエルザになびくだろうというわけだ。陰謀はうまく運び、父はエルザと会いキスをし、アンヌはそれを目にする。別荘を離れようとするアンヌをセシルは見つけ、その顔をみる。それは傷ついた泣き顔で、そのときセシルは生身の人間の心を侵してしまったことを知る。セシルは必至にアンヌを止めるも、アンヌは車で走り去ってしまう。その夜、別荘にアンヌの訃報が届く。彼女は自動車事故多発場所で死亡したという。その後セシルはシリルと別れ、父はエルザと別れ、パリへ帰る。ふたりとも新しい恋人を見つけ、もとの暮らしに戻ったが、ある感情がセシルの中に漂っていることだけが違った。ときおりその夏の暮らしのことを思い出すと、アンヌの名とともにそれが胸にこみ上げてきて、セシルはその名を呼ぶのだった。悲しみよ、こんにちは。



この小説はつまり、セシルちゃんにとっての「悲しみ」という感情を論述するものだ。その証に、物語のはじめとさいごで変わっているものはセシルが「悲しみ」を獲得したという点だけである。セシルはステキなボーイフレンドであるシリルくんとの出会いがあったし、父レイモンにはエルザとのなんやかんやがあったにもかかわらず、結局ふたりとも物語の最後には他の誰かをみつけ、ふらふらとした生活を続けている。それは「この親子マジで頭と尻が軽いんだな…」と評価するべきものではなく、「この話は『悲しみ』にフォーカスを当てることが目的なので、ヘタに他のどーでもよい部分に変化をもたせると『悲しみ』が際立たなくなってしまう」という理屈なんじゃねーかな。

しかしこの話、心情描写がスゲー緻密で感心した。これぞ文才って感じだよな。語り手のセシルはちょっとおバカな女の子って位置づけだと思うんだけど、地の文が緻密なもんで「いやお前、ゼッテーバカじゃねーだろ!」ってツッコみっぱなしだったぜ。

ちなみに、読み終わったあと感想でも言い合おうかと思いルームメイトと喋ったんだが、奴は読了すらしておらず図書館に返却してた。うんまあ、俺たちが共感を抱くようなタイプの話ではないよな。
 
| 緑色 | 感想文 | comments(0) |
| カテゴリ:ゲーム |
MHX 村クエレベル5まで



村クエレベル4までコンプしてから一ヶ月以上たったんだけど、いまだにレベル5までしかクリアーしておらん。行く手を阻んでいるのはレベル6の闘技場、五頭連続狩猟。



このクエだけ敵の攻撃とタフネスが異常に高いのはどうなってんだ? 一頭クエだとしても苦戦必至だというのに、画像の通り二頭倒した時点で30分以上が経過しており、かなり無理くさい。数週間このクエで詰まっているのでさすがにそろそろモチベーションが下がり気味だ。



チャージストライカー、弓ストライカー、太刀エリアル、大剣エリアル、ときて今は双剣ブシドーをやっている。俺の好みとしてはブシドーがいちばんかな。エリアルは使っててスゲー楽しいのだが、跳躍中に敵の突進でふっ飛ばされるのが存外ストレスフルなのだよな。

 
| 緑色 | ゲーム | comments(0) |
| カテゴリ:プログラミング |
Python 自作grep



いやその、このあいだディレクトリ単位でテキスト置換をするツールをがんばって作ったじゃあないですか。その後、「ようし、次は大文字小文字区別のオンオフ機能をつけたり、してみよう」とかわくわくしてたわけですよ。その一環としてネットで調べ物をしていたら、その機能って今使ってるエディタにデフォルトでついてたのな…。実際に使ってみたらヒジョ〜に使いやすく高速で、わくわくも高速でぶっ飛んでいったんですね。けれどまあ、せっかく思いついた目標なので「コーディングの練習になるからいいんです(震え声)」と書いたのが今回のブツ。





こんな風に設定すると、



こんな風に出る。細かいテストはしてないんでいきなり実戦投入はやめたほうが吉。sublime text3のgrep機能使ったほうが全然いいぜ。俺もそっちを使うしな! じゃあなんで作ったのかって? 作るのが楽しいからですよ。
 

# トップレベルファイル my_grep.py

RE   = 0   # 1にすると正規表現ON
CS   = 0   # 1にすると大文字小文字区別ON
FIND = 1   # 1にすると検索結果を一覧に出す
REPL = 0   # 1にすると置換する
NAME = 1   # 1にするとファイル名・フォルダ名も検索あるいは置換する

DIR  = "C:/python/my_grep実験用"   # 末尾にスラッシュ入れないこと
FW   = "real"
RW   = ""
EXT  = [""]   # 対象にしないファイル拡張子

import os, re
import sys, traceback
import my_grep_searchFile as s
import my_grep_replaceFile as r

def makeDirs():
    ### 全ディレクトリのパスをdirsに格納する ###
    dirs = []
    dirs.append(DIR)
    for directory in dirs:
        files = os.listdir(directory)
        for f in files:
            path = directory + "/" + f
            if os.path.isdir(path):
                dirs.append(path)
    return dirs

def checkExt(path):
    ### ハブく拡張子だったらTrueを返す ###
    root, ext = os.path.splitext(path)
    if ext in EXT:
        return True
    else:
        return False

### FINDが1だったときやること ###
def find(dirs):
    finds   = []
    errorsF = []
    for directory in dirs:
        things = os.listdir(directory)
        for thing in things:
            path = directory + "/" + thing
            try:
                if not checkExt(path):                   # 指定した拡張子が含まれてなければ続行
                    find = s.searchFile(thing, path)     # 見つからないときはNoneが返ってくる
                    if find:                             # ワードが見つかったなら続行
                        find = find[:-1]
                        finds.append(find)
            except Exception as e:
                # この部分は、このスクリプトそのものをデバックするときONにしてね
                info = sys.exc_info()
                tbinfo = traceback.format_tb(info[2])
                for tbi in tbinfo:
                    print(info[1])
                    print(tbi)
                exit()
                # ここまでね
                errorsF.append("%s¥n    %s" % (path, e))
    print("検索結果は")
    if not finds:
        print("アリマセン。")
    else:
        for find in finds:
            print(find)
    print("¥n検索でエラーが出たファイルは")
    if not errorsF:       print("アリマセン。")
    for error in errorsF: print(error)

### REPLが1だったときやること ###
def repl(dirs):
    dirs.reverse()
    repls   = []
    errorsR = []
    for directory in dirs:
        things = os.listdir(directory)
        for thing in things:
            path = directory + "/" + thing
            try:
                if not checkExt(path):
                    repl = r.replaceFile(directory, thing)
                    if repl:
                        repl = repl[:-1]
                        repls.append(repl)
            except Exception as e:
                # この部分は、このスクリプトそのものをデバックするときONにしてね
                info = sys.exc_info()
                tbinfo = traceback.format_tb(info[2])
                for tbi in tbinfo:
                    print(info[1])
                    print(tbi)
                exit()
                # ここまでね
                errorsR.append("%s¥n    %s" % (path, e))
    print("置換結果は")
    if not repls:
        print("アリマセン。")
    else:
        repls.reverse()
        for repl in repls:
            print(repl)
    print("¥n置換でエラーが出たファイルは")
    if not errorsR:
        print("アリマセン。")
    else:
        errorsR.reverse()
        for error in errorsR:
            print(error)

def main():
    ### これがトップレベル関数だよ ###
    dirs    = makeDirs()
    if FIND == 1:
        find(dirs)
    if REPL == 1:
        repl(dirs)

if __name__ == "__main__":
    main()
 
 

# my_grep_searchFile.py

from my_grep import *

def searchName(thing):
    ### ファイル名に検索語が含まれてたらTrueを返す ###
    if RE == 1:
        if CS == 0:
            reFW = re.compile(FW, re.IGNORECASE)
            if re.findall(reFW, thing):
                return True                     # 正規表現使う 大文字小文字区別なし
        else:
            if re.search(FW, thing):
                return True                     # 正規表現使う 大文字小文字区別する
    else:
        if CS == 0:
            reFW = re.compile(FW, re.IGNORECASE)
            if re.findall(reFW, thing):
                return True                     # 正規表現使わない 大文字小文字区別なし
        else:
            if FW in thing:
                return True                     # 正規表現使わない 大文字小文字区別する

def searchText(find, path, yeah):
    ### ファイルのテキストに検索語が含まれてたらパスとその行が書かれた文字列を返す ###
    fopen = open(path, encoding="utf-8")
    lines = fopen.readlines()
    fopen.close()
    for i in range(len(lines)):
        if RE == 1:
            if CS == 0:
                reFW = re.compile(FW, re.IGNORECASE)
                if re.findall(reFW, lines[i]):
                    find += "    [%d] %s" % (i+1, lines[i])
                    yeah  = True                # 正規表現使う 大文字小文字区別なし
            else:
                if re.search(FW, lines[i]):
                    find += "    [%d] %s" % (i+1, lines[i])
                    yeah  = True                # 正規表現使う 大文字小文字区別する
        else:
            if CS == 0:
                reFW = re.compile(FW, re.IGNORECASE)
                if re.findall(reFW, lines[i]):
                    find += "    [%d] %s" % (i+1, lines[i])
                    yeah  = True                # 正規表現使わない 大文字小文字区別なし
            else:
                if lines[i].find(FW) >= 0:
                    find += "    [%d] %s" % (i+1, lines[i])
                    yeah  = True                # 正規表現使わない 大文字小文字区別する
    return(find, yeah)

def searchFile(thing, path):
    ### もし検索語が含まれてたら、パスとその行が書かれた文字列を返す ###
    yeah = False
    find = "%s¥n" % path
    if NAME == 1:                       # ファイル名検索するなら続行する
        yeah = searchName(thing)
    if os.path.isfile(path):            # それがファイルなら開いて検索する
        find, yeah = searchText(find, path, yeah)
    if yeah == True:
        return find
 

# my_grep_replaceFile.py

from my_grep import *

def replaceName(directory, thing, yeah):
    ### ファイル名に検索語が含まれてたら、置換してTrueを返す ###
    if RE == 1:
        if CS == 0:
            reFW = re.compile(FW, re.IGNORECASE)
            if re.findall(reFW, thing):
                yeah = True                     # 正規表現使う 大文字小文字区別なし
        else:
            if re.search(FW, thing):
                yeah = True                     # 正規表現使う 大文字小文字区別する
    else:
        if CS == 0:
            reFW = re.compile(FW, re.IGNORECASE)
            if re.findall(reFW, thing):
                yeah = True                     # 正規表現使わない 大文字小文字区別なし
        else:
            if FW in thing:
                yeah = True                     # 正規表現使わない 大文字小文字区別する
    if yeah == True:
        newthing = thing.replace(FW, RW)
        os.rename(directory + "/" + thing, directory + "/" + newthing)
    else:
        newthing = thing
    return newthing, yeah

def replaceText(repl, directory, thing, yeah):
    ### もし検索語が含まれてたら、置換して、パスとその行が書かれた文字列を返す ###
    path  = directory + "/" + thing
    fopen = open(path, encoding="utf-8")
    lines = fopen.readlines()
    fopen.close()
    for i in range(len(lines)):
        if RE == 1:
            if CS == 0:
                reFW = re.compile(FW, re.IGNORECASE)
                if re.findall(reFW, lines[i]):
                    for element in re.findall(reFW, lines[i]):
                        lines[i] = lines[i].replace(element, RW)
                    repl    += "    [%d] %s" % (i+1, lines[i])
                    yeah     = True                # 正規表現使う 大文字小文字区別なし
            else:
                if re.search(FW, lines[i]):
                    lines[i] = lines[i].replace(FW, RW)
                    repl    += "    [%d] %s" % (i+1, lines[i])
                    yeah     = True                # 正規表現使う 大文字小文字区別する
        else:
            if CS == 0:
                reFW = re.compile(FW, re.IGNORECASE)
                if re.findall(reFW, lines[i]):
                    for element in re.findall(reFW, lines[i]):
                        lines[i] = lines[i].replace(element, RW)
                    repl    += "    [%d] %s" % (i+1, lines[i])
                    yeah     = True                # 正規表現使わない 大文字小文字区別なし
            else:
                if lines[i].find(FW) >= 0:
                    lines[i] = lines[i].replace(FW, RW)
                    repl    += "    [%d] %s" % (i+1, lines[i])
                    yeah     = True                # 正規表現使わない 大文字小文字区別する
    if yeah == True:
        ### 置換したものを上書き処理 ###
        temp = ""
        for i in range(len(lines)):
            temp += lines[i]
        fopen = open(path, "w", encoding="utf-8")
        fopen.write(temp)
        fopen.close()
    return repl, yeah

def replaceFile(directory, thing):
    ### もし検索語が含まれてたら、パスとその行が書かれた文字列を返す ###
    yeah = False
    path = directory + "/" + thing
    repl = "%s¥n" % path
    if NAME == 1:                                   # ファイル名検索するなら続行する
        thing, yeah = replaceName(directory, thing, yeah)
        path = directory + "/" + thing              # ファイル開くためにrename済みのパスを作っとく
        repl = "%s¥n" % path                        # 置換済みのパスを記述しとく
    if os.path.isfile(path):                        # それがファイルなら開いて検索する
        repl, yeah = replaceText(repl, directory, thing, yeah)
    if yeah == True:
        return repl



最近ちょこちょこ読んでいるオライリーpythonの記述が結構利用できて満足だ。具体的には、関数の大きさを一画面に収まる程度にするよう心がけたり、インポートファイル側からトップレベルファイルのグローバル変数を利用したいときすぐに名前空間の共有を思いつけて手早く問題をクリアーできたり、だ。

 
| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Mark Lutz『初めてのPython』つづき



先日からちょこちょこ読んでいるオライリーPython豆知識収集の続き。



  • lambda式の書き方はこう。PHPとかJSの無名関数にあたるものだが、lambdaの文字があるだけでみょ〜に難解に見えるんだよなあ…。
    lambda x , y: x + y
    
  • lambda式はコード凝縮のためのものである。def文でも同じことが必ずできる。ああよかったですハイ。
  • print()関数と同じことが、 sys.stdout.write(str(x) + "¥n") で出来る。
  • 前回も書いたがif文凝縮の方法。
    # 通常のifステートメント
    if a:
        b
    else:
        c
    # 他のパターン
    b if a else c
    # また他のパターン
    ((a and b) or c)
    
  • range()関数はリストを生成する。for文で散々使っていたrange()だったが、まったく知らなかった。そもそも関数だという認識も希薄だったな…。
  • リスト内包表記をすると入れ子構造を凝縮できる!
    lis = [x + y for x in  [0,1,2] for y in [100,200,300]]
    # lisは[100, 200, 300, 101, 201, 301, 102, 202, 302]となる
    
    と興奮したが俺の趣味の範囲ではいまのところ、for文でlist.append()を使うことが多いのでこれは大して使えんか。
  • リスト内包表記でマトリクスから要素を取り出す
  • lis0 = [[1,2], [3,4], [5,6]]
    lis1 = [row[1] for row in lis0]
    # lis1は[2, 4, 6]
    
    これはちょっと便利かも。データベースいじりではカラム単位で要素を抜き出したいことがままあるが、それと同じことができるというわけか。
  • yieldは関数をジェネレータにする文であり、ジェネレータが値を生み出す文である。
  • ジェネレータ式は次のようなものである。
    g = (x**2 for x in range(4))    # 丸カッコを使う
    g.next()                        # 0
    g.next()                        # 1
    
  • 関数づくりのコツは、役割を一つに絞ること、規模を小さく、一画面に収まる程度にすること。
  • 関数は変数にフツーに代入できる。
    def echo(a):
        print(a)
    x = echo
    x("Midori")
    
    となると、スクリプト内で組み込み関数の名に何かを代入すると、その組み込み関数を使えなくできるってことか。
  • モジュールの中で中心をなすファイルをトップレベルファイルという。
  • import文を使った際のmodule.method()みたいな書き方を完全名という。
  • from文はモジュール内の特定の変数のみコピーするものである。from module import method。なお from module import * は全変数名のコピーである。fromを使えば完全名を使う必要がなくなるが、俺は完全名が好みかな。並びに、asでモジュール名を短くするのも好み。
  • import文を二度実行して変数名をリセットすることは不可。変数のリセットがしたいときは importlib.reload() を使う。
  • モジュールの名前空間の実体はディクショナリオブジェクト。__dict__.keys()で変数の一覧を見ることができる。以前変数の自動生成を試みたときディクショナリを変数として利用する方法を思いついてクリアーしたことがあったが、あのときのひらめきは正しかったのだな。
  • ところで名前空間という用語が俺はずっと理解できなかったのだが、ここまで読み進めればさすがにわかってくる。すなわち名前空間ってのは、変数群のスコープの範囲を表すのだろう。
  • パッケージインポートとは、ディレクトリパスを指定してimportすることである。パッケージインポートで経由するディレクトリには__init__.pyが必要。このファイルは空白であってもよい。
  • import dir1.dir2.module
    
  • __init__.py内で__all__という属性内に変数のリストを作ると、import * によってインポートが行われた際にインポートするモジュールを選択できる。
  • パッケージとは、pyコードを収めたディレクトリのことである。
  • from __future__ import {機能名} とは、将来デフォルトになる予定の機能をオンにする文である。
  • ビルトイン属性__name__はモジュールを作ると自動的に与えられる。そのモジュールがトップレベルファイルとして扱われているときは"__main__"が値として格納される。サンプルコードで if __name__ == "__main__": foo() という文は腐るほど見てきて、いつも意味がわからなかったがこういうことだったのか。そのファイルがメインで使われているときはfoo()を実行し、ただimportされたモジュールとして扱われているときは何もしないという意味だったか。
  • 相対インポートとは、そのステートメントが属するパッケージを優先的に検索する方法である。from . import x という風に書く。なお from .. import x と書くとひとつ上階層のディレクトリから検索できる。



豆知識収集のスタンスではあったけれども、かなり実際書くときに役立つ部分だったなあ。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:みろりHP |
人は石である



人は多面体であるに並び、俺がよく利用する価値観を紹介する。
別に人に限らずそうなんだけど、ものごとはすべて石だ。
人は世界の一部であり、自然の一部だ。無からポッと現れたわけでもなく、母親の食べた食物がなんやかんやでたまたま人のかたちになった、ただの物体だ。俺たちの考えていることも、聞くところによると電気信号の集まりらしい。電気信号は聞くところによると、電子という物質がうにょうにょ動くことでできているらしい。人のからだも、考えも、すべてそのへんの石と同じだ。風が吹いてそのへんの石がコロッと転がるのも、人が動いているのも本質的に同じである。
この考えはストレスから身を守るのに役立つ。クソムカツクことを誰かに言われても、その状況は、ちょっと風が吹いて葉っぱがそよいだのと本質的に同じことだ。葉っぱがそよいだのと魚がはねて水しぶきが舞うのは違うことだが、どちらも物質がすこし動いただけであり、同じことだ。ムカツクことを言った奴も物質がすこし動いているだけだし、「ムカツクこと」自体も空気という物質がちょっと震えて音になっただけだし、「うわぁ」と思っている自分自身だって物質がちょっと移動しただけだ。なにもかもただの石だ。

この価値観は、高校かそのちょっとあとくらいの頃、どうすればストレスから身を守れるか考えているとき思いついたものだ。ちょっと考えてみると、俺がストレスを感じるのはだいたいが人によるもので、自然や動物によることでストレスを感じることはほとんどないことに気付いた。だったら人も自然として扱えばいいんじゃね? と思ったので、そういうことにした。

 
| 緑色 | みろりHP | comments(0) |
| カテゴリ:みろりHP |
人は多面体である



別に人に限らずそうなんだけど、ものごとはすべて多面体だ。
俺には嫌いな奴、Aくんがいる。そしてあちらも俺のことを嫌っている。たまたま鉢合わせた日にはもうサイテーですよ。だってAくんはゴミ野郎なんだもの。しかし、そんなAくんにも、彼を愛する家族や恋人、友達がいる。かれらは、俺には見えていない、彼の素敵な面を見ることができているのだ。そして俺にも素敵な面はたくさんあるのだが、その面をうまくAくんに見せることができていない。だからAくんも俺が嫌いにしかなれない。つまり、「サイテー」なのは俺のせいということになる。べつにAくんがゴミ野郎だからではない。ゴミ野郎など何処にもいない。ただ、人々にはそれぞれたくさんの面があり、人々にはそのうち限られた面しか見ることができない。それだけの話なのだ。

この考えを利用すると、人が嫌いになれなくなる。ムカツク奴ができたとき、「まあまてよ、ちょっと首をもたげてそいつの別の面を見てみれば、一気に大好きになっちゃったりするんじゃね? そして、その面を見ることができない自分の無能を棚に上げてそいつをクズ扱いしてる俺って結構見下げた男ってことになっちゃわね?」と考えるようになるからだ。いちいちむかっとするたびにイライラしないようになる。これが多面体理論の効能だ。
ちなみに、嫌いにもなれなくなるが、好きにもなれなくなる。これが多面体理論の別の面。


| 緑色 | みろりHP | comments(0) |
| カテゴリ:みろりHP |
緑流就寝術



目的はふたつだ。

  • 素早く寝入りたい。
  • 夢をみたい。

今回書くのは全部俺の経験則なんだけど、たぶん同じような体質の人もいるだろうからかれらのために書く。
夢をみるには、前日と違う方角を向いて寝ればいい。というより、いつもと違う環境で寝るのが夢見には効くようだ。ベッドの人はどうすりゃいいか知らんけど、俺は昔ながらの布団なので毎晩ごとに布団の向きがぐるぐる変わり、親愛なるルームメイトには奇異の目でみられている。上等である。
素早く寝入るには、妄想すればいい。というより、現実のことについて考えてはいけない。今日あった楽しいこととか、失敗しちまったこととか、明日やりたいこととかについて思いめぐらしていると俺は眠れない。フィクションであっても、書きたい物語のプロットとかを考えるのはダメ。それは現実のことだ。
具体的に俺が行うのは、まず上空から落下し、すこし粘性のある黒い液体の中にボチャンと落ちる妄想だ。そのあとゆっくり沈んでいって現実のことを考えなくなったら、自室の窓ガラスをぶち破り街へ繰り出し、空を飛んだりする想像をする。想像の内容は他にもいろいろあるけど恥ずかしいので書きません(ただ空を飛ぶのは一番頻繁にやる)。
ところで就寝前にPC画面やスマホ画面を見るのはよくない、目が冴えてしまうから、という言説があるけれど俺はとくに感じないな。そういうのはだいたい、黒い液体の中を沈んでいる間に消える。


| 緑色 | みろりHP | comments(0) |
| カテゴリ:プログラミング |
Mark Lutz『初めてのPython』



オライリーシリーズのPython本だ。初めての、とついてはいるが入門書という感じはしないな。ある程度pythonをいろいろ書いたあとなので、「へーアレって裏ではこういう風になってたのね」みたいな楽しみ方をしてる。気分は豆知識の収集。好きな言語なので、冒頭の言語紹介の部分からもう面白い。前半をさらっとなぞった段階でのメモをずらずら書く。いやマジでさらっとだぜ。700ページ級の技術書をじっくり読むのは緑さんには辛いよ。



  • pythonのソースが実行されるときは、まずバイトコードという中間形式にコンパイルされる。ライブラリフォルダのpycファイルがそれ。これのおかげで二度目からは読み込みが速くなる。
  • プログラムの階層は次のようになる。
    プログラム <- モジュール <- 文 <- 式
    
  • raw.input()を使うとシェルがすぐ消えない。
  • 多次元配列のことを行列、マトリクスという。
  • ポリモーフィズムというのは多態性のことで、たとえば + が数値についていれば足し算を意味し、文字列についていれば結合を意味すること。
  • 小数は浮動小数点数と違い、桁数を決められる。
  • リファレンスとは変数からオブジェクトへのリンクのこと。これまでずっと、変数という箱のなかにオブジェクトが入っているイメージだったんだけれど、それは違ったんだな。実際は変数の領域に変数が、オブジェクトの領域にオブジェクトが存在しており、両者をリファレンスが繋いでいるという図式だった。
  • is は同一(ひとつのオブジェクトにふたつのリファレンスが繋がっている)を意味し == は同等(ふたつの同じオブジェクトにそれぞれのリファレンスが繋がっている)を意味する。
  • ¥0 を文字列に混入させてもpythonは文字列読み込みを終了したりしない。
  • str[:] でオブジェクトのコピーができる。
  • "%(n)d" % {"n":1} こんな文字列フォーマットが可能。
  • vars() は存在する変数をディクショナリで返す。
  • イテレータというのは繰り返し処理のこと。
  • lis.append(foo) というのは元のリストの更新で lis = lis + lis2 というのは新しいオブジェクトの作成を意味する。
  • タプルは list(tuple) でリストに変換できる。これはもちろん新しいオブジェクトの作成がされる。
  • 誰でも一度は抱く疑問「タプルってなんに使うの?」タプルはディクショナリのキーになれる。
  • リファレンスがなくなったときオブジェクトは廃棄される。
  • オブジェクトのコピーは copy() でもできる。copyモジュールとかいうのも存在しており、ふたつは別物。
  • 別々に定義したとしても、それが短い文字列の場合同一のオブジェクトにリファレンスが繋がる。えー…。
  • 文字列を比較するとき、アルファベットのあとのほうの文字ほどデカいとされる。
  • 次のようなことをすると循環オブジェクトができるが、処理が止まってしまったりはせず [...] と出力される。
    lis = []
    lis.append(lis)
    
  • 要素がひとつだけのタプルを作る場合 (1,) というようにコンマが必要。
  • リストにリストを追加するときは + で結合するより .append() のほうが高速。後者は上書きだから、らしいがなにがだからなのかわからん。
  • 拡張代入 += などは実は結合ではなく上書きが起きている。
  • 行の最後にバックスラッシュを置くと行をまたげる。
  • 知らなかったif文の書き方。
    a = y if x else z
    
  • 文字列へのアクセスも配列へのアクセスのように str[0] とできる。
  • LEGBルールとはスコープの種類のこと。ローカル、外側の関数、グローバル、ビルトイン。
  • スコープというのは変数が見える範囲という意味。
  • 関数内の global はpython唯一の「宣言」といえる。宣言しているのは名前空間の宣言。
  • グローバル変数を関数内で変更したりするんでなければ global は使わんでいい。これは知らなかった。いっつも global していた。
  • ふつう関数内でグローバル変数のオブジェクトは上書きできないが、可変性オブジェクトは上書きができる。これは、可変性オブジェクトの引数は、値渡しではなくポインタ渡しのため。
    def foo(a):
        a.append(2)
    a = [0, 1]
    foo(a)
    print(a)         # [0,1,2]になっていやがる!
    
  • キーワード引数とは、その、次のようなやり方のことである! うん知らなかった。デフォルト値は知っていたがこんなこともできたのか。
    def foo(x, y, z):
        ...
    foo(z=2, x=0, y=1)
    
  • 仮引数にアスタリスクを使うやり方。何かに使えそうな気はするが何に使えばいいかまだ思いつかないな。
    def foo(*args):  print(args)
    foo(1, 2, 3)                 # (1,2,3)
    def bar(**args): print(args)
    bar(a=1,b=2)                 # {a:1,b:2}
    



分量でいえば半分読み終えたところだが、後半には関数についての高度なテクニックや、クラスの奴が待ち構えていやがる。あまりまじめにならずさくさく進んでがぶがぶ咬まれていこう。


| 緑色 | プログラミング | comments(1) |
| カテゴリ:プログラミング |
Python 特定ディレクトリ以下のフォルダファイルまとめてテキスト置換する



1. フォルダ名を「手記」、ファイル名を「手記201512」とかでダイアリーフォルダを作る
2. 「『手記』とかちょっと中二っぽくて恥ずかしいわ/// 全部『日記』に変えよう!」
3. 三年ぶんのフォルダ、ファイルに加えてファイル内にも手記という言葉が使われていて全部変更するのは手間…

そんなあなたに今日もやってまいりました、「1日1python」のお時間です。(ただし隔週放送)



今回晒すのはそんな事情から書いたスクリプト。指定したディレクトリ(フォルダ)内のすべてのフォルダ名、ファイル名、ファイルの中のテキストを検索置換する。え? いや冒頭のはたとえばの話で、緑さんはそんな中二っぽい名前にはしてませんよ。ハハハ。

まずトップディレクトリ、置換パターン、読み込まなくていいファイル拡張子(画像とかね)を定数チックに指定しとく。

TOP_DIR  = "D:/foo"
PATTERNS = {
            "怪文書"   :"日記",
            "Kaibunsho":"Diary",
            "kaibunsho":"diary"}
EXT      = [".png", ".gif", ".jpg", ".ico"]

次にトップディレクトリ以下すべてのフォルダのパスをリストに格納する。手順は次のような感じ。
  • dirsリストにトップディレクトリのパスを格納
  • dirs内のパスを覗いて、それがフォルダだったらそのパスをdirsに格納
  • ふたたびdirsを参照するとたった今追加したパスがあるので、それを覗いて繰り返す
ループ回数を動的に増やせるってのは試しに書いてみて初めて知った。こりゃ便利だなあ。ヘタを打つと無限ループ入ってぶっ飛ぶけど(一度ぶっ飛ばした)。

import os
dirs = []
dirs.append(TOP_DIR)
i = 0
for directory in dirs:
    files = os.listdir(directory)
    for f in files:
        path = directory + "/" + f
        if os.path.isdir(path):
            dirs.append(path)

そして次のが置換関数と拡張子チェック関数。しかし、プログラミングで遊び始めて数ヶ月になるけれど、いまだにどんなタイミングで関数を作ればいいのかよく分からないな。てきとうに「ここを関数化したら見た目カッコよくなるんじゃね?」みたいな乗りで書いちゃってんだけど。

def replacement(string):
    for key, value in PATTERNS.items():
        string = string.replace(key, value)
    return string
def ext_check(path):
    root, ext = os.path.splitext(path)
    if ext in EXT:
        return True
    else:
        return False

最後に、さきほど作ったリストを下層から順に開いて処理していく。上層から開いたらせっかく作ったパスリストがパァだ(一度やらかした)。手順は次のような感じ。
  • dirsのパスをひとつずつ展開する
  • EXTリストに登録した拡張子のファイルだったらスルーするー
  • フォルダだったらPATTERNSに従いリネームして次へ
  • ファイルだったらリネームのうえ中身を読み込んで検索置換して上書き

dirs.reverse()
for directory in dirs:
    files = os.listdir(directory)
    for f in files:
        if not ext_check(directory + "/" + f):
            try:
                g = replacement(f)
                os.rename(directory + "/" + f, directory + "/" + g)
                path = directory + "/" + g
                if os.path.isfile(path):
                    h = open(path, encoding="utf-8")
                    data = h.read()
                    data = replacement(data)
                    h.close()
                    h = open(path, "w", encoding="utf-8")
                    h.write(data)
                    h.close()
            except:
                print(path)

あんまり入れ子構造が深くなるのは望むところではないんだけどねえ。どうすりゃいいんだろ。



今回の咬まれポイントはひとつだけ。

# os.rename()の引数はどちらもパスにすること
os.rename("D:/foo/bar", "D:/foo/baz")

今回は構文とか関数の使い方よりも、全体のロジックを考えるのに時間を使ったかな。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:みろりHP |
年賀状2016



あけましておめでとうございます。
親愛なるルームメイトたちも帰郷し、元旦は俺ひとりで静かだったので一枚かいた。年賀状絵は書き初めと兼用で、テーマは今年の抱負だ。アトリビュート的というかちょっとした謎かけになってるんでよかったらひらめいてみて。

  • 書き初めの文字
  • うめつくしてる顔の特徴
  • 文字で黒コゲてる顔の特徴

以上ヒント。


| 緑色 | みろりHP | comments(0) |
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< January 2016 >>
+ みろりHP内検索
+ 閲覧記事
+ 過去記事アーカイブ
+ 年月選択
  • 2019年 02月 (1)
  • 2019年 01月 (2)
  • 2018年 12月 (6)
  • 2018年 11月 (6)
  • 2018年 10月 (3)
  • 2018年 09月 (8)
  • 2018年 08月 (4)
  • 2018年 07月 (6)
  • 2018年 06月 (5)
  • 2018年 05月 (4)
  • 2018年 04月 (7)
  • 2018年 03月 (6)
  • 2018年 02月 (6)
  • 2018年 01月 (8)
  • 2017年 12月 (9)
  • 2017年 11月 (9)
  • 2017年 10月 (4)
  • 2017年 09月 (6)
  • 2017年 08月 (6)
  • 2017年 07月 (8)
  • 2017年 06月 (4)
  • 2017年 05月 (7)
  • 2017年 04月 (8)
  • 2017年 03月 (7)
  • 2017年 02月 (10)
  • 2017年 01月 (6)
  • 2016年 12月 (8)
  • 2016年 11月 (8)
  • 2016年 10月 (5)
  • 2016年 09月 (5)
  • 2016年 08月 (7)
  • 2016年 07月 (9)
  • 2016年 06月 (6)
  • 2016年 05月 (8)
  • 2016年 04月 (10)
  • 2016年 03月 (10)
  • 2016年 02月 (8)
  • 2016年 01月 (10)
  • 2015年 12月 (9)
  • 2015年 11月 (6)
  • 2015年 10月 (5)
  • 2015年 09月 (4)
  • 2015年 08月 (8)
  • 2015年 07月 (5)
  • 2015年 06月 (3)
  • 2015年 05月 (7)
  • 2015年 04月 (8)
  • 2015年 03月 (12)
  • 2015年 02月 (8)
  • 2015年 01月 (4)
  • 2014年 12月 (5)
  • 2014年 11月 (5)
  • 2014年 10月 (7)
  • 2014年 09月 (4)
  • 2014年 08月 (7)
  • 2014年 07月 (6)
  • 2014年 06月 (4)
  • 2014年 05月 (12)
  • 2014年 04月 (9)
  • 2014年 03月 (6)
  • 2014年 02月 (6)
  • 2014年 01月 (8)
  • 2013年 12月 (7)
  • 2013年 11月 (10)
  • 2013年 10月 (10)
  • 2013年 09月 (9)
  • 2013年 08月 (11)
  • 2013年 07月 (10)
  • 2013年 06月 (9)
  • 2013年 05月 (15)
  • 2013年 04月 (11)
  • 2013年 03月 (5)
  • 2013年 02月 (7)
  • 2013年 01月 (6)
  • 2012年 12月 (9)
  • 2012年 11月 (10)
  • 2012年 10月 (10)
  • 2012年 09月 (4)
  • 2012年 08月 (2)
  • 2012年 07月 (7)
  • 2012年 06月 (13)
  • 2012年 05月 (13)
  • 2012年 04月 (15)
  • 2012年 03月 (4)
  • 2012年 02月 (12)
  • 2012年 01月 (9)
  • 2011年 12月 (5)
  • 2011年 11月 (13)
  • 2011年 10月 (2)
  • 2011年 09月 (2)
  • 2011年 08月 (1)
  • 2011年 06月 (1)
  • 2011年 05月 (4)
  • 2011年 04月 (10)
  • 2011年 03月 (8)
  • 2011年 02月 (11)
  • 2011年 01月 (14)
  • 2010年 12月 (14)
  • 2010年 11月 (17)
  • 2010年 10月 (17)
  • 2010年 09月 (19)
  • 2010年 08月 (22)
  • 2010年 07月 (18)
  • 2010年 06月 (16)
  • 2010年 05月 (19)
  • 2010年 04月 (15)
  • 2010年 03月 (22)
  • 2010年 02月 (18)
  • 2010年 01月 (18)
  • 2009年 06月 (2)
  • 2007年 12月 (10)
  • 2007年 11月 (7)
  • 2007年 10月 (9)
  • 2007年 09月 (4)
  • 2007年 07月 (5)
  • 2007年 06月 (11)
  • 2007年 05月 (6)
  • 2007年 04月 (4)
  • 2007年 03月 (1)
  • 2006年 01月 (21)
  • + カテゴリ
    + ブックマーク
    + 最近のコメント
    + アクセスカウンター
    全体(since 2010.02.03.)
    今日… 昨日…