OmniAICreator/Qiita-1.07M huggingface dataset:
文系でもわかるElixirのEnum.sortの使い方


# はじめに

本稿は、文系出身の自分が関数型言語をやるにあたり、「この関数の使い方わかりにくいな！」と思った内容を文系にもなんとなくわかる（理論とか内部のアルゴリズムは気にしない）Tipsとして残すことを目的としています。

誤用、説明不備に関する指摘大歓迎です。
情報工学的にはこう説明すべき！みたいな高尚な話はスルーします。


今回はElixirでListのsortが必要になり[Enum.sort()の公式ドキュメント](https://hexdocs.pm/elixir/Enum.html#sort/2)を読んだがよくわからなかったので色々試してみました。

# 結論

結論としては
Enum.sort(list,　fn(x, y) -> 条件式 end)
と書いた場合、
「条件式の結果がfalseの場合に前後(xとyの要素)を入れ替える」
と理解すれば使い方としてはOKかと

# 色々やった結果

## サンプルmapリストの準備

```
iex(81)> map1 = %{name: "map1", key1: 100, key2: 200}
%{key1: 100, key2: 200, name: "map1"}
iex(82)> map2 = %{name: "map2", key1: 99, key2: 201}
%{key1: 99, key2: 201, name: "map2"}
iex(83)> map3 = %{name: "map3", key1: 101, key2: 199}
%{key1: 101, key2: 199, name: "map3"}
iex(87)> map4 = %{name: "map4", key1: 100, key2: 201}
%{key1: 100, key2: 201, name: "map4"}
iex(90)> list = [map1, map2, map3 ,map4]
[
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 101, key2: 199, name: "map3"},
  %{key1: 100, key2: 201, name: "map4"}
]
```

## ソートしてみる

fn(x,y) -> x.key1 < y.key1 key1で昇順（同じ値の場合は結果がfalseなので並べ替えが起こってしまう）
fn(x,y) -> x.key1 <= y.key1 key1で昇順（同じ値の場合に並べ替えが起こらない）

```
iex(100)> Enum.sort(list, fn(x,y) -> x.key1 < y.key1  end)
[
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 100, key2: 201, name: "map4"},
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 101, key2: 199, name: "map3"}
]
iex(101)> Enum.sort(list, fn(x,y) -> x.key1 <= y.key1  end)
[
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 100, key2: 201, name: "map4"},
  %{key1: 101, key2: 199, name: "map3"}
]
```

## 第２ソート条件を指定する

 第２ソート順としてnameの降順を指定する

fn(x,y) -> x.key1 < y.key1 or ( x.key1 == y.key1 and x.name >= y.name) end)

```
iex(111)> Enum.sort(list, fn(x,y) -> x.key1 < y.key1 or ( x.key1 == y.key1 and x.name >= y.name) end)
[
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 100, key2: 201, name: "map4"},
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 101, key2: 199, name: "map3"}
]
iex(114)> Enum.sort(list, fn(x,y) -> x.key1 <= y.key1 end)
[
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 100, key2: 201, name: "map4"},
  %{key1: 101, key2: 199, name: "map3"}
]
```

x.key1 <= y.key1 or ( x.key1 == y.key1 and x.name >= y.name)
としてしまうとx.key1 <= y.key1の時点で結果がtrueになるので第２条件でのソートが行われない

```
iex(117)> Enum.sort(list, fn(x, y) -> x.key1 <= y.key1 or ( x.key1 == y.key1 and x.name >= y.name) end)
[
  %{key1: 99, key2: 201, name: "map2"},
  %{key1: 100, key2: 200, name: "map1"},
  %{key1: 100, key2: 201, name: "map4"},
  %{key1: 101, key2: 199, name: "map3"}
]
```
Rパッケージshinydashboardを使ったアプリを作ってみた。

Rパッケージshinydashboardを使ったshinyアプリケーションを作って、その内容をpdfにまとめたので、ご紹介いたします。
このアプリケーションは、Chris Beeleyさんの著書[『Web Application Development with R Using Shiny - Second Edition』](https://www.amazon.com/Web-Application-Development-Using-Shiny-ebook/dp/B016QDX5D8)を参考に作成しました。英語に抵抗が無ければ、ぜひ読んでみることをお勧めします。今後は、AWSを利用してWeb上で運用できればと考えております。なお、ソースコードは[こちら](https://github.com/Ylab-Shiny/Web-Apps/tree/master/ch5/dashboard_v4)

[Shiny_dashboard_v4解説書.pdf](https://www.dropbox.com/s/k0wu1tsdn8ljo6k/Shiny_dashboard_v4%E8%A7%A3%E8%AA%AC%E6%9B%B8.pdf?dl=0)　← ~~googleドライブでの公開~~ Dropbox経由で公開（旧アカウント名：HRYY）

##出来上がるもの##
![fig2.PNG](https://qiita-image-store.s3.amazonaws.com/0/234290/f606b3f4-53d6-5fd1-8312-8cd67eb94f0b.png)
Juliaでforループをプロセス並列化してみる

Juliaでも並列計算ができる、と
https://docs.julialang.org/en/v0.6.4/manual/parallel-computing/#Parallel-Computing-1
とある。
スレッド並列については良記事
"Juliaのスレッド並列を使って簡単な並列計算を楽しむ"
https://qiita.com/goropikari/items/dc9ceddfb2d92a744e25
があったので、この記事ではプロセス並列（MPI並列のようなもの）を行う。



# 並列化経験について
私：　Fortran90でスパコンでMPI+openmpでブンブン回している。


# バージョン
Julia 0.6.4

# (08/03/18追記)
@goropikari さんにコメントをいただいた。その結果、もっとコンパクトに書ける事がわかった。最後に追記しておく。
最終結論だけここに先に書いておくと、forループで回すindexをxとして、1からnmaxまで回した結果を配列として持ちたいときは、

```julia:test2.jl
A = pmap(x -> func(x), 1:nmax ) 
```

とすれば、サイズnmaxの配列Aが得られる。

# (08/06/18追記)
バッチジョブなどでコントロールされたクラスターマシン上では、

```bash
julia --machinefile=$PBS_NODEFILE /path/to/your/home/dir/test_julia.jl
```

とすれば、割り当てられたCPUコアを使った並列計算が動く。実際にこのやり方でやると並列化が効き計算時間が減っていくことを確認した。ここで、-pオプションは使わないことに注意。
参考にしたURL：
https://discourse.julialang.org/t/help-setting-up-julia-on-a-cluster/5519/5

# (04/28/20追記)
上のmachinefileはJulia 1.0以降では変更されていて、

```bash
julia --machine-file=$PBS_NODEFILE /path/to/your/home/dir/test_julia.jl
```
となることに注意。

# コード
forループを分割して、分割したそれぞれを各CPUコアに割り当てて計算させるコードがあれば、かなり広範囲の種類の並列化ができる。
試行錯誤して得られたコードを先に載せておく。これが最適かどうかはわからない。

```julia:test.jl
@everywhere function test(nm,nmax)
    ssum = zeros(Float64,nm)
    v = procs()
    nv = length(v)-1
    if nv == 0
        nv = 1
    end
    a = Array{Any}(nv)
    if nmax % nv != 0
        println("Error nmax % nv should be 0. But, nmax= $(nmax) and nv = $(nv)")
    end
    for i in 1:nv
        starti = 1+(i-1)*nmax/nv
        endi = starti + nmax/nv -1
        a[i] = @spawn svdsum(nm, starti,endi)
    end
    
    println("After nv loop")
    for i in 1:nv
        ssum += fetch(a[i])
    end
    
    return ssum
end



println(nprocs())
@time test(400,4000)
```

実行したいときは、

```bash
julia -p 4 test.jl
```
とすれば、4並列で動く。

forループで毎回処理したい関数は、ここでは、svdsumというものにしている。
svdsumでは、startiからendiまで、forループを実行する。このstartiやendiがプロセスごとに異なることで、全体のループを分割して実行することが可能になる。


```julia:test.jl
@everywhere function svdsum(nm,starti,endi)
    ssum = zeros(Float64,nm)
    println("Start!")
    for i = starti:endi
        u,s,v = svd((3*i).*eye(nm)+cos(i)*ones(nm,nm))
        ssum += s
    end
    println("End!")
    
    return ssum
end
```

結局、@spawnを何回も繰り返して呼べば、次々と仕事を確保したプロセス分やってくれる。
そして、それを配列aに保存しておいて、forループを回りきった後に、改めてfetchでデータを回収する。
これによって、それぞれのプロセスが自分の仕事をこなし、データが最後に集まることになる。
この方法で、使うプロセスを倍に増やすと（物理CPUコアの数よりプロセス数を超えない場合に）、計算時間は半分になることを確かめた。
なお、@everywhereをつけないと1番以外のプロセスが関数を読み込んでくれないので、@everywhereは必要。


MPIと比べて超簡単。

# (08/03/18追記)
@goropikari さんにコメントをいただき、さらに簡単に書ける事がわかった。
functionのtest部分は

```julia:test2.jl
nm = 100
nmax = 1000
@time ssum = sum( pmap(x -> svdi(nm,x), 1:nmax ) )
println(sum(ssum))
```

だけで良いようだ。ここで、要素iを引数にするfunctionとして

```julia:test2.jl
@everywhere function svdi(nm,i)
    u,s,v = svd((3*i).*eye(nm)+cos(i)*ones(nm,nm))
    return s
end
```

を定義した。この書き方を使えば、forループで様々な処理をしたあとに、それぞれの結果を配列に格納することも可能で、その場合には、

```julia:test3.jl
nm = 100
nmax = 1000
@time smat =pmap(x -> svdi2(nm,x), 1:nmax ) 
println(smat)
```
とする。svdi2は

```julia:test3.jl
@everywhere function svdi2(nm,i)
    u,s,v = svd((3*i).*eye(nm)+cos(i)*ones(nm,nm))
    return sum(s)
end
```
としている。
FIrebaseとxcodeの合体！　忘備録

# 細かいところは公式ドキュメントか以下記事参照
SwiftアプリにFirebaseを入れてみた 
https://qiita.com/tochi/items/8828fe3de5408b0bcc0b

Firebase公式ドキュメント
https://firebase.google.com/docs/ios/setup

# 本当に色々わかりやすく書いてくれているが・・・。
なぜか上手くいかなーい！

他の記事を漁りまくるが、なぜか機能しない。

# 神記事を発見**「初めてのCocoaPodsでLinker command failed with exit code 1でハマる」**
以下URLから確認できます。
https://blugrit.com/2015/02/03/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEcocoapods%E3%81%A7linker-command-failed-with-exit-code-1%E3%81%A7%E3%83%8F%E3%83%9E%E3%82%8B/




神記事の神格言。
**「CocoaPodsを使うときは、projectname.xcodeprojではなくprojectname.xcworkspace」**

注) きちんとアプリケーションの再起動、キャッシュのクリア等をお忘れなく!!
CakePHP3からAmazonS3に画像のアップロード及び削除を行う

## 環境
CakePHP 3.5

## 流れ
### S3にバケットを作成し、IAMの設定を行う
### aws-sdk-phpをインストール
```
$ composer require aws/aws-sdk-php
```
### .envファイルにS3への接続情報を書く
#### 参考：[CakePHPで.envファイルを有効化する](https://qiita.com/k-ando/items/62253c5edfca2180027f)
```config/.env
export ITEM_IMAGE_PATH = 'upload/images/'
export S3_BUCKET_NAME = '*******'
export S3_ACCESS_KEY = '*******'
export S3_SECRET_KEY = '*******'
export S3_REGION = '*******'
export S3_VERSION = '*******'
```
### ファイルのアップロード及び削除を行うコードを書く
```Model/S3Manager.php
<?php
namespace App\Model\Utility;

use Cake\Log\Log;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;

class S3Manager
{

    private $_s3Client;

    /**
     * __construct method
     *
     * @return void
     */
    function __construct()
    {
        $this->_s3Client = new S3Client([
            'credentials' => [
                'key' => env('S3_ACCESS_KEY'),
                'secret' => env('S3_SECRET_KEY'),
            ],
            'region' => env('S3_REGION'),
            'version' => env('S3_VERSION'),
        ]);
    }

    /**
     * putObject method
     *
     * @param string $directory
     * @param string $baseFileName
     * @param string $newFileName
     * @return boolean
     */
    public function putObject($directory, $baseFileName, $newFileName)
    {
        $ret = false;
        try {
            $fullPath = $directory . $baseFileName;
            $result = $this->_s3Client->putObject([
                'Bucket' => env('S3_BUCKET_NAME'),
                'Key' => env('ITEM_IMAGE_PATH') . $newFileName,
                'SourceFile' => $fullPath,
                'ContentType' => mime_content_type($fullPath),
            ]);
            $ret = true;
        } catch (S3Exception $e) {
            Log::error($e->getMessage());
        }
        return $ret;
    }

    /**
     * deleteObject method
     *
     * @param string $deleteFileName
     * @return boolean
     */
    public function deleteObject($deleteFileName)
    {
        $ret = false;
        try {
            $result = $this->_s3Client->deleteObject([
                'Bucket' => env('S3_BUCKET_NAME'),
                'Key' => env('ITEM_IMAGE_PATH').$deleteFileName
            ]);
            $ret = true;
        } catch(S3Exception $e) {
            Log::error($e->getMessage());
        }
        return $ret;
    }
}
```

## 処理を呼び出す
```HogeController.php
<?php
namespace App\Controller;

use App\Model\Utility\S3Manager;

class HogeController extends AppController
{
    /**
     * upload method
     **/
    public function upload()
    {
        if ($this->request->is('post') {
            $s3 = new S3Manager();
            $s3->putObject($baseDir, 'hoge.jpg', 'hoge.jpg');
        }
    }

    /**
     * delete method
     **/
    public function delete()
    {
        if ($this->request->is('post') {
            $s3 = new S3Manager();
            $s3->deleteObject('hoge.jpg');
        }
    }
}
```
ECCube2系で管理画面にログインできなくなった場合の対応方法

危険なやり方なので、本番環境では絶対やらないこと！！！
~~絶対だぞ！絶対押すなよ！！！絶対だぞ！！！・・・押せよぉ〜〜！！~~


## 以下のソースコードを変更してログインするだけ。
webroot/data/class/util/SC_Utils.php
大体1730行目くらい。

```php
    /**
     * パスワード文字列のハッシュ一致判定
     *
     * @param  string  $pass     確認したいパスワード文字列
     * @param  string  $hashpass 確認したいパスワードハッシュ文字列
     * @param  string  $salt     salt
     * @return boolean 一致判定
     */
    public static function sfIsMatchHashPassword($pass, $hashpass, $salt)
    {
        $res = false;
        $res = true;  /////// 追加する！！！！

        if ($hashpass != '') {
            if (AUTH_TYPE == 'PLAIN') {
                if ($pass === $hashpass) {
                    $res = true;
                }
            } else {
                if (empty($salt)) {
                    // 旧バージョン(2.11未満)からの移行を考慮
                    $hash = sha1($pass . ':' . AUTH_MAGIC);
                } else {
                    $hash = SC_Utils_Ex::sfGetHashString($pass, $salt);
                }
                if ($hash === $hashpass) {
                    $res = true;
                }
            }
        }

        return $res;
    }
```
上記のfunction内2行目に
$res = true;
を追加して、ログインしてみましょう。

パスワードが何であってもログインできると思います。
ログインしたら、ソースを戻して
システム設定 ＞ メンバー管理
より、自分のパスワードを変更しておきましょう。
これで今度からそのパスワードでログインできるようになります。
fatal error: stdio.h: No such file or directory #include <stdio.h>が出た時の対処法

#はじめに
久しぶりにC言語でプログラミングをしてコンパイルをしようとした時にコンパイルできなかった．エラー内容を確認すると

```
fatal error: stdio.h: No such file or directory #include <stdio.h>
```

いや， C言語をプログラミングする土俵にすら立てさせてくれへんやん．．．と思い
色々調べた結果の解決策を残す．

#実行環境
Mac OS high Sierra(Macbook Air early2015)

#解決策
結論から言うと，

```
xcode-select --install
```

こいつをターミナルで実行するだけ笑
なんでそうなるのかというと
もともと，usrのディレクトリ内に入っているはずのstdio.hのヘッダファイルがなくなってしまったためこのようなエラーがでるらしい．
もともとのOSがEl CapitanでHigh Sierraにアップデートした際になくなってしまったらしい．
ただstdio.hのヘッダファイルをダウンロードしてそのまま直接usrのディレクトリに入れたらよくない？っておもったのでダウンロードしてusrのディレクトリに入れようとしたが権限上無理だった．
なので上記のコマンドをターミナルで実行したらC言語に必要なものをインストールしてくれるっぽいので解決するそうだ．
IDCFクラウドで仮想マシンをrebootしたときrootでsshログインできなくなったときの対応

# 環境
- [IDCF Cloud](https://www.idcf.jp/cloud/)
- CentOS Linux release 7.0.1406

# 事象
- rebootした後、rootでsshログインできなくなる（Permission Denied）

## 原因
- `/root/.ssh/authorized_keys`が空になる

- [2016/11/31以前のテンプレートから作成されたVMで起こるらしい](https://www.faq.idcf.jp/app/answers/detail/a_id/69/kw/authorized_keys)

## 対応
- 問題のスクリプトを停止する

```
# chkconfig cloud-set-guest-sshkey.in off

error reading information on service cloud-set-guest-sshkey.in: No such file or directory
```

- 無いと言われるので探す

```
# systemctl list-units --type=service

cloud-set-guest-sshkey.service    loaded active exited  SSH Public Keys Download Client for CloudStack

# systemctl disable cloud-set-guest-sshkey.service
# systemctl stop cloud-set-guest-sshkey.service
```

- 無事ログインできたし、rebootしても`authorized_keys`が消えなくなった
ハッカソンでモブプログラミングした話

## Azure Kubernetes Service(AKS)を利用した2日間ハッカソンに参加してモブプログラミングして気づいたこと
以下は、自分がハッカソンでモブプログラミングをして気づいたことをまとめたものです。

# モブプログラミングの背景
2018/07/07-08に「Azure Kubernetes Service(AKS)を利用した2日間ハッカソン」というイベントがあり、参加しました。
私のチームでは「コンテナのfluentd -> ELK」でのAzure + Kubernetes上のログ分析基盤を「 http://level69.net/archives/25391 」を参考に作成することに取り組みました。

# モブプログラミングの感想
・良かった点
-他の人がどの部分に注目して、エラー処理しようとするか見れる。
-全体として何をしようとしているか把握しやすい

・悪かった点
-自明なエラーや入力コマンドが明らかな時には手持ちぶさたになりやすい。
-上記の状態がちょくちょく発生するため、緊張感が切れ、グダることで生産性が落ちる。

# 今後に関して
スキルがかなり離れており、できる人のコード編集やエラー処理を見ることがためになる人が結構いる場合にはいいかもしれません。
ただ、モブプログラミングは個人個人が並列でタスクをやるよりもかなり時間がかかると感じ、時間制約があるハッカソンではあまり向いてないのではないかなと思います。
実際、モブプログラミングのルールに完全に沿っていては間に合わないので、後半は並列で作業をするケースがちょくちょくありました。
Thesis in Chandigarh

![Thesis Help in Chandigarh.png](https://qiita-image-store.s3.amazonaws.com/0/248282/535a7ae8-bfa3-58d5-89ba-8b2689adfd3c.png)



A proposal or thesis is a report submitted with the help of candidature for a scholastic degree or expert capability showing the creator's exploration and discoveries. [Thesis Nation](http://thesisnation.com/) is our website for more information you can visit.
qiime2に実装されているblastでコミュニティ解析

自前で持ってる16Sとか18SとかITSのデータベースとqiime2を使ってコミュニティ解析をしたい場合に、データベースからqiime2で使えるBlastのデータベースを作る方法をメモしたものです。

もうちょっと時間がある時に更新します。(2018/8/3)

とりあえずいつもの棒グラフを出したい人（自分）向け。

#### データベースをqiime2のフォーマットにする
配列データファイル（Database.fasta）と系統情報を記したタブ区切りテキストファイル（Taxonomy.txt）をqiime2フォーマットにします。

配列データファイルの変換

```
qiime tools import \
  --input-path Database.fasta \
  --output-path Database.qza \
  --type 'FeatureData[Sequence]'
```

系統情報を記したタブ区切りテキストファイルの変換

```
qiime tools import \
 --type FeatureData[Taxonomy] \
 --input-path Taxonomy.txt \
 --source-format HeaderlessTSVTaxonomyFormat \
 --output-path Taxonomy.qza
```


#### BLASTで配列の系統分類をする
他のオプションについてはここ↓
https://docs.qiime2.org/2018.6/plugins/available/feature-classifier/classify-consensus-blast/?highlight=blast

上で作ったqiime2ファイルを元にblastで代表配列（rep-seqs.qza）を分類

```
qiime feature-classifier classify-consensus-blast \
  --i-query rep-seqs.qza \
  --i-reference-reads Database.qza \
  --i-reference-taxonomy Taxonomy.qza \
  --o-classification blast_taxonomy_out.qza
```

#### 結果を可視化する

blast結果を可視化

```
qiime metadata tabulate \
  --m-input-file blast_taxonomy_out.qza \
  --o-visualization blast_taxonomy_out.qzv
```

いつもの棒グラフへ変換

```
qiime taxa barplot \
  --i-table feature-frequency-filtered-min10-table.qza \
  --i-taxonomy blast_taxonomy_out.qza \
  --m-metadata-file sample_metadata.tsv \
  --o-visualization blast_taxonomy_bar_plots.qzv
```

棒グラフを可視化

```
qiime tools view blast_taxonomy_bar_plots.qzv
```
react-components




## react-star-rating

[React Star Rating](http://cameronroe.github.io/react-star-rating/)

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/fbef31b2-0405-fa0e-7aca-0883381dce5f.png)


## Time Sheet

[yuanyan/react-timesheet: Time Sheet Component for React](https://github.com/yuanyan/react-timesheet)

demo - [yuanyan.github.io/react-timesheet/](http://yuanyan.github.io/react-timesheet/)

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/b6a160d9-2bc7-171a-ebff-a85f531666ee.png)



## REACT IMAGE GALLERY

[xiaolin/react-image-gallery: React carousel image gallery component with thumbnail and mobile support 🖼](https://github.com/xiaolin/react-image-gallery)

![image_gallery.gif](https://qiita-image-store.s3.amazonaws.com/0/49910/4d73e7d7-c191-8a32-42e1-9fded68f2412.gif)


demo - [React Image Gallery](http://linxtion.com/demo/react-image-gallery/)


## react-burger-menu

[react-burger-menu](http://negomi.github.io/react-burger-menu/)

いい感じのバーガーメニュー

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/1cea9aeb-a9c8-503d-e5c9-d95c2473c01c.png)
Lottie-Androidで素晴らしいアニメーション試す


## Lottie-Androidとは
Airbnbが開発したアニメーションを簡単に表示できるライブラリ

詳しくは公式ページを参照
https://airbnb.design/lottie/

AndroidのGithubはここ
https://github.com/airbnb/lottie-android


## 導入

app/gradleに以下を追加

```app/gradle
    implementation 'com.airbnb.android:lottie:2.5.5'
```

アニメーションファイルは以下サイトに山ほどあるんで、好きなアニメーションのjsonをダウンロードする
LottieFiles -  https://www.lottiefiles.com/

jsonをresに配置する

自分はrawディレクトリを作ってそこに置いた

![スクリーンショット 2018-08-03 13.16.34.png](https://qiita-image-store.s3.amazonaws.com/0/52227/d162b9bb-3fbc-d9ee-6c07-2503f6df59e1.png "スクリーンショット 2018-08-03 13.16.34.png")

## 実装

自動再生させたければレイアウトxmlに追加するだけで済む

```xml
    <com.airbnb.lottie.LottieAnimationView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:lottie_autoPlay="true"
        app:lottie_loop="true"
        app:lottie_rawRes="@raw/giftbox"
        />
```

たったこれだけ、素晴らしい

<img src="https://qiita-image-store.s3.amazonaws.com/0/52227/f18618dc-d10b-a785-529f-23d9f4301a06.gif" width=40%>

もちろんコードで実装することも可能（今回はやらないけど）

## 完成物

いろいろアニメーションを載っけてみた

<img src="https://qiita-image-store.s3.amazonaws.com/0/52227/3f2e3780-7cda-d5ab-475f-24d1a199cb87.gif" width=40%>

## 感想

LottieFilesのというサイトから好きなアニメーションを選んで、簡単にアプリに導入できるのは素晴らしい

そしてアニメーションのクオリティが高い！

作ろうと思えばアニメーションは自分で作れるらしい

### 気になった事

いくつかアニメーションjsonがAndroid Studioにコピーするとビルドが失敗した

Android Studioがjsonを読み込めなかったのか、jsonが正しく書かれてないのか不明...

また、Android Studioのレイアウトxmlを修正する際にエディタがすっごく重たくなる気がする。

これはAndroid Studio 3.2 Beta 5だからなんだろうか...

## 使用コード

ikemura23/Android-Kotlin-Lab at Lotties https://github.com/ikemura23/Android-Kotlin-Lab/tree/Lotties
Vapor 3 + Leaf 3でHTML表示


VaporでHTMLどうすればいいのかと思って一回やって見た結果はこちらです。

## Step 1 - パッケージのセットアップ

|  Package     |  Version   |
|:-------------|:-----------|
| Vapor        |  3.0.0-rc  |
| Leaf         |  3.0.0-rc  | 
| FluentSQLite |  3.0.0-rc  |
| Validation   |  2.0.0     |


```Swift
// swift-tools-version:4.0
import PackageDescription

let package = Package(
    name: "project_name",
    dependencies: [
        // 💧 A server-side Swift web framework.
        .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0-rc"),

        .package(url: "https://github.com/vapor/leaf.git", from: "3.0.0-rc"),

        // 🔵 Swift ORM (queries, models, relations, etc) built on SQLite 3.
        .package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0-rc")
    ],
    targets: [
        .target(name: "App", dependencies: ["FluentSQLite", "Vapor", "Leaf"]),
        .target(name: "Run", dependencies: ["App"]),
        .testTarget(name: "AppTests", dependencies: ["App"])
    ]
)
```


# Step 2 - LeafRender作成 

- configファイルにLeafProvider取得

```Swift
try services.register(LeafProvider())
```
- LeafRenderingルート作成

```Swift
public func routes(_ router: Router) throws {
    router.get { req -> Future<View> in
        let leaf = try req.make(LeafRenderer.self)
        let context = [String: String]()
        return leaf.render("home", context)
    }
}
```

いくつかの項目あるんですが説明しましょう。

contextの入れるべき物はLeafRendererに何の情報渡したい。
例えば：

```Swift
let context = ["name": "monolithic-adam"]
```
これをRendererに渡して

```Swift
return leaf.render("home", context)
```
この二行で`home.leaf`っていうファイルに`name`の値渡してレンダリングする

# Step 3 - .leafファイル作成
上の例homeに見ているから`home.leaf`作って見ましょう

`Resources > Views > _____.leaf`に入れましょう!
問題はXcode側で.leafファイルパースできないので外部エディター使った方が効率的にいいかも

```Leaf
Hi my name is #(name)
```
これで`home.leaf`作って上記の一行入れて見ましょう。
`Leaf`ファイルに`context`使いたい時`#()`で値名入れれば表示される。

コンパイルしてランしたら

`Hi my name is monolithic-adam`が出てくるはず

![Screen Shot 2018-08-03 at 15.46.12.png](https://qiita-image-store.s3.amazonaws.com/0/147278/6ca58e11-7926-fd57-173a-12436c39c240.png)

# 結果・まとめ
HTMLページ表示するのはVapor+Leafで簡単で楽しくServer Side Swiftで色々作れます。

続きで入力ページ次回やって見たいと思います。
next.js はバックエンドではなくミドルエンド

# next.js はバックエンドでもフロントエンドでもなくミドルエンドだった

この記事に書いてあり驚愕だった

https://medium.com/the-ideal-system/next-js-is-not-what-you-may-think-it-is-8423172e7401
rails-assetsのSSL証明書が期限切れでbundle installできない

また rails-assets.com　のSSL証明書が期限切れらしい。
そのせいで`bundle install`ができずにherokuへのデプロイが失敗していた。

```
       Fetching source index from https://rails-assets.org/
       
       Retrying fetcher due to error (2/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rails-assets.org/.
       There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
       Retrying fetcher due to error (3/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rails-assets.org/.
       There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
       Retrying fetcher due to error (4/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rails-assets.org/.
       There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
       Could not verify the SSL certificate for https://rails-assets.org/.
       There is a chance you are experiencing a man-in-the-middle attack, but most
       likely your system doesn't have the CA certificates needed for verification. For
       information about OpenSSL certificates, see http://bit.ly/ruby-ssl. To connect
       without using SSL, edit your Gemfile sources and change 'https' to 'http'.
```

ずっと昔から、rails-assetsに頼るのは良くないとか、2016年にいたってはSSL証明書の期限問題が話題になったこともあり、「えー、今更rails-assetsなんかに頼ってるのー？」って人が多いと思うけど、古いプロジェクトなんかでは使っている場合もあるんじゃないだろうか。

## 解決方法

環境変数`BUNDLE_SSL_VERIFY_MODE`に`0`を設定する。
herokuでも有効。

当然、脆弱なのでおすすめしない。
おすすめしないぞ！
本番環境でこの設定を使うんじゃないぞ！？

rails-assetsからは早く逃げよう。
SourceTreeでユーザーを変更する方法

#SourceTreeでユーザーを変更する方法

GitHubのユーザー名を変更したので、SourceTree上でもユーザー名を変更した。

#変更の手順
ツール→オプション→認証タブを開く。
↓
アカウントの追加・編集・削除の画面に移る。
↓
ユーザー名変更前のアカウント情報の「編集」を選択する。
↓
「Credentials」のユーザー名を新しいユーザー名に変更する。
↓
ダイアログが開き、パスワードを要求される。
↓
ログイン
↓
認証に成功すれば完了。
CakePHP3でキャッシュをクリアする方法

## 環境
CakePHP 3.5

## 個別にクリアする場合
### 1.キャッシュのリストを表示
```
$ cd [cakeアプリのカレントフォルダ]
$ sh bin/cake cache list_prefixes
default
_cake_core_
_cake_model_
```
### 2.リストからクリアするキャッシュを選択する
```
$ sh bin/cake cache clear default
```
## 有無も言わさず、すべてクリアする
```
$ cd [cakeアプリのカレントフォルダ]
$ sh bin/cake cache clear_all
```
簡単にイラストで、OAuth2フロータイプについて理解する！

##OAuth2認証フローを理解するのは難しいですが、イラストと３つのポイントに絞って４つのタイプを分かりやすく説明します。

* Implementation Difficulty = 実装の難しさ
* Security　= セキュリティーレベル
* Use Cases = 活用度

![facebook.png](https://qiita-image-store.s3.amazonaws.com/0/192668/29b481b9-50f8-37e0-c5bd-d202853c329b.png)

##OAuth2: 実装の難しさ

Authorization Code Grantタイプ（画像右上）は、４つのタイプの中で一番、実装するのが難しいです。他のタイプにはない、Guardが存在し実装が難しくなっています。

##OAuth2: セキュリティーレベル

Client CredentialとAuthorization Code grantタイプは、セキュリティーレベルの高いタイプになります。

Client Credential grantタイプ(画像左上)ユーザーとアプリケーションが同一になりますので、関連する要素やフロー（矢印の数）が最も少なく、データ流出を軽減します。

Authorization Code grantタイプ、ユーザーは認可キーをセキュリティーで守られたGuard(バックエンド)に渡します。より攻撃に晒されやすいアプリケーション(フロントエンド)はGuard(バックエンド)を通じてのみユーザーデータにアクセスできます。これによって直接的にシステムへの攻撃可能な部分を減らし、よりセキュリティーレベルが高くなっています。

Resource Owner Password Credential grant タイプ（画像左下）は、一番セキュリティーレベルの低いタイプになります。何故なら、ユーザーはユーザーのID、パスワードをアプリケーションへ教え、アプリケーションはそのキーを使用してユーザーの全情報にアクセス出来ます。これは不必要にアプリケーションにユーザーと同じ権限を付与しています。

##OAuth2: 活用度

Client Credential Grantタイプは、実装が簡単で、セキュリティーレベルの高い１番オススメのタイプに見えますが、活用度は１番低いです。このgrantタイプはユーザーとアプリケーションが同一である場合のみ利用可能であり、そのような場合、アプリケーションの利用方法は限定されます。つまり、アプリケーションはそのユーザー専用となります。

したがって、セキュリティが他のタイプでは重要とみなされるため、アプリケーションがバックエンドを持つ場合はAuthorization Code grantタイプを使用し、１ページアプリケーションまたはネイティブモバイルアプリケーションの場合はImplicit　grantタイプ（画像右下）を使用する事が出来ます。

アプリケーションとOAuthサーバーが同じ所有者の場合で、ユーザーID/パスワードをアプリケーションと共有することがセキュリティ上のリスクとならない場合は、Resource Owner Password Credential grantタイプを使用する事が出来ます。


OAuth2について、詳しい説明は、こちらの[ブログ](https://blog.oauth.io/choose-oauth2-flow-grant-types-for-app/)から確認できます。
Dartでの非同期処理（then vs async/await）

[docomo Developer support](https://dev.smt.docomo.ne.jp/)を運用している[@akatsukaha](https://qiita.com/akatsukaha)です．

Dartでは非同期処理を実施するのにFutureというものが準備されています．JavaScriptでいうところのPromiseだと理解してもらえれば大丈夫です．JavaScript同様に非同期処理を`then`より`async/await`を用いたほうが簡潔に記述出来ます．`then`を利用する場合，階層が深くなりソースコードの可読性が損なわれるため，個人的には`async/await`を利用するのが良いと思います．下記のコードでは，タイムスタンプをコンソールに表示し，10秒後の再度タイムスタンプをコンソールに表示するプログラムです．

[DartPad](https://dartpad.dartlang.org/)にコピペしてもらえばすぐ実行出来ます．

# **1. thenの例**

```dart
import 'dart:async';

void main() async {
  print(new DateTime.now());
  futureTest()
    .then((result) {
      print(result);
    });
}

Future <String> futureTest(){
  return new Future.delayed(new Duration(seconds: 10), (){
    return new DateTime.now().toString();
  });
}
```

```
2018-08-01 22:11:33.674
2018-08-01 22:11:43.678
```
約10秒後に処理が実行されている．

ここでネストの回数が1回なので見やすいですが，実際のプロジェクトでは複数回ネストされることもあり，それぞれの階層で複数の処理を記載されるので，かなり可読性が下がります．

# **2. async/awaitの例**

```dart
import 'dart:async';

void main() async {
  print(new DateTime.now());
  var result = await futureTest();
  print(result);
}

Future <String> futureTest(){
  return new Future.delayed(new Duration(seconds: 10), (){
    return new DateTime.now().toString();
  });
}
```

```
2018-08-01 22:03:11.706
2018-08-01 22:03:21.706
```
約10秒後に処理が実行されている．

こちらのほうでしっくりきます．

# **3．最後に**

公式のサイトだとthenの実行サンプルが多数ありますが，async/awaitを利用したほうが可読性があり良いと思います．
unset()の前にisset()する必要はない

未定義変数をいきなり使わないよう、`isset()`でチェックする心がけは良い習慣ですが
`unset()`する場合は`isset()`でチェックしなくてもUndefined VariableのNoticeにはなりません。

```php:unset.php
<?php
error_reporting(E_ALL);
echo $foo;   //未定義の $fooを参照
unset($foo); //未定義の $fooをいきなりunset
echo 'Done.';
```

実行結果

```shell-session
$ php unset.php
PHP Notice:  Undefined variable: foo in /path/to/test.php on line 3  # echo はNoticeがでる
Done.            # unset は Noticeでない
```

おまけ：`unset()`は複数引数とれるので、まとめて処理できます。

```php
<?php
unset($foo, $bar, $baz);
```
wpfのBindingでハマり

銀行コードをTextBoxに入力すると、銀行名が自動で別のTextBoxに入るようにしたい。
簡単やん？と思って始めたが、ぜんぜんできなかった。

Viewはこんな感じ。

```xml
<TextBox Text={Binding BankCode, Mode=TwoWay, UpdateSourceTrigger=LostFocus}/>
<TextBox Text={Binding BankName, Mode=TwoWay} IsReadOnly="true"/>
```
ViewModelはこんな感じ

```c#
public class BankViewModel
{
    public string BankCode { get { return bankCode; }
        set
        {
            bankCode = value;
            BankName = 銀行コードを渡して銀行名を取得する関数(bankCode);
        }
    }
    private string bankCode = string.Empty;

    public string BankName { get; set; } = string.Empty;
}
```

で、これで銀行コードのテキストボックスに0001と入力する。
銀行コードを渡して銀行名を取得する関数()が"みずほ"を返す。
BankNameに"みずほ"が入る。

ところまでは良かった。
でもViewに全然反映されない。

試しに、

```c#
public string BankName { get; set; } = "ほげ";
```
に変えたら、ちゃんとTextBoxには"ほげ"が初期表示されている。ということは、Bindingの設定は間違っていない。じゃあなんでなんだぜ？ってなって数時間。
ModeをOneWayに変えたり、UpdateSourceTriggerをPropertyChangedに変えても全然ダメ。


検索して、ここにたどり着いた。
https://qiita.com/soi/items/d0c83a0cc3a4b23237ef

以下写経

```c#
using System.ComponentModel;
using System.Runtime.CompilerServices;

public class BankViewModel : INotifyPropertyChanged
{

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged([CallerMemberName]string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    public string BankCode { get { return bankCode; }
        set
        {
            bankCode = value;
            BankName = 銀行コードを渡して銀行名を取得する関数(bankCode);

            RaisePropertyChanged();
            RaisePropertyChanged(nameof(BankName));
        }
    }
    private string bankCode = string.Empty;

    public string BankName { get; set; } = string.Empty;
}
```
こんな感じにしたらうまくいった。
思ったより面倒くさかった。なんでプロパティの値変えただけじゃダメなんだろ？
５分で完了! DjangoのMiddlewareをプロジェクトへ追加する方法

# Middlewareを追加
この記事では、単純にDjangoのmiddlewareをプロジェクトに追加する方法のみを記載する。Middlewareそのものの解説や、middlewareクラス内部の解説は記載しない。

Middleware追加は単純な２ステップで実現できる。

1. middlwareの書き方に準拠したクラスを作成
2. 上記へのパスをsettings.pyで設定

この実装で、全てのリクエス毎にmiddlewareのコードが実行される。


## Middleware class作成
今回はプロジェクトルートのmiddleware.pyファイル内に作成。

この場所はSettings.pyで設定するので後に必要。

```middleware.py
	class SimpleMiddleware:
	    def __init__(self, get_response):
	        self.get_response = get_response
	
	    def __call__(self, request):
	        response = self.get_response(request)
	        
	        ## 動作テスト用のログ
	        print('---- middleware called ----')

	        return response
```

	   
## Settings.pyで設定
先に作成したMiddlewareクラスへのパスをSettings.py内のMIDDLEWAREへ追加する。

```settings.py
	MIDDLEWARE = [
		 # Djagnoがデフォルトで設定するmiddleware等 ... #
	    'middleware.SimpleMiddleware', # <= 追加
	]
```
ちなみに、ここでパスの設定を間違えるとサーバー起動時に以下のようなエラーになる。

	...ImproperlyConfigured: WSGI application '<your_prj_name>.wsgi.application' could not be loaded; Error importing module.
	


## 動作確認
サーバーを起動してdjangoで作成したページへアクセス。

先ほど作成したSimpleMiddleware内のprintの内容が表示されていたら、Middlewareの設定成功。


#### 参考文献
[django documentation Middleware](https://docs.djangoproject.com/ja/2.1/topics/http/middleware/)
アスペクト比の計算方法

ディスプレイ幅：1024
ディスプレイ高：720
画像幅：960
画像高：540

幅比率＝ディスプレイ幅 / 画像幅
高比率＝ディスプレイ高 / 画像高
比率＝min(幅比率,高比率)

比率適用後の画像幅 = 画像幅 * 比率
比率適用後の画像高さ = 画像高 * 比率

1024 x 720
960x 540

x = 1024 / 960 = 1.066666666666667
y = 720 / 540 = 1.333333333333333

min(x, y) = 1.066666666666667

960 * 1.066666666666667
540 + 1.066666666666667
既存のCognosレポートをActive Reportに移行する際の考慮点


**既存のCognosレポートをActive Reportに移行してオフラインでも活用したい！**

と言った要件は少なからずあると思います。
レポート編集画面に「アクティブ・レポートに変換」なんてメニューがあるから簡単にアクティブレポート化できるのではと思ったりもするかも知れません。
![001.jpg](https://qiita-image-store.s3.amazonaws.com/0/146283/a9fdfa4f-8283-5eec-7452-d48015efe934.jpeg)


そんな時、これから記載するアクティブレポートに移行する際の考慮点をしっかりとおさえておかないと、想像以上に大変な思いをするハメになるかもしれないので要注意です！！



※この記事は自身の経験を基に出くわした事象と解決方法を記載しています。
認識が間違っている！や、こんな手法で移行するとそれって実現できるよ！と言った情報があればぜひご教授ください。こんな考慮点も必要だよ！も、受け付けております。


##プロンプト

- レポートページでプロンプトオブジェクトを使用できない


アクティブレポートでは、レポートページにCognosのプロンプトオブジェクトを追加することができません。
レポートページ選択中はツールにも表示されません。
![002.jpg](https://qiita-image-store.s3.amazonaws.com/0/146283/c076cab7-204a-982f-1bd6-49922f98733a.jpeg)

移行元のレポートページに配置されていたプロンプトもアクティブレポートに変換したタイミングで問答無用で削除されます。

アクティブレポートでの表示データの絞込みは、アクティブレポート用ツールのドロップダウンリストやリストボックスを追加してリストやグラフと双方向の動作を新たに定義する必要があります。
プロンプトで選択された値をもとに条件ブロックの表示を切り替えている際も要注意です。

各オブジェクト間で連携が必要な箇所すべてに双方向の動作を設定していく必要があります。
レポート定義が繁雑になる原因ですね。。設定の漏れには気をつけましょう。


- プロンプトページに配置したプロンプトはアクティブレポートダウンロード時しか機能しない


プロンプトページを使用すればプロンプトオブジェクトを利用することもできます。
ただ、条件を選択してクエリーに対して取得データの絞込みができるのはアクティブレポートダウンロード時のみです。
ダウンロードしたアクティブレポートをオフラインで動かしている時はプロンプトページをまったく機能しないので使い勝手が変わってくること認識しておく必要があります。

##複数ページ
- ページの切替ができず、最初のページしかダウンロードできない

自分がアクティブレポートを使用した限り、「次のページ」に表示を切り替える操作を見つけることができませんでした。。
アクティブレポートは1ページで作成する必要がある？？
ただ、複数ページを作成できるのでここは検証の余地ありだと思っておりますが、有益な情報をお持ちの方がいれば教えてください！

##ドリルスルー

- Cognosが提供するドリルスルーが使用できない

アクティブレポートをCognos Mobileで使用する時は、アプリケーションドリルスルーの設定によって他のアクティブレポートへドリルスルーすることができるようです。
ただ、mht形式で配布してWebブラウザ上で汎用的に使用するときにはドリススルーを設定することができません。実質、ドリルスルーはないものとして設計したほうがよいかと思います。

ドリルスルーが定義された複数のレポートをアクティブレポートに移行したい場合は、1つのアクティブレポート内に集約します。
先にも記述しましたが複数ページのアクティブレポートを作成できないので、デッキなどを使用して1ページにまとめる必要あります。

	
※注意点
1つのアクティブレポートに複数のレポートを集約するとレポート定義やダウンロードするデータ量が増え、mhtファイルのサイズが大きくなります。配布時の仕方を考慮したり、アクティブレポート実行時のパフォーマンスにも影響をしてくるということを忘れないでください。
※これはmhtファイルがデータも含めて保持しているためです

- 既存のドリルスルーが残っているとサーバーに対してリクエストを投げにいく

オフラインで使用しているにも関わらずサーバーに投げられたリクエストはエラーとなって終了します。
元レポートで定義されたドリルスルーは定義をきちんと削除しておきましょう。
	
##ブラウザ設定
- ダウンロードしたmhtファイルをFireFoxで利用する場合は追加のアドオンが必要

この件はこちらの記事にまとめてありますので参照ください。
[mht形式で保存されたCognosのActive ReportをFireFoxで実行するにはUnMHTアドオンが必要](https://qiita.com/hayatoshi/items/2f85177c0a25245a140c)
	
	


#さいごに

最終的に言いたいこととしては、
**アクティブレポートは既存のレポートとはまったくの別物だ！** と言うことです。
アクティブレポートを使用したい場合は要件定義からしっかりし、アクティブレポート用のツールや実装方法をイメージしながらレポート設計をして開発・テスト、使用していくことをオススメします。
Raspberry PiにAndroid Thingsを導入する

# Raspberry PiにAndroid Thingsを導入する


1. Android Thingsってなに？
2. 使うもの
3. Android Thingsを導入してみよう
4. まとめ


## 1. Android Thingsってなに？
Android Thingsとは、Raspberry Piなどのシングルボードコンピュータ上で動かすことのできるAndroidOSです。
2015年にリリースされ、今年2018年5月7日に公式版が発表されました。
今まではRaspberry PiでIoTなどをするにはPythonやRaspbianなどの知識が必要でした。
しかし、このAndroid Thingsでは、Androidアプリと同じように開発ができるようになり、アプリエンジニアなどでも手を出しやすいようになりました。

## 2. 使うもの
- Raspberry Pi Model B
- SDカード
- Android Thingsのイメージを書き込むためのPC

## 3. Android Things を導入してみよう

[Android Thingsのコンソール](https://partner.android.com/things/console/u/0/#/signup)を使えるように登録しましょう。

<img width="757" alt="android-things-console.png" src="https://qiita-image-store.s3.amazonaws.com/0/143395/4b880492-d81a-c0ab-1697-7b5a4a9a7ea7.png">


このような画面が出てくるのでボックスにチェックを入れてcontinueを押します。

次に[Android Thingsのイメージ](https://partner.android.com/things/console/#/tools)をダウンロードしましょう。
ダウンロードが完了したら、
`sudo ~/イメージまでのパス/android-things-setup-utility/android-things-setup-utility-linux ←ここは自分のPCのOS`
このコマンドを実行しましょう。

```
What do you want to do?
1 - Install Android Things and optionally set up Wi-Fi
2 - Set up Wi-Fi on an existing Android Things device
```
このような表示になったら1を選択します。

```
What hardware are you using?
1 - Raspberry Pi 3
2 - NXP Pico i.MX7D
```
次にどのハードウェアを使うか聞かれるので、1のRaspberry Pi 3を選択します。
この選択をすることにより、Raspberry Pi 3用のイメージがダウンロードされます。
それが完了すると以下のような文言が出てきます。

```
Do you want to use the default image or a custom image?
1 - Default image: Used for development purposes. No access to the Android
Things Console features such as metrics, crash reports, and OTA updates.
2 - Custom image: Upload your custom image for full device development and
management with all Android Things Console features.
```
ここは、1のDefault imageを選択します。

`Plug the SD card into your computer. Press [Enter] when ready`
書き込みたいSDカードをセットしたらEnterを押します。
最後に、
`Would you like to set up Wi-Fi on this device? (y/n)`
と聞かれるので __n__ を選択しEnterで終了します。

これが終わったらインストール導入は完了です。

イメージを書き込んだSDカードをRaspberry Piにセットし、画面、キーボード等を繋げたら電源を入れます。

![395.jpg](https://qiita-image-store.s3.amazonaws.com/0/143395/0e39028d-e0ac-42e9-6b54-c79ca170350c.jpeg)

このような画面が出るのでしばらく待ちます。

![396.jpg](https://qiita-image-store.s3.amazonaws.com/0/143395/915b2fa5-4696-b8f0-9dcb-78551586a00f.jpeg)

この画面が出たら、CONTINUEをクリックし、setup画面でwifiの設定をしたら導入完了です。


## 4. まとめ
今回、Raspberry PiにAndroid Thingsを導入することができたのでこれから、Android Thingsの記事を書いていきたいです。
システム日付を変更したコンテナ環境でテストしたい

# 概要

日時の概念が重要となる機能をテストする際、システム日付を変更してテストを行うことがあると思います。Dockerコンテナを使用して自動テストを行う場合もテストコード内でシステム日付を変更し、テストが終わったらコンテナを破棄すれば実現できると思っていました。しかし、実際に試してみたところホスト側の日付も変更されてしまい想定する挙動とは違っていました。

ここではDockerコンテナ内のシステム日付だけを変更してテスト環境を用意する方法についてご紹介したいと思います。

# 結論

Dockerコンテナで [libfaketime](https://github.com/wolfcw/libfaketime) を使えばできます。
コンテナ内の特定のプロセスだけシステム日付を変更したり、システム全体の日付の変更もできるため、デーモンプロセスにも対応できます。

# Dockerfile

```Dockerfile
FROM centos:6

# タイムゾーン設定
ENV TZ Asia/Tokyo

# 依存パッケージのインストール
RUN yum install -y gcc git

# libfaketimeのインストール
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install \
 && echo -e '/usr/local/lib/faketime/libfaketime.so.1' > /etc/ld.so.preload

# 環境変数の設定
# Java プログラムを実行する場合は DONT_FAKE_MONOTONIC が必要です。
# システム日付の変更は1秒間隔でチェックします。
ENV DONT_FAKE_MONOTONIC=1
ENV FAKETIME_CACHE_DURATION=1

# 作業ディレクトリの変更
WORKDIR /

# システム日付の変更
# /etc/faketimerc または環境変数 FAKETIME にフォーマットを指定します。
# フォーマットは「相対日時」や「指定日時」などが指定できます。
# 詳しくは以下のURLを参照してください。
# https://github.com/wolfcw/libfaketime

# テストコマンド実行
CMD date \
 && echo -e '@2000-01-01 09:00:00' > /etc/faketimerc \
 && date \
 && echo -e '+3d' > /etc/faketimerc \
 && date \
 && echo -e '-10y' > /etc/faketimerc \
 && date \
 && rm -f /etc/faketimerc \
 && date
```

# Dockerコンテナの実行方法

**(1) イメージをビルドします。**

```
docker build -t faketime .
```
    
初回のみ CentOS のイメージのビルドに少し時間がかかります。

**(2) ビルドしたイメージ一覧を確認します。**

```
docker images
```
    
以下のようなイメージ一覧が表示されます。
    
```
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
faketime            latest              64794ea54ab0        8 seconds ago       489MB
centos              6                   70b5d81549ec        3 months ago        195MB
```

**(3) コンテナをビルドして検証用コマンドを実行します。**

```
docker run --rm <faketimeイメージのIMAGE ID>
```

検証用のコマンドが実行され、コンテナ内のシステム日付が変更されていることが確認できます。

```
Thu Aug  2 17:21:29 JST 2018　<現在日時>
Sat Jan  1 08:59:59 JST 2000　<2000-01-01 09:00:00を起点にした日時>
Sun Aug  5 17:21:29 JST 2018　<3日後>
Mon Aug  4 17:21:29 JST 2008　<10年前>
Thu Aug  2 17:21:29 JST 2018　<現在日時>
```
    
システム日付の変更にはそれぞれ以下のフォーマットを指定しています。
    
|フォーマット|説明|
|:---|:---|
|<span>@</span>2000-01-01 09:00:00|2000-01-01 09:00:00を起点にした日時|
|+3d|3日後|
|-10y|10年前|

現在日時を基準とした相対日時、ある時点からの日時などが指定できます。

フォーマットの詳しい説明は [libfaketime](https://github.com/wolfcw/libfaketime) をご参照ください。

ホスト側のシステム日付に影響を与えることなくDockerコンテナ内のシステム日付を変更しながらテストが実施できます。ぜひ自動テストに組み込んで試してみてください。

# 注意点

[libfaketime](https://github.com/wolfcw/libfaketime) の説明書にも記載されていますが、Javaプロセスに対してシステム日付の変更を反映させるためには環境変数に `DONT_FAKE_MONOTONIC=1` を設定する必要があります。設定されていない場合はプロセスがハングするようです。

説明書からの引用

> * Java-/JVM-based applications work but you need to pass in an extra argument
>   (DONT_FAKE_MONOTONIC).  See usage basics below for details.  Without this
>   argument the java command usually hangs.
多国籍チームのコラボレーションとベロシティとコーディングする喜びと

# 一人でやる時、チームでやる時
SRE, DevOps, マイクロサービス
技術選定
どのやり方を選んでも究極的には人の問題になる。
自分より力量の高い先輩とやることになってもコード品質に対する考えが違えばどちらかが必ずストレスを抱えることになりうる。
多国籍なチームの場合やはり専門用語の使い方や理解度に大きな差がありコミュニケーションが円滑に進まないことが多々ある。
背景、各技術への習熟度、好みが全く違うメンバーが一人以上集まった際に、ビジネスを前に進めるためのコラボレーションを円滑にするにはどうするか。コーディングする喜びをどうしたら殺さないことが出来るか。
ベロシティが異なる人がコラボレーション(例えばコードレビューが導入される)する場合ベロシティの低い方にあってしまう。

どれくらいYAGNIでどれくらいYAGNIじゃないべきか。
ボトルネック、単一障害点
トラフィックがさばききれないほどになるサービスは実際には非常に少なく多くのソフトウェアは品質を保ち継続的デリバリーが実現出来ればモノリスでも問題ない可能性がある。
トラフィックがさばききれないと感じた際に、現実に最もボトルネックとなるのは、技術選定ではなく、コードやデータベースの品質が低い可能性がある。
境界づけられたコンテキストを見つけられていれば、モノリスだろうとマイクロサービスだろうと品質を高められる可能性が高い。
問題が発生するのは新人エンジニアを採用した時やそのフレームワークに関する習熟が低い人が参加した時である可能性が高い。
モノリスが密結合なわけでは無い。マイクロサービスにすれば疎結合になりやすいわけでは無い。むしろエンジニアのレベルが高くない場合、マイクロサービスの密結合は文字通りカオスになる可能性が高い。
どこまで品質を落とせるか。納品があるなら落とせるか。納品がない場合落とせないのか。
品質が低くベロシティの遅いエンジニアが生きることは出来ないのか、境界を作りうまく仕事をふれないのか。

## 一人で
## 自分と同じか自分よりも力量の高いメンバーと
## 自分と採用した初心者メンバーと
## 自分と誰かとその部下と

# DHH
モノリス <-> マイクロサービス (接続部分、密結合<->疎結合)
MVC <-> MVC + アルファ (抽象化の階層・段階の必要性)
REST <-> RPC (ステートレス <-> ステートフル)

# マイクロサービス
境界づけられたコンテキスト
デプロイ
テスト
監視

3章 安定性と信頼性
4章 スケーラビリティとパフォーマンス
5章 耐障害性と大惨事対応
6章 監視
7章 ドキュメントと組織的な理解

6.3 ロギング
6.4 ダッシュボード
6.5 アラート
6.6 オンコールローテーション

https://www.amazon.co.jp/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3-Sam-Newman/dp/4873117607
https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%AC%E3%83%87%E3%82%A3%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9-%E2%80%95%E9%81%8B%E7%94%A8%E3%81%AB%E5%BC%B7%E3%81%84%E6%9C%AC%E7%95%AA%E5%AF%BE%E5%BF%9C%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%A8%E6%A8%99%E6%BA%96%E5%8C%96-Susan-J-Fowler/dp/4873118158/ref=cm_cr_arp_d_product_top?ie=UTF8


# DevOps
## コラボレーション
## アフィニティ
## ツール
## スケーリング

# SRE
分散
自動化
リリース
インシデント
テスト

https://www.slideshare.net/jallspaw/10-deploys-per-day-dev-and-ops-cooperation-at-flickr
Serverlessでオーソライザーを複数のLambdaから使うための設定方法

### 本記事について
Serverless Framework を使ってLambdaをデプロイする時、オーソライザーを複数のLambdaから使えるようにするための設定について記載

## 手順
[公式マニュアルに記載](https://serverless.com/framework/docs/providers/aws/events/apigateway/#http-endpoints-with-custom-authorizers)の通り、オーソライザーを使う全てのhttpイベントにおいて、``resultTtlInSeconds: 0``を記載する

全てに記載しないとオーソライザーのキャッシュが無効にならないので注意

```yaml:serverless.yml
functions:
  create:
    handler: posts.create
    events:
      - http:
          path: posts/create
          method: post
          authorizer:
            name: authorizerFunc
            resultTtlInSeconds: 0
```

## 解説
オーソライザーのキャッシュが有効になっていると、複数のhttpイベントからオーソライザーが呼び出された際、httpイベントが異なっても他のhttpイベントのキャッシュが参照されてしまうので、オーソライザーのキャッシュは無効にしておかなければいけない。

Serverless Frameworkにおいて、オーソライザーのキャッシュの無効化は、上記の手順で行う。
１つでも``resultTtlInSeconds: 0``設定が抜けると、キャッシュが設定されてしまうので注意。

本来、API Gatewayのオーソライザーのキャッシュの設定は、オーソライザーの定義箇所で行うが、Serverless Frameworkでは、オーソライザーの定義箇所での設定は行えず（AuthorizerResultTtlInSeconds・resultTtlInSecondsを記述しても効かない）、httpイベントの設定状況から自動で設定されてしまう。

## 元記事
- [Serverlessでオーソライザーを複数のLambdaから使うための設定方法](https://www.kwbtblog.com/entry/2019/02/19/045943)
PRIVATE TEMPORARY TABLEを試す（Oracle Database 18c）



Oracle Database 18c に搭載された PRIVATE TEMPORARY TABLE の機能を試しました。

# PRIVATE TEMPORARY TABLE とは
PRIVATE TEMPORARY TABLE はセッションの間だけ維持される一時テーブルです。従来はレコードのみが一時的でテーブル定義が永続化される GLOBAL TEMPORARY TABLE しかありませんでした。
PRIVATE TEMPORARY TABLE は、トランザクションの間だけ維持されるか、セッションの間だけ維持されるかを選択することができます。

## 作成方法
 CREATE PRIVATE TEMPORARY TABLE 文を実行します。

```
SQL> CREATE PRIVATE TEMPORARY TABLE ORA$PTT_TEMP1 (c1 NUMBER, c2 VARCHAR2(10))
  2  ON COMMIT PRESERVE DEFINITION;

Table created.
```

テーブル名の先頭の「ORA$PTT_」は、初期化パラメーター private_temp_table_prefix のデフォルト値です。PRIVATE TEMPORARY TABLE を作成する場合には、テーブル名の先頭にこのパラメーター値を指定する必要があります。
この初期化パラメーターはセッション単位では変更できません。テーブル名が指定された名前ではない場合、エラー「ORA-903: invalid table name」が発生します。

```
SQL> SHOW PARAMETER PRIVATE_TEMP_TABLE_PREFIX;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
private_temp_table_prefix            string      ORA$PTT_

SQL> CREATE PRIVATE TEMPORARY TABLE TEMP1 (c1 NUMBER, c2 VARCHAR2(10))
  2  ON COMMIT PRESERVE DEFINITION;
CREATE PRIVATE TEMPORARY TABLE TEMP1 (c1 NUMBER, c2 VARCHAR2(10))
*
ERROR at line 1:
ORA-00903: invalid table name
```

ON COMMIT PRESERVE DEFINITION 句は、トランザクション完了後もテーブル定義を維持する指定です。トランザクション完了と同時にテーブルを削除する場合は ON COMMIT DROP DEFINITION 句を指定します。
GLOBAL TEMPORARY TABLE には、ON COMMIT DELETE ROWS 句と ON COMMIT PRESERVE ROWS 句を指定できますが、PRIVATE TEMPORARY TABLE の作成時に ON COMMIT PRESERVE DEFINITION 句を指定した場合、トランザクションの完了後もレコードは維持されます（ON COMMIT PRESERVE ROWS と同じ動作）。

## 制約
マニュアルには記述がまったくありませんが、 [ORACLE-BASE] (https://oracle-base.com/articles/18c/private-temporary-tables-18c#restrictions) の記事を読むと、
PRIVATE TEMPORARY TABLE には以下の制約があります。

1. テーブル名は、初期化パラメーター private_temp_table_prefix で始まる名前で作成する必要がある（前述の通り）
2. 永続化オブジェクトは一時オブジェクトを参照できない（VIEW 定義等のことか？）
3. インデックス、マテリアライズド・ビュー、ゾーンマップは作成できない
4. 列のデフォルト値を定義できない
5. データベース・リンクではアクセスできない

インデックスが作成できないので、主キー制約も作成できません。使用できない機能を指定された場合、エラー「ORA-14451: unsupported feature with temporary table」が発生します。

```
SQL> CREATE PRIVATE TEMPORARY TABLE ORA$PTT_TEMP1 (c1 NUMBER PRIMARY KEY, c2 VARCHAR2(10))
  2  ON COMMIT PRESERVE DEFINITION;
CREATE PRIVATE TEMPORARY TABLE ORA$PTT_TEMP1 (c1 NUMBER PRIMARY KEY, c2 VARCHAR2(10))
                                                                   *
ERROR at line 1:
ORA-14451: unsupported feature with temporary table
```

PRIVATE TEMPORARY TABLE は、USER_TABLES ビューには格納されません。

```
SQL> DESCRIBE ORA$PTT_TEMP1;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 NUMBER
 C2                                                 VARCHAR2(10)

SQL> SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME='ORA$PTT_TEMP1';

no rows selected

SQL>
```
また、初期化パラメーター private_temp_table_prefix から始まる通常のテーブルは作成できません。

```
SQL> CREATE TABLE ORA$PTT_TEMP2(c1 NUMBER, c2 VARCHAR2(10)) ;
CREATE TABLE ORA$PTT_TEMP2(c1 NUMBER, c2 VARCHAR2(10))
*
ERROR at line 1:
ORA-32463: cannot create an object with a name matching private temporary table
prefix

```
プロキシ環境下でMavenProjectを作成するときのProxy設定

# 背景

Spring Tool Suite(STS)でMavenProjectを作成しようとしたら以下のエラーが発生、Proxy設定を行ったら解消したのでProxy設定方法を記載します。

```
Could not resolve archetype org.apache.maven.archetypes:maven-archetype-plugin:1.2 from any of the configured repositories.
Could not resolve artifact org.apache.maven.archetypes:maven-archetype-plugin:pom:1.2
Could not transfer artifact org.apache.maven.archetypes:maven-archetype-plugin:pom:1.2 from/to central (https://repo.maven.apache.org/maven2): connect timed out
Could not transfer artifact org.apache.maven.archetypes:maven-archetype-plugin:pom:1.2 from/to central (https://repo.maven.apache.org/maven2): connect timed out
```

# 環境

・Windows10
・Spring Tool Suite(3.9.5Release)

# Proxy設定方法

STSを開き、「ウィンドウ＞設定」から設定画面を表示する。

設定画面から「Maven＞ユーザ設定」を表示し、「ユーザ設定（ファイルを開く）」でファイルをオープンする。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/259881/55c2cbea-f266-1a4d-fba0-a1a556b04999.png)

ファイルを開いたら<proxyes>タグを追加し、Proxyの設定を行う。

```
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
  <proxies>
    <proxy>
      <id>http_proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>xxxxx</host>
      <port>8080</port>
    </proxy>
    <proxy>
      <id>https_proxy</id>
      <active>true</active>
      <protocol>https</protocol>
      <host>xxxxx</host>
      <port>8080</port>
    </proxy>
  </proxies>
</settings>

```

ファイルを保存して再度設定画面から「Maven＞ユーザ設定」を開き設定の更新ボタンをクリック

## Mavenキャッシュのクリア
一度プロジェクトの作成を試みている場合は、キャッシュにごみが出いているので削除する。私の場合は「maven-archetype-plugin」のアーキタイプの作成に失敗したので以下のフォルダを削除

```
C:\Users\admin\.m2\repository\org\apache\maven\archetypes\maven-archetype-plugin
```

## MavenProjectの作成
再度プロジェクトの作成を行い、作成できることを確認する。
wordpressで画像の一部が突然表示されなくなった場合にやった対策メモ

<h2>問題：WPで作ったページの一部の画像<img src="">が表示されなくなっていたのでその対策メモです。</h2>

※多分、ほとんどの人が該当しないと思いますが、私のようなケースの方もいると思うので、メモ書き程度ですが、投稿させて頂きます。

<h2>一般的な解決方法：</h2>
いろいろ検索したのですが、一般的にはプラグインが原因で表示されない等の場合が多いようです。よって、プラグインを停止して表示されるかチェックするのがまず大事だと思います。

<h2>解決方法：</h2>
私の場合は、httpからhttpsにしたことが主な原因で、画像を再アップすること表示されるようになりました！（解決しました）

<h2>原因：</h2>
推測ですが、httpsの導入によってリンクの仕方などに多少影響が出ると思います。

一般的には、画像を張る時は、ふつうはエディターで画像を挿入すると思います、この場合リンクの仕方ではちゃんと表示されました。

しかし、FTP経由で画像をアップするケースがあり、この場合は、httpsを導入すると、画像が表示されなくなりました。
すでに生み出されて動いているレガシーコード（テストのないコード）との戦争。結局武器はテスト

[スピード感重視なのでテストは書かない。テストはなぜ開発を遅くするか](https://qiita.com/aimof/items/d68bdb347283ee2dbccf) というという記事がバズって以降テストの記事ばかり投稿しています。この際だからテストに関するもやもやを吐き出しておきます。

上記記事にてToDoとして、
**すでに生み出されて動いているレガシーコードにどう立ち向かうか**
と書きました。

一回レガシーコードと戦って勝利一歩手前まで行った経験があるのでその経験をまとめます。

## どんなコードだったか

* 規模は小さめ
* ユニットテストなし
* 自動テストなし
* テストはデプロイしないと不可
* 前任者（作成者）いない
* UIなし

### やりたいこと

テストがあれば一時間で終わる程度の変更を加える

## 格言

レガシーコードの改変について有名な格言があり、

> ## レガシーコードのジレンマ
> コードを変更するためには、テストを整備する必要がある。多くの場合、テストを整備するためには、コードを変更する必要がある。

「レガシーコード改善ガイド」マイケル・C・フェザーズ

上記の理由で、基本的にレガシーコードは詰んでいることが多いです。このときは幸運に恵まれていたため、そのあたりを解説していきます。

## 幸運と方針

このとき幸運だったのは、UIがない、IOが（量は多いけど）シンプル、リポジトリ単位では独立している、という点でした。

方針は、コードを変更する必要がない最小の単位で自動テストを整備すること。
すなわち、**リポジトリ全体の自動試験を整備すること**、です。

## やったこと

docker-composeを用いて関係するIOをすべて再現して、IOが一致することを確認するプログラムを書きました。
docker-composeなので、自動実行です。
テストにテストが必要なレベルですが、たぶん仕方ない。

## この手のテストを書く際の注意点

* 直感的におかしくても、レガシーコードの出力が正。
* できる限りケースを網羅する。
* エラーで落ちるパターンだけは何とかする。

## 上記が完成したら

テストコードが正しいことを常に確認しながらユニットテストを整備していきます。
できる限りこまめに上記テストを実行するのがポイントです。
簡単そうに書きましたが大変です。

## ユニットテストの整備

基本的にこのようなコードはユニットの概念がないため、ものすごく苦労します。中身は密に結合しているため、一箇所に変更を加えた際に、全く意図しないところがエラーを吐く、というのがザラでした。
最初は、テストを定期的に実行しながら、読みやすくするために等価っぽい変更を繰り返します。見通しが良くなるまでは、我慢します。

次に、捨てブランチを切って思うがままに変更してテストします。このブランチはどんなにうまく行っても必ず捨てますが、代わりに何をしても構いません。たいがい適当に変更するとぶっ壊れます。

程々に挙動がわかってきたら本番の変更用ブランチを切り、微妙に疎になっている部分を見つけてちょっとずつ切り出し、ユニットテストを書きます。

## 最終的に

重要なところのユニットテストを書きおわったあたりで担当を離れることになったのでこのプロジェクトが最終的にどうなったかは知りません。

## まとめ

結局テストを書かなければレガシーコードとは戦争できない。