技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

快適コマンドプロンプト生活 (Gow + ConEmu + chocolatey)

コマンドプロンプトはレガシー。使いづらい。見た目が嫌い。これだからWindowsはクソ。
と罵られてばかりのコマンドプロンプトだけど、今回はコマンドプロンプトを最大限に使いやすいくしてやろうという話。
Cygwinはホームが変だったり所々使いにくくて嫌いだった。
(今はGit for Windowsを使っている)

コマンドプロンプト生活の末にたどり着いた、コマンドプロンプトによる快適環境構築について紹介する。

Gow (Gnu on Windows)

コマンドプロンプトを使うならば、これがないと不便極まりない。
正式名称はGnu on Windowsといって、ls,grepを始めとしたLinuxで使えるコマンドをコマンドプロンプトで使えるようにするもの。
具体的には以下のコマンドが使えるようになる。(version 0.7.0現在)

>>gow -l

  awk, basename, bash, bc, bison, bunzip2, bzip2, bzip2recover, cat,
  chgrp, chmod, chown, chroot, cksum, clear, cp, csplit, curl, cut, dc,
  dd, df, diff, diff3, dirname, dos2unix, du, egrep, env, expand, expr,
  factor, fgrep, flex, fmt, fold, gawk, gfind, gow, grep, gsar, gzip,
  head, hostid, hostname, id, indent, install, join, jwhois, less,
  lesskey, ln, ls, m4, make, md5sum, mkdir, mkfifo, mknod, mv, ncftp, nl,
  od, pageant, paste, patch, pathchk, plink, pr, printenv, printf, pscp,
  psftp, putty, puttygen, pwd, rm, rmdir, scp, sdiff, sed, seq, sftp,
  sha1sum, shar, sleep, sort, split, ssh, su, sum, sync, tac, tail, tar,
  tee, test, touch, tr, uname, unexpand, uniq, unix2dos, unlink, unrar,
  unshar, uudecode, uuencode, vim, wc, wget, whereis, which, whoami,
  xargs, yes, zip

設定は簡単、インストール用の実行ファイルを落としてきて実行するだけ。
Release Gow 0.8.0 · bmatzelle/gow · GitHub

bashを動かす

Gowのあるフォルダに/etcというフォルダを作ればbashが使えるようになる。
bash.exe in Gow 0.7.0 · Issue #65 · bmatzelle/gow · GitHub

ConEmu

その名の通りコンソールのエミュレータ。気持ち悪いPower Shellやcmd.exeの見た目をカスタマイズできるのはもちろん、同じウィンドウ内でタブで切り替えができる。ウィンドウを分割して右にPower Shell、左にCygwinを開くなんてこともできる。
具体的には、Ctrl+Shift+eで横分割 Ctrl+Shift+oで縦分割の新規コンソールを立ち上げる。コンソールを閉じる時はexitと打てばよい。
背景画像を設定して透過もできるのでこんなこともできる。
f:id:swdrsker:20170111013639j:plain:w600
f:id:swdrsker:20170121230846p:plain:w600


これも公式サイトから実行ファイルを落として実行するだけ。
ConEmu - Handy Windows Terminal

chocolatey

apt-getのようにパッケージ管理ができる、もはやWindowsユーザーは必須のスグレモノ。
chocolatey自体の導入はこの記事を参考に。
windowsの開発環境は一瞬で整うwith chocolatey - Qiita
管理者用のプロンプトを立ち上げて、以下をコピペして実行するだけ~

@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin


今までめんどくさかったwindowsへの色んなアプリケーションのインストールを何も考えず(パスを通すことも含めて!)一発でできる。
試しにwindowsでは環境設定がめんどくさいとされるemacsをinstallしてみる

choco install emacs

これだけ。

他にも

choco install nodejs
choco install git

控えめに言って最高

おわりに

コマンドプロンプトLinux風に使いやすくするという話でした。
お試しあれ(`・ω・)

カオス理論入門(pythonでアトラクタの軌跡を描く)

カオスについて勉強していた時に書いて見たかったもの。アトラクターの軌道を見てみたい。
目標としては3次元プロットして一定軌道をグルグル回っているところをプロットしてみる。有名なレスラーアトラクターとローレンツアトラクターを描いていきたい。

実際のコード

汎用性の高いものになるよう意識したので、色々カスタマイズできるようにした。
Attractorクラスを継承すれば、描画や実行は新しく書く必要がないようにした。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pdb


class Attractor:
    def __init__(self):
        self.dt = 0.01
        self.x = self.y = self.z = 0.1
        self.output = []

    def initialize(self,x,y,z):
        self.x = x
        self.y = y
        self.z = z

    def run(self,T):
        for t in range(T):
            self.step()
            self.output.append([self.x,self.y,self.z])
        return self.output

    def step(self):
        pass

    def draw(self,display=True,plotfig=None):
        if not self.output:
            print("not run...")
            return 0
        if display:
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot(*zip(*self.output))
            plt.show()
        else:
            try:
                plotfig.plot(*zip(*self.output))
            except:
                print("draw Error...")
                print("USAGE: draw(display=False,plotfig=<object plt.figure().gca>)")


class Lorenz(Attractor):
    def __init__(self,p,r,b):
        # p=10,r=28,b=8/3 in Lorenz(1963)        
        Attractor.__init__(self)
        self.p = float(p)
        self.r = float(r)
        self.b = float(b)

    def step(self):
        x,y,z = self.x,self.y,self.z
        self.x += self.dt*(-self.p*(x-y))
        self.y += self.dt*(-x*z + self.r*x - y)
        self.z += self.dt*(x*y - self.b*z)
        return self.x, self.y, self.z


class Rossler(Attractor):
    def __init__(self,a,b,c):
        # a=0.2,b=0.2,c=5.7 in Rossler(1976)
        Attractor.__init__(self)
        self.a = float(a)
        self.b = float(b)
        self.c = float(c)

    def step(self):
        x,y,z = self.x,self.y,self.z
        self.x += self.dt*(-y-z)
        self.y += self.dt*(x+self.a*y)
        self.z += self.dt*(self.b+x*z-self.c*z)
        return self.x, self.y, self.z


if __name__=="__main__":
    fig = plt.figure(figsize=plt.figaspect(0.5))
    ax = fig.add_subplot(1,2,1,projection="3d")
    la = Lorenz(10,28,8.0/3)
    la.run(10000)
    la.draw(display=False,plotfig=ax)
    ax2 = fig.add_subplot(1,2,2,projection="3d")
    rl = Rossler(0.2,0.2,5.7)
    rl.run(100000)
    rl.draw(display=False,plotfig=ax2)
    plt.show()

実行結果

f:id:swdrsker:20161208195826p:plain

参考にしたサイト:
Lorenz system - Wikipedia
Rössler attractor - Wikipedia

pythonでたまに使う用法(リスト・内包表記・三項演算子・lambda…)

pythonのちょっと特殊だけどたまに使う記法について備忘録。
※2.7系で動かしているので3系では動かないかもしれない。要調査。

リスト操作

リストの重複削除
a = [1,1,4,4,3,3,2,2,5,5]
list(set(a))
# >>[1,2,3,4,5]

※この書き方だと順序は保持されない

順序を保持するリストの重複削除はこうする

sorted(set(a), key=a.index)
# >>[1,4,3,2,5]
リストの結合
a = [1,2,3]
b = [4,5,6]
c = a + b
# >>[1,2,3,4,5,6]
リストのソート
sorted(a) # 1
a.sort()   # 2

1の場合はソートされたリストが返されるが、引数のリストは元の状態を保持。
2の場合は値が返ってこないが、ソートされた状態になるので注意が必要。
いわば2は a = sorted(a) と同じ

リスト内包表記

基本
[i*i for i in range(10)]
# >>[0,1,4,9,16,25,36,49,64,81,100]
応用

ユークリッド距離を求めるのに使ったり

import numpy as np
c1 = [1, 2, 3]
c2 = [0, 0, 0]
distance = np.sqrt(sum([(a - b)**2 for a, b in zip(c1, c2)]))

三項演算子

x = "Fizz" if True else "Buzz"

実は結構新しくて、2.5以降からできたらしい。
それ以前はめっちゃ不便だっただろうな…

リスト内包表記との合わせ技
[0 if i%3==0 else i for i in range(10)]
# >>[0, 1, 2, 0, 4, 5, 0, 7, 8, 0]

lambda式

map, filterとの組み合わせ
map(lambda x:x*x ,range(10))
# >>[0,1,4,9,16,25,36,49,64,81,100]

※リスト内包表記の上の例と同じ。

filterを使ってある文字列を含む要素を取り出すことができる

keyword = ["windows","linux","mac","android"]
filter(lambda x:"win" in x, keyword)
# >>['windows']
sortedやmaxなどとの組み合わせ

要素に注目してソートしたり、距離の最大値を求めたりできる。

import random
a = [[random.random() for i in range(2)] for j in range(20)]
sorted(a, key=lambda x:x[0])
max(a, key=lambda x:x[0]**2+x[1]**2)

可読性が悪いのであまりに複雑な処理なら関数にした方がいいかもしれない


参考サイト:
Pythonで配列内の重複する値を抽出する方法 - Pashango’s Blog
[Pythonの無名関数(lambda)の使い方 - Life with Python