OmniAICreator/Qiita-1.07M huggingface dataset:
Jupyter NotebookにRをインストール ※pyenvを使っているときの補足

# 環境構築

基本的には、こちらの記事が参考になります。
https://qiita.com/piruty/items/498ee16de62879e5a949

ただ、pyenvで実行している環境でやらないと、jupyterが認識されない。

# エラー

#### RStudio
![image.png](https://qiita-image-store.s3.amazonaws.com/0/76913/f9943a05-d545-51ed-6986-2705b79348c7.png)

#### エラー原因のコマンドをTerminalで確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/76913/03230879-1270-347c-b5de-931d32ff88b3.png)



# 対応


なので、以下の条件であることが必要。

* RStudioでやらず、Rのコマンドラインでやる。
* jupyterがインストールされている、pyenv環境であること。


こちらの記事が同じエラーに遭遇していて、参考になる。
http://aiuchi0703.hatenablog.com/entry/2017/12/25/010753
vs2010でmanaged directx その10

#概要
c#で、3Dやりたかった。
RotationYawPitchRoll、使ってみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/fa57fc40-aee7-38ab-3ec5-d8d6ea31c570.png)


#サンプルコード

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        private Device device = null;
        private Mesh mesh = null;

        float x = 0,
            y = (float) Math.PI / 2,
            z = 0;
        private Matrix rot = Matrix.Identity;

        public Form1()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            PresentParameters pp = new PresentParameters();
            pp.Windowed = true;
            pp.SwapEffect = SwapEffect.Discard;
            device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
            mesh = Mesh.Cylinder(device, 0.2f, 0.8f, 1.5f, 8, 1);
                        rot.Multiply(Matrix.RotationYawPitchRoll(y, x, z));
        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 1.0f, 7.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
            device.Transform.Projection = Matrix.PerspectiveFovLH((float) (Math.PI / 4), 1.0f, 0.1f, 1000.0f);
            device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
            device.BeginScene();
            device.SetTransform(TransformType.World, Matrix.Identity);
            device.RenderState.Lighting = false;
            

            device.Transform.World = rot;

            mesh.DrawSubset(0);
       
            device.EndScene();
            device.Present();
            this.Invalidate();
        }
    }
}

```

以上。
「新しい映像伝送プロトコル SRT を試す」の話をしました

先日開催された[Streaming Conference #4](https://streaming-lab.connpass.com/event/98404/)で「新しい映像伝送プロトコル SRT を試す(増強版)」の話をしました。
(実はその前の #3のときに5分のLT枠で話したのですが、全く時間が足りなかったので今回は15分枠でやらせてもらいました。)

発表資料のリンク: https://www.slideshare.net/tetsu.koba/try-new-transport-protocol-srt-ver-2

録画: https://freshlive.tv/tech-conference/232370
(開始後44分くらいから私の発表)

# 補足説明

## latencyの設定

latencyの設定は送信側と受信側の双方から設定可能で、大きい方が採用されます。
なので、serverになるほうは小さな値(20ms)を設定しておいて、client側がRTTを測定して、その2.5倍の値を設定するのがよさそうです。
ひとつのserverに対して複数のclientが接続できますが、latencyの設定はそのコネクションごとに別々になります。

## 送信側と受信側のどちらもserver になれるのは開発時には特に便利

RTMPでは映像を送信する側がclient, 受信する側がserver になります。
開発中などでは映像を送信する側がserverになってくれるほうがネットワーク構成が単純で使いやすかったりします。
このために映像を送信する側にrtspサーバになれる機能を入れたりするのですが、ffmpegやgstreamerではあまり簡単にできなくて、それなりにプログラムを書かなければいけなかったりします。
gstreamerでSRTを使っている場合は、`srtclientsink` を `srtserversink` に入れ替えるだけなので、そういう場面でも簡単に対応することができます。

## wasm からでもSRTは使える？

ブラウザの中で動作するWebAssembly からSRTが使えるようになったら面白いというアイディアがありますが、現状はブラウザの中で動作するWebAssemblyの環境からUDP socketを扱うことはできないので、残念ながらボツです。

## 回線状況悪化時のエンコーダへのフィードバック

SRTはその性質上、常に通信の実効帯域を把握しています。回線状況が悪化してパケットロスが増えると相手側に再送要求を出すわけですが、エンコーダ側にも実効帯域が低下したことを通知すれば、エンコードするビットレートを下げることができるはずです。ここまでの実験はしていませんが、これができると屋外からのライブ配信でも切れにくく粘ることができそうです。


# 関連
[新しい映像伝送プロトコルSRTをgstreamerとVLCで試す](https://qiita.com/tetsu_koba/items/b12a6de83185a5267217)
[ffmpeg 4.0 に入った新しい映像伝送プロトコルSRTを試す](https://qiita.com/tetsu_koba/items/b8e1868a726c6201d3ab)
[ffmpeg 4.0 をlibsrtを有効にしてビルドする](https://qiita.com/tetsu_koba/items/92c398abd96c651f4035)
[SRTを使ってWebcamの映像を送ってみる](https://qiita.com/tetsu_koba/items/3af1fcc976e2ef45bb29)
[SRTの暗号化通信を試してみた](https://qiita.com/tetsu_koba/items/1fabedf3863ee0857d82)
vs2010でmanaged directx その9

#概要
c#で、3Dやりたかった。
クータニオンで、回してみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/017d8aa7-0da8-14fc-73d4-08ded959dd1b.png)


#サンプルコード

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        private Device device = null;
        private Mesh mesh = null;

        float x = 0,
            y = (float) Math.PI / 2,
            z = 0;
        private Quaternion qua = Quaternion.Identity;
        
        public Form1()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            PresentParameters pp = new PresentParameters();
            pp.Windowed = true;
            pp.SwapEffect = SwapEffect.Discard;
            device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
            mesh = Mesh.Cylinder(device, 0.2f, 0.8f, 1.5f, 8, 1);
            qua.Multiply(Quaternion.RotationYawPitchRoll(y, x, z));
            
        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 1.0f, 7.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
            device.Transform.Projection = Matrix.PerspectiveFovLH((float) (Math.PI / 4), 1.0f, 0.1f, 1000.0f);
            device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
            device.BeginScene();
            device.SetTransform(TransformType.World, Matrix.Identity);
            device.RenderState.Lighting = false;
            
            
                        device.Transform.World = Matrix.RotationQuaternion(qua);


            mesh.DrawSubset(0);
       
            device.EndScene();
            device.Present();
            this.Invalidate();
        }
    }
}

```

以上。
webpack-dev-serverは引き続き開発継続される見通し？

# 概要
[webpack-dev-server](https://github.com/webpack/webpack-dev-server)はメンテナンスモードに入り今後は[webpack-serve](https://github.com/webpack-contrib/webpack-serve)に移行するという話でしたが、先日本家リポジトリの[readme](https://github.com/webpack/webpack-dev-server/commit/6c1d8d8ea1c06831a4360cdb661cc58bb52d77ec)が変更され、<font color=red>"メンテナンスモード入り" という宣言が**撤回</font>**されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/2ef399c2-9181-114a-d904-7c5466dd34bf.png)

# webpack-serveがwebpack-dev-serverにマージされる見込み

その後のメッセージのやりとりをみてみると

> webpack-server will be merged in webpack-dev-server (roughly speaking)

ってことで、[webpack-serve](https://github.com/webpack-contrib/webpack-serve)が [webpack-dev-server](https://github.com/webpack/webpack-dev-server) にマージされると書いてあります。

近いうちに公式アナウンスがあるらしいので、待つとしましょう。
Pythonベースの密度汎関数法ソルバGPAWをUbuntuにインストール

# 1. 目的
- Pythonベースの密度汎関数法ソルバのひとつである[GPAW](https://wiki.fysik.dtu.dk/gpaw/)をUbuntu17.10にインストールしました．
- GPAWはpipでのインストールも提供してくれているのですが，私の環境では並列計算がうまくいかなかったため，記事化してみました．

# 2. 方法
- 今回は依存ライブラリをインストールした後にコンパイルする手法を取りました．
- GPAWのドキュメンテーションに記載はあるので[(Link)](https://wiki.fysik.dtu.dk/gpaw/install.html)，本記事はその補助になれば良いかと思います．

## 2.1. 依存ライブラリのインストール
以下のライブラリをインストールします．(該当GPAWドキュメンテーション[(Link)](https://wiki.fysik.dtu.dk/gpaw/install.html#requirements))
‐ aptでインストール：BLAS, LAPACK, BLACS, Scalapack, OpenMPI
- pipでインストール：numpy, scipy, ase
- ソースからコンパイル：LibXC

LibXCのみソースファイルからコンパイルを行いました．
詳細はGPAWドキュメンテーション[(Link)](https://wiki.fysik.dtu.dk/gpaw/install.html#libxc-installation)参照ですが，
①LibXCのサイトから圧縮ファイルをダウンロード[(Link)](http://www.tddft.org/programs/libxc/download/)
②tarで解凍し，コンパイル実行[(Link)](http://www.tddft.org/programs/libxc/installation/)
でうまくいきました．
コンパイルで規定のフォルダ以外にライブラリ作成した場合は環境変数の設定が必要になります(今回はLibXCにてLD_LIBRARY_PATHを追加する必要あり)．

## 2.2. GPAWのコンパイル
ドキュメンテーションには複数の方法が列挙されているのですが，並列版のインストールはgit cloneでレポジトリをダウンロード→コンパイル→環境変数設定の手順でうまくいきました．
①gitによるダウンロード

```bash
git clone https://gitlab.com/gpaw/gpaw.git
```
②customize.pyの変更

```python:customize.py
...
Scalapack = True
...
# - dynamic linking (requires rpath or setting LD_LIBRARY_PATH at runtime):
if 1:
...
```

③Developer Installation[(Link)](https://wiki.fysik.dtu.dk/gpaw/devel/developer_installation.html#developer-installation)に従ってsetup.pyを実行

```python
python3 setup.py build_ext
```
④環境変数を追加すれば，並列版のgpawコマンド(gpaw-python)が実行可能となります．

#a1. GPAWについて
- GPAWは[ASE, Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/)とネイティブに連携が取れる点が非常に良いと思います．原子操作‐エネルギー計算‐ポスト処理をPythonで一括に回せるので，他のPythonライブラリと繋げて…などいろいろ面白そうな計算ができます．
GPU版TensorFlowをワンライナーでインストールする方法 (Windows 10)

GPU版の[TensorFlow](https://www.tensorflow.org/?hl=ja)を使うためには，[CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit)や[NVIDIA cuDNN](https://developer.nvidia.com/cudnn)をシステムに導入する必要があるという情報が多くあります．

実際にはCondaを使うことで，これらの手順をスキップできます．以下は，CUDA関連のライブラリをすべてシステムから削除した状態で実行しています．

[Miniconda](https://conda.io/miniconda.html)をインストールしている状態で，Anaconda Promptで以下を実行します．

```bash
(base) > conda create -y -n ml tensorflow-gpu keras
```

これだけです．

MNISTの手書き文字学習をおこなってみます．次のリンク先（[mnist_cnn.py](https://raw.githubusercontent.com/keras-team/keras/master/examples/mnist_cnn.py)）を好きな場所に保存します．（Chromeの場合，リンクにカーソルを置いて，右クリック⇒名前をつけてリンク先を保存）．Anaconda Promptで保存したディレクトリに移動し，実行してみます．

```bash
(base) > activate ml
(ml) > python mnist_cnn.py
～ 中略 ～
 GPU (device: 0, name: GeForce GTX 1050, pci bus id: 0000:01:00.0, compute capability: 6.1)
60000/60000 [==============================] - 13s 208us/step - loss: 0.2567 - acc: 0.9233 - val_loss: 0.0768 - val_acc: 0.9760
Epoch 2/12
60000/60000 [==============================] - 10s 159us/step - loss: 0.0875 - acc: 0.9740 - val_loss: 0.0398 - val_acc: 0.9873
Epoch 3/12
60000/60000 [==============================] - 10s 159us/step - loss: 0.0669 - acc: 0.9805 - val_loss: 0.0326 - val_acc: 0.9886
Epoch 4/12
60000/60000 [==============================] - 10s 159us/step - loss: 0.0536 - acc: 0.9842 - val_loss: 0.0311 - val_acc: 0.9894
Epoch 5/12
60000/60000 [==============================] - 10s 159us/step - loss: 0.0466 - acc: 0.9856 - val_loss: 0.0321 - val_acc: 0.9891
Epoch 6/12
33536/60000 [===============>..............] - ETA: 4s - loss: 0.0416 - acc: 0.9874
```

問題なく動作しています．

インストールされたパッケージを確認してみます（一部抜粋）．

```bash
(ml) > conda list
# packages in environment at C:\Users\daizu\Miniconda3\envs\ml:
#

# Name                    Version                   Build  Channel
_tflow_1100_select        0.0.1                       gpu
cudatoolkit               9.0                           1
cudnn                     7.1.4                 cuda9.0_0
keras                     2.2.2                         0
keras-applications        1.0.4                    py36_1
keras-base                2.2.2                    py36_0
keras-preprocessing       1.0.2                    py36_1
tensorboard               1.10.0           py36he025d50_0
tensorflow                1.10.0          gpu_py36h3514669_0
tensorflow-base           1.10.0          gpu_py36h6e53903_0
tensorflow-gpu            1.10.0               hf154084_0
```

`cudatoolkit`，`cudnn`が確認できます．

Jupyterが`ml`環境下のカーネルを認識できるようにするには，以下を実行します．

```bash
(ml) > conda install ipykernel
(ml) > python -m ipykernel install --user --name ml
```

（追記）CPU版も試してみました．

```bash
(base) > conda create -y -n ml_cpu tensorflow keras
```

1エポックの実行時間が，10s (GPU) から 約70s (CPU) まで増加しました．
Dockerで立ち上げたJenkinsの設定情報を別コンテナにマウントさせる

こんにちは

今回は、Dockerコンテナで立ち上げたJenkinsの/var/jenkins_home配下のデータを
データボリュームコンテナとして立ち上げた別コンテナにマウントさせる方法をまとめたいと思います。
すごく正攻法では無い気がしますが・・・ｗ

##データボリュームコンテナの生成

まず初めに、データボリュームコンテナを生成します。
今回選択したベースイメージはbusyboxです。

```ruby:dockerfile
# 1.Dockerイメージの取得
FROM busybox

# 2.データの設定
VOLUME /var/jenkins_home

```

上記のdokcerfileをもとに、データボリュームコンテナ用イメージを生成します。

```ruby:データボリュームコンテナ用イメージの生成
$ docker build -t jenkinsdata .
```

正しく生成されたか確認します。

```ruby:イメージファイル確認
$ docker images jenkinsdata
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jenkinsdata         latest              f6348620c17f        10 hours ago        1.16MB
```

確認できたらコンテナを立ち上げます。

```ruby:コンテナ起動
$ docker run -it --name jenkinsdata jenkinsdata
```

立ち上がったか確認します。

```ruby:コンテナ起動確認
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                                              NAMES
f5cc86a2c27e        jenkinsdata         "sh"                     10 hours ago        Exited (0) 12 minutes ago                                                      jenkinsdata
```

データボリュームコンテナ生成の作業は完了です。

## jenkins_homeディレクトリの取得

データボリュームコンテナの/var/jenkins_homeは空の状態であるため、
一度Jenkinsを構築して、Jenkinsコンテナ内の/var/jenkins_homeをコピー、
データボリュームコンテナのそれに配置します。

```ruby:Jenkinsの起動
$ docker run -p 8080:8080 -p 50000:50000 --name jenkins -d jenkins:latest                          
```

http://(IPアドレス):8080でJenkinsにつなぎ、
GUIベースで下記画面になるまで、設定作業をします。

![ここまでやる.png](https://qiita-image-store.s3.amazonaws.com/0/238412/1bf21d6c-3df4-0e80-c3f0-328f938a174f.png)

作業が完了したら、まずはJenkinsコンテナ内の/var/jenkinsディレクトリをホストにコピーします。

```ruby:Jenkinsコンテナ⇒ホストにコピー
$ docker cp jenkins:/var/jenkins_home .                         
```

次はホストからデータボリュームコンテナにコピーします。

```ruby:ホスト⇒データボリュームコンテナにコピー
$ docker cp /var/jenkins_home jenkinsdata:/var/                         
```

コピーが完了したら、データボリュームコンテナ内の/var/jenkins_homeの権限を変更します。

```ruby:権限の変更
$ docker start -ia jenkinsdata 
# chmod 1000:1000 /var/jenkins_home/
# ls -l /var/
drwxr-xr-x   17 1000     1000         4096 Sep  1 16:22 jenkins_home                      
```

今立ち上げているJenkinsコンテナは用済みなので削除します。

```ruby:Jenkinsコンテナの停止、削除
$ docker stop jenkins
$ docker rm jenkins               
```

## Jenkinsコンテナの起動

最後に、データボリュームコンテナをマウントさせてJenkinsコンテナを立ち上げます。

```ruby:Jenkinsコンテナの起動
$ docker run -p 8080:8080 -p 50000:50000 --name jenkins --volumes-from jenkinsdata -d jenkins:latest                
```

## マウントの確認

マウントできているか確認します。試しに、testというジョブを作成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238412/b3d0a2f5-f596-7f19-6633-76cf043c13d7.png)

データボリュームコンテナにマウントさせているか確認します。

```ruby:マウントの確認
$ docker start -ia jenkinsdata
# cd /var/jenkins_home/jobs/       
# ls -l
total 4
drwxr-xr-x    3 1000     staff         4096 Sep  1 16:23 test
```

作業は完了です。
svsフォーマットの画像をjpgに変換した話

## SVS is 何？
SVSとはScanScopeVirtuelSlide略称であり、[ScanScope](https://www.leicabiosystems.com/digital-pathology/manage/aperio-imagescope/)専用のフォーマット。
主に病理画像の撮影に使われており、その他利用方法が存在しない。

## どうして変換するの？
開けなくて困ってるから！！
誰ですかねこんなフォーマット作ったの。。。
色んな情報が詰め込まれていてサイズも大きいから大変。

ScanScopeインストールすればいい話だけどわざわざ開くのが面倒臭い。

## どうやら変換できるAPIが存在するらしい
[OpenSlide](https://openslide.org/)という専用ライブラリを使えば変換可能らしい
ドキュメントを見ながら手探りで使用してみる。

## 実際に変換してみた
### 導入環境
Ubuntu 16.04
### インストール
python-openslide(本体)のインストール

```
sudo apt-get update
sudo apt-get install python-openslide
```

openslide-python(ライブラリ)のインストール

```
pip install --no-deps openslide-python
```

インタプリタ起動してimportできればOK

```
$ python
Python 3.6.5 (default, May  4 2018, 23:20:02)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import openslide
>>>
```
OK

### APIの仕様
[OpenSlide Python API](https://openslide.org/api/python/)を読むとどうやら、

1. svs形式の画像を読み込んでOpenSlide objectsを作る
2. objectのread_region()メソッドを使用してjpg形式に変換
3. 保存する

で出来そう。

### いざやってみるも...

なんかエラー出た...

```
>>> osimg = OpenSlide("test.svs")
>>>
>>> osimg.dimensions
(27888, 21512)
>>> jpgimg = osimg.read_region((0,0), 0, osimg.dimensions)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/openslide/__init__.py", line 223, in read_region
    level, size[0], size[1])
  File "/openslide/lowlevel.py", line 260, in read_region
    return _load_image(buf, (w, h))
  File "/openslide/lowlevel.py", line 65, in _load_image
    return PIL.Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
  File "/PIL/Image.py", line 2398, in frombuffer
    core.map_buffer(data, size, decoder_name, None, 0, args)
MemoryError: Integer overflow in ysize
>>>
```

どうやらpillowの方でのエラーみたいだ。
pillowのfrombuffer()メソッドの仕様を探していると[github](https://github.com/openslide/openslide-python/issues/31#issuecomment-396149997)で解決策を見つけた。
ysizeが2^14、つまり16384を超えてしまっているが為にエラーが出ているらしい。

しょうがないから細かく変換してそれを結合する方針で行くことにした。
第一引数の(0,0)は切り取り開始位置を示しているので、例えば縦横5000pxで変換した後に次に変換する位置は
(0,5000)という具合になる。

結合は、以下のようにする。

```python:
def get_concat_h(im1, im2):
    dst = Image.new('RGB', (im1.width + im2.width, im1.height))
    dst.paste(im1, (0, 0))
    dst.paste(im2, (im1.width, 0))
    return dst

def get_concat_v(im1, im2):
    dst = Image.new('RGB', (im1.width, im1.height + im2.height))
    dst.paste(im1, (0, 0))
    dst.paste(im2, (0, im1.height))
    return dst

get_concat_h(im1, im1).save('dog_h_connect.jpg')
get_concat_v(im1, im1).save('dog_v_connect.jpg')
```
横に結合
![h_resize.jpg](https://qiita-image-store.s3.amazonaws.com/0/166345/020f52b7-bc82-cc73-ef53-1706dc0bdb11.jpeg)
縦に結合
![v_resize.jpg](https://qiita-image-store.s3.amazonaws.com/0/166345/01f829b9-219e-7a99-4e8c-803fe52874a8.jpeg)


### ついに
やっとこさ変換出来ました。それにしても気持ち悪い。
![qiita_resize.jpg](https://qiita-image-store.s3.amazonaws.com/0/166345/b568a381-f95c-a5a5-3ff8-3df97f4efa7c.jpeg)
もっとスマートな方法があるような気がしてならない。。。
どなたかいい方法が分かる方教えてくださると嬉しいです。


## 終わりに

今回使用したコードは一応[GitHub](https://github.com/yukitaka13-1110/convert-svs-into-jpg.git)にあげています。
Terraformに入門する

Terraformに入門する際に参考にした資料一覧です。

# Terraformとは
インフラ構築や設定をコード(テンプレートファイル)を使って自動化するためのツールです。
<img width="598" alt="Screen Shot 2018-09-02 at 15.06.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/84126/e0026f12-780b-8195-dfb4-65dc01417c15.png">

https://www.terraform.io/

# Getting Started
英語でよければ、以下の記事を進めていくと大体のTerraformの使い方について雰囲気を掴むことが出来ます。
https://www.terraform.io/intro/getting-started/install.html

日本語のほうがいいよということであれば下記の記事が参考になるかと思います。
https://dev.classmethod.jp/cloud/terraform-getting-started-with-aws/

# 複雑な構成を見たい場合
- 下記の記事が、ECS + Fargateの構成を、ネットワーク作成からCI/CDまで一貫してやっているので参考になりました。

https://thecode.pub/easy-deploy-your-docker-applications-to-aws-using-ecs-and-fargate-a988a1cc842f

# VCSでの扱い方
gitなどのVCSで扱う場合、gitのレポジトリ作成で作成できる、`.gitignore`ファイルのテンプレートに`Terraform`もあるのでそれを使うといいです

<img width="549" alt="Screen Shot 2018-09-02 at 14.57.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/84126/a20810f7-c0eb-3a43-eafb-5dd87b5ed3ad.png">

次のようなgitignoreファイルが作られます。

```plaintext:.gitignore
#  Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# .tfvars files
*.tfvars
```

# エディター環境
Terraformのスクリプトを書く場合は、各種IDEなどのプラグインを利用するといいです。

- Atom: language-terraform
    - https://atom.io/packages/language-terraform
- Visual Stduio Code: vscode-terraform 
    - https://marketplace.visualstudio.com/items?itemName=mauve.terraform
- JetBrains IDE（PHPStorm/GoLand/RubyMine...etc）: HashiCorp Terraform
    - https://plugins.jetbrains.com/plugin/7808-hashicorp-terraform--hcl-language-support


以上
ionic project directory structure

# 背景
* ionic frameworkを使う時に、root directoryに各フォルダが何か疑問がある
* ionicコードをgitでプッシュする時に何が必要であるか


# directory structor

```
platform/
plugins/
resources/
src/
www/
node_modules/
config.xml
ionic.config.json
ionic.starter.json
package-lock.json
package.json
tsconfig.json
tslint.json
```

# platform/
* AndroidやiOSなどplatformを作ろ時に、生成されるフォルダ
* その下にandroidやiosフォルダが作られて、ビルドに必要なファイルが保存される

# plugins/
* プラグインを追加する時に、このフォルダが生成される
* config.xmlに定義される内容より、プラグインを追加できる
* 注意：pluginsを追加する時に、関連するnative apiのパッケージも追加しないといけない

```xml:config.xml
<plugin name="cordova-plugin-splashscreen" spec="^4.1.0" />
```

# resources/
* iconやsplash用の画像の保存場所
* config.xmlに関連する画像のリンクを定義できる

```xml:config.xml
 <platform name="android">
        <allow-intent href="market:*" />
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
......

```

# src/

```
app/
assets/
index.html
manifest.json
pages/
service-worker.js
theme/
```
* app/
 * アプリを始める必要なファイルを揃える
* assets/
 * アプリに全てのページを表示して、html、css、jsを含む
* theme/
 * 簡単にカスタマイズし拡大するアプリの為のsassファイルを含む

# www/
* platformじゃなくてwebで表示する為に、生成されるファイルをここに保存する

# node_modules/
* nodejs用のパッケージの保存場所


# config.xml
* cordovaの全てアプリケーション動作をコントロールするためのグローバルコンフィグファイル

# package.json、package-lock.json
* nodejsのパッケージの定義ファイル


# .gitignore

```
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.vscode/
npm-debug.log*

.idea/
.sourcemaps/
.sass-cache/
.tmp/
.versions/
coverage/
dist/
node_modules/
tmp/
temp/
hooks/
platforms/
plugins/
plugins/android.json
plugins/ios.json
www/
```
指定した確率で配列要素を選択する

どのゲームでも毎回同じように重み付けの実装をしているのでメモ
ロジック自体はどの言語でも一緒だけど、今回はUE4C++でテストします

```c++
#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

USTRUCT()
struct SANDBOX_API FSomething
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	int32 Id;

	UPROPERTY()
	int32 Weight;

	FSomething( int32 id = 0, int32 weight = 0 ) : Id( id ), Weight( weight ) {}
};

UCLASS()
class SANDBOX_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
	template <class T>
	static int32 Choice( const TArray<T>& source,
		const std::function<uint32( const T* )> getWeightCallback )
	{
		check( source.Num() != 0 );

		uint64 sum = 0;

		TArray<uint32> weightArray;
		for ( const auto& row : source )
		{
			const auto weight = getWeightCallback( &row );

			sum += weight;
			weightArray.Emplace( weight );
		}

		if ( sum == 0 )
		{
			return -1;
		}

		const auto r = FMath::RandRange( 1, sum );

		uint64 tmp = 0;
		for ( int32 i = 0; i < weightArray.Num(); ++i )
		{
			tmp += weightArray[ i ];
			if ( r <= tmp )
			{
				return i;
			}
		}

		checkNoEntry();

		return -1;
	}
	
	UFUNCTION( BlueprintCallable )
	static int32 ChoiceTest()
	{
		TArray<FSomething> someArray =
		{
			FSomething( 1, 100 ),
			FSomething( 2, 200 ),
			FSomething( 3, 150 ),
		};

		return Choice<FSomething>( someArray, [ & ] ( const auto row )
		{
			return row->Weight;
		} );
	}
};

```
![321c72487627fa9a6d141fcff38db195.png](https://qiita-image-store.s3.amazonaws.com/0/41105/ba404068-871a-ff05-e3c4-2cd086b820f1.png)

実際にやってみると結構偏りがでます
>LogBlueprintUserMessages: [Untitled_C_10] 0: 2229
>LogBlueprintUserMessages: [Untitled_C_10] 1: 4460
>LogBlueprintUserMessages: [Untitled_C_10] 2: 3311

`const auto r = FMath::RandRange( 1, sum );`
これはUE4関数で乱数を生成しているためで、もっと精度を高めたいのであれば他の乱数生成アルゴリズムを用いる必要があります

[UE4の乱数生成BPの実装を見てみる(1)(Random integer in range)](http://ai-gaminglife.hatenablog.com/entry/2018/04/24/164213)
[C++11 の乱数ライブラリ <random>](http://siv3d.hateblo.jp/entry/2013/02/17/231829)
Rubyのインスタンス変数 僕の勘違い3

Rubyのインスタンス変数、学び始めたばかりの頃は全然わかっていなかった。
その勘違いをサンプルコードとともにまとめてみた。

#### 【勘違い】 インスタンス変数を参照、変更するメソッドは変数名と同じでなければならない。

以下の２つのコードは同じことである。

##### サンプル1

```ruby
class Engineer
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end
```

##### サンプル2

```ruby
class Engineer
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

  def name=(name)
    @name = name
  end
end
```

### 出力した例

```ruby
engineer = Engineer.new('aoki')
engineer.name
engineer.name = 'daisuke'
engineer.name
```

```
"aoki"
"daisuke"
```

今回の例で言えば、attr_accessorに`:name`と書くだけで`name`メソッドと`name=`メソッドを定義したことになると言うだけで、@nameを参照、変更するのに別のメソッドがあってもいい

```ruby
class Engineer
  def initialize(name)
    @name = name
  end

  def put_name
    @name
  end

  def change_name(new_name)
    @name = new_name
  end
end

engineer = Engineer.new('aoki')
p engineer.put_name
engineer.change_name('daisuke')
p engineer.put_name
```

#### 実行結果

```
"aoki"
"daisuke"
```

### 結論

今回の例で言えば、@nameと言うインスタンス変数に対して、@を取っ払った`name`で`engineer.name`とインスタンス変数の値を出力しているが、この`name`はあくまでもメソッド名なので、インスタンス変数と同じ名前でなくてもよい。
Cocoaの機能を使って3桁区切り文字列や価格文字列と数字を変換するAppleScriptハンドラ


* `numberFormat`は第1引数のクラスによって返り値が変わる
	* 文字列を引数にすると、数字を返す
	* 数字を引数にすると、文字列を返す
* `convertNumberStyle`の第2、第3引数はハンドラ名の文字列



```AppleScript:numberFormat.scpt
use scripting additions
use framework "Foundation"

log (my decimalNumberFormat:"1,234,567") as integer
--> 1234567

log (my japanesePriceFormat:1234567) as text
--> "1,234,567円"

log my convertNumberStyle("1,234,567円", "japanesePriceFormat:", "yenSignFormat:") as text
--> "¥1,234,567"

log my convertNumberStyle("¥1,234,567", "yenSignFormat:", "decimalNumberFormat:") as text
--> "1,234,567"

on decimalNumberFormat:num
	--require framework: Foundation
	set numberFormatter to current application's NSNumberFormatter's alloc()'s init()
	set numberFormatter's numberStyle to current application's NSNumberFormatterDecimalStyle as integer
	return my numberFormat(num, numberFormatter)
end decimalNumberFormat:

on japanesePriceFormat:num
	--require framework: Foundation
	set numberFormatter to current application's NSNumberFormatter's alloc()'s init()
	set numberFormatter's positiveFormat to "#,##0円"
	return my numberFormat(num, numberFormatter)
end japanesePriceFormat:

on yenSignFormat:num
	--require framework: Foundation
	set numberFormatter to current application's NSNumberFormatter's alloc()'s init()
	set numberFormatter's numberStyle to current application's NSNumberFormatterCurrencyStyle as integer
	set numberFormatter's currencyCode to "JPY"
	return my numberFormat(num, numberFormatter)
end yenSignFormat:

on numberFormat(num, numberFormatter)
	if class of (num as anything) is in {number, integer, real} then
		return numberFormatter's stringFromNumber:num
	else if class of (num as anything) is in {text, string} then
		return numberFormatter's numberFromString:num
	else
		error "Invalid argument"
	end if
end numberFormat

on convertNumberStyle(numberString, originalNumberFormatSelector, styleNumberFormatSelector)
	--require framework: Foundation
	if not (my respondsToSelector:originalNumberFormatSelector) then
		error "Invalid handler: " & originalNumberFormatSelector
	end if
	set num to my performSelector:originalNumberFormatSelector withObject:numberString
	if not (my respondsToSelector:styleNumberFormatSelector) then
		error "Invalid handler: " & styleNumberFormatSelector
	end if
	return my performSelector:styleNumberFormatSelector withObject:num
end convertNumberStyle
```

## 更新履歴

* 2018-08-19: NSNumberFormatterクラスを使って新規作成
* 2018-08-21: `japanesePriceFormat`と`yenSignFormat`を作成
* 2018-09-01: `numberFormat`と`convertNumberStyle`を作成
phpstormなどintellijのお勉強


この辺をひとまずメモ

## 機能・ショートカット

PhpStorm ツール - Google 検索
https://www.google.co.jp/search?q=PhpStorm+%E3%83%84%E3%83%BC%E3%83%AB&oq=PhpStorm+%E3%83%84%E3%83%BC%E3%83%AB&aqs=chrome..69i57.1770j0j7&sourceid=chrome&ie=UTF-8

PHP書いている人は、絶対にPHPStormを使うべき - koni blog
http://koni.hateblo.jp/entry/2016/01/12/090000#fn-17ab9071

PhpStormで他の言語を埋め込む - Qiita
http://qiita.com/crifff/items/94a2c2f269b005383ee8

ide - Phpstorm: add copyright information / licence header to files in project - Stack Overflow
http://stackoverflow.com/questions/28639538/phpstorm-add-copyright-information-licence-header-to-files-in-project

WebStorm（IntelliJ）で快適HTMLコーディング | webOpixel
http://www.webopixel.net/develop/694.html

PhpStormを使い始めた人は知っておきたい便利な使い方25選 その1 | karakaram-blog
http://www.karakaram.com/phpstorm-useful-tips1

PhpStormでまず覚えるべきショートカット - Qiita
http://qiita.com/crifff/items/bbdf850f0d90ad16415a

IntelliJ のショートカット一覧 - xykのブログ
http://xyk.hatenablog.com/entry/2013/12/18/093256

最強の開発環境を目指して 〜キーマップ編〜 - Qiita
http://qiita.com/Vexus2/items/fc328619deac316c3ff5

IntelliJ IDEAが便利になる40のショートカット - 壷ラボ
http://tubolabo.hatenablog.com/entry/20120225/1330185960

IntelliJIDEA_ReferenceCard_mac.pdf
https://resources.jetbrains.com/assets/products/intellij-idea/IntelliJIDEA_ReferenceCard_mac.pdf

WebStorm / PhpStorm Mac Cheat Sheet | ShortcutFoo
https://www.shortcutfoo.com/app/dojos/webstorm-phpstorm-mac/cheatsheet

ReSharper 2016.1 Help :: Quick-Fixes for Code Issues
https://www.jetbrains.com/help/resharper/2016.1/Code_Analysis__Quick-Fixes.html

忙しい人のためのIntelliJ IDEAショートカット集（´-`） - Qiita
http://qiita.com/yoppe/items/f7cbeb825c071691d3f2#-%E5%A4%89%E6%95%B0%E3%81%AE%E6%8A%BD%E5%87%BA

	暗黙の引数(implicit parameters)を表示
	変数の抽出

IntelliJでリファクタリング - Septeni Engineer's Blog
http://labs.septeni.co.jp/entry/2017/02/23/122428

	メソッドのインライン化（⌥⌘Nまたはメニューのrefactor - Inlineを選択します）
	メソッドの抽出

## 設定

### gitでsshがうまく繋がらない

![Kobito.96ESwX.png](https://qiita-image-store.s3.amazonaws.com/0/18421/d62f3bc1-fad0-6f18-7785-0bf355bfb215.png "Kobito.96ESwX.png")

Nativeに変更したらいけた。

### gitのアカウント切り替え

GUIではなく自分でコマンドでmasterを変更すれば接続できた

IntelliJ IDEAのプロジェクトをGitHubのリポジトリに連携する - ジムには乗りたい
http://su-kun1899.hatenablog.com/entry/2016/04/27/230000


```bash
git remote get-url origin
git@github.com:/user/repo.git
git remote set-url origin git@接続名:/user/repo.git
```
GPSの研究　その48

#概要
gpsを理解したかった。
アグリナビで、遊んでみた。
androidで、gpsシュミレータ作って、動かしてみた。
アグリナビからは、bluetooth　gpsに見える。
ヘッドアップしない。履歴消せない。

#写真

![CIMG2691.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/0571cd6b-c8cf-064b-74e2-5bf69bdf5057.jpeg)

#動画

https://www.youtube.com/watch?v=pAZ22qh9MrQ

以上。
ラズパイでラジオをタイマー録音〜Google ドライブ転送

2019/4/14追記:2019年4月より、RadikoによるNHKラジオ第二(JOAB)が終了しています。らじるらじるを録音する方法はこちらを参考にしてください。
- [NHKらじるらじるをタイマー録音〜Googleドライブ転送](https://qiita.com/yuppejp/items/d0a49bb03be02c303e4d)


# はじめに
ラズパイでラジオ録音に挑戦してみます。
これまでPCを使ってRadikoをタイマー録音していたのですが、スリープ復帰に失敗することがあったのですが、PCを起動しっぱなしにしておけば、するわけにもいかず・・・
それじゃラズパイでいいじゃんということで、やってみます。

### 使用機材
- Raspberry Pi Zero W (PI 3とかでもOKです）
- Micro SDカード 16GB

Google Driveの認証のためにラズパイ上でブラウザを使うので、ラズパイに物理的にアクセスする環境も必要です。

- mini-HDMI-HDMI変換ケーブル
- Micro USB-USB A変換ケーブル
- キーボード、マウス（USBハブがなかったので抜き差しで対応。ほんとは良くないかも）
- 液晶モニター

# パッケージを最新化
念のためラズパイのパッケージを最新化しておきます。

```
$ sudo apt-get update
$ sudo apt-get upgrade
```

# 必要なパッケージをインストール
ラジオ録音に必要なパッケージをインストールします。

```bash
$ sudo apt-get install rtmpdump
$ sudo apt-get install swftools
$ sudo apt-get install libxml2-utils
$ sudo apt-get install ffmpeg
$ sudo apt-get install libavcodec-extra
```

# Radiko録音スクリプトをダウンロード
gitでスクリプトをダウンロードします。

```
$ git clone https://gist.github.com/3956266.git
```

スクリプトに実行権を与えます。

```
$ chmod 755 rec_radiko.sh
```

お試しで、NHKラジオ第一を1分間録音してみます。

```
$ ./rec_radiko.sh JOAK 1
```

こんな感じで出力されます。
> RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
WARNING: No application or playpath in URL!
Connecting ...
WARNING: Trying different position for server digest!
INFO: Connected...
Starting Live Stream
For duration: 60.000 sec
INFO: Metadata:
365.842 kB / 60.03 sec
Download complete

「WARNING: No application or playpath in URL!」という警告が出ていますが、良しとします。

# 留守録設定（タイマー録音）
cronで留守録をしかけます。

```
$ crontab -e
```

編集例

```bash:crontab
0 23 * * 2 sleep 15; /home/pi/rec_radiko.sh JOAK-FM 50 radio NHKFM-MISIA
```

sleepを入れていますが、Radikoはストリーミングの時差があるので、開始時刻の補正用です。自分の環境では15秒遅らせると、ぴったり番組の開始時間と合いました。


# Googleドライブにアップロード
ブラウザを使ってGoogle Driveの認証が必要なためラズパイのGUIが必要です。ラズパイのGUI上のターミナルで作業をします。

```
$ cd ~
$ wget -O gdrive https://docs.google.com/uc?id=0B3X9GlR6EmbnVXNLanp4ZFRRbzg&export=download
```

gdriveに実行権を与えます。

```
$ chmod 755 gdrive
```

Google Driveを認証します。コマンドを実行すると、URLのリンクが表示されるので、ブラウザに開いて認証します。ブラウザに表示されたアクセスコードをコマンドに貼り付けるとgdriveコマンドが使えるようになります。

```
$ ./gdrive about
```

録音スクリプトを変更します。録音終了後にGoogle Driveにアップロードするように書き換えます。

```bash:rec_radio.sh（ファイルの末尾）
if [ $? = 0 ]; then
  rm -f "/tmp/${channel}_${date}"
  
  # この行を追加
  /home/pi/gdrive upload "${outdir}/${PREFIX}_${date}.mp3"
fi
```

# さいごに
ラズパイでしばらく運用していますが、非常に安定しています。録音に失敗したことはほぼゼロです（Raspberry PIゼロだけに:）。ただし、Radikoの仕様変更がたまにあるので、録音スクリプトが使えなくなる可能性がありますので、注意してください。

それでは、素敵なラジオライフを！

---
### 参考
- [ubuntuでradikoを予約録音する ～radikoを録音できるところまで～](http://nomusicnolife.hatenablog.com/entry/ubuntu-radiko-rec)
- [[RaspberryPi]google driveにファイルをアップロードする](https://qiita.com/jun1_0803/items/bd0ea883b9fe41bb1e69)
- [Radiko 放送局ID一覧](http://www.dcc-jpl.com/foltia/wiki/radikomemo)
- [Radiko 地域判定と修正依頼](https://radiko.jp/contact3)
Pythonでコマンドラインオプションの代わりにJSON形式の設定ファイルを読み込む

# はじめに
Pythonでコマンドライン引数を実行時に受け取りたい場合は[ArgumentParser](https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0)が有用ですが，オプションが増えてきて一々入力するのが面倒という人にはJSONを利用するのが便利かもしれません。

# 方法
オプションをプログラム実行時にコマンドに記述する代わりにJSON形式の設定ファイルに書いておき，読み込んで利用します。

## JSONとは？
Pythonの辞書型のような形でキーと値を記述するフォーマットのことです。
標準ライブラリがあるので簡単に読み込めます。

JSONの例：

```json:setting.json
{
    "learning_rate": 0.0001,
    "optimizer": "Adam",
    "batch-norm": true,
    "data": ["data1.zip", "data2.zip"],
    "network":{
        "layer": "linear",
        "activation": "relu"
    }
}
```

## 使い方
`json`モジュールをインポートすることで使用できます。
`json.load()`で読み込むと辞書型のオブジェクトが返されるのでキーから参照して使います。

例：

```python
import json

with open("setting.json","r") as f:
    json_dict = json.load(f)    # json.loadの引数はファイル名の文字列ではなくopenで得られるファイルオブジェクト

print(json_dict["learning_rate"])
print(json_dict["optimizer"])
print(json_dict["data"])    # リスト
print(json_dict["network"])    # 入れ子にもできる
```

## 小技
辞書形式で受け取れるので，プログラム内で利用する関数・メソッドの引数名とキーを合わせておけば，まとめてそのまま渡すこともできます。

例えば，以下のように定義された関数`func`に渡す引数をJSONから指定したいとします。

```python
def func(path, txt, x, y, z):
    print(path, txt, x, y, z)
```

設定ファイルは次のようにします。

```json:setting2.json
{
    "func": {
        "path": "/path/to/something",
        "txt": "abcdefg",
        "x": 1,
        "y": true,
        "z": ["あ", "い", "う"]
    }
}
```

こうしておけば，次のように`func`を呼び出すことができます。

```python
import json

with open("setting2.json", "r") as f:
    setting = json.load(f)

# キーワード引数を利用してまとめて渡す
func(**setting["func"])
```

# おわりに
JSON形式の設定ファイルを書いておくことで，

- 実行コマンドがシンプルになる（設定ファイルだけ受け取れば良い）
- 一度書けば別のプログラムからも使いまわせる

といった利点があります。
また，実行時に出力先に設定ファイルもコピーするようにしておけば，後でどのような条件で実行したのかも分かります。
きつねさんとLLVMで作った電卓を追証してみた

# msys2で更の状態からLLVMの環境を構築する。
1. msys2-x86_64-20180531.exe を使ってC:\msys64にインストールします。
2. pacman -S mingw-w64-x86_64-clang で、clangとついでにLLVMを入れます。
3. 環境変数のパスに、C:\msys64\usr\bin;C:\msys64\mingw\binを追加します。
4. flexは入っていたので、pacman -S bison でbisonを入れます。
5. makeが入ってないので、pacman -S make でmakeを入れます。
6. [きつねさんとLLVMで作った電卓](https://gist.github.com/ptr-yudai/a732c1218c9e8c551b62d63872fc8a9f)の、calc.lとcalc.yからコメントを消します。
7. bisonなので、y.tab.*でなくcalc.tab.*で書き換えます。
8. Makefileを書き換えます。
9. GOROOT=C:\msys64\mingw64\lib\goとGOPATH=C:\msys64\mingw64\lib\goを適切に設定しないと、エラーで動かない場合があります。


# calc.l


```C
%{
#include <stdio.h>              
#include "calc.tab.h"           /* "calc.tab.h"はbisonコマンド実行時に出力されます。 */
int yywrap(void) { return 1; }  
%}
		
%%

"+" return OPERATOR_ADD;
"-" return OPERATOR_SUB;
"*" return OPERATOR_MUL;
"/" return OPERATOR_DIV;
"\n" return EOL;

[1-9][0-9]* {
    double temp_box;
    sscanf(yytext, "%lf", &temp_box);
    yylval.double_value = temp_box;
    return DOUBLE_LITERAL;
}
"0" {
    yylval.double_value = 0.0;
    return DOUBLE_LITERAL;
}

[0-9]*\.[0-9]* {
    double temp_box;
    sscanf(yytext, "%lf", &temp_box);
    yylval.double_value = temp_box;
    return DOUBLE_LITERAL;
}

%%
```
# calc.y

```C
%{
#include <stdio.h>
#include <stdlib.h>
%}

%union {
    double double_value;
}

%token	<int_value>	INT_LITERAL   
%token	<double_value>	DOUBLE_LITERAL 
%token		OPERATOR_ADD 
			OPERATOR_SUB 
			OPERATOR_MUL 
			OPERATOR_DIV
			EOL          

%type	<double_value>	expression term primary_expression
			
%%

source_code
: line
| source_code line
;

line
: expression EOL
{
    printf(">> %lf\n", $1);
}
;

expression
: term
| expression OPERATOR_ADD term
{
    $$ = $1 + $3;
}
| expression OPERATOR_SUB term
{
    $$ = $1 - $3;
}
;

term
: primary_expression
| term OPERATOR_MUL primary_expression
{
    $$ = $1 * $3;
}
| term OPERATOR_DIV primary_expression
{
    $$ = $1 / $3;
}
;

primary_expression
: DOUBLE_LITERAL
;
%%

int yyerror(char const* str)
{
    extern char *yytext;
    fprintf(stderr, "Error near %s\n", yytext);
    return 0;
}

int main(void)
{
    extern int yyparse(void);  
    extern FILE *yyin;         

    yyin = stdin;              
        if (yyparse()) {
	    fprintf(stderr, "ERROR!\n");
	    exit(1);
    }
    return 0;
}
```
# Makefile

```makefile
CC		:= clang

all:	calc

calc:	calc.tab.c lex.yy.c	
	$(CC) -o calc.exe calc.tab.c lex.yy.c

calc.tab.c:	calc.y
	bison -d calc.y 

lex.yy.c:	calc.l 
	flex calc.l 

clean: 
	rm calc.tab.*
	rm lex.yy.c
	rm calc.exe 
```

# 参考
[言語を作る！bisonとflexを使ってみた](https://qiita.com/toru0408/items/483c77cb76198d4c6ceb)
ReactやVueのJSXについて曖昧に理解する

# JSXの事始め
Reactを勉強し始めに **「JSXとはなんぞや」** というのを理解するとき **「なんとなくHtml風に書けるJavaScriptの拡張構文」** と理解している人が多いと思う。

ただ **「JSXはJavaScriptに変換される」** というのをどこかで勉強しないと途中でつまづくので、JSXについての理解をもう少し深める必要がある。

# JSXはJavaScriptに変換される
babelの変換結果を見れば一発なのだけど、JSXを書いているとき、babelでは次のように変換しているのだということを理解しておく必要があるんだけど、これについて解説しているものがあまりない。

例えば次のコード

```jsx
import React from 'react';

function render() {
  return <div>Foo</div>;
}
```

これはbabelでは次のように変換される

```jsx
import React from 'react';

function render() {
  return React.createElement('div', null, 'Foo');
}
```

つまり **我々がJSXを書いているとき、それは実際にはReact.createElementを書いている** ということ。
もう少し複雑にしてみる

```jsx
import React from 'react';

function render() {
  return (
    <ul>
      <li>Foo</li>
      <li>Bar</li>
    </ul>
  );
}
```

これは次のように変換される

```jsx
import React from 'react';

function render() {
  return React.createElement( 
    'ul',
    null,
    React.createElement('li', null, 'Foo'),
    React.createElement('li', null, 'Bar')
  );
}
```

どう見てもReact.createElement書くより、JSXの構文で書いた方がスッキリする。
これを理解していると「JSXは存在するべくして存在するのだ」ということに納得できるんじゃないだろうか。
またJSXのとき `import React from 'react';` が一見不必要そうに見えて実は必要な理由は、変換後のコードを見れば分かってもらえるのではないかと思う。

初学者のうちは「HtmlをJSの中に書いている」という感覚でも構わないんだけど、ある程度理解が進んだらHtmlは書いてないんだなと理解しないと、文字列でHtmlを組み立てるコードを書きたくなり、でもJSXだと出来ないことにモヤモヤしたりする（経験者談）
Htmlは文字列で扱うのに長けているけども、そのHtmlの特性をJSXでは発揮できない、というのが結構大きな違いだと思う。

# JSXをReact以外で使う

ところでこのJSX、要するに

```
関数（決まった引数）
```

にという形に変換するだけなので `React.createElement` を別の関数にする、とすれば、他のライブラリでも使えそうである。
この「`React.createElement` を別の関数にする」を実現するのが `transform-react-jsx` というbabelプラグインである。

transform-react-jsxを入れて、babelの設定を次のようにする

```json
"plugins": [
  ["transform-react-jsx", {"pragma": "h"}]
]
```

ここの `{"pragma": "h"}` というのがミソで、普通だったら `React.createElement` と変換される部分を、任意の文字に置き換えてくれる。

例えばVueのコード

```jsx
new Vue({
  el: '#app',
  render: function(h) {
    return <div>Foo</div>;
  },
});
```

これは次のように変換される

```jsx
new Vue({
  el: '#app',
  render: function (h) {
    return h('div', null, 'Foo');
  }
});
```

Vueの場合は `React.createElement` に相当する役割の関数 `h` が引数で渡ってくるので、それを使ってJSXを利用している。
renderの引数を `h` にしているコードをよく見ると思うけど、要するにJSXを `h` 関数に変換するから引数も `h` にしているだけなので、babelの `pragma` 設定を変えれば `h` である必要はないんだけど、仮想DOM界隈ではよく `h` を使うことがお決まりになっている。
Rubyのインスタンス変数 僕の勘違い2

Rubyのインスタンス変数、学び始めたばかりの頃は全然わかっていなかった。
その勘違いをサンプルコードとともにまとめてみた。

## 【勘違い】 インスタンス変数を参照、変更するにはクラス内部からでもattr-accessorに書かないといけない

```ruby
class Engineer
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end
end

engineer = Engineer.new('aoki', 34)
p engineer.age
engineer.weight = 35
p engineer.age
```

#### 実行結果

```
34
35
```

ただし、同一クラスの(この場合はEngineerクラスの）インスタンスメソッド内でインスタンス変数の値を使うなら、attr_accessorに記述しなくていい

```ruby
class Engineer
  attr_accessor :name
  def initialize(name, age)
    @name = name
    @age = age
  end

  def instroduce_myself
    "私は#{@name}です。#{@age}歳です"
  end
end

engineer = Engineer.new('aoki', 34)
p engineer.instroduce_myself

```

#### 実行結果

```
"私はaokiです。34歳です"
```

そもそも、instroduce_myselfメソッドに限って言えば、attr_accessorに:nameも不要

```ruby
class Engineer
  def initialize(name, age)
    @name = name
    @age = age
  end

  def instroduce_myself
    "私は#{@name}です。#{@age}歳です"
  end
end

engineer = Engineer.new('aoki', 34)
p engineer.instroduce_myself

```

### 結論

クラスの外部から使うのでなければ、attr_accessorに定義しなくてもいい。
postfixで送信したメールにて、Receivedヘッダを隠す

tl;dr
-----

ここを読めば出来る

http://www.omakase.org/mail/mail_header_localip.html



なぜReceivedヘッダを隠すのか？
-------------

postfixはデフォルトでReceivedヘッダをそのまま送ります。

「送信元クライアント」とは自分が送信した時のマシンの事で、メーラーとしてOutlookを使った場合以下の情報をReceivedヘッダへ乗せます。

- コンピュータ名
- プライベートIP

なので、恥ずかしいコンピュータ名をつけていればその情報が受信者に渡ってしまうし、プライベートIPから内部ネットワークについてのヒントを与えてしまう事になります。

これをSMTPサーバに到達した時点で隠したい。


手順
-------------

postfixにはメールの内容をチェックして書き換えたり、行を削ったり、Rejectしたりできる機能があるので、これを使います。

- 参考
    - http://www.postfix-jp.info/trans-2.1/jhtml/postconf.5.html#header_checks
    - http://www.postfix-jp.info/trans-2.2/jhtml/header_checks.5.html

### `/etc/postfix/main.cf`を書き換え

header_checks の設定がコメントアウトされているので、以下の形にする

```
header_checks = pcre:/etc/postfix/header_checks
```


### `/etc/postfix/header_checks` を用意

デフォルトで空っぽ(コメントだけ)なので、以下を書き足す

```
/^Received:/ IGNORE
```

ただ、これだとリレー中に付与されたReceivedヘッダも削除されるので、プライベートIPっぽいものが含まれていたら削除するようしたいかもしれません。

以下は192.168もしくは10.で始まるIPが含まれた行を削除する例。172.16.はめんどいので。。。

```
/^Received:.*192\.168\.[0-9]+\.[0-9]+/ IGNORE
/^Received:.*10\.[0-9]+\.[0-9]+\.[0-9]+/ IGNORE
```

### 確認

Receivedヘッダが削られていることを確認しましょう。

GMailに送った場合は、メールを開き、「メッセージのソースを表示」から確認できます。
Outlookで受け取った場合、メールを開き、ファイル→情報→プロパティからインターネットヘッダーから確認できます。
DEV/OPS時の役割

* DEV/OPSを作る際の役割案

https://github.com/syunchanp/devopsdoc

いろいろな会社を巡るが、常に同じ資料を作っているので面倒になったのでとりあえず公開しておく

どこの会社に行っても話をするところとしては、特に以下が判りづらいらしい

・エスカレーションフローの役割分担の定義
・外部に移管する際の切り分けポイントの定義

なので、大事なところは絵にしていたので共有しておく
DynamoDBを使うサーバーレス設計で失敗した

DynamoDBを使うサーバーレス設計を使ったときに失敗したことがあったので書きます。
なお、この体験は**ハッカソン等での個人の体験であり、 実サービスとは関係ありません。**
また、関わったエンジニアの方々を馬鹿にしたいわけでなく、同じ失敗を繰り返さないために自分用のメモとしても載せております。

## わかること
- DynamoDBを使うサーバーレス設計を利用するときの失敗例から導入すべきかどうか
- 料金や工数は本当に下がるのか

## 要件
- 投稿があったらその投稿にメールを返信したい
- SNSログインもある
- 件数は無限に多いと予想
- Railsのomniauthとアクションメーラーでも良かったが、「サーバーサイドの負荷が楽になる＋かっこいい」という理由で選択
    - Lambdaに任せるとスケールを自動でやってくれる
    - フルマネージドなので、サーバー運用管理、保守や障害時の対応など、システム管理をしなくて良い
    - オートスケーリングの設定やサーバーの保守をやりたくなかった（工数削減）
    - 投稿がないときは料金がかからない(EC2インスタンスを構えて置く必要がないが、DynamoDBはかかる)
    - サーバーレス設計ってかっこいい

## 実装作戦
- APIGateway + Lambda + DynamoDB でフルマネージドなサービスとして実現、ServerlessFrameworkでコードで管理する (参考: [serverless frameworkを使って本格的なAPIサーバーを構築（魅力編）](https://qiita.com/okamu_/items/e246887cb6f2621ad40a))
- SNSログインは、DynamoDBにセッションを保存してCookieと組み合わせて、CallbackURLを用意しておくだけで実現できる
- DynamoDBストリームを使って、putされたらメール送信
- 管理画面がないので、今putされている件数を毎日10時にgoogleSheetに書き込む
- DynamoDBのバックアップを毎日5時に、DataPipelineを使ってS3に保存する **<- これがあかんかった**
- 気をつけるのはキャパシティユニットの計算のみ **<- これもあかんかった**
- あとは、フロントでAPIを叩いてもらうだけ

## 失敗したこと(1) 負荷試験編
~時系列で説明します~

- 1, 負荷試験を終え、DynamoDBに数万件のデータが溜まった状態で、キャパシティユニットを最小に下げる
- 2, `DynamoDBのバックアップを毎日5時に、DataPipelineを使ってS3に保存する` これが、キャパシティユニットを最小に下げたことにより、一瞬で終わらなくなった
    - t2.xlargeのEC2インスタンスが一瞬立ち上がって消えていたみたいだが、立ちっぱなしになってしまった
- 3, 気づかず放置していたためt2.xlargeのEC2インスタンスが大量発生！！！
- 4, 莫大な請求金額へと跳ね上がる

## 失敗したこと(2) キャパシティユニット編
~時系列で説明します~

- 1, 本番公開前の練習として、動作確認を担当者に依頼
- 2, 本番時のキャパシティユニットはこちら！！というコメントを担当者がみつけたので、そのとおり設定
  - ServerlessFrameworkを利用していたため、serverless.ymlに該当のコメントがあった
  - 実際には、投稿されるであろう文字の最大文字数（20項目最大500文字）をすべて入力された状態でも耐えられる数字だったので、当日の本番はもっと抑えた数字でローンチする想定だった
  - DynamoDBのキャパシティユニットは、上昇させてから減少させると、スペックが変わってしまうので、最初から上げるのは無能である
- 3, 無事、本番環境公開の練習が完了
- 4, 担当者がそれを下げ忘れる（オペミス + キャパシティユニットの料金の理解不足）
- 5, 数日放置
- 6, (1)よりも莫大な請求金額へと跳ね上がる

## まとめ
- DynamoDBを使うサーバーレス設計は、フルマネージドなサービスであるがゆえにとても便利ですが、予備知識がないと膨大な料金がかかってしまうことがある
- DynamoDBの知識はある程度持っておいたほうが良い、とくにキャパシティユニット
- フルマネージドであるがゆえに、それぞれの管理画面が別にありどういう経路でどのFunctionが使われているかなどを把握しておかないといけない
- CloudWatchLogでのログ反映が若干おそいので、少しやりにくい
- 実装工数は、Railsで実装したほうが削減できたと思う
- スケーリングもある程度は任せられるが、キャパシティユニットの調整はローンチしてからある程度見守りが必要だと思う

## 合わせて
- 「[Firebaseで失敗した](https://qiita.com/okamu_/items/4a616da7f7dc8aa011aa)」という記事も書きました
Rubyのインスタンス変数 僕の勘違い1

Rubyのインスタンス変数、学び始めたばかりの頃は全然わかっていなかった。
その勘違いをサンプルコードとともにまとめてみた。

## 【勘違い】インスタンス変数はinitializeメソッドでしか定義できない

実際は、以下の様なことが可能。

```ruby
class Engineer
  attr_accessor :name, :age

  def initialize(name)
    @name = name
  end

  def set_age(age)
    @age = age
  end
end

engineer = Engineer.new('aoki')
p engineer.name
engineer.set_age(35)
p engineer.age
```

#### 実行結果

```
"aoki"
35
```

initializeメソッド内では定義していない@ageという変数を
別のset_ageというメソッドを使って定義している。

### 結論

あくまで、新規インスタンス生成時にインスタンス変数を定義したい時にinitializeメソッド内に書く。新規インスタンス生成時でなくてもいいなら、別のインスタンスメソッドを使って定義してもいいい。
RLoginでログインしたまま一定時間経過すると切断される

# TL;DR

**オプション -> サーバー -> プロトコル -> KeepAliveパケットの送信間隔(sec)**
このオプションをチェックし、時間を`60` 秒などに設定しておけばOK。
![rlogin.png](https://qiita-image-store.s3.amazonaws.com/0/27443/12c06e8b-bce2-9c0b-ede0-b6465fcafe5a.png)

# この現象について
サーバー側の設定によりわざとTMOUTでログアウトさせている場合もありますが、たいていの場合は何も設定してません。

私がよくなるのは接続したまま放置してしまい、画面上は接続できているように見えても何かキーを押すと反応がなく、少し経過してから切断されているというエラーがでて終了してしまいます。

このケースに当てはまる人は、ルーターなどの中間機器によって切断されているケースがほとんどだと思います。
NAT(ネットワークアドレス変換)しているルーターが、一定期間パケットが流れていないコネクションを、切断済みと判定して、NATテーブルをクリアしていると思われます。

NATテーブルクリア時に、IN/OUT両方に通知でもしてくれれば良いですが、何もしてくれないルーターが多いようです。少なくともうちはこのタイプでした。

で、NATテーブルにない状態の後で、キー入力などによりパケットを送ろうとすると、既にないので、このときに初めてクライアントは切断されたと気づくわけです。
これを防ぐには定期的に無害なパケットを送り込めば良いのですが、その設定はRLoginで言うと、以下にあります。

**オプション -> サーバー -> プロトコル -> KeepAliveパケットの送信間隔(sec)**
このオプションをチェックし、時間を60 秒などに設定しておくと、ルーターからクリアされることはなくなりました。

RLogin以外のSSHクライアントでも、PuTTYなどにも同じ機能が入っています。

## その他の解決方法

クライアントが対応していなくても、Heartbeatパッチというものがあるようです。

**2020/01/22 追記**
~~http://www.sc.isc.tohoku.ac.jp/~hgot/sources/openssh-watchdog.html~~
リンク先がなくなっていましたので貼り換えます。
https://www.imglab.org/m/hgot/sources/openssh-watchdog.html
SVNに追加/削除をコマンドで一気に行う

## コマンド

カメなどのGUIのツールからなら楽ですが、コマンドでやる場合が面倒。
一度ステータスを取得し、?は追加、!は削除として処理することで可能。

* 追加

```bash
svn st | grep '^?' | sed -e 's/\?[ ]*//g' | xargs -i svn add {}
```

* 削除(コミット前のファイルも削除する場合--force)

```bash
svn st | grep '^!' | sed -e 's/\![ ]*//g' | xargs -i svn del --force {}
```
vimで貼りつけ時に自動インデントをしないようにする

ガチのVimmerではないので、よくはまる。
他の場所からコードをコピペでVimに張り付けると、元々ついているインデントに加えてさらにVim側で自動インデントが走ってひどいことに。

### 貼りつけモードにしてから、貼りつけを行う。

これを先にやっておくことで解決できます。
> :set paste
Tomcat 8でDB接続時に BasicDataSourceFactory が ClassNotFoundException

Tomcat 7 から Tomcat 8に移行したときのメモ

## DB接続時に BasicDataSourceFactory が ClassNotFoundException となった。

> 2015/01/16 10:30:01 ProxyManagerLogger
> 重大: java.lang.RuntimeException: javax.naming.NamingException: Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory]

## Tomcat8からパッケージが以下に変わっている。

> org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory.class

## 対応方法
context.xmlのfactoryを変更(`org.apache.tomcat.dbcp.dbcp` -> `org.apache.tomcat.dbcp.dbcp2`)

```xml:context.xml
factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"
```
Riot.jsで真偽値属性(disabledなど)が「__disabled」になる問題(v3.0.0)

**<font color="Red">この内容はv3.0.0の場合の話です。最新版では発生しません。</font>**

## Riot.jsについて

最近のフロントエンド開発ではReactを使うことが多いですが、私は少数派ですので、「<a href="http://riotjs.com/ja/" target="_blank" rel="noopener">Riot.js</a>」をよく使っています。
検索から来た人は、Riot.jsのことはよく知っているはずなので良いですが、そうでない人はぜひ使ってみてください。

## __disabled問題
Riot.jsでは、`disabled="{ !data.reference[0] }"`のように判定式でdisabledが出来る。と公式ガイドに書いてある。

> 真偽値属性 (checked, selected など) はテンプレート変数がfalse的であれば無視されます。
`<input checked={ null }>`は `<input>`になります。
http://riotjs.com/ja/guide/#真偽値属性

しかし、いざ使おうとすると、なぜか「`__disabled`」になってしまい、全然機能してくれなかった。
どこで「`__disabled`」になっているかというと、コンパイル時に変換されているのだが、それでも普通はDOM評価時には「`disabled`」になるはずが、DOM評価されても、「`__disabled`」となっていた。

## 解決策

仕方がないのでdomReady後に無理やり「__disabled」を自前で置き換えて回避してましたが、別件でnpmモジュールを更新していたら、この問題が解決。
**riotjs-loaderを3.0.0から4.0.0にしたら、ちゃんと「disabled」になりました。**
単純な解決方法だけど、調べた限り全然情報がなかったので、同じようにハマっている人の救いになればと思います。
(まだv3.0.0を使っている人がいればだけど…)

## 余談
これは私だけかもしれませんが、riotjs-loaderを4.0.0にしたら、webpack.config.jsの書き換えが必要でした。
`type: 'babel'` -> `type: 'none'` に変更。

```javascript:webpack.config.js
  {
    enforce: "pre",
    test: /\.tag$/,
    exclude: /node_modules/,
    use: [
      {
        loader: 'riotjs-loader',
        options: {
          type: 'none'
        }
      }
    ],
  }
```
【Access】起動している環境がRuntime版かを判別したいとき

VBAの処理内で、起動している環境がRuntime版のAccessかどうかを判別して処理を分岐する方法


- 対象
    - 通常版とRuntime版での起動時に内部の処理を分けたいとき
        - Runtime版だと動かない操作（リボンの表示制御など）などの処理

- 動作環境
    - Windows10
    - Access2016

- 方法
    - `SysCmd` の `acSysCmdRuntime` を利用して判定する。
        - Runtime版のAccessが実行されている場合は、 True (-1) を返します。

```
If SysCmd(acSysCmdRuntime) Then
    'Runtime版のAccessで実行された場合の処理
Else
    '通常のAccessで実行された場合の処理
End If
```