Mac へ anaconda をインストール。pyenv と homebrew を使って。

python を使う授業があったので履修してみることにした。

履修人数が多いので簡単に管理できるよう,Anaconda という開発環境含めて一括で管理できるものを使うらしい。

Mac への Anaconda の導入方法を調べた。
OS: macOS High Sierra (バージョン 10.13.6)

調べた背景

しかし私の mac には,デフォルトで入っていた python2.7, Homebrew で入れた python3.6 が既にあり,
ただ python とだけ打つとpython2.7 が,python3 と打つと python3.6 が,立ち上がる状態となっている。

授業ではLinuxにただダウンロードしてただインストールしていたが,このMacに同様に Anaconda を入れても大丈夫なのだろうか。

結論から言うと,pyenv で使い分けられるので Homebrew で入れた python3.6 を消す必要はない。
適当に調べたら,Homebrew で先に入れた python3 と Anaconda 上の python3 とが干渉するかどうかなどということを試している人は居なくて,環境を気にする必要のある人はそもそも何らかの方法を使ってpython のバージョンを切り替えられるようにしているらしい。その一つの手段がpyenvらしい。

とはいえ、もっと調べていくと, Homebrew と Anaconda とが (config ファイルの関係で?)ぶつかり合うらしい。
Anacondaを入れたらHomebrewの環境が吹っ飛んだ話 - Qiita
それは厳しい。もしぶつからせてしまうとHomwbrewの設定が壊れて path の設定もしなおさなきゃ、と。厳しい世界だ。。。

ということで,Anaconda が Homebrew の config ファイル群や path を壊すらしい?のを回避できる方法を調べた。

検索でよく引っかかったやり方は,

Homebrew で pyenv を入れた後,
pyenv で Anaconda をインストールし,
Anaconda のバージョン含め pyenv で管理する。

というもの。*1

これを主に参照してそのような理解に至った。
MacにAnacondaでPythonの開発環境を構築してみる


詳しくはこれらのブログにもお世話になった。
pyenvのインストール、使い方、pythonのバージョン切り替えできない時の対処法 - Qiita
MacでおすすめのPython環境作成方法 – CodeAid(コードエイド)

Homebrew を用いて, pyenv をインストール

Homebrew が入っているなら,ターミナルに

% brew install pyenv

を打ち込めば終わり

ちなみに,
MacにAnacondaでPythonの開発環境を構築してみる
にあった pyenv のインストール方法のところにあった以下の path の設定は,私は必要なかった。ので取り消し線。
#パスを通す
% echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile brew で pyenv を入れたなら設定済なのでそもそも要らない
% echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile 上に同じ

#pyenv の初期化?((これを二重にすると brew 使う時になんか言ってきた。でもこれしないと pyenv がスムーズに使えない。1回言おう。))
% echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
% source ~/.bash_profile

私は ~/.bash_profileではなく、 ~/.zshrc に書き込みました。

eval "$(pyenv init -)"

pyenv を用いて Anaconda をインストール

pyenv は環境管理ソフトなので複数の仮想環境を作ることができる。
が,ここではただ Anaconda を Homebrew の python と干渉させずにインストールしたいだけなので,1つの環境を作ることに絞って書く。

インストールできるものの一覧を表示。(・・・は省略)

% pyenv install -l
Available versions:
  2.1.3
  ・・・
  3.6.5
  ・・・
  anaconda-1.4.0
  ・・・
  miniconda-latest
  ・・・
  stackless-3.5.4

python, anaconda 以外にも色々入れられるらしい。

ここでは Anaconda の中で最新だった anaconda3-5.1.0 をインストールした。

% pyenv install anaconda3-5.1.0

インストールできたことの確認は,

% pyenv versions
 * system (set by /Users/username/.pyenv/version)
   anaconda3-5.1.0

system (もともと入っている python2.7 )に加えて,anaconda が表示される。
* が付いている方が,今 python と打つと起動する方である。

pyenvの使い方

% pyenv versions
   system
 * anaconda3-5.1.0 (set by /Users/nyaaaaoooon/current/directory/.python-version)

と打つと,今いるディレクトリ内で起動する python が anaconda3-5.1.0 に変えられる。
上に書かれている通り,そのディレクトリ内に存在する .python-version というファイル(ls -a などで存在を確認できるし,cat などで中身も見られる。)によって設定されている。

コンピュータ全体の python を変えてしまいたいときは,

% pyenv global anaconda3-5.1.0

とすればオーケー。

ローカルな設定を消すためには,

% rm .python-version

Homebrew の警告を無くす

とか言って真似してインストールすると,下のように homebrew が軽い警告を発して邪魔だよと言ってくる。
一応対処したくなる。

% brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and what additional flags to use when
compiling and linking.

Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew provided
script of the same name. We found the following "config" scripts:
  /Users/nyaaaaoooon/.pyenv/shims/icu-config
  /Users/nyaaaaoooon/.pyenv/shims/libpng16-config
  /Users/nyaaaaoooon/.pyenv/shims/python3.6m-config
  /Users/nyaaaaoooon/.pyenv/shims/python-config
  /Users/nyaaaaoooon/.pyenv/shims/python3-config
  /Users/nyaaaaoooon/.pyenv/shims/ncursesw6-config
  /Users/nyaaaaoooon/.pyenv/shims/pcre-config
  /Users/nyaaaaoooon/.pyenv/shims/python3.6-config
  /usr/local/root-6.12.06/cmake_build/bin/afterimage-config
  /usr/local/root-6.12.06/cmake_build/bin/pcre-config
  /usr/local/root-6.12.06/cmake_build/bin/root-config

ROOT の config ファイルも邪魔だと言われている。ので一緒に対処した。


これは,以下のリンクのやり方で回避できた。
www.task-notes.com


.zshrc に,

alias brew="env PATH=${PATH/\/Users\/username\/\.pyenv\/shims:\/usr\/local\/root-6\.12\.06\/cmake_build\/bin:/} brew"

を書き足した。
(2020.09.27追記:ROOTを消したので、

alias brew="env PATH=${PATH/\/Users\/username\/\.pyenv\/shims:/} brew"

でうまくいく。)

パスについては 〇〇env をまとめて解説してるこのページも参考になるかも。
casualdevelopers.com

エイリアスの設定

ついでなので py3 で python3 に繋がるエイリアスも設定した。

alias py3="python3"

PyROOT との兼ね合い

私は,Homebrew でインストールしてあった python3.6 の場所を指定して ROOT をビルドすることで PyROOT を使えるようにしている。*2
PyROOT を壊したくなかったので,anaconda で同じものをインストールできるにも関わらず,そのまま Homebrew で先にインストールしてあった python3.6 を残している。
pyenv で system の python を使うよう指定しておけば,今まで通り使えた。
AnacondaからROOTが使えないのは勿体無い気もするが、面倒を考えるとしょうがないか。

使えたというのは,
私のパソコン上で "IPython" は homebrew で入れた Python3.6 によって起動するようになっているが(詳細は忘れた)その IPython 上から ROOT を import 出来たので,問題なさそうということ。

% pyenv local system
% ipython
Python 3.6.5 (default, Mar 30 2018, 06:41:53) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
Python Startup!

In [1]: import ROOT

がエラーを吐かずに成功した。

anaconda を指定していると,

import ROOT が出来ず,error の山が吐かれる。

% pyenv local anaconda3-5.1.0
% ipython
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.
Python Startup!

In [1]: import ROOT

 *** Break *** segmentation violation
・・・(エラーの山)・・・
[] (no debug info)

*1:これだけ多く検索結果が見つかるということはもはやポピュラーなやり方なのだろうか。

*2:今のところ,私は実際のデータを扱っていないのでまだ ROOT 講習会以外で使ったことはない。先輩が,python 使って書く必要があるから勉強中とか言っていたのでそのうち使う必要もあるのかもしれない。

小指が痛かったので,Shift key の代替キーを設定した

Shift keyとしてはたらくように別のキーに Shift を割り当てた。それはKarabinar-Elementsというソフトウェアで実現可能だった。

導入背景

昨日くらいから左手の小指に違和感を抱え始めた。

スマホをいじる際に小指にスマホを乗せているなど色々心当たりもあるが、数年来してきているので、今更影響しないと想像して、
最近新しくかかり始めた小指へのストレスの一つとして、キーボード上での力の入り具合を気にし始めた。

何より、痛みが気になって作業に集中できない。

今私は、 Shift, Tab, Control key や A に左手の小指を使っている。
これまでの私の人生の中で最も左手の小指が活躍している数ヶ月だと思う。
私はEmacs使いではないけれどEmacs小指みたいな言葉があるくらいだからキーボードでも小指の腱鞘炎とかにはなりうるのでしょう。左手の小指の痛みを軽減できる方法を調べてとりあえず導入してみる。

何をしたかったか

ということで,
Shift キー以外はそのまま、
左の Shift キーに相当するキー入力を
小指で押さなくて済む場所にあるキーに対して割り当てる

方法を調べた。

解決策

検索によれば、Karabiner-Elements というアプリケーションで,キーの動作を変更できるらしい。
Karabiner-Elements


早速インストールして起動してみる。
まず今使っているキーボードのタイプを認識するためか,2-3 のキーを押すよう指示された。その通り押す。

すると設定画面が出てきた。

設定画面

色々ポチポチしてみる。

設定画面詳細1
いろんなキーの挙動を細かく変更できるらしい。


Complex Modifications タブ画面中にある、Add rule ボタンをクリックする。
3つの設定例が出てきた。

画面のスクリーンショット
Add Rule ボタンをクリックすると出てきた画面
その中に,

「Space key を押しながら他のキーを押すと,Shift key として動作する(Space key だけが押された時は Space を入力する)」

という設定があった。とりあえず導入。

他のキーにシフトキーの役割をさせることだけを考えればこれで良い気がする。

導入後

結果

小指の痛みを感じずにShiftキーを使用できるようになった。
Space key を離すまで空白文字が入力されない点に違和感がある。慣れれば気にならないだろう。
Space key を押すことで大文字を入力するという操作に慣れないためタイプスピードが落ちている。
これらに伴い,かな・英数・スペースなどの親指を用いる動作に混乱がある。

感想

キーボードの設定を変えることそのものもストレスになっている。数日使って、この設定を続けるか否かを考えようと思う。

数ヶ月経っての感想(2019年7月)

スペースキーにShiftキーが割り当てられていないPCで違和感を持つ程度に慣れた。スペース長押しでスペースたくさんが入力できないことは引き続きストレス。
割当を継続することにする。

業務用の Windows PCを扱うようになってからの感想 (2023年5月)

WindowsMacとのキーボード操作の差分が大きすぎたため、万人に薦められるものでないことを理解した。複数PCを扱うならば、標準的なキー配列に慣れておくのが楽なよう。Windows PC 数台を行き来しながらの業務のため、Macのスペースキー長押しへのシフトキー割当てには弊害があった。

その他試したこと

小指ではなく薬指に働いてもらうことも試したが、ストレスが溜まった。
Tab key を薬指で押すことは問題ない。F のキーから人差し指を離さず行き来出来る。がしかし、Shift は少し負担が大きかった。手首を回すか、薬指にかなり力を入れなければいけなかった。
右側の Shift key を使う癖を付けるのが一般的なのかもしれない

早く寝なきゃいけませんね

夜な夜なブログ書いたりTwitterしたり漫画読んだり音楽聴いたりしてて当たり前ですけれども、風邪ひいたり病んだりしやすい体質のようです。
今年は手洗いをちゃんとしているからでしょうか。風邪を引いていません。やったね。

手は洗って、早く寝て、そして余裕作れた時があればこういうのを更新しましょうね。自分。


夜に仕事が捗っている気がしたり、いろいろな打合せに毎度微妙に遅刻したりすることを気にしてこういう本を買ってみました。
www.seiwa-pb.co.jp

というのも、
本屋を立ち読みしながらぶらついてまして、大人のための時間管理ワークブックかぁ、ADHDタイプかあ、って思い、手に取ってみたんですよ。そしたら前書きにあった
「本書をおすすめする方」http://www.seiwa-pb.co.jp/search/bo05/bn896.html
の項目が綺麗に当てはまりすぎてですね。
ADHDという診断を受けたわけではなく、自分がADHDなのかそれともその他の傾向なのかは分からないのですが、買ってしまいました。


昨日からスタート。何か生きやすくなると良いなと期待してますけども続けられると良いな。1回120分かかるワーク × 8回〜8週間。続けられている未来が今のところ想像できていませんが。

乱数の Fill 3通り(CERN ROOT)

乱数を振ってヒストグラムに積むやり方についてのメモを書いておく。

元々正規分布ガウス分布)に従う乱数を、C++ の標準ライブラリを用いて生成して Fill してというのを for 文で回すみたいなことをしていた。どうやら ROOT の機能だけを用いて簡単に乱数生成と Fill ができるらしいと知ったので自分のコードを書き直した。ROOTで3通り、C++標準ライブラリで1通り下にまとめたつもり。

その際、まだクラスと言う概念を理解しておらず苦戦したので、未来の自分と誰か用のメモとして、ROOT での乱数生成と Fill について書いた。
*1

TH1::FillRandom()

    hist->FillRandom("funcname", number);

とすれば良いらしい。ということで、使い方。

"funcname" としては、自分で定義した TF1 クラスのROOT内の名前を入力する。"gaus" や "landau" などのもともとパラメタ込みで定義されているものも使える。
https://www-he.scphys.kyoto-u.ac.jp/member/n.kamo/wiki/doku.php?id=study:software:root:main#fillrandom

{
    TH1D *hist = new TH1D("", "", 100, 0, 5);
    TF1* func = new TF1("gaussdayo", "TMath::Gaus(x, 2.0, 0.5, true)", 0, 5);  // ここの "gaussdayo" というROOTのための名前が、 TF1 インスタンスに与えられる。ポインタ名 func で呼び出せる。
    hist->FillRandom("gaussdayo", 1000000);  // ROOTのためのTF1インスタンスの名前 "gaussdayo" を入れる。1,000,000個Fillする。
    hist->Draw();
}

ちなみに、"" なしではTF1を定義できなかった。

f:id:nyaaaaoooon:20180922024053p:plain
gaus で画面に出力した画像

TF1::GetRandom()

TF1::GetRandom は、TF1 クラスのメンバ関数なので、TF1 class のポインタにアロー演算子(->)をくっつけて GetRandom() としてやると乱数の値が得られる。

{
    TH1D *histo = new TH1D("", "", 100, 0, 5);
    TF1* funct = new TF1("gausdayo", "TMath::Gaus(x, 2, 0.5, true)", 0., 5.);
    for (Int_t i = 0; i<1000000; ++i){
        Double_t r = funct->GetRandom();  // TF1のポインタ funct に->演算子を付け、GetRandom()を呼び出して乱数の値を得る。その値を r に代入する。 
        histo->Fill(r);
    }
    histo->Draw();
}

とすると同様に以下のようなヒストグラムの画像が得られる。

f:id:nyaaaaoooon:20180922024309p:plain
gausdayoで画面に出力した画像


TRandom::分布名

分布一覧(メンバ関数一覧)はこれ。Sphere とか Circle とかを簡単に作れるのが良いと思った。
ROOT: TRandom Class Reference

TRandom::Gaus() で乱数を得る。

    TRandom3 r; // TRandom を継承するTRandom3 classを用いる。
    
    // generate a gaussian distributed number with:
    double x1 = r.Gaus(); // average = 0, sigma = 1 (初期値)
    double x2 = r.Gaus(10,3); // use average = 10, sigma = 3 のガウス分布

ROOTUsersGuide

となっていた。(乱数の「シード」がどこでどう定義されているかは理解していない。)
これを用いて、

{
    TH1D *histog = new TH1D("", "", 100, 0, 5);
    TRandom3 *rnd = new TRandom3();
    for (Int_t i = 0; i<1000000; ++i){
        Double_t r = rnd->Gaus(2, 0.5);
        histog->Fill(r);
    }
    histog->Draw();
}

とできた。

f:id:nyaaaaoooon:20180922024532p:plain
gausus で画面に出力した画像
(ただ使っただけとは言っても初心者な私にはまだ簡単ではないので参考にしたサイトがあり、これ。)
ROOTでランダムな数を生成するTRandommorephotons.wordpress.com


C++標準ライブラリの を用いる方法。)

ROOT のクラス群を使わずに書いていた時はこうしていた。
にも normal 以外の分布はたくさんあるが、自分の分野でROOTで解析する限り ROOT での乱数生成のほうが楽に書けると思う。どうでしょう。

// normaldist.cxx
#include <random>
using namespace std;    // 毎回std::と打たなくてよくなる

int normaldist(void){

    TH1D *hist = new TH1D("<random>", "", 100, 0, 5);
    
    int n=1000000; // 出力数

    // <random> ライブラリから
    mt19937_64 mt(3);  // mersenne twister の 64 bit ver. のオブジェクトに、シードとして3を入力
    normal_distribution<> norm(2, 0.5); // 平均2, 標準偏差0.5(元にしたプログラムでは分散と書かれていたが、Std Devが0.5程度になったので標準偏差のはず)の正規分布に整えてもらう
    
    for (int i = 0; i<n; ++i){
        hist->Fill(norm(mt));
    }    
    hist->Draw();
    
    return 0;
}

f:id:nyaaaaoooon:20180922023322p:plain
normaldist で出力した画像



Fit 用のTF1::Gausのメモ。

関数のパラメタを後から代入してFillしないだけのものも置いておく。2行増えてFillしないだけ。

void gaus(){
    TH1D *hist = new TH1D("", "", 100, 0, 5);
    TF1* func = new TF1("gaussda", "TMath::Gaus(x, [0], [1], true)", 0, 5);  // "gaussda"と言う名前を TF1 のオブジェクトに与える。"" なしでは定義できなかった。
    func->SetParameter(0, 2);   // TMath::Gaus の [0] の所にはガウス分布の平均値が入る。
    func->SetParameter(1, 0.5);   // [1] の所にはガウス分布の標準偏差が入る。
}

*1:注意としてたまに書かれていること:TRandom クラスが出力する擬似乱数列は、目的によっては性質がよくないので使えない場合もある。以下の記事のTH1やTF1の持つ乱数生成器はTRandom から来ているので、そのままでは用いることが出来ないことがある。(if(gRandom) delete gRandom; gRandom = new TRandom3(0); とせよというQ&Aを見かけたのでそうすることにしている)

TF1 の情報の載ったサイトのメモ

CERN ROOT のTF1 クラスの情報を色々な人がまとめている。

TF1 の諸々
TF1の諸々 - 微妙録

TF1 Class Reference v608
ROOT: TF1 Class Reference

users-guide の,fit についてのまとめ
Chapter: Fitting Histograms

読み慣れるのに時間がかかったが、class referenceを読むのが一番勉強になるな。

C++ のお勉強から ROOT のお勉強に移行した

先週 C++ についての記事をひとつ書いただけなのに,C++ でポインタを渡すこともできてしまい,1週間経った今はブログを書く前に満足してしまっている。

C++の本「やさしいC++」の後半は読み流してしまえた。

C++ で遊んでいる間,ROOTの勉強はしなかった訳だが,どうやら研究室の一つ上の先輩たちは関数を main ひとつしか作らずにズラッと書いているらしく,関数の勉強のいくらかの部分は無駄だったんじゃないかと思い始めた。

演算子,ポインタ,クラス,ライブラリ,標準入出力などの概念を知ったのは良かったが,依然として ROOT の分からないことは多い。
今日までの「やさしいC++」での勉強がどれほど今後のプログラムに役立つのかがあまり明らかではないなあと思う。

はてな記法でコードを書くためのメモ@はてなブログ

プログラムのメモをしていくにはまずここにコードを貼り付ける方法を知る必要がある。
昨日投稿した Markdown 記法に続いて,はてな記法について。

はてな記法の何が良いかと言うと,自動で色付けしてくれて見やすいのだ。

参考にしたのはこちら。
はてな記法について。
はてな記法ってなに? - はてなダイアリーのヘルプ

はてな記法においてコードを色付けしてくれるスーパーpre記法について。
入力したコードやはてな記法をそのまま表示する(スーパーpre記法) - はてなダイアリーのヘルプ

目次

目次の作り方

[:contents]
を書くとその場所に見出しリストを挿入してくれる。


見出しの作り方

* を付けると,h3 タグに相当する見出し,
** で小見出し (h4)
*** で小小見出し (h5) となる。*1

コードブロック

pre記法と呼ばれている記法でコードブロックを作れる。
>|| だけの行と, ||< で囲むと良い。*2

 >||
 int x; 
 ||<

と書けば,int x; が枠に囲まれる。

int x;

コードブロックとスーパーpre記法

スーパーpre記法を用いると,色付きのコードが書ける。

>|cpp|
# include <iostream>
using namespace std;

int main (void)
{
    cout << "aiueo" << endl;
    return 0;
}

のように,初めの >|| にcpp などのファイルタイプを打つと,勝手に色付けしてくれて,

# include <iostream>
using namespace std;

int main (void)
{
    cout << "aiueo" << endl;
    return 0;
}

引用 (blockquote)

>> 
引用されてるよ!
>> 
2重に引用されてるよ!
<< 
<<

のように >> や << だけの行を書けば,

引用されてるよ!

2重に引用されてるよ!

と表示させることができる。

*1:ちなみに * の前にスペースを置けばこの3行のように見出しへと変換されずに済む

*2:これも同じくスペースを置いた。