いっぽんの猟銃のむこうに (DAIZOじいさんとGun)

ヌルめの技術メモとか。フリーランスやってます (http://acez.jp/)

Pythonで文字列が16進数かどうかを判別する

普通にやるなら

def _is_hex(val):
    try:
        int(val, 16)
        return True
    except ValueError, e:
        return False

とか書くんですけど、まあ冗長っていえば冗長ですよね。

どうしても、なんとなく例外処理とか書きたくない場合は、

a = 'FF00FF'
import string
set(a).issubset(set(string.hexdigits))
-> True

という荒業もあります。

まあ、素直にreモジュールで正規表現使った方が早いかもしれませんけどね・・・

Pythonで相対URLとかうさんくさいのを綺麗にする

urlnormというライブラリを使うと良いっぽい。

以下公式サイトからそのままですけど、相対参照とかうさんくさいドメインとかを適宜綺麗にパースしてくれるみたいです。素敵。

>>> import urlnorm
>>> urlnorm.norm("http://xn--q-bga.com./u/u/../%72/l/")
u'http://q\xe9.com/u/r/l/'

でも僕の出くわしたトップレベル以上の相対参照("http://www.dom.com/../img/hoge.gif → http://www.dom.com/img/hoge.gif)には無力でした。Webデザイナさんのフリーダムさ加減には勝てない。

patchとか送ってみるかなー。

追伸: 送ってみた。
https://github.com/jehiah/urlnorm/pull/6

DebianとかUbuntuにapt-getで適当にJenkinsを入れる

yumで適当にJenkinsを入れるのapt版。

# リポジトリ登録
$ sudo wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - 
$ echo "deb http://pkg.jenkins-ci.org/debian binary/" | sudo tee -a /etc/apt/sources.list

# インストール
$ sudo apt-get -y update
$ sudo apt-get -y install jenkins

これだけでjavaとか入ってなくてもよしなに入れてくれます。素敵ですね。

Linux用 CUI版Dropboxインストール

最近は.emacsやら.vimやらをDropboxに入れ、それにパスを通して管理したり、はたまたgithubで管理したりするのが、ナウいヤングのお作法だと聞いて。

というか、そもそもCUIDropbox使うってのがよくわからんですよね。

以下手順。基本的に/home/user/の直下で作業するので、sudoとかいらないです。

### 32-bit版:
$ cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86" | tar xzf -
        
### 64-bit版:
$ cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

# ダウンロードされたのを確認
$ ls ~/.dropbox/
command_socket  config.db  config.dbx  dropbox.pid  filecache.dbx
host.db  host.dbx  hostkeys  iface_socket  l  
photo.dbx  sigstore.dbx  unlink.db

# 起動(認証)
$ ~/.dropbox-dist/dropboxd
このクライアントはアカウントにリンクされていません...
このマシンをリンクするには https://www.dropbox.com/cli_link?host_id=XXXXXXXXXXXXXXXXXXXXXXXXX&cl=ja を開いてください。

→このURLをブラウザで開く
(他マシンからでOK。ブラウザ認証が求められるので、パスワードを入れる)

(ちょっと待つ)

クライアントはリンクされました。kizm teru さん、ようこそ!

Ctrl + Cでとりあえず停止

# Dropboxフォルダが作成されているのを確認
$ ls ~/Dropbox/
local Public ...etc (Dropboxの中身)

# 操作用pythonスクリプトを取得(せっかくなので~/Dropbox/に)
$ wget -O ~/Dropbox/dropbox.py http://www.dropbox.com/download?dl=packages/dropbox.py

# LAN Sync(LAN内の同期を行う、普通要らない)の無効化
$ python ~/Dropbox/dropbox.py lansync n

# バックグラウンドで常に起動
$ ~/.dropbox-dist/dropboxd &

# 同期状況確認
$ python ~/Dropbox/dropbox.py status
7 ファイルをダウンロード中 (217.9 KB/秒、残り 1 時間)

とこんな感じ。

あとはどうせ個人ユーザでしか使わないんなら、

.bash_profile
---
if [ -z `pgrep dropbox` ] ; then
     ~/.dropbox-dist/dropboxd & > /dev/null
fi
---

とか書いておけばいいんじゃないですかね。

あとはスクリプトのパスとか書き換えだなー。めんどいです

ThinkPad USB Keyboard with TrackPoint

ThinkPad USB Keyboard with TrackPoint Driver 1.07で
Firefoxでスクロールできない系の問題は解決したっぽい。

http://support.lenovo.com/en_US/downloads/detail.page?DocID=DS013897

tp4table.datを普通に用意してくれるだけでもいい気がするんですが、自分用メモ。

Homebrewで入れたPythonにvirtualenvwrapperが入らない

.bash_profileにvirtualenvwrapper.shを読ませるところでエラーが出て、export VIRTUALENVWRAPPER_PYTHON=`which python`を指定してるし、きちんと/usr/local/のbrewで入れたpythonを見てるのになんでだろう……と思ってしばしハマったんですが、どうもpip入れた時点でMacの古い方のpython見てる気配。

Macのhomebrew使ってvirtualenv環境切るには、以下のようにするのが無難っぽい。

$ sudo brew install python

$ sudo /usr/local/share/python/easy_install pip
$ sudo /usr/local/share/python/pip install --upgrade distribute
$ sudo /usr/local/share/python/pip install virtualenv
$ sudo /usr/local/share/python/pip install virtualenvwrapper

.bash_profile
---
export WORKON_HOME=${HOME}/v_env/
export VIRTUALENVWRAPPER_PYTHON=`which python`
source /usr/local/bin/virtualenvwrapper.sh
---

$ mkdir ~/v_env/
$ . ~/.bash_profile

一回virtualenv環境作れば、あとは毎回virtualenv環境切ってその下でpip使うように徹底すればいいので、最初だけめんどくさいですけどフルパスで指定する感じですかね。

わざわざbrewで入れなくても、Mac OS X は2.7系入ってるのでそのまま使えばいいのかもしれませんけど。

6分割コンプガチャの出現確率はおおむね混一色くらい

いま話題のコンプガチャの確率を数学的に証明してくださったエントリを見て。(http://doryokujin.hatenablog.jp/entry/2012/05/09/034209)

うーん……正直数学ガール見て実際お手上げめいた似非理系プログラマの僕には数式みるだけで目眩が……

というわけでシミュレーションコード書いてみました。はい。力技です。

  1. いわゆるガチャをコンプするのに何回、回す必要があるか
  2. 1.を単一の超出現確率の低いカード(いわゆるスーパーレア)1枚に置き換えるとどのくらいの出現確率になるか

をざっくり求めてみたものです。Python 2.7。

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import sys, random

# 試行回数(デフォルト)
AVG_TRIALS = 10

"""
M枚分割されているコンプガチャ1枚を、単純に
非常に出現率の低いスーパーレアカード1枚に移行したとして、
損にならない程度の出現確率を求める
"""
def main(part):
    # ガチャコンプリートまでの平均回数を求める
    cnt = 0
    for i in range(0, AVG_TRIALS):
        cnt += getCompGachaCount(part)

    # ガチャコンプリート平均回数
    comp_times = cnt / AVG_TRIALS

    # 上で求めた回数回したとして、ギリギリ出現する程度になる
    # スーパーレアカード出現確率の平均を求める
    cnt = 0.00
    for i in range(0, AVG_TRIALS):
        cnt += getSuperRareOdds(comp_times)

    # 対応するスーパーレアの確率"
    s_rare_odds = cnt / AVG_TRIALS

    return (comp_times, s_rare_odds)


'''
part 枚分割のガチャをコンプするのに必要な回数を求める
'''
def getCompGachaCount(part):
    # 分割カードを準備
    p = (int)(part)
    list = [False] * p  # 初期状態
    comp = [True] * p   # コンプ状態

    # 全部コンプするまで回す
    cnt = 0
    while(list != comp):
        i = random.randint(0, part - 1)
        list[i] = True
        cnt += 1

    return cnt


'''
times 回数回してレアなカードがギリギリ出現する程度の
スーパーレアカードの出現確率を求める
'''
def getSuperRareOdds(times):
    i = 0
    # 10%から0.1%刻みで減らしていく
    ### (ここの処理、もっといい方法ないか???)
    odds = 0.1
    while(True):
        i += 1
        # レアカードが出現した場合
        if (random.random() <= odds):
            odds -= 0.01
            i = 0
            continue

        # 規定回数回しきった場合、その時の確率値を返す
        if times <= i:
            return odds


# main method
if __name__ == '__main__':
    argv = sys.argv
    argc = len(argv)
    if (argc != 3):
        print 'usage: python %s [part] [trials]' % argv[0]
        quit()

    part = (int)(argv[1])
    AVG_TRIALS = (int)(argv[2])

    timesum = 0.0
    s_raresum = 0.0
    for i in range(0, AVG_TRIALS):
        times, s_rare = main(part)
        timesum += times
        s_raresum += s_rare

    print "試行 %d回" % AVG_TRIALS
    print "ガチャコンプ平均回数 %f回" % (float)(timesum / AVG_TRIALS)
    print "対応スーパーレア平均確率 %g" % (float)(s_raresum / AVG_TRIALS)

で、以下が実行結果です。それぞれ4枚分割、6枚分割、9枚分割、12枚分割。

tkizmMBA:~ teru$ python CompGachaMigrateToSuperRare.py 4 100
試行 100回
ガチャコンプ平均回数 7.790000回
対応スーパーレア平均確率 0.089075

tkizmMBA:~ teru$ python CompGachaMigrateToSuperRare.py 6 100
試行 100回
ガチャコンプ平均回数 14.280000回
対応スーパーレア平均確率 0.077232

tkizmMBA:~ teru$ python CompGachaMigrateToSuperRare.py 9 100
試行 100回
ガチャコンプ平均回数 25.080000回
対応スーパーレア平均確率 0.056412

tkizmMBA:~ teru$ python CompGachaMigrateToSuperRare.py 12 100
試行 100回
ガチャコンプ平均回数 36.810000回
対応スーパーレア平均確率 0.038563

なんとなく怪しい部分がいくつかありますが、まあ参考程度に。

結論としては、6枚分割コンプガチャは麻雀の役で言えば混一色(6.1%)より出やすい程度、ってことですかね……
(http://www2.odn.ne.jp/~cbm15900/html/y99.html)

こうして値だけ見れば、思ってたより意外に出るような気がしますが、射幸心煽られちゃってるんですかねえ……


※このシミュレーションは全カードの出現確率は均等であるという前提です※