OmniAICreator/Qiita-1.07M huggingface dataset:
「pythonで素因数分解」を参考にSymPy LiveとWolframAlphaとgoogleでやってみた。

(オリジナルポスト)

https://qiita.com/roadto93ds/items/e14379b0e2e75c92fabf

(参考)

https://qiita.com/mrrclb48z/items/0a740d35f2773b8445ba

##SymPy Liveで

https://live.sympy.org/	

入力
print (factorint(80))
出力
{2: 4, 5: 1}

##WolframAlphaで

https://ja.wolframalpha.com/input/?i=80%E3%81%AE%E7%B4%A0%E5%9B%A0%E6%95%B0%E5%88%86%E8%A7%A3&lang=en

##googleで

https://www.google.com/search?client=ms-android-huawei&sxsrf=ALeKk00p-gnGRdkL4ikzESmVjz1pQP7O5Q%3A1607769156185&ei=RJzUX9zKCoGTr7wP656RwAQ&q=80%E3%81%AE%E7%B4%A0%E5%9B%A0%E6%95%B0%E5%88%86%E8%A7%A3&oq=80%E3%81%AE%E7%B4%A0%E5%9B%A0%E6%95%B0%E5%88%86%E8%A7%A3&gs_lcp=ChNtb2JpbGUtZ3dzLXdpei1zZXJwEAMyBggAEAQQJTIFCAAQzQI6BwgAEEcQsAM6BwgjEOoCECdQ3hVYnzBg6kBoAXAAeAOAAfoEiAHsEpIBCzAuMS4yLjMuMC4xmAEAoAEBoAECsAEPyAEIwAEB&sclient=mobile-gws-wiz-serp
CentOSで日付・曜日・時間を指定して定期実行したいんだよなあ

#前の記事
[CentOSで定期（繰り返し）実行したいさー](https://qiita.com/waokitsune/items/6197d4f74098ecd9280c)

この記事ではシェルスクリプト作成、systemd作成、timer作成を1回やったことあるから大体要領分かるよ、な人向けです。
やったことねえ！やったけど忘れた！な人（自分も含めて）は上記のリンクをクリック！


#毎日特定の時間に実行
シェルスクリプト。
テキストにただ書き込むだけの簡単なやつ。
（権限付与を忘れずに…）

```sh:/cocoa.sh
#!/usr/bin/bash
echo `date` oneetyannnimakasenasa-i >> /chino.txt
```

シェルスクリプトをキックするやつ。

```sh:/etc/systemd/system/cocoa.service
[Unit]
Description=cocoa

[Service]
Type=simple
ExecStart=/cocoa.sh

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

ここからが本題！
シェルスクリプトをキックするやつを起こすタイマー。

```sh:/etc/systemd/system/cocoa.timer
[Unit]
Description=cocoa

[Timer]
Unit=cocoa.service
OnCalendar=*-*-* 9:55:00

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

タイマー起動！

```sh:コマンド
systemctl enable cocoa.service
systemctl enable cocoa.timer
systemctl start cocoa.timer
```

さて9:55を過ぎた後にchino.txtを開くと…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9507cab1-aff2-d014-3db1-8f2b5dab9dcf.png)
ちゃんと書き込まれてますです。


#OnCalendarってどんなふうに設定するん？
一番細かい指定方法を見るのが分かりやすいと思います。
**毎月1日～4日の月 or 火曜12:00に起動** という指定です

```sh:
OnCalendar=Mon,Tue *-*-01..04 12:00:00
```

* ```Mon,Tue``` = 月曜と火曜
* ```*-*-``` = 年と月は指定しないよ（ワイルドカード）
* ```01..04``` = 1日～4日（ ```..``` で範囲指定ができる）


#OnCalendarは複数指定できる
**毎月1日～4日の月 or 火曜に起動**
ただし、 **月曜は12:00に起動、火曜は13:00に起動** という指定です。

```sh:
OnCalendar=Mon *-*-01..04 12:00:00
OnCalendar=Tue *-*-01..04 13:00:00
```

#指定したタイミングに丁度電源落ちていて実行できなかった時
下記のように ```Persistent=true``` を記載しておくと **OS起動時に実行漏れしてたやつは即実行** してくれます。

```sh:
OnCalendar=Mon *-*-01..04 12:00:00
Persistent=true
```
仮にちょっと長い間電源が落ちてるなどして、いろんなバッチ処理が溜まっていると、OS起動と同時にそいつらが一斉に走り始めちゃいます。
その辺の考慮漏れに注意です。


#蛇足
今回もDocker上のCentOS8で検証しました。

**『毎日〇時に再起動してるから起動後〇時間後の指定でいいや』** だと、イレギュラーな再起動をした時に想定外なタイミングで実行されちゃいます。
イレギュラーな作業をしてる時って他のことって頭から抜けちゃってるんだよね(´・ω・`)
なので、相対的な指定ではなく、時間を決め打ちした指定の方が良いかと思います。


#参考サイトさん
[https://wiki.archlinux.jp/index.php/Systemd/タイマー](https://wiki.archlinux.jp/index.php/Systemd/%E3%82%BF%E3%82%A4%E3%83%9E%E3%83%BC)


#バージョン
Windows10 Pro バージョン1909 OSビルド19042.685
Docker Desktop:3.0.0（50684） Engine:20.10.10 Compose:1.27.4
CentOS Linux release 8.2.2004 (Core)
Qiitaではじめるアウトプットチャレンジ

## はじめに
場面に合わせてなんとなく乗り切ってしまったがゆえに、地盤なしの浮いている状態で迷走した2年。。。
そんななか出会った「[Qiitaを1年間ほぼ毎日投稿した話と転職の話](https://qiita.com/miriwo/items/681ff186f4d6f9057135)」がかなり心にささり、まずは飛び込むことからはじめるアウトプットチャレンジを始めます

■経歴
Web制作全般 → Webディレクター → 開発ディレクター
→ フロントエンド 👈イマココ


## チャレンジルール（2020/12/12時点）
何事も習慣化できれば、呼吸するたびに成長する超人になる（はず）
超めんどくさがり＆超言語化が苦手なので、まずは簡単なルールでトライ
### 毎日1行
「めんどくさい横着人の極み」なのでまずはキーボードに手を置く

* PCの前に座る
* エディタを開く
* 1行書く

### 毎日言語化
頭の中にしまわずに、まずテーブルにだしてみる

* Twitterにあたまにあること出してみる
* 数日分の頭の中をQiitaでまとめる

### ツール
Twitter / Notion / Github

## 経過観察

#### 初日
まずはJavascriptの基礎振り返りからスタート
[JavaScript コードレシピ集](https://www.amazon.co.jp/JavaScript-%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AC%E3%82%B7%E3%83%94%E9%9B%86-%E6%B1%A0%E7%94%B0-%E6%B3%B0%E5%BB%B6/dp/4297103680)
VSCodeで設定しておくと便利なこと

VSCodeの環境構築する上で、便利なことを色々調べたのでまとめてみます。

# 環境
MacOS Catalina 10.15.7

# 目次
[VSCodeダウンロード](# VSCodeダウンロード)
[設定を開く](# 設定を開く)
[1. 日本語化](#1. 日本語化)
[2. コード整形](#2. コード整形)
[3. エンコーディングを変更・自動判別](##3. エンコーディングを変更・自動判別)

# VSCodeをダウンロード
1. 公式サイトにいき、ダウンロードページからMac版をダウンロード
2. ターミナルを使ってダウンロード(下記参照)

```
$ brew cask install visual-studio-code
Updating Homebrew...
(( 略 ))
==> Downloading https://update.code.visualstudio.com/1.51.1/darwin/stable
==> Downloading from https://az764295.vo.msecnd.net/stable/e5a624b788d92b8d34d13
######################################################################## 100.0%
==> Installing Cask visual-studio-code
==> Moving App 'Visual Studio Code.app' to '/Applications/Visual Studio Code.app
==> Linking Binary 'code' to '/usr/local/bin/code'.
🍺  visual-studio-code was successfully installed!
```  
ダウンロードが完了！

# 設定を開く
(注)日本語になっているのは[1. 日本語化](##1. 日本語化)を参照
1. `Shift + Command / Ctrl + P`でコマンドパレットを開く。
2. 「**setting**」と入力。候補にでてくる**Open User Settings**を選択。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/3e71d316-441f-dea2-8cc1-64da73b776b1.png" width=480px>

左下、歯車アイコンから**設定**を選択することで開くこともできます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/2bd9fb7f-be8f-c68f-c0a9-04f87e67f05a.png" width=320px>

#1. 日本語化
メニューなどの表記が日本語になっているほうが、使いやすくなると思います。
### 拡張機能から日本語パックをインストール
(注)四角形で構成されているアイコンが「拡張機能」です。
1. `Extension`で「**Japanese Language Pack for Visual Studio Code**」と検索。
2. [install]ボタン(緑色)をクリック。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/a27c1d08-4a89-f772-c905-22a3e4964d92.png" width=720px>

### 日本語パックを反映する
1. `Shift + Command / Ctrl + P`でコマンドパレットを開く。
2. 「**config**」と入力。候補にでてくる**Configure Display Language**を選択。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/2d2ac220-58a6-118f-b03e-13ee09f4c235.png" width=480px>
3. [**ja**]を選択。  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/44d743df-e2d2-8345-f8cf-4124cb8456ef.png" width=320px>
4. 再起動を求められるので、再起動すると反映されます。

#2. 自動コード整形
プログラミングで、コード整形を自動でしてくれると助かると思ったときに役立つ機能です。
1. 設定を開く。
2. [設定の検索]で「**formatOn**」と入力。出てくる**Format On Paste・Format On Save**の2つにチェックを付ける。
- FormatOnPaste：コードをペーストしたときに整形します。
- FormatOnSave：ファイルを保存するときに整形します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/a267db7e-2d37-262f-c094-ac6e767164a6.png" width=640px>

#3. エンコーディングを自動判別
VSCodeは、`UTF-8`でエンコーディングします。他の文字コードの場合、文字化けが発生してしまいます。
他の文字コードのファイルを読み込むときに、自動で判別し、エンコーディングするように設定してみましょう。
1. 設定を開く。
2. [設定の検索]で「**file.auto**」と入力。出てくる**Auto Guess Encoding**にチェックを付ける。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/6e274a49-f123-bab9-a57c-e3433d4e94c6.png" width=640px>
#### 参考
[VS Codeでエンコーディングを変更、自動判別するには](https://www.atmarkit.co.jp/ait/articles/1806/01/news051.html)

# おわりに
他にも便利な機能があれば紹介していきたいと思います。
快適なVSCodeライフを送りましょう！
Laravel 外部キーが消せない

##概要

あ、このテーブル、ユーザーIDで管理すると思ったけど違った！このカラム不要やわ！

 $table->dropColumn('user_id'); 

php artisan migrate  ポチーーーーー！！

エラーーー！ファーーーーーwwwww

となったときの対処法です。


##結論
外部キー制約と、インデックスを消してからでないと、カラムは削除出来ない。

```
   public function up()
    {
        Schema::table('items', function (Blueprint $table) {
            $table->dropForeign('items_user_id_foreign');
            $table->dropIndex('items_user_id_index');
            $table->dropColumn('user_id'); 
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('items', function (Blueprint $table) {
            $table->integer('user_id')->unsigned()->index();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 
        });
    }
```

DBから直接消そうとしてもエラーになるそうなので、DB的にそういうものだと覚えました。。。
Macで動画を消しても容量が思ったよりも減らない時の対処方法

ユーザー > ユーザー名 > ライブラリ > ScreenRecordings 　の中に動画が入っているので、そちらを削除すればOK。

スクリーンキャンプチャで動画を撮ると、ScreenRecordingsにも動画が保存されるっぽい。
Unity ML-Agentsでテトリスを学習させてみる


「QualiArts Advent Calendar 2020」 13日目の記事になります。
昨日の12日目の記事は塩塚くんによる[「アセットバリデーション用のBlenderプラグインを作ってみる」](https://yshio.hatenablog.com/entry/2020/12/12/000000)です。興味がある方はこちらもどうぞ。
#はじめに
はじめまして、Unityエンジニアの山下といいます。この記事では、テトリスに対し、Unity ML-Agentsを用いて強化学習をしてみたことについて説明します。
テトリスは、皆さんご存知かと思いますが有名な落ち物パズルゲームです。最近、ぷよテトやテトリス99で遊んでいて自分で遊ぶちょうどいいレベルの相手を作れないかと思い、お題に選んでみました。
以下、自作してみたテトリスの画面。
<img width="25%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121360/6a6e6bb8-1df1-3945-14ac-356b93d1a14e.png">

落下、左右への移動、回転、列消し程度は実装してあります。T-SpinやRENの実装は一旦要らないかと思い、実装してありません。

# Unity ML-Agentsとは
Unity ML-Agentsとは、Unityが提供している機会学習用のフレームワークです。AIに行動の選択肢と現在の状況、適度な報酬を与えることによって学習を行わせ、自動的に操作を行わせることができるようになります。
詳細な内容はこちらの本が日本語で詳しく書いてあるのですが、ML-Agents v0.4当時のものなので少し古いです。Agentの作り方は今でもあまり変わらないので参考になると思います。
[Unity ML-Agents実践ゲームプログラミング](https://www.borndigital.co.jp/book/6702.html)

こちらの記事ではRelease10を使用しました。[Unity ML-Agents Release10](https://github.com/Unity-Technologies/ml-agents/releases/tag/release_10)
また、Unityは2018.4.30f1を利用しました。
この他、pythonの実行環境が必要です。python3.7と、pipでmlagentsパッケージをインストールしました。
# 学習方法の詳細
学習させるに当たって、AIに行わせる操作と、AIに渡す観測情報、報酬を考える必要があります。
まず操作についてですが、基本的なテトリスで行えるアクションは左移動、右移動、下移動、左回転、右回転の5つです。（さらに言うならハードドロップやホールドもありますが今回は省略しています）
移動と回転は別軸として考えても良かったのですが、移動と回転を同時に行わないものとしてアクションは1次元でどれかしか選べないようにしてみました。離散値なのでDiscrete、何もしないを含めて1次元でサイズ6までです。
![スクリーンショット 2020-12-12 18.23.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121360/d6243c51-0960-0a87-63f2-49e64117d9a5.png)

次に観測ですが、テトリスの盤面情報をAIに簡単に渡そうと思って、Visual Observationを使いました。CameraSensorコンポーネントを利用して、画像情報で現在の盤面を渡しています。Unity ML-Agentsではこの他にVector Observationというのがあって、オブジェクトの位置や、回転、盤面等をベクトル情報として渡すこともできます。
![スクリーンショット 2020-12-12 18.26.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121360/1417061e-32dd-7349-f27d-98446166ed6f.png)

最後に報酬です。Agentクラスを継承したTetorisAgentクラスを作り、そこで上記の操作、観測と共に報酬の実装を行います。
列を消したら+1、ゲームオーバーで-1、そして毎ステップごとに-0.001という設定をしました。ゲームオーバーにならずに、列を消せていれば報酬が増えるはずなので、うまくいけばいい感じに列を消してくれそうです。


# 実行
上記の設定で5万ステップほど学習させてみました。
ターミナルで以下のコマンドを実行させると

```
# mlagents-learn config/ppo/tetoris.yaml --run-id=tetris
```
以下のような画面が出てくるはずなので、この状態でUnityを実行するとUnity側で勝手に学習を進めてくれます。
![スクリーンショット 2020-12-12 18.39.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121360/376c24d8-72d1-a2ba-be6f-0f1630618988.png)
今回の環境では5万ステップで16分ほどかかりました。
# 結果

<img width="25%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121360/a30ae255-28e1-86c4-ac97-9796dd49182d.gif">
こちらが学習させたもの。意外と全然列を消す動きをしないですね...。報酬の情報を見直せばもう少しまともになりそうな気がします。例えば、前のステップより積んである分の高さが増えてたらマイナス等でしょうか。
また、時間がある時にでも挑戦してみようと思います。
ここまで読んでいただきありがとうございました！
Python初学者がVSCodeでイケイケに開発する

これは [求ム！Pythonを使ってAzureで開発する時のTips！【PR】日本マイクロソフト Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/azure-python) １０日目の記事です。

## TL;DR;

Python初学者でもVSCodeのRemoteContainersでイケイケに開発できる

## 背景

Pythonで書かれたコードを触る機会がありました。
しかし私はGoやJava、TypeScriptは書いていても、Pythonを書いたことはありませんでした。

そんな私がPythonの開発環境構築をバシュッと行った方法をご紹介します。

## とりあえず VSCode RemoteContainers

私はVSCode派なので、VSCodeを使って開発がしたいと思いました。
そこで、RemoteContainersで環境を作れば良いよねってことで環境構築していきました。

## RemoteContainersとは

VSCodeの拡張機能の一つで、ローカル上のDockerコンテナを立ち上げてその中で開発作業を行うものです。

[![概略図](https://code.visualstudio.com/assets/docs/remote/containers/architecture-containers.png)](https://code.visualstudio.com/docs/remote/containers)

拡張機能の正式名称はVisual Studio Code Remote - Containersであり、本記事ではRemoteContainersと呼ばせていただいています。

使い方やさらなる詳しい説明は他の文献を参照ください。
- [Visual Studio Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)
- [Developing inside a Container using Visual Studio Code Remote Development](https://code.visualstudio.com/docs/remote/containers)
- [VSCode Remote Containerが良い - Qiita](https://qiita.com/d0ne1s/items/d2649801c6f804019db7)

## どんな感じでやったのか

公式で各種言語用のサンプル設定があるので、それをベースに構築しました。

今回はPythonだったので、[microsoft/vscode-remote-try-python: Python sample project for trying out the VS Code Remote - Containers extension](https://github.com/microsoft/vscode-remote-try-python)の`.devcontainer`ファイルをプロジェクトにコピーして利用しました。

あとは開発に必要な拡張機能だったり、ツールだったり、設定だったりを定義していくだけで開発環境が構築できます。

### 拡張機能を入れたい場合

ローカルで使っているVSCode拡張がそのままRemoteContainersでも使えるという訳ではないため、別途拡張機能を入れる設定を記述しなければいけません。
その場合は、`.devcontainer/devcontainer.json`の`"extensions"`に必要な拡張機能のIDを入れていけばRemoteContainers起動時に自動で追加していってくれます。

### 開発に必要なツールを入れたい場合

こちらもローカルにある`aws`コマンドがそのままRemoteContainersでも使えるという訳ではないため、設定を記述していきます。
先ほどとファイルが異なり、`.devcontainer/Dockerfile`の最下部にインストールコマンドを追加するとRemoteContainers起動時にインストールしてくれます。

### その他

RemoteContainersの起動時に`requirements.txt`に定義されたパッケージも自動でインストールしてくれるので、RemoteContainersが起動した時点で全部入りの環境が手に入ります。

## バシュッと出来たのか

実質、`.devcontainer`を作ってRemoteContainersを起動しただけでマジでバシュッと環境が出来ました。

またVSCodeのPython拡張が優秀で、コードアシストしてくれたり、フォーマットしてくれたりで、「俺、Python書ける！」って思うくらいイケイケに開発することができました。

（実際は初学者なので、Goなどで書くよりウン倍も時間かかりました）

## まとめ

どの言語でも共通して言えると思いますが、初学者にとって環境構築が鬼門になりますが、
そんな環境構築でも、VSCodeのRemoteContainersを使うと、Pythonの全部入りの環境が手に入ります。

そのため、Python初学者であってもイケイケに開発することができます。

またRemoteContainersで開発環境を構築すると、開発環境毎にランタイムを変えることがなくなります。
今回の場合は、Macで開発しており、MacのPythonは2系でしたが、RemoteContainersの中ではPython3系で開発できていました。
fluent-bitを使ってApache Pulsarにログを送る

これは [Kubernetes Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/kubernetes) の12/15(火)の記事です。

## TL;DR;

kubernetes上のアプリケーションログを集めて、[Apache Pulsar](https://pulsar.apache.org/)に送る[Fluent Bit](https://fluentbit.io/)のアウトプットプラグイン(のプロトタイプ)を作成。

<a href="https://github.com/transnano/fluent-bit-go-pulsar-output"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/transnano/fluent-bit-go-pulsar-output.png" width="460px"></a>

## 背景・課題

（実際にあったものではなく、空想・シミュレーションです）

これまでログを解析するためにAというツールを使ってきましたが、今回新たにBというツールでも別の角度から解析を行いたいシチュエーションになった場合にどのようにこの課題を解決しようかと考えました。

解決法としてはいくつか方法は考えられますが、今回はログの発生元と解析ツールの間にメッセージングプラットフォームなどを置いて解決しようと考えました。

```
app-log -> log-collector -> tool
```

↑だったものを、↓に置き換えるイメージ

```
                                          ┌ tool-A
app-log -> log-collector -> messaging-pf -┤
                                          └ tool-B
```

## 解決案

ログコレクタにFluent Bitを、メッセージングプラットフォームにApache Pulsarを採用しようと考えました。

### Fluent Bit とは

> Fluent Bit is an open source Log Processor and Forwarder which allows you to collect any data like metrics and logs from different sources, enrich them with filters and send them to multiple destinations. It's the preferred choice for containerized environments like Kubernetes.

ログコレクタです。

### Apache Pulsar とは

> Apache Pulsar is a cloud-native, distributed messaging and streaming platform originally created at Yahoo! and now a top-level Apache Software Foundation project

メッセージングプラットフォームです。
メッセージングプラットフォーム界では他にもKafkaなど有名なものがいくつもありますが、Apache Pulsarも[CNCF Cloud Native Interactive Landscape](https://landscape.cncf.io/)の「Streaming & Messaging」の項目に記載があるくらい有名なものになります。

### 本構成の問題点

[Outputs - Fluent Bit: Official Manual](https://docs.fluentbit.io/manual/pipeline/outputs)を見ても、Apache Pulsar用のアウトプットプラグインがない。

ないとなれば書くしかありません。
Fluent BitはFluentdと異なりCで書かれています。

私はCは書けませんがGoなら少し書けます。そこで調べてみるとGo用のマニュアルやライブラリがありました。

公式マニュアル：[Golang Output Plugins - Fluent Bit: Official Manual](https://docs.fluentbit.io/manual/development/golang-output-plugins)

<a href="https://github.com/fluent/fluent-bit-go"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/fluent/fluent-bit-go.png" width="460px"></a>

## 出来たもの

<a href="https://github.com/transnano/fluent-bit-go-pulsar-output"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/transnano/fluent-bit-go-pulsar-output.png" width="460px"></a>

プラグインを書いたと言ってもプロトタイプであり、認証なしの最低限のものが動いたまでです。

## 実際にk8sに導入してみる

本当はこの先までやりたかったけど、環境構築が間に合わずここまで。すみません。:bow:

<a href="https://github.com/fluent/fluent-bit-kubernetes-logging"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/fluent/fluent-bit-kubernetes-logging.png" width="460px"></a>

↑この辺を見て、Kafkaの部分をApache Pulsarに置き換えれば出来るはず。

## まとめ

kubernetes上のアプリケーションログを集めて、[Apache Pulsar](https://pulsar.apache.org/)に送る[Fluent Bit](https://fluentbit.io/)のアウトプットプラグインのプロトタイプを作成しました。

今後はk8sで動かしてみたり、プラグイン自体をしっかり実装していこうかと思います。
技術的負債には利子がつく

### 技術的負債とは

チームで長く開発していると、どうしても~~クソコード~~技術的負債が積み重なっていきます。
要因としては以下のものが挙げられます。

* スキル不足でそのやり方しか浮かばなかった
* 早く終わらせたいからとりあえず動くものを作った
  * 無理な開発スケジュールだったり、大分値切られた業務委託で工数かけたくないときとかになりがち
* その作り方が慣習になってしまっている
* 設計の時点でおかしい

そうして積み重なった負債にはしっかり利子がついていきます

### 利子とは

クソコードなので

* 可読性が悪い
* 拡張・改修しにくい

ので、結果として

* ちょっとした改修でも時間がかかる
* バグが起きやすくなる

ということで、後々の無駄な工数が利子としてついてきます。

さらにひどい場合、そのクソコードが流用されてしまい、さらに広がってしまう可能性もあります。
特に新しく参画したメンバーの場合、「ここではこういう作り方が慣習」と思ってクソコードを広めてしまう可能性が高いです。

### 元本をしっかり返す

負債が溜まりに溜まってしまった結果、利子の返済で手一杯になってしまう時が来るかもしれません。
そのままだといつまで経っても負債はなくなるばかりか、増える一方です。
クソコードを根本から淘汰して、負債の元本をしっかり返していくのが大事です。

### ご利用は計画的に

元あるソースを改修するのは勇気のいる作業です。
しかし誰かが勇気を持って負債を淘汰しなければ、チームは疲弊していく一方です。
少しずつでもいいからなにかの改修のついでに負債を返済したりして、計画的に返済を止めずに進めていくことをおすすめします。
Confluence編集が楽しくなる！おすすめマクロ機能紹介

# この記事について

この記事は、[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html)の開発チーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu)」にて行っているアウトプット企画である「[チーム「オキザリス」Advent Calendar](https://qiita.com/advent-calendar/2020/oxalis)」の12日目の記事です。

# この記事の立ち位置

本アドベントカレンダーの7日目に、[「Confluenceを使いこなそう！便利な機能5選」](https://qiita.com/aykooo/items/2131fb0bdb393ecb7d96)という記事を書きました。その中でConfluenceの「豊富なマクロ」機能について簡単に紹介したのですが、この記事ではさらに深堀りしようと思います。

# Confluenceマクロの使い方

Confluenceページの編集モードに入ると、下図のようなヘッダーが現われます。ヘッダーの中のボタン一つ一つがマクロです。赤い四角で囲んだ「＋」ボタンを押すと、ヘッダーには表示しきれていないすべてのマクロを参照できます。また、一部のマクロはコマンドで呼び出すこともできます。

![マクロ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/0317336b-b2ed-3aad-8921-50124258fdfd.png)


# おすすめマクロ機能【デフォルト機能編】

まずは、Confluenceにデフォルトでついている（＝Confluenceが利用できる場合は無料で使える）マクロ機能のご紹介です。

## 目次

ボリュームの多いページに必須の機能。本文中で「見出し」に設定している行のみを、目次としてページ冒頭に表示します。見出しのリンクをクリックすると、本文中の該当する場所に移動します。
コマンドも用意されており、Confluenceページ編集中に`{目次`または`/目次`等と打つことで使えます（お使いのConfluenceのバージョン等によります）。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/d21d72e4-f92f-3af6-6306-1fbf7565b258.png" width=60%>


## 情報

特に重要な情報等を、目立たせて表示するマクロです。情報、注意、警告などのレベルが用意されています。こちらも`{情報`または`/情報`等のコマンドが用意されています。

![情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/40f88d22-2c50-3f16-ed9a-6444637a52e6.png)


## 展開

長い文章など、Confluence上には残しておきたいが閲覧の邪魔になる、と思うことはありませんか？展開マクロに含めた文章は、初見では非表示にしておくことができます。クリックすることで非表示だった文章が展開されます。
こちらも`{展開`または`/展開`等のコマンドで呼び出し可能。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/4c078e6e-4855-119d-e112-618be6b6947f.png" width=70%>



# おすすめマクロ機能【有償プラグイン編】

ここからは、有償プラグインを導入することによって使える機能のご紹介です。Confluence上級者の方々向けに。

## テーブルフィルタ

Confluenceで作成した表に対し、フィルタをかける機能です。例えば、定例会議で報告するテーマを表に追記していくと、どんどん表が膨れ上がりやがて見づらくなってしまいます。このようなときに、テーブルフィルタを設定しておくことで管理が楽になります。
機能自体は、Excelに慣れている方にはとてもなじみの深いものではないでしょうか。
※「Table Filter and Charts for Confluence」という有償プラグインが必要です。フリートライアルもあります。


![テーブルフィルタ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/5e8524fd-3d3e-a6d5-5e7b-4ac78ebf189b.png)


## チャート

Confluence上で表に表したデータを、グラフ表示する機能です。例えば、とあるサービスの利用者数推移の可視化にこのマクロを用いると、データの記録がてら報告資料も作れて良い感じです！図のような時系列表示グラフ以外にも、円グラフや棒グラフなど様々な種類のグラフを表現できます。
こちらも「オンラインでExcelのような機能が使いたい！」という方にピッタリの機能です。
※こちらも同じく「Table Filter and Charts for Confluence」という有償プラグインが必要です。


![グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559424/38321069-f2e8-d49e-b991-b5aa193f6403.png)


# 最後に

他にも様々なマクロ機能が用意されています。ぜひ色々なマクロに触れて楽しいConfluence編集を体験してみてください！
macにvirtualboxをインストール

# 0. 環境
Mac：Hight Sierra 
VirtualBox : 6.1.12
# 1. VirtualBoxインストール
### 1-1. isoファイルダウンロード
ダウンロード元：https://www.virtualbox.org/wiki/Downloads
![スクリーンショット 2020-08-22 17.28.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/c9febfd3-88aa-39e7-a451-ad7560692576.png)
「OS X hosts」をクリックするとdmpファイルがダウンロードできる。
時間がかかる場合があります

- VirtualBoxを最新のもの以外で使いたい場合
 - 過去分：https://www.virtualbox.org/wiki/Download_Old_Builds
 - サポート終了しているものもあるので、自己責任

### 1-2. VirtualBoxをインストール
- ダウンロードしたdmpファイルをダブルクリックすると、画像のような画面が出てくる
![スクリーンショット 2020-08-22 17.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/f840f457-8adc-6299-154e-1f1ace55a6c9.png)
1 Double click on this iconにある「VirtualBox.pkg」かアイコンをダブルクリック

- インストール画面が出てくるので全てデフォルトのまま進めてOK
以下のように進める

- 「続ける」をクリック
![スクリーンショット 2020-08-22 18.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/3cffc20b-f751-a55f-762b-dcc8f06ace88.png)
- 「続ける」をクリック
![スクリーンショット 2020-08-22 18.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/77610962-b81c-6046-f7a4-2a95a0441edc.png)
- 「インストール」をクリック
![スクリーンショット 2020-08-22 18.04.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/1db654a9-686e-960b-b05c-da1c62e5f611.png)
- パスワードを入力
![スクリーンショット 2020-08-22 18.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/3f35062c-ddf2-9310-0435-d88ca821ee72.png)
パスワードを入力すると、インストールが始まる

- 「拡張機能がブロックされました」と出た場合
 - 「システム環境設定」→「セキュリティとプライバシー」を開く
 - 一般タブの所で「開発元 "Oracle America, Inc." のシステム・ソフトウェアの読み込みがブロックされました。」に許可ボタンがあるので、クリックする

- 「閉じる」をクリック
![スクリーンショット 2020-08-22 18.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/3fd7b56d-3200-bb7c-55ab-1d8164f4410d.png)

- 「ゴミ箱に入れる」を選択
![スクリーンショット 2020-08-22 18.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/e0420ee2-e60d-0d66-e9c1-397fe67eeb75.png)

# 2. VirtualBoxを開く
- Command + スペースの検索機能を使ってVirtualBoxを呼び出す
「Virtual」と入れると候補表示されるので、Enterする
![スクリーンショット 2020-08-22 18.25.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/ba359e83-eb09-6c21-0b9f-b8f290e336cb.png)
- VirtualBoxが開ける

※過去にVirtualBoxを使っていたので、リスト表示されている
初回は何もない状態が正しい
![スクリーンショット 2020-08-22 18.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696107/1462cb38-d84c-1bcf-319b-f34c9adec243.png)
以上で、macにVirtualBoxを入れる手順は終了
VNCとVPN

業務でなんとなく使っていますが、仕組とかどのような仕様なのか
ちゃんと理解して使っていなかったので、いろいろ調べてみました。

---
### VNC(Virtul Network Computing)
>VNCとは、ネットワークを通じて別のコンピュータに接続し、そのデスクトップ画面を呼び出して操作することができるリモートデスクトップソフトの一つ。また、オリジナルのVNCを元に開発された派生ソフトウェア群の総称。様々な環境に移植され、相互に接続可能なため、異なるOSで操作するコンピュータの画面を呼び出して操作することができる。
>>[IT用語辞典より](http://e-words.jp/w/VNC.html)

---
### VPN  【 Virtual Private Network 】  仮想プライベートネットワーク
>VPNとは、通信事業者の公衆回線を経由して構築された仮想的な組織内ネットワーク。また、そのようなネットワークを構築できる通信サービス。企業内ネットワークの拠点間接続などに使われ、あたかも自社ネットワーク内部の通信のように遠隔地の拠点との通信が行える。
>>[IT用語辞典より](http://e-words.jp/w/VPN.html)

---
### VPN
VPNはトネリングと暗号化によって実現しており、トネリングを行えるプロトコルはPPTP,L2F,L2TP,IPsec,GREなどがあり、これらのうちIPsecのみが暗号化を行える。
ただIPsecはマルチキャスト(1対N間のVPN接続)ができない。
なのでマルチキャスト対応可能な実装なら、トネリングにGREかL2TPを使用し、暗号化はIPsecで実装するということになるが、データ処理が2過程必要となるため通信速度は遅くなる。

現在最も信頼性の高いプロトコルはOpen VPNなようです。(オープンソース)
ただデメリットとして、サードパーティアプリが必要になり場合があるようです。
※それ以上の信頼性の高いプロトコルがあればコメント頂けるとと幸いです。

---
### トンネリングとカプセル
1.インターネットを介していれば、セキュリティ上の問題に疑問がわきます。
この問題を防ぐために送り手と受け手間に、仮想的なトンネル(トンネリング)を作り通信を行うのがVPNプロトコルである。
2.データの通信を行う際にカプセルで保護してから通信を行う(カプセル化)
3.上記だけだとセキュリティ的にまだ安全と言えないため、認証と暗号化を行う。

VPN接続される側 > VNCサーバ
VPN接続する側 > VPNクライアント
のソフトウェアを導入する必要がある

### VPN接続する拠点にVPN対応のルータが必要
対応ルータにはトンネリングや暗号化機能がある
(ルータによって仕様はいろいろある)

### VPNカプセル化(暗号化技術)
カプセル化した通信=トンネリング
Taurusを用いてJMeterのレポートを作成する


JMeterにも統計情報やレポートを作成する機能はありますが、Taurusを用いることでより多くの情報を見やすい形でレポートを作成することができるため、今回はその方法について紹介します。

## Taurus

[Taurus](https://gettaurus.org/)は[BlazeMeter](https://www.blazemeter.com/)が公開しているオープンソースのテスト自動化フレームワークです。
JMeter以外にもGatlingやLocustなど様々な負荷試験ツールのラッパーとして動かせることや、レポーティング機能が充実しているところが特徴です。

## インストール

今回はDocker Imageを使用しますが、各OSの環境にインストールして動かすこともできます。

```bash
$ docker pull blazemeter/taurus
```

## 準備


Taurusの設定ファイル（yaml）を`my-config.yml`という名前で`/tmp/my-test`に配置します。

```yaml:my-config.yml

execution:
- scenario: simple # Taurusのシナリオ名
 
scenarios:
  simple:
    script: my-scenario.jmx # JMeterのシナリオファイルを指定
 
reporting:
- module: console     # 実行中の情報を表示
- module: final-stats # サマリを表示
- module: blazemeter  # オンラインレポートを作成
```

`/tmp/my-test`にJMeterのシナリオファイル（jmx）を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/9e97f36a-8273-e23e-aac2-9ee8b63119c3.png)


## 実行

以下のコマンドを実行すると`my-config.yml`で指定した内容でTaurusが実行されます。

```bash
$ docker run -it --rm -v /tmp/my-test:/bzt-configs blazemeter/taurus my-config.yml
```
実行中はコンソールに実行中の状況がダッシュボードで表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/281ab3d8-bcd7-5709-9ac7-eaecf172d9f5.png)

## 結果

実行が完了するとレポート用のトークン付きのリンクが出力されます。（無料版は7日間で消えます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/06720938-7092-b8c6-4470-a5cca2907569.png)

### Summary
サマリ用のメインダッシュボードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/7ad5b214-9402-eb7a-af01-07f310150a5b.png)

### Timeline Report
ユーザー、リクエスト、レイテンシなどの情報をタイムラインで見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/6b3c1239-4c63-002e-8a1b-dd44a1d7fb61.png)

### Request Stats
JMeterの統計情報と同様の情報を見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/f702390b-fc6c-a2d6-a4c0-6861df0bcf8e.png)

### Engine Health
実行側のリソース状況を見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385323/7ced42f6-7502-ab46-4922-40b6b457d83d.png)

## まとめ

今回はシンプルな例でしたが、複雑な試験やシナリオになる場合は、より見やすさを実感できると思います。
また、GatlingやLocustなども同様に扱えるため、複数のツールを併用する場合は、まとめて実行やレポーティングすることで試験を効率化できるかもしれません。
機械学習の実装の勉強の記録①（Kerasのデータセット） 

# はじめに
基本的に自分のためのブログです。
MarkDownなど、書き方に慣れてないのであしからず。

#筆者のスペック
- 物理学専攻出身で、ただし統計はど素人。
- Pythonでの実装経験は素人レベル
- 機械学習はなんだかんだとこれまで勉強会（岡谷先生の青本輪講）やセミナー（Google中井先生講師）には参加していたが、Kaggle参加は数回程度。
- インプレス　Python 機械学習プログラミングをいちおう一通り読了。ただし実装経験に乏しい状態。
- 2020年10月のG検定合格


#動機
2020年度10月のG検定に合格した。
ただ、この資格を取っても何か機械学習の実装ができるようになったり、
データサイエンティストみたいな仕事がこなせるようになったりするわけではない。
このため、自分のために勉強のついでにまとめていくことにする。

今回はKerasのデータセットをまとめる。
前にKaggleに参加した際、データ形式や変換のところでいきなり躓き、
なかなか前に進まなかったため、
とっかかりとして整備されているデータセットを知っておくことは重要だ。

#Kerasとは
Kerasは，Pythonで書かれた，ディープラーニングに特化したTensorFlowのラッパー。
簡単にモデルを構築したりできる（らしい。）
詳細は以下参照。
https://keras.io/ja/#keras


#Kerasのデータセット
詳細は以下を参照だが、どんなデータセットが用意されているか箇条書きしておく。
https://keras.io/ja/datasets/

- CIFAR10 画像分類
- CIFAR100 画像分類
- IMDB映画レビュー感情分類
- ロイターのニュースワイヤー トピックス分類
- MNIST 手書き数字データベース
- Fashion-MNIST ファッション記事データベース
- ボストンの住宅価格回帰データセット
CombineのflatMapを書いたらiOS14以上しか使われないって怒られる件について 

初投稿です。@dsxsxsxsです。
ここ最近本格的にCombineを使いはじめました。
割としょうもない話をしたいと思います。

# 怒られる実装
```flatMapNoNo.swift
["hoge"].publisher
    .flatMap { _ in
        URLSession.shared.dataTaskPublisher(for: URL(string: "https://qiita.com")!)
    }
```
上記コードはなぜか上手く行かず、`'flatMap(maxPublishers:_:)' is only available in iOS 14.0 or newer`っとコンパイラーに怒られる。
そんなわけないですよね。

# 解決案
upstreamに`setFailureType(to:)`を繋いであげれば大丈夫。

```flatMapYaYa.swift
["hoge"].publisher
    .setFailureType(to: URLError.self)
    .flatMap { _ in
        URLSession.shared.dataTaskPublisher(for: URL(string: "https://qiita.com")!)
    }
```
# どういうこと？
iOS14以降オンリーのメソッドを呼んでしまったからです。
定義がこうなっています：

```flatMapFromNeverFail.swift
@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
extension Publisher where Self.Failure == Never {
    public func flatMap<P>(maxPublishers: Subscribers.Demand = .unlimited, _ transform: @escaping (Self.Output) -> P) -> Publishers.FlatMap<P, Publishers.SetFailureType<Self, P.Failure>> where P : Publisher
}
```
Failure型がNeverの場合、`setFailureType(to:)`を内部でやってくれる`flatMap`が追加されましたという。
ちなみに、`switchToLatest()`も同様です。🍎さんはいつも通り、さり気なく[サプライズ](https://developer.apple.com/forums/thread/650584)を用意してくれます。



```switchToLatestFromNeverFail.swift
@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
extension Publisher where Self.Failure == Never, Self.Output : Publisher {
    public func switchToLatest() -> Publishers.SwitchToLatest<Self.Output, Publishers.SetFailureType<Self, Self.Output.Failure>>
}
```
# どの人たちがよくハマるの？

- XCode12から始めた人 
- Rxに慣れた人
- サポートOSバージョンをiOS13指定しまっている人

僕は見事に上記３点フルコンボでした。😅

# どの人たちがハマらないの？

- 去年からCombineを始めたトップバッター勢
- そもそもiOS13を切った勢

## 参考した記事
- Donny Wals [Configuring error types when using flatMap in Combine](https://www.donnywals.com/configuring-error-types-when-using-flatmap-in-combine)
- @shiz さんより[flatMapでFailureTypeがNeverの場合にsetFailureTypeの変換が不要に](https://qiita.com/shiz/items/5efac86479db77a52ccc#202073%E8%BF%BD%E8%A8%98-ios14%E6%9B%B4%E6%96%B0)
通信の安全性とSSL/TLSについて

# はじめに
本記事は[セキュリティ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/security)の記事となります。
SSL/TLSはHTTPS通信などで使用されていることで有名な通信のセキュリティを担保してくれるプロトコルです。通信のセキュリティ(安全性)には様々な要素が含まれていますが、SSL/TLSは主に通信が周囲に読まれないこと、情報が改ざんされていないことを保障するプロトコルとなります。

本記事では、以下のことについて記載を行います。

+  通信の安全性とは
+  SSL/TLSの役割
+  SSL/TLSで使用されている技術


# 通信の安全性とは

通信の安全性について説明を行います。

##### 情報セキュリティの3要素

通信の安全性は以下の3大要素で構成されています。

+ 機密性(Confidentiality)・・・情報へのアクセス許可のある人だけが情報を利用できること
+ 完全性(Integrity)・・・情報資産に正確性があり改ざんされていないこと
+ 可用性(Availability)・・・情報へのアクセス許可のある人が必要な時に情報にアクセスできること

この3要素は上記の3要素の頭文字をとって情報セキュリティのCIAと呼ばれています。

# SSL/TLSとは
SSL/TLSは二つのプロトコルの名前であり、それぞれSSL(Secure Socket Layer),TLS(Transport Layer Security)となっています。SSL→TLSへ発展したという経緯があります。現在はTLSがメインで使用されています。

### SSL/TLSの機能
SSL/TLSは主に以下のことを行います。

+ 通信の暗号化
+ 認証(なりすまし防止)
+ 改ざん検知

通信の暗号化は第三者に情報が読めないようにします。従って、機密性がある程度保証されます。また、改ざん検知の機能もあるため、完全性についても保障されます。ただし、可用性についてはSSL/TLSの範囲外となります。(可用性を脅かす通信の攻撃としては、DoS攻撃などが挙げられます。)

先ほどの情報セキュリティのCIAのうち機密性と完全性に対してある程度保証されます。

### SSL/TLSの技術

SSL/TLSは上記の機能を有するために様々な技術が使用されています。

+ 暗号技術(ハイブリッド暗号方式)
+ MAC(Message Authentication Code)
+ デジタル署名
+ サーバ証明書

#### 暗号技術

クライアントサーバ間の通信を暗号化します。この際に使用されるものは公開鍵暗号方式と共通鍵暗号方式の両方が使用されます。(ハイブリッド暗号方式と呼ばれます。)

######公開鍵暗号方式
公開鍵暗号方式では、公開鍵と秘密鍵のペアで暗号化、復号化ができます。公開鍵は誰でも参照でき、秘密鍵は持ち主しか知らない情報となります。したがって、送りたい相手の公開鍵で暗号化した通信は送りたい相手にしか復号化できないという仕組みです。

######共通鍵暗号方式
通信したい相手と鍵を共有して、暗号化復号化を行う仕組みです。

######ハイブリッド暗号方式
公開鍵暗号方式は、暗号復号による負荷が高いことがデメリットとして挙げられます。共通鍵暗号方式は負荷は少ないが、鍵の伝達方法、鍵の管理が大変になります。そこで、二つを複合したハイブリッド暗号方式がSSL/TLSでは使用されています。ざっくりとした仕組みとしては、共通鍵の交換を公開鍵暗号方式で実施し、後は共通鍵で暗号化を実施するという流れです。

#### MAC
MAC(Message Authentication Code)はメッセージ認証符号と訳されます。この技術は完全性を保障するために使用される技術となります。

#### デジタル署名
なりすましや、否認防止のために使用されます。公開鍵暗号方式では、送付したい相手の公開鍵で暗号化することでその人にしか復号できないという仕組みです。逆に秘密鍵で暗号化した場合、送付元の情報があれば、誰でも復号化はできますが、暗号化できる人は送付した本人しかできないため、否認防止、なりすまし防止に役立つという仕組みです。通信相手が本当に正しい人か判断することができます。

#### サーバ証明書
ドメイン名 + サーバの所有者が正しいことを証明するものです。認証局に証明書発行要求を出すことによって認証された証明書を手にすることが可能となります。


SSL/TLSはこれらの技術を使用して、通信の安全性を高めてくれています。

# その他拡張機能

SSL/TLSには拡張機能と呼ばれるものがあります。SNIについて記載を行います。

### SNI(Server Name Indication)
従来は、一つのサーバ(一つのIPアドレス)につき一つのサーバ証明書を使用するということが基本でした。SNIを使用すると一つのサーバ内に複数のWeb サーバを構築することができ各々に対して証明書を登録することができます。その際、IPアドレスのみの情報では、どの証明書を使用していいかわからないため、TLSハンドシェイクの中に拡張フィールドとしてSNIフィールドがあります。その情報を見てサーバ側も証明書を選択することができます。(HTTPヘッダにホスト名等の情報があるが、SSL/TLSの場合はデータの交換より前に情報が必要となる。)

# TLS通信の確認
実際に、httpsサーバを構築し、TLSハンドシェイクのパケットキャプチャを確認しました。
基本動作としてはクライアント→サーバへ使用可能なTLSバージョン情報や暗号方式、SNIの情報を伝えます。(Client Hello)そのレスポンスとしてサーバ→クライアントへ暗号方式決定、TLSバージョンの決定を行います(Server Hello)。その後証明書の情報等をクライアントへ送付します。(Certificate)

クライアント→サーバへの通信
![TLS1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174901/083a02f6-e7f7-7301-7953-e5d0b9367861.png)

サーバ→クライアントへの通信
![TLS3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174901/5bc468da-f0ae-f926-0d50-4332aba47843.png)

これらの通信が終わった後、データが暗号化されて通信されます。
暗号化を一度行うとセッションIDが発行されるため、再度通信を行う際はハンドシェイクのすべてを行う必要がありません。そのため、二度目の通信は最初に比べて少し軽いみたいです。


# さいごに
以上、TLSについてちょっと簡単にまとめてみたという文書です。セキュリティ技術関連は無意識のうちに使用しているところが多いので、改めてふたを開けるといろいろ面白かったです。
TLSの話をざっくりとした感じで書いていますが、間違い等ございましたらご指摘のほうお願いいたします。
ありがとうございました。
ケモインフォマティクス解析 Tips（メモ）

#解析関連
###クロスバリデーションの分割数  
- 1000 サンプル以上 : 2-fold クロスバリデーション
- 1000 から 100 くらいまで : 5-fold クロスバリデーション
- 100 から 30 くらいまで : 10-fold クロスバリデーション
- 30 以下 : leave-one-out クロスバリデーション

参考：[「DCE tool」に機能を追加しました！クロスバリデーション・カーネル関数・ベイズ最適化（金子研究室HP)](https://datachemeng.com/post-3484/)   

#その他
###matplotlib を日本語表示対応させる
japanize matplotlibをインストール

```
pip install japanize-matplotlib
```

japanize_matplotlibをmatplotlibと共にインポートする

```python
import matplotlib.pyplot as plt
import japanize_matplotlib
```
【Typescript】baseUrlでの絶対パスインポートが「import/no-unresolved」で怒られる場合の対応



Typescriptでは`tsconfig.json`の`baseUrl`を指定すれば絶対パスでインポートができる。
しかし、eslintの`import/no-unresolved`ルールに怒られてしまったので、そのときの対応を記載する。

![スクリーンショット 2020-12-12 17.51.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282929/5070977b-3df0-2cfa-4021-2eb526fc6b68.png)


## 1. [eslint-import-resolver-typescript](https://github.com/alexgorbatchev/eslint-import-resolver-typescript#readme)をインストールする

tsのインポート問題を解決してくれるライブラリらしい。

```
$ npm install -D eslint-import-resolver-typescript
```

## 2. eslintrcに設定を追加する
settingsの`import/resolver`に設定を追加する。
これだけで絶対パスでのインポートでも怒られないはず。

```.eslintrc.js抜粋
  settings: {
    'import/resolver': {
      typescript: {},
    },
  },
```

## おまけ: tsconfigが複数ある場合
resolverが見るtsconfigを指定できる。
以下はsrc/以下のtsconfigを指定する場合。

```
  settings: {
    'import/resolver': {
      typescript: { project: 'src/' },
    },
  },
```

## Appendix
- だいたいここに書いている
    - https://github.com/benmosher/eslint-plugin-import/issues/1485
【Swift】型の構成要素〜プロパティ前編〜

#プロパティ
プロパティとは、**型に紐づいた値のことで型が表すものの属性の表現などに使用されます。**

車を例にしますと、車は車種やタイヤ、エンジンなどの属性を持っています。

これを型とプロパティの関係で表すと、
**車という型は、車種やタイヤなどのプロパティを持っているということになります。**

車種は車によって異なりますので、
プロパティは型のインスタンスに紐づいた変数や定数であるとも言えます。

##定義方法
プロパティはvarキーワードもしくはletキーワードで定義します。

変数や定数と同様に、**varキーワードは再代入可能なプロパティを定義し、
letキーワードは再代入が不可能なプロパティを定義します。**

定義する際のコードは下記のようになります。

```swift

struct 構造体名 {
    var プロパティ名： プロパティの型の値 = 式   // 再代入可能なプロパティ
    let プロパティ名： プロパティの型の値 = 式   // 再代入不可能なプロパティ
}
```

プロパティにアクセスするには、型のインスタンスが代入された変数や定数に
`.(ドット)`と`プロパティ名`をつけて`変数名.プロパティ名`のように記述します。

私が将来乗りたい車であるレクサスを例にしてコードを書いてみます。

`let myCar = Car()`で、定数myCarに対してCar型の構造体をインスタンス化しています。

struct内で定義された定数nameに対してアクセスするためには、
変数名.プロパティ名の形で記述するので`myCar.name`という形になります。

```swift

struct Car {
    let name = "LEXUS LS"   // 車名
    let price = 9000000   // 値段
    var mileage = 20000   // 走行距離
}

let myCar = Car()
print(myCar.name)
print(myCar.mileage)

実行結果
LEXUS LS
20000
```

プロパティの型の整合性を保つために、
**インスタンス化の完了までに全てのプロパティに値が代入(=初期化)されてなければいけません。**

初期化されていないプロパティが存在するとコンパイルエラーが発生します。

**したがって、全てのプロパティは、宣言時に初期値を持っているか、
イニシャライザ内で初期化されるかのいずれかの方法で値を持つ必要があります。**
(イニシャライザに関しては別の記事に記載してあります。)

##プロパティの分類
プロパティは、紐付く対象により２種類のプロパティに分類することができます。

前者のプロパティの方が主流ですが、
ぜひ両方とも覚えておきましょう！

###インスタンスプロパティ
インスタンスプロパティとは、型のインスタンスに紐付くプロパティになります。

インスタンスに紐付くため、
**インスタンスごとに異なる値を持たせることができるのが特徴です。**

単にプロパティと呼ぶ場合はこちらを表すことが多い気がします。

**varやletで定義したプロパティはデフォルトではインスタンスプロパティとなります。**
なので、先ほどの車の例で出たプロパティは全てインスタンスプロパティです。

下記の例では、同じ型を使ってインスタンス化しても、
異なるインスタンスになるので異なった値を持たせることができます。


```swift

struct human {
    var name = "Aoki"
    var age = 11
}

let human1 = human()
var human2 = human()
human2.name = "Tanaka"

print(human1.name)
print(human2.name)

実行結果
Aoki
Tanaka
```

###スタティックプロパティ

スタティックプロパティは型のインスタンスではなく型自身に紐付くプロパティで、
**インスタンス間で共通する値の保持などに役立ちます。**


スタティックプロパティの定義方法は簡単で、
プロパティの宣言時に先頭にstaticキーワードを追加するだけです。

スタティックプロパティは他のプロパティとは異なり、
`型名.スタティックプロパティ名`で値を参照することができます。

例として、メールに関する構造体Mailを作成してみました。

宛先は毎回同じでいいので、`static let from`のように
スタティックプロパティで定義しております。

このスタティクプロパティにアクセスする際には`Mail.from`でアクセスします。

また、`func mailer(mail: Mail) { }`のように、
引数の型を今回作成したMail型にしていますので、
`let mail1 = Mail()`でインスタンス化したMail型のmail1を引数に渡すことができます。


```swift

struct Mail {
    static let from = "Tanaka for iPhone"
    var to = "Matsumoto"
    var body = "Hello!"
}

func mailer(mail: Mail) {
    print(Mail.from)
    print("To:\(mail.to)")
    print(mail.body)
}

let mail1 = Mail()
var mail2 = Mail()
mail2.to = "Okada"
mail2.body = "See you Okada"

mailer(mail: mail1)
print("---")
mailer(mail: mail2)

実行結果
Tanaka for iPhone
To:Matsumoto
Hello!
---
Tanaka for iPhone
To:Okada
See you Okada

```

プロパティ前編は以上になります。

結構長くなりそうなので、前編と後編に分けました！
後編の方が大切な内容が書かれているのでぜひご覧ください。

後編はコチラ
-> [【Swift】型の構成要素〜プロパティ後編〜](https://qiita.com/onishiApp/items/b8a60d5caab57aea15a5)

最後までご覧いただきありがとうございました。
AWS SDK for JavaScript をdeveloper toolのコンソールから使用する

# 主題
Amazon S3の署名付きURLをChromeの開発者ツールだけで発行した話。環境構築不要(認証情報さえあれば)。
ブラウザでSDKが使えるのを知り、手軽に試せないかと思い。

ブラウザスクリプトの使用開始
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/getting-started-browser.html

# 手順
認証情報を拝借するユーザーに必要なポリシーは指定するメソッドだけ(以下の場合は`s3:GetObject`権限のみ)。

ブラウザを開き、URLに`about:blank`を入力して画面をまっさらにする(これしないと動かない、なんで)。
以下のどちらかで、SDK読み込み。

```javascript
(script = document.createElement('script')).src = 'https://sdk.amazonaws.com/js/aws-sdk-2.809.0.min.js'
document.getElementsByTagName('head')[0].appendChild(script)
```
または

```javascript
var ele = document.createElement("script");
ele.type = "text/javascript";
ele.src = "https://sdk.amazonaws.com/js/aws-sdk-2.809.0.min.js";
document.body.appendChild(ele);
```

以下で関数定義。アクセスキー、シークレットアクセスキー、バケット名を適宜変更。

```javascript
    const S3 = new AWS.S3({
        accessKeyId: 'xxxxxxxxx',
        secretAccessKey: 'yyyyyyyyy',
        signatureVersion: 'v4',
        region: 'ap-northeast-1'
    });
 
    function getSignedUrl(fileName) {
        const params = {
            Bucket: "YOUR_BUCKET_NAME",
            Key: fileName,
            Expires: 60
        };
            S3.getSignedUrl("getObject", params,function(err,url){
                console.log(url)
            });
        return;
    }
```

以降は `getSignedUrl("hello.html");`を実行すると、`YOUR_BUCKET_NAME/hello.html`に対して60秒GETできるURLが出力される。

# 参考
## コンソールでのライブラリの読み込み

Chromeコンソールでお手軽クローリング
https://qiita.com/cognitom/items/babefa7b85ffc050d4bd

ChromeのJavascriptコンソールで外部ライブラリを使いたいとき
http://duyoji.hatenablog.com/entry/2013/05/01/172731

## S3の関数記述部分

getSignedUrl(operation, params, callback) ⇒ String
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
github desktopで、merge後にpull originできない時の対処法

自作のWebアプリ作成中です。githubでブランチを切ってmaster branchへ
mergeした後に、github desktopで「pull origin」を実行しようとしたら、
「pull origin」のコマンドがなく焦りました、、

試行錯誤の末に簡単に解決できたので、忘れる前にアウトプットします！

[前提]
ruby 2.6.5
rails 6.0.0

githubの使い方は、簡単に言うと以下の流れだと思います。

master branch　→　branchを切る　→実装　→　commit + push →
pull request　→　merge　→　master branchに戻る　fetch origin　→
pull origin（今回このコマンドがgithub desktopに表示されていなかった）

結果的には、github desktopでの操作では解決はできなかったので、
ターミナルで「git pull origin master」を実行することで一発で解決しました！
そのコードは以下です。

```
$ git pull origin master
From https://github.com/user name/アプリ名
 * branch            master     -> FETCH_HEAD
Updating fa0a3b0..65b12df
Fast-forward
 Gemfile                                            |  3 +
 Gemfile.lock                                       |  8 ++
 app/assets/stylesheets/style.css                   | 99 +++++++++++++++-------
 app/controllers/tweets_controller.rb               |  4 +-
 app/models/tweet.rb                                |  1 +
 app/views/tweets/_form.html.erb                    | 11 +--
 app/views/tweets/_tweet.html.erb                   |  3 +-
 app/views/tweets/new.html.erb                      | 12 +++
 app/views/tweets/show.html.erb                     |  5 +-
 config/storage.yml                                 |  4 +-
 ..._create_active_storage_tables.active_storage.rb | 27 ++++++
 db/schema.rb                                       | 41 ++++++++-
 12 files changed, 177 insertions(+), 41 deletions(-)
 create mode 100644 db/migrate/20201211063452_create_active_storage_tables.active_storage.rb
```
「pull origin」が出てこなかった原因は、アプリの作成開始のタイミングでgitと
連携をしていなかったことが関係しているようでした。

基本的なことですが、gitとアプリ開発は連動しながら行わなければいけないと痛感しました💦

gitに関するコマンドでの操作は他にも色々あるみたいなので、初心者向けにまとめを近々投稿します！
ストロングパラメーターに外部キーを渡す方法

##概要

ポートフォリオに投稿機能を実装中、ストロングパラメーターを用いて値を渡そうとしたのですが
何度やっても投稿が保存されませんでした。

```
  def create
    @post = Post.new(post_params)
    binding.pry
    if @post.save
      flash[:success] = "投稿しました"
      redirect_to posts_path
    else
      render action: :new
    end
  end
```

binding.pryを差し込んでデバッグしたみたのですが結果は

```
permitted: true
```

じゃあなんで投稿できない。。

調べたところ単純な記述ミスでした。

軽くハマってしまったので自分の備忘録も兼ねての投稿です。

##開発環境

+ Rails 6.0.3.4
+ ruby 2.6.3

##実装方法

元々のコード

```
def post_params
  params.require(:post).permit(:user_id, :title, :content, :price, :img)
end
```

正しいコード

```
def post_params
  params.require(:post).permit(:title, :content, :price, :img).merge(user_id: current_user.id)
end
```

<br>

外部キーのuser_idを渡す時にmergeメソッドを使ったら投稿できるようになりました！！
Raspberry Pi 3 ModelBとBluetoothスピーカーを接続(コマンドライン操作)

## 目的
たまにBTスピーカーと接続したいときにやり方を忘れるので備忘録[^1]
[^1]: 基本的に一度pairingすれば勝手に接続してくるはずだが、色々構成をいじっているとpairingが切れたりするので・・。

## 環境
Raspberry Pi 3 ModelB
BTスピーカー：JBL GO 2

## 作業メモ

#### 参考サイト
https://qiita.com/propella/items/6daf3c56e26f709b4141

+ ラズパイを起動して、コンソール上で以下を実行するだけ！以上(# が実行するコマンド)


各コマンドの詳細は[参考サイト](https://qiita.com/propella/items/6daf3c56e26f709b4141)を参照

```
$ bluetoothctl
# scan on
・・・
[NEW] Device [JのMACアドレス] JBL GO 2
# scan off
# pair [JBL GO 2のMACアドレス]
・・・
[CHG] Device [JBL GO 2のMACアドレス] Paired: yes
# trust [JBL GO 2のMACアドレス]
[CHG] Device [JBL GO 2のMACアドレス] Trusted: yes
# connect [JBL GO 2のMACアドレス]
Attempting to connect to [JBL GO 2のMACアドレス]
[CHG] Device [JBL GO 2のMACアドレス] Connected: yes
Connection successful
```
#2 Ruby始めました 「たのしいRuby 第６版」第二章   便利なオブジェクト

こちらの分かりやすい図で前回は、制御フロー、本日はデータ構造になります。
https://speakerdeck.com/machu/zerokarawakarurubychao-ru-men-falsebu-kifang?slide=7

それでは書いたものは実際にどう処理されるのか処理系を使い学んで行きます。
https://tanoshiiruby.github.io/6/opal.html

#2−1 配列（Array） P.50

```ruby
aname=[]
```
```ruby
aname=["小","並","大"]
p aname[1]
```
並。
いつもこれしか言ってませんｗ

配列は生データという感じですね。
中のものは０１２３４で管理される。
並び替えも、取り出しもこの数値管理。

```ruby
aname=["大","並","小"]
p aname
aname[0]="小"
aname[2]="大"
aname[3]="特盛"
p aname
```

腹減った・・・特盛食ったことないけど、500円は躊躇しますｗ
実際にスーパーで500円分の牛ロース肉（オージー、アメリカ）買うとかなり買えますからねｗ
玉ねぎ３つ150円と一緒にぶっ込んで作ったら特盛何杯分？みたいなｗ


#2−2 ハッシュ（Hash） P.56

```ruby
hname = {:Aset => "おしんこ、卵、味噌汁", :Bset => "キムチ、たまご、味噌汁", :Cset => "たまご、味噌汁"}
p hname[:Cset]
```
おしんこもキムチもいらんから安いやつ提供してみたいなｗ
まあおしんこ旨いけど、スーパーで買ったやつで食うから見たいな。
まあそれ言ったら卵とか1個80円ってなんやアレ？50円で十分やろｗ

・配列
配列タグ＝管理番号＋データ
・ハッシュ
ハッシュタグ＝：シンボル＋データ
ハッシュ名[キー]

の違いですね。





#コメント
このデータ構造ですが、私的に、一番わかっていないところでもあります。

スクリプト系開発は、ほとんどの場合、箱ものであり、器というものが用意されています。
DBでもOracle、Access、Excelシート、Web系でもHtml CSSなど全て器が用意されており、ソフトウェア内での処理になり、ソフトウェアの用意した器にデーターであるオブジェクトやら変数と言われるキャラクターを格納、放り込んで行くことになります。

このデータ構造というものはその器になるのか？
データをまとめて扱う道具とあるので、きっと器、テーブルそのもののことだと思います。

Excelが一番わかりやす例で例えるなら

配列が列で、ハッシュが行ですかね？
でもただのデータに列も行も関係ないかｗ

parlのようなソフトウェアではない、開発環境のデータは、全てただのテキストファイルに格納されていきます。
そしてやはり取り出しやら表示はこうした配列、ハッシュで扱われるような気がしたので、そんな感じですかね。

まあ配列とハッシュというものはコンテナと呼ばれているので、ただの器と思っていいと思います。

タンス型の小物入れみたいなもので、そこからハサミを取り出す、ペンを出すみたいなものですね。

そしてたくさんのコンテナにタグ（名前）をつけて保管する。

まあAccessで言うならテーブルのこと、Excelならセルですが、その器であるテーブルやセルとデータの関係は１：１ですが、プログラミングの場合、コンテナのとして扱われるので、若干ニュアンスが違いますが、テーブルやセルの中に複数のデータを入れて部品だけ取り出すみたいなものですね。
M1 Macで Homebrewインストールした時のメモ


MacOS ARMでは ```/opt/homebrew``` にインストールしてくださいとの記述がある。
> [Installation — Homebrew Documentation](https://docs.brew.sh/Installation#alternative-installs)
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/9c76f6e7-eeb4-f856-7bc6-055701dc46cc.png)


```zsh
# /opt/homebrewのディレクトリ作成
sudo mkdir /opt/homebrew
chown ${自分自身USER名} /opt/homebrew

# HomebrewのGitからcloneする。
sudo curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew

# brewコマンドのPATHを通す
sudo vi /etc/paths
## 下記内容を/etc/paths/に追加
/opt/homebrew/bin

# brewのキャッシュパス設定
sudo vi ~/.zshrc
## 下記を ~/.zshrc に追加。
export HOMEBREW_CACHE=/opt/homebrew/cache

# brewコマンドの確認 --prefixはbrewのインストール先を返す。
brew --prefix
```

## 参考にしたサイト
[Installation — Homebrew Documentation](https://docs.brew.sh/Installation#alternative-installs)
[Homebrew のインストール先を変更する - Qiita](https://qiita.com/usamik26/items/601f5612bd3f8a21cc41)
[PATHを通すとは？ (Mac OS X) - Qiita](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)
[macos - OSX: Cannot unlock etc/paths file - Super User](https://superuser.com/questions/703256/osx-cannot-unlock-etc-paths-file)
今年もお世話になったMacショートカット

年末ですね。
ということで、今年も大変お世話になったキーボードショートカットを、メモがてら残しておきたいと思います。

使用ブラウザはChromeです。

# クリップボードへ範囲指定スクショをコピー → ペースト
#### ■ `command + shift + control + 4` → `command + V`

#### ポイント
- 撮ったスクショをクリップボードにコピーでき、`command + V` でペーストできること
- Finderに保存されないこと

　

仕事していると、画像を貼り付けたい場面に結構遭遇しますよね。
Slackに貼り付けたり、などなど。

僕は今フロントエンジニアとして開発をしているのですが、
「デザイン周りでプルリクを出す際に作ったUIの画像をコメント欄へ貼り付けてチェックしてもらう」
という状況がそれなりに発生します。

ちょっと前までは、その度に`command + shift + 4` でとったスクショをPCに保存して、貼り付けたいところへドラック＆ドロップしていました。

ただある時先輩から、「それめんどくね？」と言われ、 `command + shift + ctrl + 4` があることを教えてもらいました。
**衝撃でした。**

このショートカットの出会いから、

- スクショを撮る
- どっかに貼り付ける作業（ドラック＆ドロップ or Finderから選択）
- 要らなくなったスクショを消す

という作業が

- スクショを撮る
- スクショを貼り付ける

で、完結するようになりました。
もちろん保存したい時もあるので、使い分けは必要ですが。

もちろん`command + shift + ctrl + 3`でも使えます。
ただし、コピーされる画面は、macで表示されている画面で、モニターの画面のコピーができません。



# 書式を省いてプレーンテキストでペースト
#### ■ `command + C ` → `command + shift + option + V`

`command + C` でよくクリップボードにコピーを取ったりしますよね。
ただコピーした内容に書式設定やリンクが含まれている場合、 `command + V` すると、以下のようにそのままペーストされてしまいます。
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322224/701da96e-e708-4c5d-7bd8-4aa97803d0e0.png" />
その時は`command + shift + option + V` で解決。

余計な書式は取り除かれ、プレーンテキストとしてペーストができます。
背景色やフォントなど反映されてしまって、(´･ω･`) となることがなくなりました。



# ブラウザで閉じたタブの復元
#### ■ `command + shift + T`

たまに勢い余って `command + W` （タブを消す）を連打して、あーっ消しすぎた！となる時ってありませんか？
僕だけですかね？

そういう時に限って、「あとで読む」みたいな記事を消していたりするんですが、URLだったり、なんて検索して出てきたページか覚えてない場合が大半です。
僕だけですかね？

その時は、`command + shift + T` で終わり。
あざます！という気分になります。

まあ使う頻度は少ないですが、知ってても良いかなというショートカットでした。




# タブ複製
#### ■ `command + L` → `command + Enter`

これも地味に便利なショートカット。

Webブラウズしてると、今開いているタブを残したまま次のページに進みたいときありますよね？
単純に、カーソルをタブへ移動、右クリック、タブを複製、でも良いんですが、キーボードを離したくない時は、`command + L` → `command + Enter` でタブが複製されます。

が、一番右端に複製タブができるので、ありったけのタブを開き尚且つ左側にあるタブを複製したい場合にはカーソルを使用した方が速いと思います。
（もしくは良い方法があれば教えてくださいmm）

`ｔab + ctrl` や `tab + ctrl + shift`　
でタブを左右に移動するということもできますね。


# その他
ショートカットではないですが、コピペを多用する場合、[Clipy](https://clipy-app.com/)も便利ですね。

Clipyが、[クリップボードへ範囲指定スクショをコピー → ペースト](https://qiita.com/drafts#%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E3%81%B8%E7%AF%84%E5%9B%B2%E6%8C%87%E5%AE%9A%E3%82%B9%E3%82%AF%E3%82%B7%E3%83%A7%E3%82%92%E3%82%B3%E3%83%94%E3%83%BC--%E3%83%9A%E3%83%BC%E3%82%B9%E3%83%88
https://qiita.com/iwaseasahi/items/023964b426305375489e
)に対応していたらと思うとゾッとします。
（ぜひ対応してほしい。）

## 最後に

良いお年を。
【Rails】投稿アプリに基本的な検索機能を実装

# 概要
検索機能を実装する方法をまとめました。

例として、写真投稿アプリに基本的な検索機能を実装する方法を紹介します。

**初学者なので、間違いがあればご指摘いただきたいです。**

# 参照
以下のページを参照しました。ありがとうございました。
<a href="https://techacademy.jp/magazine/22330"> Railsで検索機能を実装する方法を現役エンジニアが解説【初心者向け】
 </a>

# 完成イメージ
今回は、投稿写真のキャプションで検索する機能を実装します。
![貼り付けた画像_2020_12_12_19_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727548/2b7e6b93-a60b-166f-5c17-8a209f618a32.png)
[![Image from Gyazo](https://i.gyazo.com/7fad8891ce8883144d24632d2258d65f.gif)](https://gyazo.com/7fad8891ce8883144d24632d2258d65f)

# 環境
* macOS Catalina 10.15.7
* ruby 2.6.5
* Rails 6.0.3.4

# 実装の流れ
+ ルーティングを追加
+ コントローラーにsearchメソッドを作成
+ 検索フォームを作成
+ 検索結果表示画面を作成

# 今回のコード
## 1. ルーティングを追加
```routes.rb
  resources :photos do
    resources :comments, only: :create
    collection do
      get 'search'
    end
  end
```
1. photosコントローラーにsearchアクションを追加します。
2. collectionとすることで:idを含まないルーティングになります。
<br>ちなみに、memberとすると:idを含むルーティングになります。
<br>参照：https://qiita.com/k152744/items/141345e34fc0095217fe

## 2. コントローラーにsearchメソッドを作成
```photos_controller.rb
  def search
    if params[:keyword].present?
      @photos = Photo.where('caption LIKE ?', "%#{params[:keyword]}%")
      @keyword = params[:keyword]
    else
      @photos = Photo.all
    end
  end
```
1. 検索ボタンをクリックするとsearchアクションが呼び出され、入力した検索ワードをparams[:keyword]で取得できます。:keywordでなくとも好きなキー名をつけることができますが、今回は:keywordとしました。
2. 今回は写真のキャプションで検索するため、Photo.where('caption LIKE ?', "%#{params[:keyword]}%")としました。これで、入力した検索ワードがキャプション内に含まれる写真をすべて取得できます。whereメソッドの使い方については、以下をご参照ください。https://techacademy.jp/magazine/22330
3. 何も入力せずに検索ボタンをクリックした場合は、Photo.allですべての写真を取得することとしました。
4. 入力した検索ワードを取得して検索結果表示画面で使用するため、@keyword = params[:keyword]としました。

## 3. 検索フォームを作成
```erb:index.html.erb
  # クラス名などは省略してあります
  <%= form_with url: search_photos_path, local: true, method: :get do |form| %>
    <%= form.text_field :keyword %>
    <%= form.submit "検索" %>
  <% end %>
```
1. form.text_field :keywordとすることで、検索ボタンをクリックした後、:keywordキーに、入力した検索ワードが値として設定されます。コントローラーのsearchメソッドでparams[:keyword]と設定すると、その値を取得することができます。

## 4. 検索結果表示画面を作成
```erb:search.html.erb
  ## クラス名などは省略してあります
  <h2>検索結果 "<%= @keyword %>"</h2>
  <ul>
    <% @photos.each do |photo| %>
      <li>
        <%= link_to photo_path(photo.id) do %>
          <%= image_tag photo.image.variant(gravity: :center, resize:"640x640^", crop:"640x640+0+0"), if photo.image.attached? %>
        <% end %>
      </li>
    <% end %>
  </ul>
```
1. 上記のとおり、コントローラーのsearchメソッドで、検索ワードが含まれる写真を@photosに格納しました。@photos.each do |photo|で、それらひとつひとつの写真を取り出し、画面に表示させます。
2. <%= @keyword %>で、入力した検索ワードも表示させました。

## おわりに
以上が、今回行った基本的な検索機能実装の方法です。
ハッシュタグ検索など、より高度な検索も今後挑戦してみたいですね。
10秒で分かるExcelショートカット！拡大&縮小

#10秒で分かるExcelショートカット！拡大&縮小
Excelの拡大縮小（ズームイン&ズームアウト）のショートカットは、以下キーの同時押しで可能です。

拡大：Ctrキー、altキー、-(マイナス)キー、shiftキー
縮小：Ctrキー、altキー、-(マイナス)キー

※ただしOfficeのバージョンによっては不可です