OmniAICreator/Qiita-1.07M huggingface dataset:
2020年　とらのあなLT：今年チャレンジしてみたい技術

（このスライドはLTのためにだけ作成しているので読み物としては想定していませんが、当時のリアルな雰囲気を尊重したいので手を加える事はしていません。）

## ネイティブアプリの難しさを一気に解決したい
[2020/02/18 【とらのあなLT】今年チャレンジしてみたい技術 in 秋葉原](https://yumenosora.connpass.com/event/164204/)

---

## スライドは公開しています。
会場に入って30分で作ったようなものなのでクオリティ＜納期

![QR_023207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122800/68120c51-56ef-af8d-98bd-d53ca23d40e8.png)

---

## わたしは誰？
```
{
  name: "のむらやごろう",
  job: ["フルスタック", "AIデータエンジニア", "プログラミング講師"],
  lang: ["JS(Vue)", "Tensorflow(Python2)", "Flesk(Python3)",
        "Rails(Ruby)", "PHP"],  // desc 最近やった案件順
  news: "Jamstackなサイト作って経歴書をAPI化しました"
}
```

---

## 過去にやったこと
- LINEとSlack,GmailなどなどをGASでサーバーレス連携
  - LINE入れたくないおとんやおかんにサクサク連絡
  - SpreadSheetでロギングもバッチリ
  - 
仕事中にLINEやると怒られるからSlackからLINEやる

- 求人登録サイトに登録する情報を一元管理するサービスを検討

---

## アジェンダ
- ネイティブアプリの問題点
- 解決ソリューションの提案
- デモ（時間があれば）

---

## ネイティブアプリの難しさ:技術
- Android版作らなきゃだめ
  - Kotlin技術者探す
- iPhone版作らなきゃだめ
  - Objective-C技術者探す
  - そもそも高い高い審査の壁

---

## ネイティブアプリの難しさ:テスト
- テストめんどい
  - Appiumでなんとか頑張る
  - ユーザーテストどうすんの？
- バグるたびに★１つけられる
  - ユーザーサポートつらい

---

## ネイティブアプリの難しさ:集客
- アプリをダウンロードしてくれない
  - ダウンロードしてくれるけど使ってくれない
- アプリを入れたくないユーザーがいる
  - 結局似たようなことをWebページでも作っている
    - PWAで解決できそう→開発コスト増

---

# とてもつらい:cry: 

---

## そこでLINE MiniApp
[LIFF(LINE Frontend Framework)](https://developers.line.biz/ja/docs/liff/overview/)で作れる
- LINEの上でHTML書ける
- Canvasタグを銀の弾丸のように酷使する
- [PlayCanvas](https://playcanvas.jp/)がヒントになるかも？

---

## デモ
（時間があれば）
[ホーム画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122800/593f9fc9-20d2-b7c7-ee61-d4b868f8dc40.png)
[アプリ起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122800/b28a0dd7-9a37-43ba-cd66-7a1127cedb8b.png)
[操作.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122800/ccbc172b-4e4e-00ee-bcc9-1c36d3e11c4d.png)
[送信.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122800/6aa3060d-a008-ea4b-855e-8591efabba8f.png)

---

## 疑問：テストどうすんの？
→LINE社内でもベストプラクティスないのかな:question: 
- LIFF自体はただのFrameworkなのでブラウザでガチャガチャできる
  - Selenium系で何とかなる？

---

## 活動方針
- そもそもLIFFについて知見が足りない
  - どうせならLINE API Expert目指そう
- ネイティブアプリの課題をLINE MiniAppで解決できるのでは？
  - 認知度が低いので頑張ってDevRelやる！
- 技術書典に参加してみる
RspecでDevise認証を使ったテストを行う方法【Rails5編】

## 参考記事
[rspecのテスト環境でdeviseにログインする方法【rails】]
(https://qiita.com/Kohei_Kishimoto0214/items/e29e509b12a6eb484a42)

こちらに大まかな実装の流れを分かりやすく解説して頂いていたので、共有させていただきます。

## やりたいこと
上記、参考記事に書かれている方法を**Rails5**でも行えるようにする。

# 実装 
**参考記事と照らし合わせながら下記の実装解説をお読みください。**

## 1. support配下を読み込み可能にする
```ruby:spec_rails_helper.rb　(修正前)
# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
```
```ruby:spec_rails_helper.rb　(修正後)
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
```
コメントアウトのままだとsupport配下が読みこめていないのでコメントアウトを解除。

## 2. controller_macrosの作成
```ruby:spec/support/controller_macros.rb　(修正前)
module ControllerMacros
  def login_admin(admin)
    @request.env["devise.mapping"] = Devise.mappings[:admin]
    sign_in admin
  end

  def login_user(user)
    controller.stub(:authenticate_user!).and_return true
    @request.env["devise.mapping"] = Devise.mappings[:user]
    sign_in user
  end
end
```
```ruby:spec/support/controller_macros.rb　（修正後)
module ControllerMacros
  def login_admin(admin)
    @request.env["devise.mapping"] = Devise.mappings[:admin]
    sign_in admin
  end

  def login_user(user)
    allow(controller).to receive(:authenticate_user!).and_return(user)
    @request.env["devise.mapping"] = Devise.mappings[:user]
    sign_in user
  end
end
```
8行目に注目してください。修正前は**stub**と書かれていますがこのままだとエラーが出ちゃうので変更。


## 3. deviseのtest_helperとmacrosをcontroller内で使えるようにする
```ruby:spec_rails_helper.rb　(Rails5未満)
RSpec.configure do |config|
  config.include Devise::TestHelpers, type: :controller
  config.include ControllerMacros, type: :controller
end
```
```ruby:spec_rails_helper.rb　(Rails5)
RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include ControllerMacros, type: :controller
end
```
3行目に注目してください。**config.include Devise::TestHelpers, type: :controller**は**Rails5**からはこの書き方は廃止されたので**config.include Devise::Test::ControllerHelpers, type: :controller**に変更。以上です。
【React】【MaterialUI】InlineDatePickerが正常に動作する環境

#InlineDatePickerとは
material-ui-pickersモジュールが提供するモダンな日程入力コンポーネント．
<img width="338" alt="スクリーンショット 2020-02-18 19.35.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458915/3a8ecfa4-04ba-ac51-d739-ba412272cabe.png">

#導入環境
```
npx create-react-app
```
でスターターキット使いました．

```react:.js
import { MuiPickersUtilsProvider, InlineDatePicker } from "material-ui-pickers";
import DateFnsUtils from "@date-io/date-fns";
```
MaterialUIからのモジュール読み込み．

```react:.js
<MuiPickersUtilsProvider utils={DateFnsUtils}>
  <InlineDatePicker
    label="ライブ日程"
    format="yyyy/MM/dd"
    onChange={date => this.handleDateChange(date+input)}
    value={this.state.selectedDates[input]}
  />
</MuiPickersUtilsProvider>
```
InlineDatePickerの呼び出し．

#躓いた点
これ，普通にモジュールインストールを

```
yarn add モジュール
```
みたいにしてると最新版がインストールされてしまい，なぜか最新版@date-ioはエラーを吐きます．

#解決法

```json:package.json
"@date-io/date-fns": "^1.3.13"
```
でバージョン1.3.13で指定．これで上手くいきます．
参考：https://stackoverflow.com/questions/59600125/cannot-get-material-ui-datepicker-to-work

#疑問
一番上の画像でもあるようにDatePickerウィンドウ内の言語は英語になっています．これ日本語にすることって可能ですかね？だれか教えていただけると嬉しいです〜
textareaの右下の伸縮ボタンを1行で消す

# 目的
textareaのこのチョンチョンを消すcssを毎回忘れるのでメモをソッと残しておきます

![スクリーンショット 2020-02-18 19.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/dee5a678-7078-882c-7761-49d4f9aaf137.png)

## 解決法
```
textarea {
  resize: none;
}
```

## 結果
![スクリーンショット 2020-02-18 19.46.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/40e1cd16-a39d-e4a5-7d2a-170070503a70.png)
無事に消えましたっ
each_with_objectでwith_indexしたい

# いけた
が、使える引数の順番が複雑な感じ。カッコも必要。
カッコ内の引数：each_with_objectの第1引数、第2引数
カッコ外の引数：with_indexで追加された引数
ということのようだ。

```ruby
(1..3).each_with_object([]).with_index do |(data, arr), index|
 data # (1..3)の配列内のデータ
 arr # each_with_objectの引数に渡した配列
 index # インデックス
end
```

# 参考
- [each_with_indexしつつinjectしたい](https://qiita.com/ymstshinichiro/items/366b738ceefd224b5d41)
Node.jsで画像変換処理

# 目次
- [sharp](#sharp)
- [node-imagemagick](#node-imagemagick)
- [GraphicksMagick](#graphicksmagick)

***

# sharp
## sharp - 概要
Node.jsをサーバとして利用した時に、画像リサイズ処理の最適な方法は何かを調査する。
有名どころでは、ImageMagick。ただ、調べると  **sharp** というNodeモジュールが、ImageMagickよりも速くリサイズ可能とのことなので、これを調べてみる。

## 参考
Node.js の画像変換モジュール sharp の使い方 **基本的な使い方はこれ一つでok**
https://r17n.page/2019/08/15/nodejs-sharp-image-converter-how-to-resize/
  
Node.jsのライブラリsharpでリサイズを試してみる **読みやすい上の記事のライト版**
https://blog.kozakana.net/2019/04/sharp-resize/
  
Node.jsのライブラリsharpの出力形式について **出力形式についてのまとめ**
https://blog.kozakana.net/2019/04/sharp-output-format/
 

## sharp - 環境構築
```js
npm i sharp
```


## sharp - 使い方
```js
sharp(`画像ファイルパス or 画像ファイルバイナリ`)
  .resize(1080, 1080)
  .toFile(`出力パス`)
```


***

# node-imagemagick
## node-imagemagick - 概要
sharpは直感的ですごく使いやすいが、heic形式（iPhoneで撮った写真の形式）については対応していないとのこと。  
※公式のQ&Aのやり取りを見ると、対応する方法があるみたいだが、少し複雑。

その為、heic形式も対応するとなると、imagemagickを利用する必要があり、
imagemagickをNodeから実行する方法として、node-imagemagickというnodeモジュールがある。

## node-imagemagick - 環境構築
```js
// imagemagickのインストール
brew install imagemagick

// node-imagemagickのインストール
npm i imagemagick
```

※ windowsでは、下記からstaticバージョンをインストール。
http://www.imagemagick.org/script/download.php

C:\Program Files\(インストールしたimagemagick)\magick.exeにある実行ファイルを複製し convert.exe に変更。（npmパッケージから参照するため）

↓こちらの記事を参考にさせていただきました。
[Windows10環境でNode.jsを使って画像処理を行う](https://blog.narumium.net/2018/08/08/windows10%E7%92%B0%E5%A2%83%E3%81%A7node-js%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86%E3%82%92%E8%A1%8C%E3%81%86/)


## node-imagemagick - 使い方
convertの例。imagemagickはコマンドが多すぎるので、都度調査する。

```js
const im = require('imagemagick')

// imagemagickのコマンドを配列形式で指定する
im.convert(['/path/image/image.png' '/path/image/image.jpg'], (err)=> {
  console.log('image magick convert finish')
})

// コマンド文字列を半スペでsplitするほうが使いやすい
const cmd1 = `/path/image/image.png /path/image/image.jpg`
im.convert(cmd1.split(' '), (err)=> {
  console.log('image magick convert finish')
})

// 一つの画像から複数種類の画像を書き出す場合のコマンド文字列例
const cmd2 =
  `${file.path} `+
  `-resize 3840x1080 -write ${filePath}image.jpg ` +
  `-resize 1080x1080 -write ${filePath}imageProFile.jpg ` +
  `-resize 150x150 -write ${filePath}thumbnail.jpg`

im.convert(cmd2.split(' '), (err)=> {
  console.log('image magick convert finish')
})
```

***

# GraphicksMagick
## GraphicksMagick - 概要
おまけ。
node-imagemagickのgithubリポジトリのReadMeを確認すると、長い間メンテナンスされていない為、GraphicksMagickを利用推奨とのこと。  
使い方もsharpの用にメソッドチェーン方式なので、使いやすそうなので良き。
※ただ、heicの書き出しがうまくいかなかったので不採用。

## GraphicksMagick - 環境構築
```js
// imagemagickとgraphicsmagickのインストール
brew install imagemagick
brew install graphicsmagick

// WebPに対応する場合
brew install imagemagick --with-webp

// gmモジュールのインストール
npm i gm
```

## GraphicksMagick - 使い方
```js
const gm = require('gm')

gm('/path/to/my/img.jpg')
.resize(240, 240)
.noProfile()
.write('/path/to/resize.png', function (err) {
  // 書き出し完了後の処理
});
```
【Brackets】MarkDownを表示させる

Adobe社テキストエディタであるBracketsでMarkDownを表示させる方法です。
拡張機能のインストールにより、実現できます。

## 使用ツール
- Brackets（ダウンロードは[コチラ](http://brackets.io/)から）

## 手順
1.「ファイル」 > 「拡張機能マネージャー」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/1195311c-801c-0250-b554-346dc31fdae1.png)
2.「入手可能」タブにて、「MarkDown」と入力して検索し、「MarkDown Preview」の右端の「インストール」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/3c37a67a-9f89-44f4-ccb9-2198832da898.png)
3.「表示」 > 「MarkDown Preview」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/bffe8e90-9bd4-e1dd-2f3b-a1bea992972c.png)
4.表示されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/2e94b0f9-e3d6-639c-5c9f-4fc8e601a806.png)

## 参考
[Bracketsでマークダウン記法をライブプレビュー出来るようにする拡張機能 | 9ineBB](https://9-bb.com/brackets%E3%81%A7%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%80%E3%82%A6%E3%83%B3%E8%A8%98%E6%B3%95%E3%82%92%E3%83%A9%E3%82%A4%E3%83%96%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E5%87%BA%E6%9D%A5%E3%82%8B/)
Let’s Encryptの動作サーバがDockerでcertbotなんかをインストールできない場合

こいつを利用してサクッと作ってしまったが
https://sslnow.ml/

次は以下のコマンドを使用する。

```bash
$ certbot -d example.com --manual 
```

サイトで作ると更新が超面倒
Amazon AppStream 2.0の基礎

AppStreamは記事やマニュアル、blackbeltも詳細が乏しいので記載してみました。

# 2種類のWindowsインスタンス
|||
|---|---|
|image builderインスタンス|イメージをビルドするためだけに存在するインスタンスです。ビルドが終わったら役割を終えます|
|fleetインスタンス|ビルドしたイメージを実際の配信に使う、auto scaling可能なインスタンスです。1配信1インスタンスのはず。|


# ビルドするための3つのユーザー
image builderで利用します。
## template user
配信したいアプリケーションのセップアップをするユーザーです
このユーザー上で設定したものが新しいユーザーにコピーされ、配信されます
Windowsユーザー名：`DefaultProfileUser`
## administrator user
用途は2つ。

- イメージをビルドするツールで実際にビルドすること
- template userが使うようなOS全体の設定を行うこと

例えばOSの地域設定やlocal group policyの変更など。
こみいったことをする場合Windowsの知識が必要です

Windowsユーザー名：`ImageBuilderAdmin`

## test user
template userの設定を検証できるユーザーです
しかし残念ながら配信時の完全に同一な環境ではありません
例えば配信時に実行されるsession scriptは実行されませんし、ホームフォルダの場所も異なります

Windowsユーザー名：`ImageBuilderTest`

# 作ったイメージはどこに行くか
Images -> Image Registoryにあります
GUIがわかりにくいのですが、絞り込み可能です

# session script
session scriptというもので配信時にスクリプトを実行できます。
image builderインスタンスの中に`C:\AppStream\SessionScripts\config.json`があるので、administratorユーザーで修正しましょう。
実行ログはs3に出力されます。
https://docs.aws.amazon.com/ja_jp/appstream2/latest/developerguide/use-session-scripts.html
検証時は管理者権限でメモ帳を開いて修正しました。

# 配信アプリを実行するWindowsユーザー
PhotonUserというWindowsユーザーです。
デスクトップなども`C:¥PhotonUser`配下にあります

# 残る課題
## 開発サイクル
純粋に時間がかかります
- ビルド 40分ぐらい
- fleet 起動10分ぐらい 
- 初回セッション 2,3分ぐらい
また、単体のデバッグ機能に乏しいので、外部へのメトリクスやログ送信があると良さそうです。
セッション終了後もしばらくセッションが残るところも少し困ります

## セキュリティ
まだ発展途上にみえます。

sampleのFirefoxからフォルダを開いてみた事例です
https://aws.amazon.com/jp/appstream2/try-sample-applications/
メモ帳も一瞬開かれた後消えます。様々なコマンドも実行できそうです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37384/f420924e-f0cb-b94f-2bb1-e92b0b4af77d.png)

不特定多数への配信はあまり向かず、特定のある程度信頼できるユーザーへの配信なら有効活用できそうです
デモ環境など。
GitHubActionsで、特定のファイル変更をトリガーにする

## 背景
特定のファイルが変更されたときのみ、githubでレビュワーをアサインする仕組みを作りたい

## 検討
GitHubActionsのifで、条件が書けそう
→「ファイルが変更されたら」の書き方がわからない

## 解決案
ifじゃなくて、onで「ファイルの変更差分がpushされたら」の条件にする

```
on:
  push:
    paths:
    - 'dir/**'

```

これでトリガーをファイル変更にできる
コーディング中の警告解消時の注意点

#はじめに

みなさん！コーディング時の警告はちゃんと解消してますよね？

ただ、「はいはいいつものやついつものやつ」とか「またこれねハイハイ」とか容易にソースを修正してませんか？

特にテストやらなんやら終わった後のクラスとかで「あれ？警告でてるじゃん、消しとこ」とかで軽い気持ちで修正しちゃったりとかありませんか？

その修正が思わぬ不具合につながるかもしれませんよ？

#まえおき

理解してる人はあたりまえの話なのでそこはあたたかい目で読んでいただければと思います

例を作るにあたり、いろいろ突っ込みどころがあると思いますがご容赦を・・・！

#ほんだい
極端な例ですが、例えばこんなclassがあったとします。

```java
public class TestClass {

    TestClass() {

        hogeInt hogeInt = new hogeInt();

        ...

        if (特定の条件) {

            Log.d("TAG", "前");

            Boolean flg = hogeInt.getIntParam().equals(1);

            Log.d("TAG", "後");

            Toast.makeText(context,"サーバーに truncate table * のクエリを投げました",Toast.LENGTH_LONG).show();
        }

        ...

    }

}

class hogeInt {

    private Integer intParam = null;

    @Nullable
    public Integer getIntParam() {
        return this.intParam;
    }

    public void setIntParam(Integer intParam) {
        this.intParam = intParam;
    }
}
```

そして特定の条件内に入るのが極稀なケースだったとします。


ここでひとつPointなのですが、これを何もせずに実行した場合、

```java
Toast.makeText(context,"サーバーに truncate table * のクエリを投げました",Toast.LENGTH_LONG).show();
```

が**実行される前**にクラッシュします。
（ hogeInt.getIntParam() はNull なのに equals を実行しようとしているので）

そして本題。

```java
Boolean flg = hogeInt.getIntParam().equals(1);
```

こいつは警告として表示されます。
今回だと「’NullPointerException’を生成する可能性があります」ってやつですね。わりかしよく見かける部類の警告だと思います。

これをアプリ改良中に「あれ？ここ警告でてるからついでに修正しておこう」とか「そういえばたまにクラッシュ報告あるけどこいつかも」
といった軽い感じで何も考えずにソースを修正した場合

ソースがこう変化します

```java
public class TestClass {

    TestClass() {

        hogeInt hogeInt = new hogeInt();

        ...

        if (特定の条件) {

            Log.d("TAG", "前");

            if (hogeInt != null) {
                Boolean flg = hogeInt.getIntParam().equals(1);
            }

            Log.d("TAG", "後");

            Toast.makeText(context,"サーバーに truncate table * のクエリを投げました",Toast.LENGTH_LONG).show();
        }

        ...

    }

}
```
今までクラッシュしていた部分をnullチェックでスルーする事によって後続が流れるようになり、めでたくサーバにTruncate文が投げられる事になりました。


ちなみに今回のお話は**警告は残しておいてもいいよ！**という事ではなく、**小さな警告を消す場合でも慎重になれ**という事です。

何かしら修正を入れる場合、その一文だけを見ずに、全体の流れをちゃんと把握した上で修正しましょう！
初心者がplaygroundを用いてアプリ作ってビューをフルスクリーンにするのに困った件。

# まず初めに
大学の授業でアプリ作ることになったので、作りました。
playgroundを使って本当に困ったことを書いていきたい。
本当に初心者だからそんなの当たり前だろと思うかもしれないがご了承ください。
俺の気持ちわかってくれ。



# フルスクリーンできん問題

困ったことはこの問題や。

<img width="1440" alt="スクリーンショット 2020-02-18 18.36.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/f2f44502-d71a-57ac-01d3-9936fe6ee9d0.png">

初期画面がこれだが、スクリンビューを追加します。
ボタンも配置しておきます。

<img width="606" alt="スクリーンショット 2020-02-18 18.38.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/821d6ddf-8886-ac10-0632-cb77485f6bb8.png">

そしてここに遷移することを伝えると。
....
...
.
<img width="608" alt="スクリーンショット 2020-02-18 18.38.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/47b310c7-5511-d73f-ef07-1412bfffa887.png">

.....?


<img width="255" alt="スクリーンショット 2020-02-18 18.38.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/b52de159-4739-978e-6e56-d5f7f70bb429.png">

### は？なんでフルスクリーンじゃないの？

こんなことに僕は、物凄い時間をかけてしまいました。

# じゃあ解決策は？

解決するには簡単なことでした。
さきほどののビューの黒い上の部分をクリックして右のメニューから操作します。

<img width="260" alt="スクリーンショット 2020-02-18 18.53.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/308ae9b9-4d8f-c686-fa7c-f0e56d307df6.png">

presentationという欄のAutomaticをFull Sureenに変えてあげるだけ。

<img width="255" alt="スクリーンショット 2020-02-18 18.53.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/cdb10b86-feaf-da8e-0329-96699bafd860.png">


<img width="588" alt="スクリーンショット 2020-02-18 18.58.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549502/d5eb6919-5398-a25a-0198-69ae1ab1177a.png">

### できました......
結構簡単な操作ですね。
検索してもなかなか見つからなかったので記事書きました。以上。

### デフォルトをこれにするには.....

### To be continued...
OculusQuestのハンドトラッキングで指ジェスチャに色々つけたら大混乱


## はじめに

Oculus Quest がアップデートでハンドトラッキングに対応してます。
ハンドトラッキングでは、コントローラ等一切無しで自分の手・指のみでVR操作ができるようになります。
SDKとしては各手・各指関節の曲がり具合が取得できるのですが、
これをアプリの操作に利用すれば **各指の伸ばす・曲げるにボタン割当すれば１０指１０ボタンまでいける**

じゃ指10本を思うがままに個別に動かせるのかというとそんなわけないだろと..
この記事はそんなハンドトラッキングとアプリ操作について考察・試行錯誤した事例を紹介するものです。

(なおこの記事は 2020/1月から書いていた記事 ["ついにでたOculusQuestハンドトラッキング×VRMでアバター空間満喫してみた"](https://qiita.com/sa_w_ara/items/ee60639bd4bb1250ca29) からの派生記事です)

## ハンドトラッキング・指操作についての考察

ハンドトラッキングで指に操作割り当てしようとすると、色々課題にぶつかります。
大きく人間側起因の課題と、ハンドトラッキング起因の課題があるなかで気づいたものを整理しておきます。
（なお摘まむジェスチャをピンチと呼んでます）

* 人が自然に独立して動かせる指と・そうでない指がある
    * 人によってできる・できない違いそうなのですが、私の場合こんな具合
        * 親指＋他指のピンチ
            * 人差指 : いける。
            * 中指 : 一緒に薬指・小指まがっちゃう
            * 薬指 : 一緒に中指曲がっちゃう
            * 小指 : できるけどちょっと苦しい
        * 親指＋他指２本のピンチ
            * 人差指・中指 : 一緒に薬指曲がっちゃう
            * 中指・薬指 : いける
            * 薬指・小指 : 一緒に中指曲がっちゃう
        * 親指＋他指３本のピンチ
            * 人差指・中指・薬指 : いける
            * 人差指・薬指・小指 : 苦しい
            * 人差指・中指・小指 : 苦しい
            * 中指・薬指・小指 : いける
* OculusQuest のハンドトラッキングで得意・苦手な手がある
    * 手を静止してジェスチャ
        * 視界から奥のほうの隠れた指がプルプルする..
    * ジェスチャしたまま手を動かす
        * 薬指ピンチしようとするとプルプル..
    * 他、様々 ”普通やらないでしょ” ってジェスチャほどプルプル..
    * LeapMotion同様、ハンドトラッキングもののデバイスあるあるだと思うので、これはそういうものと
        割り切ったうえでアプリデザイン考えることに。

## 指の操作をつたえるの、とても大変

**サンプルアプリ作って試してもらったら..**

自分以外の人に使ってみて貰おうとしたら、これがとても大変。
なにせ、各種指ジェスチャを呼ぶ名前が無くって、さらにはユーザーとの概念の共通認識もなくって。

* ”右手の五本の指を全部開いて、そこから人差し指と親指だけ閉じてくっつけて”＝ピンチ
* ”目の前に見えてる四角い箱をピンチすると掴めて”＝ピンチしたままドラッグ？
* "ピンチしてたの離す”＝ピンチ..アウト？？
* 指で摘まむ＝ピンチイン, 摘まんだまま動かす＝ピンチドラッグ, 摘まんだの離す＝ピンチアウト、とか？

基本のクリック、ドラッグ操作すら伝えるの難しい。
それが済むと今度 ”それを指でピンチして” というと手５指でグリップしちゃって別操作になったり。

今回のサンプルアプリは使える操作として、

* "左手の中指をロングピンチするとメニューon/off"
* "左手の人差指・中指でピンチドラッグするとワールド全体移動”
* "左手・右手を視界正面からちょっと外側でピンチドラッグするとワールド全体拡大縮小"

なんてのも付けてみたのだけど、ここまでくると解説動画でもないと理解してもらえる気がしない..。
上手なアナウンスと操作に対する習熟が必用か..。

ここまでくるとハンドトラッキングめんどくさくない？コントローラ使えばいいじゃんってなりそうなんですが、
しかしコントローラから解き放たれたVR-HMDの使うの簡易さといったら、もうこれなしじゃ嫌なわけですよ。
なのでなんとかこれに慣れていきたい・慣らしていきたい次第です。

今回のサンプルの使ってるとこ動画(twitter)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">QuestHandtrackingで遊ぶ・使うジェスチャ増えてきて指が混乱してきた、あと指つりそうになる <a href="https://twitter.com/hashtag/%E6%89%8B%E8%A3%BD?src=hash&amp;ref_src=twsrc%5Etfw">#手製</a> <a href="https://twitter.com/hashtag/unity?src=hash&amp;ref_src=twsrc%5Etfw">#unity</a> <a href="https://twitter.com/hashtag/OculusQuest?src=hash&amp;ref_src=twsrc%5Etfw">#OculusQuest</a> <a href="https://twitter.com/hashtag/handtracking?src=hash&amp;ref_src=twsrc%5Etfw">#handtracking</a> <a href="https://t.co/daJLwLdcEU">pic.twitter.com/daJLwLdcEU</a></p>&mdash; sa_w_ara△ (@sa_w_ara) <a href="https://twitter.com/sa_w_ara/status/1229707139309957120?ref_src=twsrc%5Etfw">February 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## まとめ

* ハンドトラッキングは指操作できる素敵夢技術
* 指でおこなう空間操作にまだ馴染みがないので、どの指操作は多数の人が普通にできるのか知見が欲しい。
* インサイドアウトのデバイスでのハンドトラッキングには、手の姿勢によって検出の得意・不得意あるので、
    どの指操作は検出しやすいのかの知見が欲しい。
* 指で行うジェスチャー群に一般的な名称がついて、みんな分かるくらいまで普及してほしい。
    * マウスが出て右クリック・ダブルクリック・ドラッグ＆ドロップが普及、スマホでフリック入力が普及したように。
MacからWindowsにlaravel開発環境を移してみた！（サーバー起動まで）

#用意したもの
* virtual box
* vagrant
* cyberdock
* tera term


#作業手順
vagrant upしてvirtual boxを起動します。

virtual boxにログインするためtera termを使いsshでログイン

その後、virtual boxにファイルをアップロードするためcyeberdockを使いアップします。

php artisan serveを起動するとこんなエラーが・・・・

```
PHP Parse error:  syntax error, unexpected '?' in /home/vagrant/laravel_lessons_copy/myblog/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php on line 500
```

>Laravel5.5はPHPのバージョンが7.0.0以上を必要としています。PHPのバージョンが７未満だと上記エラーになる場合があります。特にCentOSをはじめとするサーバOSはデフォルトでPHP7以上になっているものが少ないため、注意が必要です。
Laravel初期設定でやりがちなミス:引用元URL(https://www.inet-solutions.jp/technology/laravel-setting/)

ということなのでバージョンアップします。

```
sudo yum install --enablerepo=remi,remi-php71 php php-devel php-mbstring php-pdo php-gd php-mcrypt
```

これで`php artisan serve`が実行できるはずです。


ちなみに上記コマンドでもサーバー起動しなかったので下記を行いました。

`$ php artisan serve --host 192.168.33.10 --port 8000`
metabaseでのWHERE変数の組み方メモ

# metabaseとは

OSSのWEBベースBIツールです。以下のQiitaが詳しい
https://qiita.com/acro5piano/items/0920550d297651b04387

特に気に入っているのがdockerでの利用が超かんたんな所。
適当なRDBと一緒にyamlを書いてcomposeを立ちあげれば、すぐに分析に使えます。

# docker-composeのサンプル

なお、よくあるサンプルではmetabase.dbをvolume指定していないので、コンテナを再作成すると作った分析データが消えます。
Volume指定だいじ。

```yaml:docker-compose.yml
version: '3'
services:
  metabase:
    image: metabase/metabase
    volumes:
      - ./metabase-data:/metabase-data
    environment:
      MB_DB_FILE: /metabase-data/metabase.db
    ports:
      - "3000:3000"
    links:
      - db
  db:
    image: mysql:5.6.26
    environment:
      MYSQL_ROOT_PASSWORD: ****
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: ***
      TZ: 'Asia/Tokyo'
    volumes:
      - ./db:/var/lib/mysql
      - ./mysql_conf:/etc/mysql/conf.d
    ports:
      - 3306:3306
volumes:
  db:
  metabase:
```

# 便利なSQLでの定義作成

metabaseはSQLでガシガシ条件を書いて、定義（分析）を公開することができるので、土方社内SEにもおすすめです。
ただし、使い込みの情報があまり国内になく、stackoverflowやgithubのissueからノウハウを拾って作らなければいけないケースが、結構あります。

詳しい使い方は以下の公式が詳しい。
https://www.metabase.com/docs/latest/users-guide/writing-sql.html

この文書では、この中に記載があるもの、無いものの中から使いたいケースがあったものを記載します。

## 変数
SQLで問い合わせを書いた場合に、変数が使える。
公式のヘルプもあるが、『こういう時どうすればいいんだ？』という事が結構記載がなかったりする。海外のフォーラムなどで解が得られたものをメモしていく。随時追記する。

2020-02-18：取り急ぎなんとかしたかったLIKEとINがわかったので、下書きから公開にします。

### 参考ページ
https://www.metabase.com/docs/latest/users-guide/13-sql-parameters.html

### 基本構文
metabaseの変数は基本的に以下のルールで構成される。
1. `{}` で囲むと変数になる。
    - 変数は半角英数で命名する。
    - フィルターラベルを指定すると入力枠に名称が表示される。
    - 必須の制御は変数設定メニュー
    - デフォルト値は事前に決めた固定しか登録できない
2. `[[]]`で囲むと、囲まれた範囲内の変数が入力されたときのみ、その中の構文が評価される。
### デフォルト値の設定
参考：https://www.metabase.com/docs/latest/users-guide/13-sql-parameters.html

metabaseの変数設定エリアにも初期値を指定できるが、今日の日付などといった動的な値は設定できない。
metabaseの説明によれば、値を入力した時だけ、初期値がコメントアウトされるように記入すればよいとのこと。

```sql
WHERE createdAt = [[ {{dateOfCreation}} -- ]]CURRENT_DATE()
```

このSQLで記載し、該当の項目に何も入力しないと以下のクエリとして評価される。

```sql
WHERE createdAt = CURRENT_DATE()
```
何か入力するとこの様になる。

```sql
WHERE createdAt = '2020-02-01 00:00:00' -- CURRENT_DATE()
```

ちょっとHackっぽいが、結果が取れればよい。というスタンスのようだ

### LIKE の書き方
LIKEで文字列を検索したい場合は以下のように記載するとよい。
ダブルクォーテーションでくくるとうまいことやっくれるようだ。

```sql
name LIKE "%"{{name}}"%"
```

また、比較対象の文字列に%を含めればよいのであれば、以下のような書き方でもOK
もちろんCONCAT以外でも各RDBの文字結合ができる書き方なら通る

```sql
name LIKE CONCAT('%',{{name}},'%')
```

### IN の書き方

v0.25 から **数値タイプ** のみIN句がNativeSupportされています。

```sql
/* 値タイプを数値にする */
id IN ({{id}})

```

それ以外の型はまだIssueがCloseされておらず、以下のような形での回避が提示されています。
https://github.com/metabase/metabase/issues/4728

```sql
/* mysql */
select count(*) from T
where find_in_set(day, {{day}}) <> 0;

/* postgresql */
select count(*) from T
where day = ANY (string_to_array({{day}},  ','));
```

## ON/OFFのような条件指定
いわゆるチェックボックスで対応したい、クエリ上では文字列で指定するが、エンドユーザーには0/1の指定で切り替えをしたい場合の書き方

```sql
[[AND NOT type_column= CASE WHEN {{type_reject}} = 1 THEN 'hoge' ELSE '-1' END]]
```
このように書くと、type_rejectの入力枠ができるので、ここに1を入力してもらうと、```type_column = hoge``` の結果が除外され、それ以外の値をいれるか、値をセットしないと、hogeの結果が表示されます。
これまたHackぽいですが、結果がでればよいのです。
webアプリにおける破壊的処理のキャンセル

ionicを使ったときの破壊的処理のキャンセル方法のメモ

## デモ

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256344/a1aa56e8-0a89-a4d5-d2be-ae56b1ccf9de.gif)


## ポイント
- 非同期処理を入れる関数には，`async`を先頭につける
- splice()が配列操作を破壊的に行うため，非破壊なsplice関数を作成

## 参考
- [公式サイト](//https://ionicframework.jp/docs/api/toast)
- [javascriptの配列操作を非破壊にまとめサイト](http://jitl.hatenablog.com/entry/2016/09/07/184915)


## コード
```ts

import { ToastController } from '@ionic/angular';
・
・
    constructor(
 ・
・
     private toastCtrl:ToastController,
    ) {}
・
・
splice(arr:any, index:number, howMany:number /*, elements*/){
  if(toString.call(arr) !== '[object Array]') return null;
  if(arr.length === 0) return null;
  var copy = arr.slice(),
    arg = Array.prototype.slice.call(arguments);
  arg.shift();
  Array.prototype.splice.apply(copy, arg);
  return copy;
}

async deletePost(index:number){

  const pre_posts=this.posts
  this.posts=this.splice(pre_posts,index,1)
  
  const toast = await this.toastCtrl.create({
    message:`削除されました`,
    duration:3000,
    // header: 'Toast header',
    // message: 'Click to Close',
    // position: 'top',
    buttons: [
      // {
      //   side: 'start',
      //   icon: 'star',
      //   text: 'Favorite',
      //   handler: () => {
      //     console.log('Favorite clicked');
      //   }
      // }, 
      {
        text: '元に戻す',
        role: 'cancel',
        handler: () => {
          // console.log(deleate_post)
          // this.posts.push(deleate_post);
          console.log('キャンセルしました');
          this.posts=pre_posts;
        }
      }
    ],
    
  });
  await toast.present();

}
```
突然「シングルサインオン（ＳＳＯ）を検討して」と言われたら－第１回

# はじめに

### 本記事シリーズの位置付け

上司やお客様から突然「シングルサインオン(SSO)を検討して」と言われた場合、どうしますか？
いずれ弊社（オープンソース・ソリューション・テクノロジ株式会社）のような専門ベンダに連絡するとしても、
その前に、ベースの知識を得ておくためにWeb上で情報を探してみるのではないでしょうか。

シングルサインオン(SSO)という分野は、アプリ開発の分野に比べると関わっている人が
少ないということもあり、初めての人向けの纏まった＆最新化された情報というのは
中々見つけづらいものかな…と思っています。
少なくとも、私がシングルサインオンを扱い始めた際は、わりと苦労しました。

というところで本記事シリーズでは、SE様のようにシングルサインオンを導入なさる側の皆様を意識し、
ベース知識を得るための情報源となるべく執筆していきたいと思います。
もし記事をお読みくださったら、ベンダ候補として弊社も加えていただけますと嬉しいです。

### 今回のお題

まずは何より、お客様や社内の皆様に意義を語る必要があったりしますよね。
というわけで、この第１回目の記事では、なぜシングルサインオン化すべきかについてざっくり書いてみます。

# なぜシングルサインオン化すべきか

Before ⇒ After の形で、なぜシングルサインオン化すべきかを書いてみます。

### Before（シングルサインオン化されていないと…）

シングルサインオンする前の姿、つまりユーザが各アプリケーションへ個別にサインオンする形は、様々な視点で問題があります。

| # | 視点 | 内容 |
|:---|:---|:---|
| 1 | ユーザビリティ | アプリ毎にログイン作業をするのはユーザにとって負担になる。アプリ毎に異なるパスワードポリシだったりするとさらに辛いことに…。 |
| 2 | セキュリティ | アプリケーション毎にログイン処理を開発した場合、その分セキュリティ脆弱性の存在可能性も増えてしまう。仮に１つのアプリの脆弱性でパスワードが漏洩し、それが他アプリへのリスト攻撃の引き金になったりすると酷い状況に…。| 
| 3 | コスト | アプリケーション毎にログイン処理を開発した場合、その分開発やメンテナンスコストがかかる。上記したようなセキュリティ問題を発生させないための開発・テストのためには高いコストがかかる…。 |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316192/8b8e8076-e2b4-b96d-7b7b-6c746e76edf7.png" width=80%>


### After（シングルサインオン化された姿）

シングルサインオン化された姿では、以下のように問題が解消されます。

| # | 視点 | 内容 |
|:---|:---|:---|
| 1 | ユーザビリティ | 一度ログインすれば、認証連携済みのアプリ群を全部利用できるので楽。 |
| 2 | セキュリティ | シングルサインオンサーバのログイン実装を使う事で、高いセキュリティを確保できる。2段階認証やFIDO2/WebAuthnといった高度な認証方法を採用することでさらにセキュアにできる。 | 
| 3 | コスト | Webアプリケーション側は、シングルサインオンサーバとの認証連携をするのみで認証を完了できる。認証連携も、SAMLのような標準プロトコルのライブラリが出揃ったので、比較的楽に実現可能。 |


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316192/12a35666-d663-8965-3471-c8efae4cdde6.png" width=80%>


# おわりに

今回は、以下のことを記しました。
・本シングルサインオン解説シリーズの位置づけ
・なぜシングルサインオン化すべきか

次回以降、大枠から段々詳細に向かうよう執筆していく予定です。
第28回　JSTQB認定テスト技術者資格 Foundation Level　を受験してみた


## きっかけ
はじめまして。長年接客業をしている者です。プログラミングとは無縁の生活でしたが、ひょんなことからQA業務に関わる機会があり、JSTQBという資格試験があることを知って、2020年2月、受検してきました。
なぜ「受検してきた。」などふんわり書いているかといいますと、QA業務に関わってから、QA部署の方に「青本の４章を読んでみない？」とふんわり声をかけていただいたことが受験のきっかけだからです。
わたくし、もともと趣味が勉強なので、「なるほど、４章を熟読するくらいならいっそ受検してしまおう！」と、難易度も何もまったく分かっていないまま、2020年2月8日の第28回の試験を申し込みました。（最初のフットワークだけはいつも軽い）

## 勉強を始める前に
翔泳社の書籍「ソフトウェアテスト教科書 JSTQB Foundation 第4版 シラバス2018対応」（青本）を購入しました。翔泳社は結構好きです。ORACLE MASTER Bronzeの試験対策もこんな雰囲気の本だったような・・・・。

これまでいろんな試験を受けてきていたので、てっきりこの教科書は試験対策専用で、もっと「初心者向け」というか分かりやすいステップにできるような本も出版されていると思っていたんですよね。

どれどれ、初心者向けのテキストはどこだ、と。。。。。

ところがこの試験ほかに出版されている書籍、ない気配・・・。

困った。

とはいえ、大枚ハタいて申し込んだからには、できれば一発合格したいのであります。
こうなると、「お金を払ってでも、講習会みたいなのを探して参加するかな～」と思ってみてみると、１０万円と、わたしには高額な講座が検索結果にヒット。。。。

うーん。わたしが今まで受けてきた試験とは、ちょっと次元が違うぞと、ここに来てようやく気づきました。
QAの部署の方々は口を揃えて「簡単ですよ」って言うけど、いやいやいやいや。まずまず単語の意味が分からないから。カタカナだらけだし。

## わたしなりの勉強方法
わたしは学ぶ時、書籍にいろんな書き込みをするタイプなので、まずは書籍をまるまる拡大コピー！
いまはPDFでの販売もありますが、９月の発売当初はまだPDF　なかったような・・あったかな？？？

１週間くらいかけて、ひたすらひたすら拡大コピーをしました。MINISTOPはB4までならコピーが一枚５円でお得でした。

で、１章から順番に、スマホを辞書代わりに、ひたすらマーカー引いたり、コメント書いたりしていきました。１０月が一番モチベーションが高く、毎週土日はコワークにこもって書籍を一巡しました。一ヶ月くらいは頑張った！

ひとにもよると思いますが、わたしは一巡目に一番時間をかけます。「きちんと読んだ」感が得られて、身についたつもりになれるからです。

## わたしなりの(つもり)勉強方法
ここからはやるつもりだったのに、モチベーションだだ下がりでやらなかったことを書いておきます。
青本はなぞるようにあと２巡し、合間にネットにある模擬試験を100％解けるまで繰り返す。

はずだったのですが・・・・・

## 結局、正味一ヶ月だけの勉強で受験
模擬問題をやるときに、できれば１章の範囲だけひたすら解くというように、章ごとに徹底していきたかったのです。

ただ、わたしが見つけたサイトは、まんべんなく出題されるタイプだったので、やる気がなくなり、テキストも開く気がなくなり、３ヶ月が過ぎてしまいました。受験票が届いたころのは、そもそも行くか行くまいかという次元までモチベーションが下がってしまっていましたが、受験料２万円！と思うと、当日の問題の様子だけでも見に行こうと、重い腰を上げて受験だけしてきました。

試験会場、有明の空は広かったです。

## The 試験
受検してみた感想は・・・2018対応後最初の試験だったからかもしれないのですけど、「え、なんでこんなに簡単な出題？」と思いました。先に「（つもり）」と書いた部分をきちっと勉強しておけば、一発合格間違いなしです。

とはいえ、試験の３～４ヶ月前に詰め込んだだけの脳では、取れても50点くらいだと思います。
あと２分の１の確率で当たっている問題が合ったとしても合格ラインの６５％は厳しいと思います。
試験が終わったあと、事務局側で配点の調整とかもされるみたいなのでどうなるか分かりませんが・・・・

##最後まで読んでいただきありがとうございました。
次回は試験結果と、差し支えない範囲で感想を書こうと思います。
その次は夏の受験に向けてまた何か書いていこうと思います。

be continued
Dockerコマンド自分用メモ

dockerfileをビルドしてイメージを作成

```
docker-compose build
```

コンテナの起動(イメージがない場合は構築も)


```
docker-compose up -d
```

コンテナの停止

```
docker-compose stop
```
コンテナを停止して削除

```
docker-compose down
```
実行中のプロセス確認

```
docker ps
```
プロセス確認

```
docker ps -a
```
コンテナ全削除

```
docker rm -f `docker ps -a -q`
```
イメージ確認

```
docker images
```
イメージ全削除

```
docker rmi `docker images -q`
```
コンテナin

```
docker exec -it hogehoge bash
```
[Chrome Developer tool] Networkでpost parameterでリクエストを確認する

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#network のrequest を確認する！

1: Network
2: Allを選択する
3:「Name」に表示されたファイル名をクリック
4:「Headers」を選択
5:「Headers」の中の一番下の「Request Payload」の部分で、パラメータを確認できる！

![Screen Shot 2020-02-18 at 4.32.56 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/26a568a6-3f71-1460-fd1f-9d585af7e0c6.png)

#参考記事
・[ChromeデべロッパーツールでPOSTされたパラメータの中身を確認する](https://www.tsukimi.net/chrome-developer-tools_post.html//)
・[Chromeデベロッパー・ツールを使ってヘッダー情報を確認する](http://dev.blog.fairway.ne.jp/chrome%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%83%BB%E3%83%84%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E6%83%85%E5%A0%B1%E3%82%92//)
【記事一覧】＃0 Webディレクター見習いが知識ゼロからSQLを学ぶ

こんにちは、はじめまして! saku-chanです!
このアカウントは、社会人1年目のWebディレクター見習い(初心者)がSQLを学ぶ成長記録になっています。
ひよっこから成長する過程を残し、ついでに皆さんからアドバイスを頂けたら良いな! 私と同じように知識ゼロからSQLを始める人の一つの指針になればいいな!という思いで作成しました。
ちなみに、ブログを含め記事などを書いた経験がないため読みづらい部分も多々あるかと思いますが、そこも含めて皆さまアドバイス頂けると嬉しいですmm

##記事一覧
◆随時更新していきます！◆
[＃1【備忘録】](/saku-chan/items/0fb8bc28e34a133344e1)
[＃2【SELECT句とFROM句】](/saku-chan/items/673d910d708a985f1f5b)
[＃3【集約関数】](/saku-chan/items/71bfa462d8a1384e2965)
[＃4【WHERE句】](/saku-chan/items/9cfe22decee081848772)　
[＃5【GROUP BY句】](/saku-chan/items/951d36e75bfce3fbcb1f)
[＃6【HAVING句】](/saku-chan/items/30de684ae6d0d8aae084)
[＃7【ORDER BY句とLIMIT句】](/saku-chan/items/c5970e6af275a00798fc)
Let's Encryptから発行した証明書を更新した履歴

# 証明書の更新が切れた
Let's Encryptの有効期限は60日なので更新しないと有効期限は切れます

## 更新に使ったコマンド
環境
OS: CentOS v6.10

```bash
./certbot-auto renew --force-renew
```

実行したところエラーが出て更新が出来ない。
※エラーを既に消してしまったため詳細はわからないが「pythonのバージョンが2だったので、３以上に上げて欲しい」というような内容だった。

## pyenvでpython3をインストール

現時点でのPythonのVersionが、3.8.1だったのでそれのインストールを試みるが、下記のエラーがでる。

```bash
$ pyenv install 3.8.1                                                                                                    [17:46]
Downloading Python-3.8.1.tar.xz...
-> https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tar.xz
Installing Python-3.8.1...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (CentOS release 6.10 (Final) using python-build 1.2.16-5-g7097f82)
```

下記を見ろと書いてあるので、URLにアクセスしてこのエラーを検索。
https://github.com/pyenv/pyenv/wiki/Common-build-problems

※CentOS v6ではPython 3.7以降は入らないようだ。

ということで、v3.4.3をインストール

```bash
$ pyenv install 3.4.3
Downloading Python-3.4.3.tar.xz...
-> https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tar.xz
Installing Python-3.4.3...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?
Installed Python-3.4.3 to /home/kawakami/.pyenv/versions/3.4.3
```

インストール出来た。

```bash
$ pyenv versions                                                                                                           [18:01]
* system (set by /home/kawakami/.pyenv/version)
  3.4.3
```

## Pythonのバージョンを変更

```bash
$ pyenv global 3.4.3
$ pyenv rehash
$ pyenv versions                                                                                                           [18:02]
  system
* 3.4.3 (set by /home/kawakami/.pyenv/version)
```

### 証明書の更新

証明書の更新を再度実行。

```bash
$ ./certbot-auto renew --force-renew
...
Problem binding to port 80: Could not bind to IPv4 or IPv6.. Skipping.
```

WebServerを止めないと行けないようだ

```bash
$ sudo service nginx stop
$ ./certbot-auto renew --force-renew
...
(success)
```

やっと更新できた！
kotlinで時間を扱うならDurationが便利

時間をLongで表していると、単位が何なのかわからなくなって困ったことはありませんか？
そんな時は `Duration` を使うと便利です

[Duration](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-duration/index.html)



```kotlin
    // 作成
    val duration = System.currentTimeMillis().milliseconds

    // Doubleで取得
    val hour = duration.inSeconds

    // Longで取得
    val milliSec = duration.toLongMilliseconds()

    // Intで一括取得
    duration.toComponents { days, hours, minutes, seconds, nanoseconds ->
        // 使う値
    }
```

これならもとの値が何であれば、同じ単位として使うことができます。便利ですね。
[GitHub] 行の変更履歴（blame）から対応する PR を探す

## Tl;Dr
GitHub上の Blame からリンクをホバーすると対応する PR が見つかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/7586ba8f-d022-d7d7-eb2a-676fdecb4e97.png)

~~たぶんこれが一番早いと思います。~~

## その修正をした PR を探したい
現代において、GitHub などのホスティングサービスによる『Pull Request』を利用した開発は非常に一般的になっている。

Git では標準で`git blame`と呼ばれる、あるファイルの特定の行を修正した『コミット』を特定する仕組みが備わっており、その特定した『コミット』のメッセージや修正内容を確認することで、どういった意図で修正されたのか分かる。

```text
$ git blame bin/deploy-firebase.sh
1c4cc183 (Yusuke Hosonuma 2018-12-08 02:50:47 +0900  1) #!/bin/bash -xe
1c4cc183 (Yusuke Hosonuma 2018-12-08 02:50:47 +0900  2)
1c4cc183 (Yusuke Hosonuma 2018-12-08 02:50:47 +0900  3) cd `dirname $0`
…
```

左端に表示されている`1c4cc183`というのがコミットSHA（の短縮形）で、 `git show`コマンドを利用すればそのコミットの詳細な内容を確認できる。

```text
$  git show 1c4cc183
commit 1c4cc1837fe653e9101d0a9cf19068d747fe27e8
Author: Yusuke Hosonuma <tobi462@gmail.com>
Date:   Sat Dec 8 02:50:47 2018 +0900

    add: deploy script for firebase

diff --git a/bin/deploy-firebase.sh b/bin/deploy-firebase.sh
new file mode 100755
index 0000000..eaa1a7a
--- /dev/null
+++ b/bin/deploy-firebase.sh
@@ -0,0 +1,34 @@
+#!/bin/bash -xe
+
+cd `dirname $0`
…
```

しかし、前述したように『Pull Request』による開発が一般化したことで、修正の単位としてはむしろ『コミット』よりも『Pull Request』の方が分かりやすくなっていることが多い。また、PR でのディスカッションによる『意思決定』を確認したいことも非常に多い。

## GitHub 上で対応する PR を探す
ローカルの`git log`から対応するPRを探す方法もあるし、スクリプト一発で特定する方法もすでにナレッジとして記事化されていたと思う。

しかし、そうした手間を掛けずとも GitHub の blame 機能から探すこともできる。

### ファイルを絞り込む
該当リポジトリの画面でキーボードの **T** キーを押すと、インクリメンタルなファイルの絞り込みが行える。
![47CB0565-FF0C-4B3B-9AFF-CFF9566024DD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/2af49660-044c-c8c6-1973-bfd2b0d1db50.png)

もちろん検索機能を活用してもよいし、ディレクトリツリーから探しても良いが、ファイル名が事前に分かっているのであれば個人的にはこれが一番早いように感じる。

### Blame を表示する
ファイルを選択したら、右上に配置されている **Blame** ボタンから Blame を表示できる。
![11C6090F-B4AF-499E-8154-B7A41070F03A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/d7dfaf77-c173-7d2e-4ca3-007cd64d8c46.png)

### PR へのリンクを探す
Blame が表示されたら、冒頭のようにリンクにフォーカスすると対応する PR へのリンクが表示される。
![C267E4AB-3003-46A0-862E-F8023FD62582.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/27b45435-fe95-b132-0c02-18f9d1283aae.png)

## 過去の Blame を表示する
これは Git にも備わっている機能だが、同じ行が複数のコミットに渡って修正されている場合、過去の Blame も表示することができる。

GitHub の Blame 画面でそれに該当する場合、行番号のルーラの左側にアイコンが表示され、そこをクリックすると過去の Blame が表示できる。
![F3F5B1B0-F2A6-43B4-A933-999FF19BCB6C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/012a9e78-c405-29c7-3239-e6a7063f11de.png)

この操作は再帰的に行え、最古のコミットまで辿ることができる。

## 終わりに
Git は非常に多機能であると言われ、実際にそうであり本当に使いこなすのには長い時間を要すると個人的には感じる。

しかし、GitHub も着実に進化しており、最近では『コードジャンプ機能』や『刷新された Notification 画面（beta）』など、かなりのタスクが GitHub 上だけで完結できるようになりつつあるとも感じる（もちろんすべてとは言わない）。

*GitHub の機能も使いこなして快適な開発ライフを。*
firestore データインポート、エクスポート

# 概要

firestore のデータインポート、エクスポート手法メモ
*後日ちゃんと書きます。

## やりたいこと

firestoerにたまったデータを別プロジェクトのfirestoreに展開したい

下図のようにProjectAのFirestoreのバックアップをStorageに作成し、それを展開先のProjectBのFirestoreにインポートする形で実行します。

<img width="787" alt="スクリーンショット 2020-02-18 16.41.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252067/b3a8e213-6d55-9643-d36e-096c452083c8.png">


## 大まかな手順

手順を見ると大したことない操作ですが、重要なのは2の適切な権限を設定することです。
あと、無料プランではインポート、エクスポートできません。

1. バックアップするfirestoreと同じリージョンに storageを用意する
2. storageに適切な権限を設定する
3. gcloud をインストールする
4. データをエクスポートする
5. データをインポートする

## 1.プロジェクトのプラン変更とstorageの用意

取得するバックアップの保存先と、保存したバックアップを展開する先のプロジェクトどちらとも有料プランに変更します。

バックアップ（エクスポートしたデータ）を保存する場所を用意しておく。フォルダとかを用意しておけば大丈夫です。


## 2.権限の設定

次にバックアップを展開するプロジェクトのサービスアカウントをバックアップ元のプロジェクトにメンバーとして追加し、権限を設定します。

google cloud platform コンソールを開き、バックアップするfirestoreプロジェクトを選択します。

ナビゲーションメニューからリソースを管理を選択します。

バックアップ元のプロジェクト名にチェックを入れ、右ペインに表示される「メンバーを追加」をクリック。
サービスアカウントを入力し、役割を選択から以下の役割を選択し、「保存」を押します。

- Cloud Database インポート/エクスポート管理者
- ストレージ管理者

## 3. gcloudをインストールする　

インストール＆設定は下を参照

https://cloud.google.com/sdk/docs/quickstarts?hl=ja

まずは、gcloud のプロジェクトをエクスポートするfirestoreのプロジェクトに設定します。

```
gloud config set project [project_id（A)]
```

## 4. データをエクスポート

以下のコマンドを実行します。

```
gloud firestore export gs://[BUCKET_NAME]/[export-name]
```
BUCKET_NAMEはstorageの名前、export-nameはバックアップファイルのフォルダ名を設定することができます。


## 5. データをインポート

次にgloudのプロジェクトをバックアップ展開先のプロジェクト名に変更します。

```
gloud config set project [project_id（B)]
```

変更したら、データをインポートします。

```
gcloud firestore export gs://[BUCKET_NAME]/[export-name]
```

作成されたデータのフォルダ名までのパスを設定します。

これで、データがインポートされます。
ちなみに既にデータが入っていた場合は追加でインポートされます。
同じIDは上書きされるのかな... 後ほど確認して記事を更新します。
2台以上のArduino同士でシリアル通信

#説明
親機と子機1～5があって、親機から、1.2.3.4.5の順でシリアル信号が送信され、それを受信した子機が自分の番号のときにLEDを光らせます。つまり、親機一台で子機を制御していることになります。
![DSCPDC_0001_BURST20200218161047515.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421600/858ba04c-a65d-7098-3da8-482d167baefa.jpeg)

#接続方法
親機の ”→RX” 端子を子機の ”←TX” 端子につながるようにブレッドボードを上手い事します。...以上。
#受信側
```c:serial_receive.ino
int No = 1; // 個体番号
int led = 13; // 13番ピンをledに設定

void setup(){
  Serial.begin(9600); // シリアル通信の設定
  pinMode(led, OUTPUT); // ledをアウトプットに設定
}

void loop(){
  while(Serial.available()){ // 受信データがある時
    byte s = (byte)Serial.read(); // 信号を読み取り、"s"に収納
    if(s == No){ // 読み取った信号が自分の番号か？
      digitalWrite(led, HIGH); // LEDを点灯
    }
    else{ // そうでなければ
      digitalWrite(led, LOW); //LEDを消灯
    }
  }
}
```

#送信側
```c:serial_Serve.ino
int led=13; //13番ピンをledに設定
int sw=3; //スイッチを3番ピンに設定
int g=0; //モード番号
int c=0; //for文用

void setup(){
  Serial.begin(9600); //シリアル通信の設定(子機と同じ番号で)
  pinMode(led,OUTPUT); //ledをアウトプットに設定
  pinMode(sw,INPUT_PULLUP); //スイッチをインプットに設定
}
//INPUT_PULLUP：プルアップ抵抗をつけなくても、これでチャタリングを回避できます

void loop(){
  if((digitalRead(sw)==LOW)and(g==0)){ //モード1を選択
    g=1;
    digitalWrite(led,HIGH);　//モードを選択したらLEDが光ります。
    delay(500);
    digitalWrite(led,LOW);
  }
  else if((digitalRead(sw)==LOW)and(g==1)){ //モード0を選択
    g=0;
    digitalWrite(led,HIGH); //モードを選択したらLEDが光ります。
    delay(500);
    digitalWrite(led,LOW);
  }
  else if(g==0){ //モード0を実行
    for(c=1; c<=5; c++){
      Serial.write(c);
      delay(100);
    }
  }
  else if(g==1){ //モード1を実行
    for(c=1; c<=5; c++){
      Serial.write(c);
      delay(100);
    }
    for(c=5; c>=1; c--){
      Serial.write(c);
      delay(100);
    }
  }
}
```
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">複数のArduinoでシリアル通信をしてみました。<br>詳細はQiitaへ<a href="https://t.co/OlitOjlqk2">https://t.co/OlitOjlqk2</a> <a href="https://t.co/iky6Zn1UrX">pic.twitter.com/iky6Zn1UrX</a></p>&mdash; Qiita@yusuke005 (@Qiitayusuke0051) <a href="https://twitter.com/Qiitayusuke0051/status/1229696022185594881?ref_src=twsrc%5Etfw">February 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#終わりに
これで、たった2本のケーブルで複数の子機を制御できるというわけです。
モータドライバとか使って相互通信できるようにしてみたいですね。
PyEphemで宇宙がヤバい

# はじめに

月の位置や月齢を取得したいなーと思って最初は安直にスクレイピングを考えていたんだけど、PyEphemというとっても便利なライブラリがあることを知った。
qiitaには1個もPyEphemのタグがついた記事がないので書いときます。

# PyEphemについて
- https://pypi.org/project/ephem/ (ソース)
- https://rhodesmill.org/pyephem/ (リファレンス)

詳しくはリファレンスを読んでもらうこととして、ここでは簡単な使い方をどうぞ。

```python
import ephem
import datetime
from math import degrees as deg

# Body(天体)クラスのインスタンスを作成。

moon = ephem.Moon()

# Observer(観測者)クラスのインスタンスを作成。

shinjuku = ephem.Observer()
shinjuku.lat = '35.6846'
shinjuku.lon = '139.7106'
shinjuku.elevation = 60
shinjuku.date = datetime.datetime.utcnow() # 任意の年月日の位置を求められる

# 観測者から見た天体を計算。

moon.compute(shinjuku)
print(deg(moon.alt)) # 20.88288333068003(地平線からの仰角(degで度に変換))
print(deg(moon.az)) # 218.0421642706897(北を0度とした方角)
print(moon.moon_phase) # 0.2820702016225599(月相)
print(shinjuku.date - ephem.previous_new_moon(shinjuku.date)) # 24.138740752328886(月齢)
```

上記を実行すると、新宿における現在の月の位置や満ち欠け(南南西に高さ20度の三日月)を教えてくれるわけです。
簡単で便利過ぎワロタ。

# 人工衛星の位置もわかる、、、だと！？

JAXAやNASAなどの軌道情報提供サービスが提供するTLE(Two Line Element)というデータを用いて人工衛星の位置なども計算できる。(pyorbitalでも可能)

国際宇宙ステーション(ISS)のTLEは、
https://spaceflight.nasa.gov/realdata/sightings/SSapplications/Post/JavaSSOP/orbit/ISS/SVPOST.html
の `TWO LINE MEAN ELEMENT SET` というセクションに書かれている。(予測含めたくさんある)
値は軌道変更などにより変動するため、適宜取得する必要がある。
2020/048/17:15:00.000 (2月17日? 17時15分UTC?)時の値は、

```text
ISS
1 25544U 98067A   20048.52024880  .00016717  00000-0  10270-3 0  9000
2 25544  51.6378 225.5202 0004926 282.0303  78.0295 15.49172297 13304
```

上記をもとに現在(shinjukuに設定した時刻)のshinjukuから見たISSの位置を計算してみる。

```python
line1 = 'ISS'
line2 = '1 25544U 98067A   20048.52024880  .00016717  00000-0  10270-3 0  9000'
line3 = '2 25544  51.6378 225.5202 0004926 282.0303  78.0295 15.49172297 13304'
iss = ephem.readtle(line1, line2, line3)

# shinjukuから見た位置
iss.compute(shinjuku)
print(deg(iss.alt)) # -51.61249863302519
print(deg(iss.az)) # 142.92199525046195

# ISSがいる位置
iss.compute(datetime.datetime.utcnow())
print(deg(iss.sublat)) # -50.990213758123666
print(deg(iss.sublong)) # -139.8713732199458
print(iss.elevation) # 433325.5
print(iss.eclipsed) # True
```

shinjukuから見ると南東の地平線の下51度くらいの位置、ニュージーランドの東の上空43万メートルにいて、食のようですね。

<img width="348" alt="iss.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287199/2f6ad09e-8812-d4cd-dff7-b5447162b8af.png">
↑ここら辺

# おわりに

うちではラズパイで動かしているtwitterやLINEのbotで月の情報を表示するのに利用しています。

<img width="270" alt="pt2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287199/ac872cd4-d049-6cec-10db-c34fe8746ec3.png">
毎時、自宅周辺の天気、ラズパイのCPU温度、月齢を投稿するTwitterボット。

<img width="319" alt="pl2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287199/313b7c83-2644-7ae2-4178-4e74890606d2.png">
月って聞くと月齢と位置を教えてくれるLINEボット。

# 追記
https://qiita.com/floatnflow/items/810c2c7664831efcb109

にも書いたように、上で紹介している軌道情報提供サービスは2021年2月にサイトごと終了してました。

https://www.nasa.gov/feature/spaceflightnasagov-has-been-retired/

他の同様なサービスとしては

 https://celestrak.com/NORAD/elements/stations.txt

などが使えました。(実際のISSの軌道で確認済み)
Lambda内でpythonを使用してCloudWatchに新規のロググループを生成する方法

##概要
AWSのCloudWatchに新しいロググループをつくる。
その処理をLambdaでできないかを検証してみた。

#####単純にロググループを生成する
```python:make
import boto3

logs = boto3.client('logs')
response = logs.create_log_group(
 logGroupName = "log/group/name"
)
```
#####ログの保持期間を付与
```python:make
response = logs.put_retention_policy(
# 付与したいロググループ名
  logGroupName = "log/group/name",
# 保存期間(日)を設定
  retentionInDays = 14
)
```

###参考にしたサイト
[Boto 3 DocumentationのCloudWatchLogs]
(https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html#CloudWatchLogs.Client.create_log_group)
Rails 日時フォーマットにI18nを使うときはレコード数に注意

[追記] 以下の内容ですが、違った可能性があります。ja.yamlの初回読み込みに時間がかかり、２回目以降はキャッシュが使われ早くなるという可能性があります（未検証）
[解決] 初回ロードに時間がかかるだけで、2回目以降は問題ありませんでした。I18nは便利なのでどんどん使っていきましょう


日付・日時のフォーマットにI18nを使用していたところ、処理時間がだいぶかかってしまいました。
そこで

- I18n#l
- Time#to_s
- Time#strftime

の処理時間を調べてみました。
I18nに関しては[こちら](https://qiita.com/jnchito/items/831654253fb8a958ec25)

#測定
```ruby
time = Time.now
sum_i18n = 0
sum_to_s = 0
sum_strftime = 0

# I18n#lの測定
100.times do
  s = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  I18n.l(time)
  e = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  sum_i18n += e-s
end

# Time#to_sの測定
100.times do
  s = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  time.to_s
  e = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  sum_to_s += e-s
end

# Time#strftimeの測定
100.times do
  s = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  time.strftime("%a %b %d %H:%M:%S %z %Y")
  e = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  sum_strftime += e-s
end
```


#結果

|  |I18n#l [s]  |Time#to_s [s]  |Time#strftime [s] |
|---|---|---|---|
|1回目  |0.8247481999860611  |0.002034699995419942  |0.0011146999459015206  |
|2回目  |0.9185206999682123  |0.0023584999435115606  |0.0014091000193729997  |
|3回目  |0.8858548999996856  |0.0011633000249275938  |0.0014278999879024923  |

I18nは圧倒的に遅いですね。
レコード数が多い時はTime#strftimeを使った方が良さそうです。
serverless Referenceメモ（随時更新）

### 目的
serverless.ymlにてリソースを作成する際の定義方法のメモです。

[Serverless.yml Reference](https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/)

# リソース用の作成されるIAMロールにサービスポリシーを追加する
Athenaのアクセス権限を設定する場合は、Obejectへのアクセスと、Athena用のポリシーを設定する。

```yml
iamRoleStatements:
  - Effect: 'Allow'
    Action:
      - 'ssm:Get*'
    Resource: '*'
  - Effect: Allow
    Action:
      - s3:putObject
    Resource: "arn:aws:s3:::${self:custom.S3Bucketname}/*"
  - Effect: Allow
    Action:
      - s3:ListBucket
      - s3:GetObject
    Resource:
      - "arn:aws:s3:::${self:custom.S3Bucketname}"
      - "arn:aws:s3:::${self:custom.S3Bucketname}/*"
iamManagedPolicies:
  - arn:aws:iam::aws:policy/AmazonAthenaFullAccess
  - arn:aws:iam::aws:policy/service-role/AWSQuicksightAthenaAccess
```
# 作成したIAMRoleのARNを取得する

```yml
            Credentials: 
              Fn::GetAtt: 
                - S3AccessRole
                - Arn
```
参考：[AWS::IAM::Role](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#aws-resource-iam-role-return-values)
Backtraderで「TkAggを使用できない」というエラーが出てプロットできない場合の対処法

Pythonバックテスト用ライブラリのbacktraderで、以下のようなエラーが出た場合の（一時しのぎの）解決策です。

backtraderにてバックテストの結果をcerebro.plot()とする際に、環境によっては、

    ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running

のようなエラーがでることがあります。私は、google colaboratoryを使っている場合に直面しました。

## エラーの内容：plotモジュールをimportするとき、matplotlibのbackendとしてTkAggが使われてしまう
`backtrader/plot/__init__.py`にかかれているとおりですが、plotモジュールを使おうとすると、`matplotlib.use('TkAgg')`が実行されてしまうのがエラーの原因です。

もし、使用環境でTkAggを使えれば問題はありませんが、colaboratoryのjupyter notebookはheadlessモード(--no-browser)で動作しているため、backendとして（例えば）aggを設定する必要がありました。

matplotlibのbackendとして、単に他のものを使うだけなら、
`cerebro.plot(use="agg")`
のように対応できそうですが、そもそも、TkAggを利用できない環境では、モジュールのimportの段階でエラーがでます。

Cerebroクラスのplotをオーバーライドしようにも、`matplotlib.use('TkAgg')`は、`__init__.py`で読み込まれてしまうため、回避できません。

## 解決策：`__init__.py`を書き換えて、別のライブラリとしてimportする
苦肉の策として、backtraderのリポジトリをforkして、`matplotlib.use('TkAgg')`を削除するという手を使いました。

```python:backtrader/plot/__init__.py

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

try:
    import matplotlib
except ImportError:
    raise ImportError(
        'Matplotlib seems to be missing. Needed for plotting support')

# ここの部分を削除した
# else:
#    matplotlib.use('TkAgg')


from .plot import Plot, Plot_OldSync
from .scheme import PlotScheme

```

このようにしたフォークリポジトリをgithubにあげています。
私がcolaboratoryでbacktraderを使うときには、

    pip install git+https://github.com/yuki-data/backtrader@dev/ito/remove-tkagg-import

としています。colaboratoryでbacktraderを使って困った方は、是非どうぞ。

**よりスマートな解決策をコメントしていただけると大変助かります。**
lambda内でパラメータストアから値を取得する方法(python使用)

#概要
AWSのlambdaでパラメータストアの値を取得する方法をまとめる。

#実際のコード
```python:get
# 1. boto3をインポート
import boto3

ssm = boto3.client('ssm')
# 2. get_parameterメソッドでパラメータを取得
response = ssm.get_parameter(

# 3. パラストに登録されているキー名を設定
            Name = '/add/company-codes',
# 4. 値のみ取得したい場合はWithDecryption = False
   # 全ての情報を取得したい場合はWithDecryption = True
            WithDecryption=False
        )
value = response['Parameter']['Value']
```

##boto3で使用できるメソッドについて

ここにいくつかのメソッドが載っています↓
(上で使用しているget_parameterも)

[Boto 3 Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)