みろりHP


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

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

| スポンサードリンク | - | - |
| カテゴリ:ゲーム |
フリーゲーム「滅亡世界」



ダウンロードはここ。

魔物が現れて人類はほぼ滅亡。人類側の最後っ屁として改造人間となった英雄たちが魔王を倒すべく立ち上がるお話。
とはいったものの見どころは人類文化が壊滅したフィールドを駆け回って魔物連中を銃で吹き飛ばす2Dアクションにあろう。戦闘の難易度はわりと高めと感じた。ガンガン死んだ。



プレイしやすくて楽しめた。周回が容易だったんでエンドをコンプした。

これで完クリってことでいいんかな。

レベルはこんなになった。

射撃がイイ感じだ。最初キャラ・ワイバーンで始めたのもあってずっと銃を使ってた。

軽い攻略tips。
  • とりあえず設定でオートセーブをONに。これは周回で自動リセットされちゃうので周回時は注意。
  • とりあえず銃のリロードを無変換キーに。元の場所はボス戦のとき(つねに駆け回っている状態)押しづらい。
  • ボス戦の基本戦術は「弱攻撃は受け回復薬連打で凌ぐ」「強攻撃は絶対避ける」。
  • スキルにダッシュがあるキャラがおすすめ。てかダッシュがなかったらボス戦抜けれなかった。
  • 各キャラクリアはクリア直前で人体改造装置を使うと容易。材料であるクリスタルの欠片はホワイトファングのお店でリセマラすると出やすい気がした。

妖精さんといっしょに走り回るのはとても楽しかった。

ベッドを作成できるようになったので、あとクリスタルを作れば自分だけの拠点が作れるんかなと思ったんだがクリスタルのレシピがとうとう見つからなかった……。それに周回するとオブジェクトは削除されるみたいだから、あんまり拠点作る面白みはないかも。


| 緑色 | ゲーム | comments(0) |
| カテゴリ:みろりHP |
緑さんとファッション



「みどりん♪ その服装で私の隣歩かないで♪
って親愛なるルームメイトに言われたことがある。

みどりんは吹き出した。
「クソワロタwwそんなこと言われたことねえwwそういう歯に衣着せぬ物言い好きだぜw」

そしたらルームメイトが俺にインナーからアウターからパンツまで一式買い与えてくれた。
「これ着てね♪」

おや? もしかしてみどりんのファッションセンスってガチでヤバイ?

それから数年、俺は服をひとりで買いに行くのが怖い症候群を患った。こえーよ。ファッションこえーよマジでわかんねーよ。ルームメイトたちも最初はアドバイスくれようとしたんだけれど、連中メンズファッションはわからんし俺は俺で
「いやスキニーパンツとかおかしくね? なんでわざわざ歩きにくい服着んの?」
「ランニングシューズ以外のクツって価値なくね?」
「手が塞がるトートバッグよりリュックのほうがいいに決まってんじゃん」
「てか片手にバッグもつと重心が狂うから整体的に害悪じゃね?」
とか言うから手に負えん。

だけどこないだちと転機が訪れた。きっかけは親愛なるルームメイトのこんな言葉だった。
「私がお洒落するのは、もちろん自分のためでもあるけど、一緒に歩く人に気分よく歩いてもらうためでもあるよ。」
「なるほど!」
なるほど、だった。確かに連中は素敵で、一緒に歩いていると俺は良い気分になる。だけどこの俺は果たして、連中に一緒に歩くのが嬉しいと思われるような奴だろうか? そんなこと一度も考えたことがない……。



そんなわけで。

そんなわけで服とブーツを買った。決意したからといってファッションセンスが舞い降りるわけじゃないので、こんな手法を用いた。
  • ルームメイトたちにお店についてきてもらう。
  • 店員さんに今風のコーディネイトを着せてもらう。
  • その中から、ルームメイトたち好みのコーディネイトをチョイス。
  • その服を何も考えず全部買って何も考えずそれを着る。
これが大正解だった。まあ親切な店員さんに出会うまでいくらか苦労したが、自分に合った価格帯のお店を探して、話しやすそうな店員さんを探して、少しお喋りして仲良くなりつつ相談した。最後の項目がとても大事で、俺は何も意見しないこと。少しでも意見をすると皆様に「んー(汗)」されてしまう。


服はあってもコーディネイトがわからんので、店員さんが教えてくれた組み合わせを写真にとって、これに沿って着替えるようにした。これで完璧だ。「最近服いいですね!」「今週なんかめちゃめちゃイメチェンしてないですか!?」「この一週間でお前に何があった!?」と評判も上々。


| 緑色 | みろりHP | comments(0) |
| カテゴリ:みろりHP |
ブレスレットを作ろうとした



ブレスレットが欲しくなったから、作ろうとしたのだよ。金属製で、文字を刻めたらいいな〜と思って色々考えてみたんだが、作るのに火が必要になりそうで金属はキツそう。であればと思いついたのがレザークラフト。装飾部分を革にして、留め具部分をチェーンにするとか。文字は刺繍で作ればいいし、いけるんじゃね?



とりあえずブレスレット状にしてみた。

ん……? これはどうもイメージと違う。
えーと。
次は刺繍に挑戦してみる。

ん……? これは割とクソなのでは? あれ? 刺繍って思ったよりすごくむつかしいぞ? 缶バッヂのときのような「できたぜー!」感がまるで感じられない。
うーん。
ちょっとこの作りは諦めて、革紐を編んでみる。

ううーん?

うーん? 魅力を感じない。



はい断念です。つーか今回は完成想定図がもやもやしたまま作り始めたのがイカンかったかもしらん。缶バッヂは完成図が結構明確だったもんなー。てか生まれてこの方ブレスレットを持ったことがないんだから、まずひとつ買ってみるか。


| 緑色 | みろりHP | comments(0) |
| カテゴリ:プログラミング |
Python Decimalでひとネタ



パイソニスタ・ショート・ショート。『float と Decimal』。

print(0.1 * 3.0)
# 結果 0.30000000000000004  なんじゃそらー

print(Decimal('0.1') * Decimal('3.0'))
# 結果 0.3

つかえねーな float は。へへへ Decimal の旦那ぁ! 頼りになるのは旦那だけでさ!

print(1.0 / 3.0 * 3.0)
# 結果 1.0

print(Decimal('1.0') / Decimal('3.0') * Decimal('3.0'))
# 結果 0.9999999999999999999999999999  なんじゃそらー

テメーもかよ Decimal のクソが!! 何のためにアンタを import したと思ってんのよ!! ペッ!!


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
シンタックスハイライトを導入する



プログラミングのブログとかでさー、スクリプトに色がついてるやつ(シンタックスハイライトっていうらしい)がよくあるじゃん。あれに憧れてみろりhpも少し装飾してみた。ただこのブログサービスの仕様による条件がひとつ。このjugemブログ、新たにCSSファイルとかJSファイルをアップロードできないんだよ。それを踏まえて今回の変更をノートしておく。



シンタックスハイライト。 code-prettifyなるライブラリを使う。Javascriptではあるのだが、ネットにスクリプトが上がっているのでそれをインポートするだけでOK。jugemブログでもそれは可能。こういうの助かるなー。
<!-- コードの装飾 -->
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>

背景色とかフォントの装飾。 CSSを自作した。新たにCSSファイルを追加することはできないのだけど、CSSを追記することは可能なので。
pre.mycode {
    padding: 0.5em, 1em;
    overflow: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
}

pre.mycode code {
    font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    font-size: 15px; /* ろりhpのデフォルトが15.2なので気持ち小さめに。 */
}

pre.mycode code:first-line {
    line-height: 0px;
}

pre.beige {
    background: #f3e9dd;
}

pre.lightgreen {
    background: #ebf9cb;
}

使い方。
<pre class="mycode lightgreen"><code class="prettyprint">
# ここにスクリプトを書く。
</code></pre>



さらにガッツリ装飾したり、行番号をつけたり背景色ごと変更するのも主流みたいだったけれど、この程度のあっさり具合がろりhpに合うと思ったんでこのくらいで。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python プログラミング問題をやってみた2 後半戦



先回の続き。



4. ボックスサイズ
単位がセンチメートルの3つの引数をとり、体積を計算しリットルとして返す関数をかけ。
def problem4(cm1, cm2, cm3):

    # 値チェックします。
    cm = [cm1, cm2, cm3]
    for c in cm:
        if not (isinstance(c, int) or isinstance(c, float)):
            print(f'引数はintかfloatにしてよー: {c}')

    # Decimal化します。
    import decimal
    cm = map(lambda c: decimal.Decimal(str(c)), cm)

    # 立方センチメートル出します。reduceってのはなんか配列を片っ端から処理してくれるやつ。
    import functools
    cubic_cm = functools.reduce(lambda x, y: x * y, cm)

    # リットルに変換します。1000立方cm = 1.0リットル。
    return cubic_cm / 1000

実行結果。
print(problem4(2.0, 2.0, 2.0), end='\n')
print(problem4(10.0, 10.0, 10.0), end='\n')
print(problem4(123.4, 123.4, 123.4), end='\n')
print(problem4(2, 2, 2), end='\n')
----------
0.008
1.000
1879.080904
0.008

先回知った Decimal を早速使っちゃったぜ。モジュールを使用しちゃうのはちとずっこい感じがしたんだけれど、問題2があまりに面倒だったからさ……。で、1個インポートしたら2個も3個も一緒でしょと functools も使っちゃったぜ。map関数も使っているし lambda にも慣れてきたぜ。



5. 最悪のFizzBuzz
最悪の - しかし動作する - FizzBuzzプログラムをかけ。

こういうの大喜利みたいで楽しいね。ふたとおり作ってみた。

def problem5(start, end):

    # ■ 最悪POINT 1: 変数名が日本語。ぞわっとするー!
    結果リスト = []

    # ■ 最悪POINT 2: 一回しか使わない変数をわざわざ作成してる。意味ねー!
    end2 = end + 1
    for i in range(start, end2):

        # ■ 最悪POINT 3: 真偽用の変数を作るにしてもboolじゃなく文字列を使用してる。Falseにしとけー!
        iは3の倍数です = 'いいえ'
        iは5の倍数です = 'いいえ'

        # ■ 最悪POINT 4: 3の倍数の求め方が「ずっと3を足していって該当したら」。頭わるそー!
        three = 3
        while True:
            # ■ 最悪POINT 5: コードを見れば分かることをわざわざ説明するコメントを書いてる。意味ねー!
            # threeがiと同じときiは3の倍数ですを'はい'にする。threeがiより大きくなっちゃったらwhileを終了。
            if three == i:
                iは3の倍数です = 'はい'
            elif three > i:
                break
            # ■ 最悪POINT 6: three += 3 という書き方を知らない。知っとけー!
            three = three + 3

        # ■ 最悪POINT 7: 上と同じような処理なのに関数化してない。しとけー!
        five = 5
        while True:
            if five == i:
                iは5の倍数です = 'はい'
            elif five > i:
                break
            # ■ 最悪POINT 8: って、+=知ってんのかよ! だったら上のも += 3 にしろよ!
            five += 5

        # ■ 最悪POINT 9: 無駄に ! を使ってる。この場合 == 'はい' にするべき。
        if iは3の倍数です != 'いいえ':
            if iは5の倍数です != 'いいえ':
                結果リスト.append('FizzBuzz')
                continue

        # ■ 最悪POINT 10: このあたりは if elif でまとめればいいのにばらばらにifしてる。
        if iは3の倍数です != 'いいえ':
            結果リスト.append('Fizz')
            continue

        if iは5の倍数です != 'いいえ':
            結果リスト.append('Buzz')
            continue

        # ■ 最悪POINT 11: ここまで処理が進むってことは絶対両方 'いいえ' なのにわざわざifに入れてる。意味ねー!
        if iは5の倍数です == 'いいえ':
            if iは3の倍数です == 'いいえ':
                結果リスト.append(str(i))

    # ■ 最悪POINT 12: for部が長すぎる!

    結果の文字列 = ''
    # ■ 最悪POINT 13: すごくダメな例外処理の使い方してる。で、出た〜〜w except pass 奴〜〜ww
    try:
        i = 0
        while True:
            結果の文字列 = 結果の文字列 + 結果リスト[i] + ','
            i += 1
    except:
        pass

    return 結果の文字列
昔の俺が書いてたようなpython」がテーマだ。初心者あるあるを詰め込んだようなFizzbuzz。
もう片方は逆に、いまの俺じゃないと書けないpython
def problem5(start, end):
    # ■ 最悪POINT: ワンラインで読みづらい(横長になりすぎないよう改行はしてる)。
    return list(
        map(
            lambda i:
                str(i)
                if (i % 3 and i % 5)
                else ('' if i % 3 else 'Fizz') + ('' if i % 5 else 'Buzz'),
            range(start, end + 1))
    )
最近覚えた高階関数や三項演算子をバリバリ使って一行Fizzbuzzを作ってみた。上のより高度ではあるけど、クッソ読みづらいから逆に最悪と言っていいんじゃね?

実行結果。
print(problem5(1, 10), end='\n')
print(problem5(100, 110), end='\n')
print(problem5(1500, 1510), end='\n')
----------
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,
Buzz,101,Fizz,103,104,FizzBuzz,106,107,Fizz,109,Buzz,
FizzBuzz,1501,1502,Fizz,1504,Buzz,Fizz,1507,1508,Fizz,Buzz,


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python プログラミング問題をやってみた2 前半戦



こんなのを見つけたので、また腕試しにトライしてみたぜ。ちと長くなっちゃったので前半後半にわける。3問目はコードを書く問題じゃなかったから抜かしてる。



1. アナグラム
2つの引数を取り、引数がアナグラム(どちらも全く同じ文字を含んでいる)ならばtrueを、そうでないならばfalseを返す関数をかけ。
def problem1(arg1, arg2):

    # まず引数チェックをします。
    if not (isinstance(arg1, str) and isinstance(arg2, str)):
        print(f'引数は文字列だけ認めるよ: {arg1}, {arg2}')
        return False

    # 長さが違う時点でダメです。
    if len(arg1) != len(arg2):
        print(f'長さが違う時点でダメ: {arg1}, {arg2}')
        return False

    # arg1の文字が全部arg2に同数含まれてるか? という判断基準でいく。
    for a in arg1:
        if arg1.count(a) != arg2.count(a):
            print(
                f'arg1の文字"{a}"がarg1には{arg1.count(a)}個あるけど'
                f'arg2には{arg2.count(a)}個あるよ: {arg1}, {arg2}'
            )
            return False

    print(f'OKだよーん: {arg1}, {arg2}')
    return True

実行結果。
print(problem1('abcde', 'edcba'), end='\n')
print(problem1('abcde', 'abcdei'), end='\n')
print(problem1('abcde', 1), end='\n')
print(problem1('abcde', 'edcbf'), end='\n')
print(problem1('日本語はどうでしょうね', 'ううしでどねはょ日本語'), end='\n')
print(problem1('ABA', 'ABB'), end='\n')
----------
OKだよーん: abcde, edcba
True
長さが違う時点でダメ: abcde, abcdei
False
引数は文字列だけ認めるよ: abcde, 1
False
arg1の文字"a"がarg1には1個あるけどarg2には0個あるよ: abcde, edcbf
False
OKだよーん: 日本語はどうでしょうね, ううしでどねはょ日本語
True
arg1の文字"A"がarg1には2個あるけどarg2には1個あるよ: ABA, ABB
False

最近使いこなせるようになってきた isinstance とか楽しんで使ってみた。けどまあ、こういう問題を解くときはそういうのナシで短くまとめるようにしたほうが見栄えがよかったかと思わんでもない。



2. 税金計算
金額(ドル)と、税率(%)を引数にとり、答えの金額をセントとして配列で返せ。

これが曲者だった。ところでこれは、金額に税額を足せってことで合っているよな? ほんでその金額をドルとセントに分けて [ドル, セント] にしろってことだよな? 俺はそういう理解でやってみたぞ。

def problem2(dollar, tax_rate):

    if not (isinstance(dollar, float) and isinstance(tax_rate, float)):
        print(f'引数はfloatだけ認めるよ: {dollar}, {tax_rate}')
        return False

    dollar, tax_rate = str(dollar), str(tax_rate)

    # 小数点は右からいくつめにあるの? **.**** なら 4 を取得します。
    # [::-1]は文字列の反転。pt_lctnはpoint_locationのことです。
    dollar_pt_lctn = dollar[::-1].find('.')

    # 税率は%単位だから、最後に/100ぶんの2を足すよ。 *.* なら 3 を取得します。
    tax_rate_pt_lctn = tax_rate[::-1].find('.') + 2

    # ドル、税率から小数点を削除ります。晴れてintになりました。さらばfloat。
    dollar_int = int(str(dollar).replace('.', ''))
    tax_rate_int = int(str(tax_rate).replace('.', ''))

    # 税金額を出します。floatでやると誤差が生じてワヤになるからintで。
    tax_amount = dollar_int * tax_rate_int

    # 元のドルを税金額に桁あわせします。float同士だと足し算ですら狂うのでintでやります。
    # 小数点を削除ったドルに、税率の小数点の位置ぶん0加えたものがそれ。
    original_dollar = int(str(dollar_int) + '0' * tax_rate_pt_lctn)

    # 元のドルに税金額を足します。
    result = str(original_dollar + tax_amount)

    # 削除ってた小数点を戻します。
    # 位置は、最初に削除ったふたつの小数点の位置を足したところ。
    # 100.1ドル と 9.75% だったら 右から5番目になる。(%ぶんの+2を忘れずに。)
    pt_lctn = dollar_pt_lctn + tax_rate_pt_lctn
    result_ = (str(result)[0:-pt_lctn] + '.' + str(result)[-pt_lctn:])

    print(f'額は ${result_} になりました。結果の配列は下に表示されます。')

    # なんやかんやで $***.***** を [***, **.***] にして返します。
    dollar_part = str(result)[0:-pt_lctn]
    dollar_part = int(dollar_part if dollar_part else '0')
    cent_part = str(result)[-pt_lctn:] + '0'
    cent_part = float(cent_part[0:2] + '.' + cent_part[2:])

    return [dollar_part, cent_part]

実行結果。
print(problem2(100.0, 8.00), end='\n')
print(problem2(0.10, 10.56), end='\n')
print(problem2(100.10, 9.75), end='\n')
print(problem2(100, 9.75), end='\n')
print(problem2(123.456789, 8.1234), end='\n')
print(problem2(4.64, 9.75), end='\n')
print(problem2(0.10, 10.56), end='\n')
print(problem2(1.0, 100.0), end='\n')
----------
額は $108.0000 になりました。結果の配列は下に表示されます。
[108, 0.0]
額は $.11056 になりました。結果の配列は下に表示されます。
[0, 11.056]
額は $109.85975 になりました。結果の配列は下に表示されます。
[109, 85.975]
引数はfloatだけ認めるよ: 100, 9.75
False
額は $133.485677797626 になりました。結果の配列は下に表示されます。
[133, 48.5677797626]
額は $5.092400 になりました。結果の配列は下に表示されます。
[5, 9.24]
額は $.11056 になりました。結果の配列は下に表示されます。
[0, 11.056]
額は $2.0000 になりました。結果の配列は下に表示されます。
[2, 0.0]

見づら。何この見づらい関数。それもこれもすべて float の計算が微妙に狂うせいなのだよ。
print(0.1 * 3)  # 0.30000000000000004 になる。なんでだよ。
print(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1)  # 0.7999999999999999 になる。なんでだよ!!
なんかねえ、二進数が小数がうまく表せないせいで起こるらしいよこれは。そういうわけで float 同士の計算は避けようと思って上述のクソ長い関数は爆誕した。

のだが、のちにググったら「そういうときは Decimal を使え」とあってですね……。Decimalというのはintでもfloatでもない数値型で、正確な小数を表せるとかで。
import decimal

def problem2(dollar, tax_rate):

    # Decimal型(正確な小数)に変換します。
    dollar = decimal.Decimal(str(dollar))
    tax_rate = decimal.Decimal(str(tax_rate))

    # 元の額 + 税額
    result = dollar + dollar * (tax_rate / 100)

    # ドル部とセント部に分けます。
    return [int(result), float((result - int(result)) * 100)]
これで上述関数と同じ結果が出る。ほなら float を廃止して Decimal にしたほうがいいんじゃないの、pythonの旦那?



後半に続く。

| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python ユニットテストノート



先日の読書に影響されて、ユニットテストっていうものを調べてみたぜ。えーとまとめると以下のような感じか?
  • スクリプトはたくさんの関数が集まってできてるじゃん?
  • 大雑把にいえば、関数が全部バグなしだったら全体もバグなしってことになるじゃん?
  • ユニットテストは関数単位でテストすること。いろんなパターンの引数で関数を呼び出しまくって、返り値が正しいかチェックしまくる。
  • これをスクリプト書いてる最中に定期的に実行してれば、どっかのタイミングで関数が壊れたらスグわかる!

なるほどって感じだ。これまで、作った関数のチェックといえば、実際に使うところでちょろっと呼び出して結果を print するくらいだったもんね。全体のリファクタリングをやるときも有効そう。以下目次。
とりあえず pip しとく
テスト対象
ユニットテストファイル
カバレッジ



とりあえず pip しとく
  • $ pip install nose
  • $ pip install coverage
  • $ pip install mock
  • $ pip install parameterized



テスト対象。foo.py って名前にしといた。この中のメソッドをユニットテストしていくぜ。
class Foo:

    # test_1 と test_2 で扱うよー。
    @staticmethod
    def static_method(x, y):
        return x + y

    # test_3 と test_4 で扱うよー。
    @staticmethod
    def exception_method(x):
        if x is True:
            raise TypeError()
        elif x is False:
            raise ValueError()
        elif x == 1:
            return x
        else:
            return None

    # test_5 で扱うよー。
    @staticmethod
    def use_other_class_method():
        return Bar.static_method()


class Bar:

    # test_5 で扱うよー。
    @staticmethod
    def static_method():
        return 1

    # test_7 で扱うよー。
    X = 1

    # test_7 で扱うよー。
    @classmethod
    def class_method(cls):
        return cls.X



ユニットテストファイル。foo_test.pyって名前にしといた。テストファイルの名前は test_ か _test をつけないとダメ。とりあえず使う予定の import を並べとく。
from nose.tools import ok_, eq_, with_setup
from mock import Mock
from parameterized import parameterized

import foo  # これはテストするモジュール。

実例1: 基本的なテスト。Foo.static_methodをテストする。
def test_1():

    # Input.
    x = 1
    y = 2

    # Expected.
    expected = 3

    # Verify.
    actual = foo.Foo.static_method(x, y)
    eq_(expected, actual)

実例2: たくさんの入力値、期待値パターンを一気に書く。ぶっちゃけ実例1は忘れて全部コレでよさげ。
@parameterized([
    (1, 2, 3),
    (3, 4, 7),
    (6, 3, 9),
])
def test_2(x, y, expected):

    # Verify.
    actual = foo.Foo.static_method(x, y)
    eq_(expected, actual)

実例3: 例外をテスト。Foo.exception_methodをテストする。raises っていうアノテーションを使う方法もあったけれど、それと parameterized を組み合わせる方法がよくわかんなかったからコレで。
@parameterized([
    (True, TypeError),
    (False, ValueError),
])
def test_3(x, expectedException):

    try:
        foo.Foo.exception_method(x)
    except Exception as e:
        ok_(isinstance(e, expectedException))
        return
    ok_(True is False, 'Exception must be thrown.')

実例4: parametarized に例外を含む。実例2,3の合成。例外を出すかもしれないし普通に返り値が来るかもしれないメソッドをテストする。このかたちが今回の完成形って感じがする。あとは必要に応じて後述のモックを使えばよいか。
@parameterized([
    (True, True, TypeError),
    (False, True, ValueError),
    (1, False, 1),
    ('a', False, None),
])
def test_4(x, expectException, expected):

    # 通常の返り値期待。
    if not expectException:
        actual = foo.Foo.exception_method(x)
        eq_(expected, actual)
        return

    # 例外期待。
    try:
        foo.Foo.exception_method(x)
    except Exception as e:
        ok_(isinstance(e, expected))
        return
    ok_(True is False, 'Exception must be thrown.')

実例5: メソッドをすげ替える(モックする)
def test_5():

    # 対象メソッド内の Bar.static_method をモックします。
    # フツーに実行したら 1 が返ってくるけど、そこを 5 にすげ替える。
    foo.Bar.static_method = Mock(return_value=5)

    # Expected.
    expected = 5

    # Verify.
    actual = foo.Foo.use_other_class_method()
    eq_(expected, actual)

実例6: モジュールの前後に関数を実行させる
def setup():
    '''setupって名前で作れば自動で実行。'''
    print('実例6: setup')
def teardown():
    '''teardownって名前で作れば自動で実行。'''
    print('実例6: teardown')

実例7: 関数の前後に関数を実行させる
def setup2():
    foo.Bar.X = 5
def teardown2():
    foo.Bar.X = 1

@with_setup(setup2, teardown2)
def test_7():
    eq_(5, foo.Bar.class_method())

実行は下記コマンドを打てばよい。test_、_testのついたファイル、関数を全部自動実行してくれる。あるいはテストファイル内に実行スクリプトを書いてもよいぞ。
$ nosetests -v -s --with-coverage

# テストファイル内に書く場合。
nose.main()
テストをちゃんとクリアしたかどうかズラッと出てくれる。vがテスト名の表示、sが標準出力の表示、with-coverageがカバレッジの出力。



カバレッジ。このカバレッジってやつが楽しくてな。テストがスクリプトをすみずみまで舐め回したかどうか見せてくれるんだよ。下記コマンド実行で閲覧用htmlを出力してくれる。
$ coverage html


こんなんが出る。楽しすぎるじゃん。今回は Bar.static_method は実行してないから(モック例に使ったため)舐め回し不足として赤くなってる。わかりやすいな。
注意事項として、テスト実行に
nose.main()
を使うとカバレッジが中途半端に赤くなる。具体的にはスクリプトの定義文部分。本当なら定義とかを全部終わらす前に網羅率の計測をしなくちゃならないんだが、スクリプト内に実行文を書いちゃうと定義処理が終わってから計測を開始することになっちゃってダメなんだろう。スクリプト内からのテスト実行も可能って話だったが、実際はターミナルから実行したほうが無難かもしんない。



オッケー終了! わりと実用的にまとまった気がする。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Gitノート



2015 年のエンジニアに Git は欠かせない。
っていうフレーズを読んで以来、そのGitというものが気になっていてな。最近そろそろと手を出してみたらクッソ便利じゃんこれ。バージョン管理システムっていうらしいぜ。つまりは、スクリプトのバックアップがとれるわけだろ? しかもフォルダ単位でカンタンに。そしてそのバックアップの履歴を見ることもサクサクできて、そのバックアップ群をどっかのサーバに上げれば他の人と更新をいっしょにできるんだろ? サーバとかよくわからんから俺には関係ないな、ってちょっと思ったけどそれってDropboxでもできるんだろ? だったら全然できちゃうよ。
しかも、ブランチってシステムを使えば、上書きしあっちゃったりしないようにできるんだろ? すげーな。エンジニアではなくても全然有用じゃん。
というわけである程度使ってみて、よく使ったコマンドとかエイリアスとかノートしとく。



■ 準備

インストールするまで
$ brew doctor
$ brew install git
$ git --version

Gitのテキスト入力を相棒のSublime Text3で行う準備
$ ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl
$ git config --global core.editor "subl -w"

設定をする
$ git config --global user.name Midoriiro (ユーザ名登録)
$ git config --global user.email メアド (メアド登録しないと使えなかったような気がする)
上のを打つとユーザフォルダに .gitconfig ができるので [alias] 項目を作ってエイリアスを書く。俺はこんなのを用意してみた。
graph = log --graph --date=short --pretty='format:%C(yellow)%h %C(green)%cd %C(blue)%an%C(red)%d %C(reset)%s' --all
graph5 = log --graph --date=short --pretty='format:%C(yellow)%h %C(green)%cd %C(blue)%an%C(red)%d %C(reset)%s' --all -n 5
graph10 = log --graph --date=short --pretty='format:%C(yellow)%h %C(green)%cd %C(blue)%an%C(red)%d %C(reset)%s' --all -n 10
stt = status -uno
diffno = diff --name-only
diffwd = diff --word-diff
co = checkout
br = branch
inicom = commit --allow-empty -m 'Initial Commit.'
adda = add --all



■ 実用(上のエイリアスを適用しているものとする)

基本
$ git init (開始)
$ git inicom (空っぽで保存)
$ git adda (全部ファイルをステージング)
$ git commit -m "保存コメント" (保存)
$ git commit --amend (ひとつ前のコミットを修正)
$ git stt (状態確認)
$ git graph (コミット履歴を見る)
$ git diffno リビジョン番号 リビジョン番号 (リビジョン間でどのファイルが変更されてたっけなって確認)

Gitに含まないファイルの登録
.gitignoreを作成する。「python gitignore」でググったらよいのが出てきたので使わせてもらった。
$ git rm -r --cached (.gitignoreが反映されないとき)

ブランチを作って作業
$ git br ブランチ名 (新しいブランチ作る)
$ git co ブランチ名 (作ったブランチに移動)
$ git merge --no-ff 取り込むブランチ名 (ブランチを今のブランチに吸収)
$ git br -D ブランチ名 (いらんブランチを削除)

masterブランチの内容を他ブランチに反映させたいとき
pullとかでmasterを最新状態にする。
他ブランチに移動する。
$ git rebase master
コンフリクトが起きたらそれを解消する。
$ git add コンフリクトしたファイルのパス
$ git rebase --continue

やっべ間違えたってとき
$ git reflog (戻る履歴のリビジョン番号を確認する)
$ git reset --hard リビジョン番号 (指定したところまでフォルダをリセットする)
$ git co リビジョン番号 -- ファイルパス (ファイル単位でリセットする)

リモートリポジトリを使う(俺はDropboxでやってみた)
まずcdコマンドとかで対象フォルダまで行く。
$ git init --bare --shared=true (フォルダをリモートリポジトリに)
ローカルリポジトリへ戻る。
$ git remote add リモートリポジトリ名 リモートフォルダまでのパス (リモートリポジトリを登録)
$ git remote rm リモートリポジトリ名 (いらんくなったら消す)
$ git push リモートリポジトリ名 ブランチ名 (ローカルの保存履歴をリモートに上げる)

他のPCでリモートの保存履歴を引っ張ってくる
$ git init
$ git clone リモートフォルダまでのパス (最初の一回はこう。DLみたいなもんか)
$ git pull リモートリポジトリ名 ブランチ名 (二回目以降の履歴更新)



とりあえずこのあたりを使って、Mac-Windows間のスクリプト移動、更新をやってみてる。外部のPCにデータを置くとなるとサーバが必要になってくる、みたいな思い込みがあったので、Dropboxで大丈夫ってのは目ウロコだったぜ。


| 緑色 | プログラミング | comments(0) |
   1234
567891011
12131415161718
19202122232425
2627282930  
<< November 2017 >>
+ みろり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.)
    今日… 昨日…