OmniAICreator/Qiita-1.07M huggingface dataset:
UnityのUniversal RPを既存のプロジェクトに適用する手順

ゲーム画面にエフェクトをかけようと思って調べたところ、これからはURPを使うのがいいらしいとのこと
さっそくネットで調べてエフェクトを掛けて遊ぼうとおもったのだが、思いっきりハマったので手順を残しておきます

# 開発環境
- MacBook Air
- Unity 2019.4.16f
- Universal RP 7.3.1

# やりたいこと
↓素のゲーム画面
![スクリーンショット 2021-02-19 11.03.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/811027/c27449e5-12b4-7c28-405d-7a0c46248d63.png)
↓エフェクトをかけたゲーム画面（深度ボケとビネット）
![スクリーンショット 2021-02-19 11.03.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/811027/99ec6cee-22c5-4b9a-6e51-44623b089311.png)

# 手順
1. 既存のプロジェクトを開く
2. Universal RPの導入
    1. Window > Package Manager で Universal RPをインストール
    2. Create > Rendering > UniversalRenderPipeline > PipelineAssetからUniversalRenderPipelineAssetを作成
    3. Edit > ProjectSettings > Graphics > ScriptableRenderPipelineSettingsに上記を設定
(※オブジェクトがピンクになるが正常なので焦らず続ける)
    4. Edit > RenderPipeline > Universal Renderpipeline>Upgrade Project Materials to UnivesalRP Materialsを選択
    5. ピンク色のままのオブジェクトがあればUniversal Render Pipeline系のシェーダーに１つづつ変更する
3. カメラの設定変更
    1. Main CameraにUniversal Additional Camera Data(Script)コンポーネントをアタッチする
    2. Main CameraのCameraコンポーネントのなかのRendering > Post Processingをチェックする
4. エフェクトを設定
    1. 空のゲームオブジェクトを作り（名前は何でも良い）、Volumeコンポーネントをアタッチする
    2. Volumeコンポーネントの中のProfileのNewをクリック
    3. Volumeコンポーネントの中のAdd Override > Post-Processing > Vignette（ビネットエフェクト）を選択
    4. Vignetteの中のIntensityをチェックして値を変更してゲーム画面に黒い枠が出るか確認する
![スクリーンショット 2021-02-19 11.26.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/811027/ad6e00d0-db02-c345-c0b4-9cd899179b44.png)

5.Vignette以外のいろんなエフェクトを楽しむ！
（自分用）基礎　変数と定数

#変数と定数

変数・定数とは、プログラムに登場する値を記憶する入れ物のこと。
値を一時的に保存し、一定の範囲内で必要に応じて再利用できる。
変数・定数に値を入れることを"代入"という。

また、全ての変数・定数は代入できる値の種類を表す"型"を持っている。

#変数と定数の違い
代入できる回数が違う。
変数は何度でも値を代入可能、定数は一度のみ。


#宣言方法
宣言とは、新たな変数や定数を定義すること。
それぞれvar、letキーワードを使う。
（var: variableの略、　let: 英単語let ）


```
//変数の宣言
var 変数名: 型名

//定数の宣言
let 定数名: 型名

```

例

```Swift

var a: Int   // "a"という名前のInt型の変数

let b: Int   // "b"という名前のInt型の定数

```

上記の「： Int」部分を"型アノテーション"という。
※annotation：注釈、注解
※Int：integer（整数）の略



#値の代入方法

=演算子を使って、左辺に代入先の変数名または定数名、右辺に代入する値を書く。

```
変数名または定数名 = 代入する値
```

例

```Swift

// Int型の変数aを宣言し、値1を代入
var a: Int
a = 1

// 宣言と値代入は同時にできる
var a = 1
```

#代入可能な値
変数や定数に代入可能な値は、変数や定数の型と一致しているものだけ。
型アノテーションで指定した型と代入する値の型が一致しない場合、コンパイルエラーとなる。


```Swift
let a: Int = 123   //OK

let b: Int = "abc"   //コンパイルエラー

let c: Int = 1 + 2   //演算結果がInt型のため代入OK
```


#代入による型推論

変数や定数の宣言と同時に値を代入する場合、変数や定数の型は代入する値から推論できる。
プログラムの文脈から暗黙的に型を決定するしくみを"型推論"という。

通常、型推論が利用できるケースでは型アノテーションは省略し、
型アノテーションがなければ変数や定数の型を決定できない場合にのみ型アノテーションを追加する。

例

```Swift
let a = 123   // Int型の定数
type(of:a)   // 型を調べる関数

let b = "abc"   // String型の定数
type(of:b)   // 型を調べる関数

// 実行結果
Int.Type
String.Type
```

#定数への再代入

変数には何度でも値を代入できるが、定数は一度だけ。
定数への再代入はコンパイラが自動的に検出しエラーとするため、定数が意図せず変更されることはない。

例

```Swift
let a = 1
a = 2    //2度目の代入はコンパイルエラー
```

```Swift
let a: Int
a = 1   //1度目の代入はOK
a = 2   //2度目の代入はコンパイルエラー
```

#値の利用方法

変数や定数の値を利用するには、値を使用する箇所に変数名や定数名を記述する。
変数名や定数名は、実行時にその値を返す式として解釈される。

```Swift
let a = 1

let b = a   //定数aの値である "1" が定数bに代入される
```


#初期化前の変数や定数の利用

変数や定数への最初の代入を"初期化"という。
初期化されていない変数や定数は値を持っていないため、変数や定数の値を参照する式では値を取り出すことはできない。
Swiftのコンパイラはそのような式を自動的に検出し、コンパイルエラーを出す。

```Swift
let a: Int    // Int型で宣言。値は代入してない（初期化してない）

let b = a + 1   //aが初期化されていないためコンパイルエラー
```
AWS CloudTrailでrootユーザーの証跡を取得する

# コマンド

lookup-eventsコマンドに対して、下記の属性キーと値のペアを一つだけ指定できます。
1. AccessKeyId
2. EventId
3. EventName
4. EventSource
5. ReadOnly
6. ResourceName
7. ResourceType
8. Username

例：UserNameの値がrootのイベントを取得

```terminal
aws cloudtrail lookup-events --lookup-attributes AttributeKey=Username,AttributeValue=root
```

イベントがある場合

```terminal
{
    "Events": [
        {
            "EventId": "<UUID>",
            "EventName": "イベント名",
            "ReadOnly": "Boolean値",
            "EventTime": "2021-02-19T17:55:07+09:00",
            "EventSource": "イベントソース",
            "Resources": [],
            "CloudTrailEvent": "{jsonデータ}"
        }
    ],
    "NextToken": "ランダム文字列"
}
```

イベントがない場合

```terminal
{
    "Events": []
}
```

# 用途
特定のユーザーから不正アクセスがなかったか等、固有のイベントログを取得して確認したい場合に使ったりできます。

# 参考
[AWS CLI を使用して CloudTrail イベントを表示する](https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/view-cloudtrail-events-cli.html)
Visual Studio Code上のJupyter Notebookで使えるキーボード ショートカット

Jupyter Notebook in Visual Studio Codeのコマンドモード（※）で使えるキーボード ショートカットの一覧。~~JupyterLabと比べると意外に少ない… セルの結合が無いのがなぁ(-_-)~~(21年8月追記: VSCode v1.59の新UIで対応しました)
※セルを選択している状態。セルを編集している状態は編集モードという。

# コマンドモードで使えるショートカット

|コマンド|キーボードショートカット| コマンドパレット|
|:--|:--|:-|
| 編集モードにする         | Enter     |
| マークダウンセルにする   | m  |
| コードセルにする         | y  |
| フォーカスを上/下のセルに移動 | k or Up / j or Down|
| 複数セルを選択（連続）    | Shift + (Up/Down or クリック) |
| 複数セルを選択（個別）    | Ctrl+クリック |
| 選択したセルを上/下に移動 | Alt+Up/Down <br> (Fabric: Ctrl+Up/Down)
| セルを実行し、下のセルに移動  | Shift+Enter  |
| セルを実行             | Ctrl+Enter |
| セルを実行し、下にセルを追加  | Alt+Enter |
| 上/下にセルを追加       | a / b  |
| セルをコピー            | c | 
| セルを切り取り          | x | 
| セルを貼り付け          | p | 
| セルを削除              | dd （dを2回） |
| セルの削除をやり直す     | z  |
| セルの入力を表示/非表示  | Ctrl+k Ctrl+c | 
| セルの出力を表示/非表示  | o or Ctrl+k t |
| 上/下のセルと結合        | Shif+Alt+Win+j / Alt+Win+j | 
| セルを下にコピー         | Shift+Alt+Down  |
| 行番号の表示・非表示       | l |
| ブックを保存              | Ctrl+s |
| 選択したセルを結合        | | Notebook:Join Selected Cells|

# 編集モードで使えるショートカット
|コマンド|キーボードショートカット|
|:--|:--|
| セルを分割する         | Ctrl+Shit+-     |

# 参考
- 公式（[Working with Jupyter Notebooks in Visual Studio Code](https://code.visualstudio.com/docs/python/jupyter-support)）
- [【完全版】Jupyter Notebook ショートカット](https://qiita.com/zawawahoge/items/baa2a5318df079c5f7e5)
Animate CC TIPS

Animate CCもだいぶ使い込んできてTIPSも溜まってきたのであまり慣れていないのですが公開していこうと思います
Animate CCは特に日本でユーザーが少ないようで情報を集めるのが大変ですね
そのため海外のサイトを参照することが多いです

最初は投稿の練習もかねています

■グローバル変数

rootにグローバル変数を書いてexportRoot.変数名でアクセスする方法もありますが頻繁に使う変数や関数は「グローバル」という特殊なスペースに記載しておくとどこからでもアクセスできて便利です。

アクションスクリプトウィンドウの左側に出てくるグローバルの中のスクリプトです（下図参照）

![アセット 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162586/05c7192b-eb4f-a880-9b14-8276c2884a89.png)

ただしここに記載したものは書き出しの際、jsではなくhtmlファイルに書き出されますので簡単に見られていいものに限定したほうがよいです。

グローバルスクリプトには関数も置けますので乱数を発生させる関数を置いたりしています。

あとはサウンド関連ではデフォルトでplaySoundがhtmlファイルに書き出されますが一時停止や消音などはないために
グローバルスクリプトに書きます。

サウンド関連はまとめて後で書こうと思います。

こんな感じでいいのかな・・とりあえず
【Rails】バリデーションエラー後のフォーム画面が崩れる時の対処法

#結論

以下を追記して、**その後Railsを再起動**。

```ruby:config/application.rb
config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag }
```


#これで解決する理由
（※解決しない人は、条件が当てはまっていない可能性があります。）

フォーム画面の崩れている部分のHTMLをブラウザの検証機能で確認すると
その近辺に「**field_with_errors**」というclassが記載されたdivタブが見つかると思います。

Railsはバリデーションエラーの際に、自動的にこのタグを追加します。

上記のソースコードはその挙動をオフにするための記述です。
【TypeScript】tscコマンドが使えない時の対処法

# 状況
1. `$ npm i typescript -g`した後に`$ tsc --version`としても`command not found`となる場合
2. iTerm2ではtscコマンドが使えるが、VSCodeでtscコマンドが使えない場合

# Too Long, Didn’t Read
1. PATHを通す
2. 再起動、Nodeの再インストール

# 環境
- MacOS Big Sur v11.2.1
- node v15.9.0
- npm v7.5.3

# 対処
**1. `$ tsc --version`としても`command not found`となる場合**


PATHを通します。
参考：[PATHを通すとは？](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)

npmがグローバルで使用しているディレクトリを確認する

```terminal
$ npm bin -g
/Users/xxx/.nodebrew/node/v15.9.0/bin
```

`.zschr`に追記する（bashの方は.bash_profileで置き換えて読んでください)

```terminal
$ sudo vi ~/.zshrc
```

`i`キーを押してINSERTモードにし、最終行に下記を追記。
私は見やすいようにコメントアウトで説明を書いています。

```terminal
export PATH=$PATH:`npm bin -g`
```

`esc`キー→`:wq`→`enterキー`で保存し、`vi`を抜けます。
`$ source ~/.zshrc`コマンドでやっと編集内容を反映できます。

何も出力されなければ反映成功なのですが、何故か私は反映できないと怒られてしまいました。

```terminal
$ source ~/.zshrc
(not in PATH env variable)
/Users/xxx/.zshrc:export:129: not valid in this context: /Users/xxx/.nodebrew/node/v15.9.0/bin
```

PATHを直で書いてみる。

```terminal
(省略）
# TypeScript
export PATH="/Users/xxx/.nodebrew/node/v15.9.0/bin$PATH"
```
再び`$ souce ~/.zshrc`で反映できました。

```terminal
$ tsc --version
Version 4.1.5
```

**1, `$ tsc --version`としても`command not found`となる場合**は以上です。


**2. iTerm2ではtscコマンドが使えるが、VSCodeでtscコマンドが使えない場合**

上記１のやり方で、tscコマンドをiterm2で使うことが可能になったわけですが、何故かVSCodeのターミナルでは`command not found`のままだったので解決法を探ることに。

1. VSCodeの再起動
2. Macの再起動
3. Node, TSを入れ直す

私は３でやっと直りました。

まず、npmをアンインストール

```terminal
$ npm uninstall -g npm
$ rm -rf .npm \
>node_modules
```

続いてNodeのアンインストール。ソース版だとアンインストールの方法が違います。今までソース版を使っていた方はこれを気にパッケージ版で楽に管理しましょう！

```terminal
$ brew uninstall --force node
...

# homebrewのアップデート
$ brew update

# nodebrewのインストール
$ curl -L git.io/nodebrew | perl - setup
$ export PATH=$HOME/.nodebrew/current/bin:$PATH
$ source ~/.zshrc
```

以下のコマンドを打ち、nodebrewのバージョンが出ればインストール成功。

```terminal
$ nodebrew -v
nodebrew 1.0.1
```
Nodejsのインストール。

バージョン指定もしくは最新のものをインストールできます。
｛｝に次のどちらかを入力

- v○.○.○（例v6.11.4） → バージョン6.11.4
- latest → 最新“

```terminal
$ nodebrew install-binary {}
...
Installed successfully

# インストールしたバージョンのものが入っているか確認
$ nodebrew ls
v15.9.0

# 使用するバージョンを指定する
$ nodebrew use v15.9.0

# 最後にNodeのバージョンを確認！
$ node -v
v15.9.0
```

やっとこれで再起動前と同じ状態のとこまで戻ってきました...

ためしにtscコマンドを打ってみます。

```terminal
$ tsc --version
zsh: command not found: tsc
```

もちろんできません。
最後にTypeScriptをインストールしてあげましょう！

```terminal
$ npm install typescript -g

$ tsc --version
Version 4.1.5
```

VSCode上のターミナルでも問題なく使えました！


参考
---
- [PATHを通すとは？](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)
- ['tsc command not found' in compiling typescript](https://stackoverflow.com/questions/39404922/tsc-command-not-found-in-compiling-typescript)
- [【Mac版】node.jsのアンインストールと再インストール手順メモ](https://qiita.com/wagi0716/items/94193a80502f9d81a9e0)
Laravel ルートディレクトリに packages ディレクトリを配置する

## 概要

Laravelのappディレクトリ配下であれば、自作のPHPクラスやディレクトリを掘って行っても自動的に認識されるのでその場合は特別な設定は不要です。
Laravelのルートディレクトリに、Laravelのコードと明確に分けて自作のPHPクラスを定義したいという時のtipsです。

## ディレクトリ構成

```
.
├── app # Laravel関連のコード
├── bootstrap
├── config
├── database
├── packages # 追加する自作のPHPクラス
│   └── Acme
│       └── Service
│           └── HogeService.php
├── public
├── resources
├── routes
├── storage
├── tests
├── vendor # Laravel本体のコード
├── composer.json
└── composer.lock
```

今回は `Acme\Service\HogeService` クラスを登録します。

補足: `Acme` について
架空のルーニーテューンズ社を指すみたいです。また、「最高点」を意味します。
https://en.wikipedia.org/wiki/Acme_Corporation

`Acme` はSymfony2の頃にプレースホルダーとして使用されていました。(今は違うかも)
Laravelの `App` と被らないから良いなと思って今回採用してます。(`Acme` の代わりにプロジェクト名にするのも良いかなと思います)

## 登録方法

`composer.json` の `autoload.psr-4` のキーに `"Acme\\": "packages/Acme",` を追加します。

```json:composer.json
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Acme\\": "packages/Acme",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
```

## packages 内にクラスを作る

```shell-session
$ mkdir -p packages/Acme/Service
$ touch packages/Acme/Service/HogeService.php
```

```php
<?php declare(strict_types=1);

namespace Acme\Service;

final class HogeService
{
    /**
     * @return string
     */
    public function handle(): string
    {
        return 'hogehoge';
    }
}
```

## オートローダー更新

```shell-session
$ composer dump-autoload
```

tinkerを実行して追加したクラスが認識されればokです。

```php
$ php artisan tinker

>>> $hogeService = app()->make(Acme\Service\HogeService::class);
=> Acme\Service\HogeService {#4569}

>>> $hogeService->handle();
=> "hogehoge"
```

`Acme\Foo\Bar` クラスがLaravelに認識されるようになったのでokです。
一度オートローダーが作られてしまえば、以降作られるファイルは自動で認識されるようになります。

```shell-session
$ touch packages/Acme/Service/FugaService.php
```

```php
<?php declare(strict_types=1);

namespace Acme\Service;

final class FugaService
{
    /**
     * @return string
     */
    public function handle(): string
    {
        return 'fugafuga';
    }
}
```

```php
$ php artisan tinker

>>> $fugaService = app()->make(Acme\Service\FugaService::class);
=> Acme\Service\FugaService {#4567}

>>> $fugaService->handle();
=> "fugafuga"
```

こんな感じです。

## 参考

- https://qiita.com/KEINOS/items/9ff64fe02624df494b44
- https://github.com/shin1x1/laravel-ddd-sample
- https://stackoverflow.com/questions/12599170/what-does-acme-stand-for-in-symfony2
【初心者向け】MVCの全体像をざっくり理解する

# 概要

MVCとは、モデル（データを扱う部分）・ビュー（ユーザーインターフェイス）・コントローラー（ユーザーからの要求を処理し、モデルとビューへの命令に変換する）の3つを頭文字にとったものです。

MVCを理解するには、実際にRailsで一通りコードを書いて流れをつかむことで理解できます。

ですが、コードを書く前にMVCがどんなものか簡単でいいので雰囲気をつかむために、本記事を執筆しました。

**他にもプログラミング学習に役立つような情報を発信しています！**
[アカウントをフォロー](https://qiita.com/techpit-jp)してお待ちください！


## リクエストとレスポンス
ユーザーがブラウザからウェブサイトにアクセスしたとき、ブラウザから**リクエスト**がWebサーバーに送信されます。Webサーバーは送信されたリクエストに対応する**レスポンス**をクライアント側のブラウザに送信します。これが基本的なウェブサイトの仕組みです。

![image](https://user-images.githubusercontent.com/17942948/53431186-5d071880-3a33-11e9-81c0-0f90139fa15f.png)


## ルーティングとコントローラー
リクエストに対応するレスポンスを返すためにRailsでは、ルーティング・コントローラー・ビューという順番で処理を行います。

ユーザーからのリクエストはURLとして届きます。届いたURLから、どのコントローラーのどのアクションを実行するか判断するのがルーティングになります。ファイル名でいうと、`config/routes.rb`にあたります。

![image](https://user-images.githubusercontent.com/17942948/53467887-51e7d300-3a9b-11e9-8457-2f71d64ca92e.png)


## モデル
リクエストが保存しているデータを取得したいときや、新しいデータを保存したいとき、データベースとのやり取りが発生します。ユーザーから呼び出されたアクションは、モデルを介して、データベースとのやり取りを行い、データを取得したり新しいデータを保存したりします。

![image](https://i.gyazo.com/be1adcb428847a38567df21594acc4dd.png)

Railsでは、データベースのテーブル毎にモデルが用意されています。


## ビュー
モデルを介して取得したデータをビューに渡します。ビューは渡されたデータを使ってHTMLを作成しコントローラーに返します。HTMLを受け取ったコントローラーはそのデータをブラウザに返します。

![image](https://i.gyazo.com/ed562bd32775dce2ccbd2286ca8a1d0c.png)

以上がRailsアプリケーションがリクエストを受けた時の処理の流れです。MVCがどんなものか雰囲気は掴めたと思います。次のパートから実際にコードを書いていくので、その際に少しづつMVCを理解して行きましょう。

本記事は[Techpit](https://www.techpit.jp/?utm_source=qiita&utm_medium=social_media&utm_campaign=qiita&utm_content=mvc)の教材[【Ruby on Rails 6】Instagram風簡易SNSアプリを作ってみよう！](https://www.techpit.jp/courses/2/?utm_source=qiita&utm_medium=social_media&utm_campaign=qiita&utm_content=mvc2)を一部修正したものです。
ESP32でBLEの実装作業【スキャン】

# はじめに
今回は前回[ESP32でBLEの実装作業【ブロードキャスト】](https://qiita.com/C0118185/items/32da60974e1593e0587b)の話の続き、ESP32同士にBLEで通信を構築する際にどのような方法でブロードキャストされたパケットを発見することについて紹介します。
# 環境
- IoTデバイス（ESP-WROOM-32）
- ファームウェア（MicroPython1.13）

この記事の作業を始める前にmicropythonのバージョンが1.13であることを確認してください。確認手順は下にある図を参考してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739847/f5df4626-0fd4-5154-8e28-b704e3254890.png)
※バージョンがずっと更新しているので, 異なるバージョンで機能しない可能性があります．
# ソースコード及び結果（ESP32）
今回はBLEをオフにするプログラム`ble_stop.py`とスキャンするプログラム`ble_scanner.py`を分けて説明していきます。
## ble_stop.py
[前回](https://qiita.com/C0118185/items/32da60974e1593e0587b)も軽く言ったと思いますが、BLEを長時間使うと、ブロードキャスターであれオブザーバーであれ、ESP32に膨大な負荷がかかってしまいます。APIとの反応が遅くなるのはともかく、プログラムが機能しないケースも時々起こります。したがって、使用しないときはBLEをオフにすることをお勧めします。
### コード
BLEを稼働するままでオフにする時に下記のコードを使用します。

```ble_stop.py
import ubluetooth
import utime

ble=ubluetooth.BLE()
# macアドレスを十六進数で表示
def form_mac_address(addr: bytes) -> str:
    return ":".join('{:02x}'.format(b) for b in addr)

if ble.active()== True:
    ble.active(False)#BLEをオフ

    print(ble.active())
    #macアドレスを表示する
    print("BLE current mac address: {}".format(form_mac_address(ble.config("mac"))))
```
### 結果
結果は下図の通りでまず今のBLE状態を出力して、次に現在のmacアドレスを表示することにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739847/7aef91a2-029b-29eb-71ef-72c347b93351.png)


## スキャンのプログラム
今回は簡単なBLE電波をキャッチして中身の情報を表示するプログラム`ble_scanner.py`を紹介します。他にも電波をキャッチすることができるデバイス[Bluetooth LE(BLE)のcapture用のTI CC2540 dongle](https://qiita.com/C0118185/items/b49996f51748c1ae2ef2)をとりあえずここで貼っておきます（必要であれば）。
### コード
irqはイベントを喚起する関数です。BLEがスキャンする際に二つEVENTが発生し、それぞれは_IRQ_SCAN_RESULT、_IRQ_SCAN_DONEです。意味は[micropythonのオフィシャルサイト](https://micropython-docs-ja.readthedocs.io/ja/latest/library/ubluetooth.html#observer-role-scanner)を参考する方がよいでしょう。

```ble_scanner.py
import ubluetooth
import utime
import ubinascii
from micropython import const

_IRQ_SCAN_RESULT                     = const(5)
_IRQ_SCAN_DONE                       = const(6)


ble=ubluetooth.BLE()

if ble.active()== False:
    ble.active(True)#BLEを起動する

# イベント喚起関数irq
def bt_irq(event, data):
    if event == _IRQ_SCAN_RESULT:
        # A single scan result.
        addr_type, addr, connectable, rssi, adv_data = data
        print('type:{} addr:{} rssi:{} data:{}'.format(addr_type, ubinascii.hexlify(addr), rssi, ubinascii.hexlify(adv_data)))
    elif event == _IRQ_SCAN_DONE:
        # Scan duration finished or manually stopped.
        print('Scan compelete')
        pass

        
ble.irq(bt_irq)
# スキャン!!
ble.gap_scan(10000, 30000, 30000)


```
### 結果
結果は下図のような成功にスキャンしたパケットの中身を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739847/525e29b4-32ad-2539-2ae0-73ccace4241c.png)


# 最後に
今回はBLEをオフにするプログラム`ble_stop.py`と前回のブロードキャストされたパケットを発見するスキャンプログラム`ble_scanner.py`を紹介しました。次回は本格的にESP32同士のBLE通信を構築する内容を紹介します。
無限スクロールのメリットとデメリット

#プログラミング勉強日記
2021年2月19日
無限スクロールのメリットとデメリットをちゃんと把握していないかったので、まとめる。

#無限スクロールとは
　大量のコンテンツを表示させて、名前の通り終わりなく数ロールされる。具体的には、ユーザがページの1番下までスクロールすると次のコンテンツが追加されて読み続けられるようになる。TwitterやFacebookなどが代表的である。

#メリット

##1. Webページの滞在を長くできる
　コンテンツが続けて表示されるので、ユーザはスクロールを続けることで滞在時間が長くなる。また、興味のあるコンテンツが続けて表示されていれば見たくなる。

##2. クリックよりも優れている
　クリックよりもスクロールの方が早くて簡単に行えるので、ユーザはクリックするよりもスクロールするときの方が心地よく感じている。そのため、ユーザビリティにおいて優れている。


##3. モバイル・タブレット端末に適している
　無限スクロールはもともとモバイルユーザに向けて開発されたようなもので、モバイル端末はスクロール操作を基本としているので適している。また、画面が小さいほどより長いスクロールをすることができる。

##4. 迫力のあるサイトを実現できる
　無限スクロールはビジュアル面を重視したサイトにも最適である。Pinterestスタイルのように、無限のイメージ写真を表示することが可能である。イメージ写真の数やサイズ、形に制限はないので様々なビジュアルを作成できる。

##5. サイトの閲覧が簡単になる
　無限スクロールはシンプルなので、使い方がわかりやすい(サイトが複雑でユーザがわかりにくいということがない)。

#デメリット

##1. フッター情報がない
　フッター部分がなくなってしまう。(フッターを固定すればこの問題は解決する。)

##2. ナビゲーションとリンクがわかりにくい
　無限スクロールの場合、ナビゲーションメニューが複雑になりやすくなってしまう。サイトマップのリンクを付けるとさらに複雑化してしまう。

##3. 読み込み時間が増える
　無限スクロールの場合、ページが固まってしまう可能性もある。

##4. アクセス解析が難しい
　


#参考文献
[無限スクロール vs ページネーション：それぞれの特徴と使い分け](https://uxmilk.jp/50150)
[無限スクロールで確認したい10個のメリット、デメリットまとめ](https://photoshopvip.net/73353)
プリザンター(PostgreSQL版)で大量のデータを削除してゴミ箱を空にしても、DB上にデータが残る対応

# うちのプリザンターで何が起こったか？

プリザンター上で、大量のデータが入ったフォルダを削除し、その後ゴミ箱からも削除したが、
数日後、プリザンターがエラーで接続ができなくなってしまった。

# 原因

OSのディスク容量が100%になっていたため。
どのファイルが悪さしているんだろう？とduコマンドで追っていくと、
日次でバックアップしているプリザンターのデータベースバックアップファイル（dumpファイル）に行き着いた。
毎日、巨大なdumpファイルが出力されており、その結果、ディスク容量を食いつぶしてしまっていた。

※psqlで確認すると、Items_deletedテーブルとResults_deletedテーブルがそれぞれ1GBを超える容量となっていた。

# 対処法

以下のテーブルの全レコードを手動で削除しました。

・Issues_deleted
・Results_deleted
・Items_deleted
よく使うPythonコード　　画像処理編

```python
#画像の読み込み
img = cv2.imread('img.png') 
img = cv2.imread('%d.png'%(i))#画像名，ファイル名に変数が含まれているとき

#画像の保存
plt.imsave("img.png",img)
plt.savefig("img.png")#描画したものを保存したいとき

#画像のトリミング
ymin, ymax, xmin, xmax = 0, 0, 0, 0 #任意に指定
img=img[ymin:ymax, xmin:xmax] 

#画像色変換
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #3d→2d

#画像リサイズ
img2 = cv2.resize(img , (100, 100))

#空画像作成，空配列作成
test = np.zeros((100,100), dtype=np.uint8)#2次元配列全部0
test = np.full((100,100),0, np.uint8)#↑と同じ 変換後の数字を指定できる
Railsチュートリアルのherokuへのpushエラーの対処法(悪い例)自分用メモ

#※この記事に書いてある解決方法は誤りです。
__正確な解決方法はこちらをご覧ください。__
__@jnchitoさんの記事: [リンク](https://qiita.com/jnchito/items/c3035cc49a9cef053549)__
(ご指摘いただいた@jnchitoさん本当にありがとうございます！)
 

以下の内容は自分の戒めのために残しておきます。



3.1 セットアップ

herokuにデプロイする際に以下のエラーが発生。

```
remote:  !
remote:  !     The Ruby version you are trying to install does not exist on this stack.
remote:  !     
remote:  !     You are trying to install ruby-2.6.3 on heroku-20.
remote:  !     
remote:  !     Ruby ruby-2.6.3 is present on the following stacks:
remote:  !     
remote:  !     - cedar-14
remote:  !     - heroku-16
remote:  !     - heroku-18
remote:  !     
remote:  !     Heroku recommends you use the latest supported Ruby version listed here:
remote:  !     https://devcenter.heroku.com/articles/ruby-support#supported-runtimes
remote:  !     
remote:  !     For more information on syntax for declaring a Ruby version see:
remote:  !     https://devcenter.heroku.com/articles/ruby-versions
remote:  !
```


対処法

どうやらherokuのバージョンをダウンさせないといけないようです。
以下の入力で対処しました。

```
$ heroku stack:set heroku-18
Setting stack to heroku-18... done


```

その後もう一度デプロイするとさらに以下のエラーが発生。

```

remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !

```
bundle installが必要なよう。
なので以下をさらに入力


```
 $ bundle install --without production

```
すると、さらにエラー発生


```

You have requested:
  listen = 3.1.5

The bundle currently has listen locked at 3.4.1.
Try running `bundle update listen`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`


```

そこで、再度bundle installを入力後にもう一度install

```
$ bundle update
$ bundle install --without production
```

これで何とかデプロイできました。

しかしながら、この方法は間違っているとご指摘いただきました。
正しい手法はこの記事上部のリンクを踏んでください。
ウェブブラウザの開発者ツールを使用して情報を収集する

開発者ツールには Google Chrome に組み込まれた Chrome DevTools を使用します
ほとんど使用感は同じなのでお好きな開発者ツールを使用してください
ウェブ関係の知識があることを前提にしています

**ウェブ関係の知識?**
自分でもそれがなにか説明できませんが、HTML や CSS、JavaScript の知識があれば大丈夫でしょう
こうなると、どの程度かも必要ですね... もう書きません(諦め)

今回は例として、 ファミリーマートの中華まん の情報を収集します
## 始める
これがそのページです [https://www.family.co.jp/goods/chukaman.html](https://www.family.co.jp/goods/chukaman.html)
ここから商品の情報を収集していきます
準備はページを開き、開発者ツールを開けば完了します
とても簡単でお手軽ですね
## 収集の準備
表示されている情報は収集できます
画像の場合は文字にできないこともないですが、**確実**には収集できないかもしれません

"もっと見る"があった場合は押しておいて、収集したい情報が**表示されている**状態にしておきましょう

まずは名前の要素を見つけましょう
見つけるというか、クリックすればわかります

DevTools の左上にこのようなボタンがあります
![Screenshot from 2021-02-19 17-21-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882623/46e383c5-6021-0310-5762-b2f5e4fbc20f.png)
その後に名前をクリックすると、名前の要素に案内してくれます
その要素のクラス名が、ほかの名前の要素にもついていたらできます
クラス名をメモしておきましょう
## 収集
収集には"Console"を使うので、移動しましょう

このようにして実行すると"NodeList"が返ってきます
その中に収集したい名前の要素がすべて入っていたら成功です

```javascript
document.querySelectorAll('./*クラス名*/')
```

このように実行してコンソールに出力されたら、情報が取れたことがわかります

```javascript
document.querySelectorAll('./*クラス名*/').forEach((v) => {
console.log(v.innerText)
})
```
これで完了です🎉
よく使うPythonコード　　動画作成編

#画像をつなぎ合わせた動画の作成方法
```python
import cv2

fourcc = cv2.VideoWriter_fourcc('X','V','I','D')
video = cv2.VideoWriter('movie.avi', fourcc, 30.0, (100, 100)) #fps, size 
#20.0 = 1秒間に20コマ

  for i in range(0, 100):
    img = cv2.imread("%d.png"%(i))
    video.write(img)

video.release()
```
よく使うPythonコード　　図作成編

#図の作成
```python
#ライブラリ
import matplotlib.pyplot as plt

#図のサイズ指定
plt.figure()
plt.figure(figsize=(20,15))

#微調整
plt.rcParams["xtick.direction"] = 'in' #x軸の目盛の向き: 内側('in'), 外側('out'), 両側('inout')
plt.rcParams["ytick.direction"] = 'in' #y軸の目盛の向き: 内側('in'), 外側('out'), 両側('inout')

plt.rcParams['xtick.major.width'] = 5  #x軸の主目盛りの太さ
plt.rcParams['ytick.major.width'] = 5  #y軸の主目盛りの太さ

plt.rcParams['xtick.minor.width'] = 1.5  #x軸の補助目盛りの太さ
plt.rcParams['ytick.minor.width'] = 1.5  #y軸の補助目盛りの太さ

plt.rcParams['xtick.major.size'] = 20   #x軸主目盛り線の長さ
plt.rcParams['ytick.major.size'] = 20  #y軸主目盛り線の長さ

plt.rcParams['xtick.minor.size'] = 5   #x軸補助目盛り線の長さ
plt.rcParams['ytick.minor.size'] = 5   #y軸補助目盛り線の長さ

plt.rcParams["axes.linewidth"] = 3

plt.rcParams['font.family'] = 'Times New Roman' #フォント

plt.tick_params(labelsize=55)#目盛りの数字の大きさ調整

plt.legend(loc='upper left',fontsize=35)#凡例の位置

plt.gca().yaxis.set_tick_params(which='left', direction='in',bottom=True, top=True, left=True, right=True)　#軸の目盛りの向き

#データ定義
data = pd.read_csv("test.csv")

X = test['X']
Y = test['Y']

#データプロット
plt.plot(X, Y, color="black", label="test", linewidth = 3.0)

plt.xticks([i for i in range (0, 100)])
plt.xlim([0, 100])
plt.yticks([i for i in range (0, 100)])
plt.ylim([0, 100])


#図の画像保存
plt.savefig('test.png')
```

#その他
```python
#軸にπを使いたいとき
plt.yticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
          [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
```
pythonで24時間を超えて時間計算を行う

# はじめに

野暮用で「100 時間 + 35 時間 20 分 = 135 時間 20 分」のような計算をする必要がありました。
時間計算を行うといえば datetime などが利用できますが、24 時間を超えると 1 日として換算されてしまいます。
私には上記のような計算が簡単にできるライブラリを見つけることができませんでしたので、自作した次第です。

コードは[こちら (github)](https://github.com/doranko/time_calculator)です。

# 機能一覧

### 時間表記文字列を時間と分に分割 split_time_str(time)

文字列 time から時間、分を取得して int で返します。

```
import time_calc as tc

hour, minute = tc.split_time_str('123:45')
print(hour)   # 123
print(minute) # 45
```

### 時間表示文字列を分に変換 get_minute_time_str(time)

文字列 time が表す時間を分に直して int で取得します。

```
import time_calc as tc

minute = tc.get_minute_time_str('1:15')
print(minute) # 75
```

### 時間、分から時間表記文字列を生成 generate_time_str(hour, minute)

hour, minute から時間を表す文字列を生成します。
hour, minute はどちらも int です。

```
import time_calc as tc

time_str = tc.generate_time_str(123, 5)
print(time_str) # '123:05'
```
### 分から時間表記文字列を生成 conv_minute_to_time(minute)

minute を時間を表す文字列に変換します。
minute は int です。

```
import time_calc as tc

time_str = tc.conv_minute_to_time(75)
print(time_str) # '1:15'
```

### 時間の足し算 add_time(time1, time2)

文字列 time1 と time2 を足した時間を返します。

```
import time_calc as tc

time_str = tc.add_time('1:30', '2:40')
print(time_str) # '4:10'
```

### 時間の引き算 sub_time(time1, time2)

文字列 time1 から time2 を引いた値を返します。
time2 の方が大きい場合は差分が負の値で返ります。

```
import time_calc as tc

time_str = tc.sub_time('2:10', '1:20')
print(time_str) # '0:50'
```

### 時間の割り算 div_time(time, divide)

文字列 time を divide 分割した時間を返します。
x 日で合計 y 時間にするには、1 日あたり何時間なのか？を求めるために実装しました。

```
import time_calc as tc

time_str = tc.div_time('1:30', 3)
print(time_str) # '0:30'
```

### 時間の比較 comp_time_str(time1, time2)

文字列 time1 と time2 を比較した結果を int で返します。
time1 が大きければ正の値、time2 が大きければ負の値、同じならば 0 が返ります。

```
import time_calc as tc

time1 = '1:00'
time2 = '0:59'
comp = tc.comp_time_str(time1, time2)
if comp > 0:
	print(time1 + ' > ' + time2)
elif comp < 0:
	print(time1 + ' < ' + time2)
else:
	print(time1 + ' = ' + time2)
# 1:00 > 0:59
```
jarを実行するとjava.lang.NullPointerException: Location is required.が出る

#エラー内容
```
■ビルドは通るが、jarにすると下記のエラーが出る
Caused by: java.lang.NullPointerException: Location is required.
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
        at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
        at code.Main.start(Main.java:13)
```

■ソースの階層
src
　∟codeフォルダー
　　∟main.class
　　∟controller.class
　∟fxmlフォルダー
　　∟mainView.fxml

■該当のソースコード
Parent root = FXMLLoader.load(getClass().getResource("../fxml/mainView.fxml"));


#とりあえずの解決
【../fxml/mainView.fxml】
fxmlを呼び出すときに上階層だと読めない？

■ソースの構造を変える
fxmlフォルダーをcodeフォルダーの中に入れる
src
　∟codeフォルダー
　　∟main.class
　　∟controller.class
　　∟fxmlフォルダー
　　　∟mainView.fxml

コードの変更
【../】を削除する
Parent root = FXMLLoader.load(getClass().getResource("fxml/mainView.fxml"));


jarが実行できた！
よく使うPythonコード　

#基本的なライブラリ

```python
import cv2
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
```

#配列変換
```python
#ndarray→list
arr_2d = np.arange(6).reshape((2, 3))
# [[0 1 2]
#  [3 4 5]]
list_2d = arr_2d.tolist()
# [[0, 1, 2], [3, 4, 5]]

#listに変換
test = list(test)

#list→pd
test = pd.Series(test)#１列
test_pd = pd.DataFrame(test)#２列以上

#pd→list
test = test.values.tolist()
```

#データ型変換
```python
#文字列→数字
test = "test"
test2 = float(test)

#数字→文字列
test = 100
test2 = str(test)
```

#CSVファイル系
```python
#csvファイル読み込み
csv = pd.read_csv('csv.csv',header=None)#ファイルの中身そのまま読み込みたい場合

#csv出力
test.to_csv("test.csv",  header=False, index=False)#header, index 指定しない場合

#csvトリミング
test = test.iloc[y_min:y_max,x_min:x_max]

#pd変換
test_pd = pd.DataFrame(test)
result = pd.concat([test_pd1, test_pd2], axis=1)#列を横に連結

#csvデータ名を定義
X=X.rename(columns={0:'X'})
X.to_csv("test.csv")#header, index 指定する場合
```

#リスト
```python
list = []
list.append(test)
```
SQLServerでメモリ不足

メモリ不足でエラーとなりました。

```SQL
このクエリを実行するには、リソース プール 'internal' のシステム メモリが不足しています。
```

サーバで確認すると、タスクマネージャも立ち上がらず。

下記を実施。

```SQL
DBCC DROPCLEANBUFFERS
```

（各クライアントがエラーとなる中、焦っていろいろ調べてみるとサービス再起動とかOS再起動とか物騒なアドバイスが多く、そんなの無理。と思うのは私だけ？）

この後正常に接続できるようになり、SQLも実行できたのでSSMSで下記の設定を行う。
max server memory
実際はインスタンスのプロパティのメモリの上限を変更。
初期値は2,147,483,647 メガバイト。。そんなサーバ無い。
今回は１０００メガバイトでまずは運用してみようかな。
こんなに違うよSQLServer

長年ご愛好してきたOracleからSQLServerへ移り住んでみた感想です。

###テーブル名、列名が大文字小文字が判別される！
Oracle：大文字小文字なんて気にしない。
SQLServer：大文字小文字も見てますよ！

###COMMITがいらない！
Oracle：insert、update、deleteはコミットを忘れずに。
SQLServer：トランザクションを定義しないとコミットしたら、逆にエラー。

・・なんの単位でコミットしてるんだろ。

###テーブル、データのバックアップの構文が違う！
Oracle：Create table hoge as select * from hogehoge;
SqlServer:Select * into HOGE from hogehoge;

・・構文の最初がselectだと誤って実行しそう。

他にも気がついたら更新します。
なんだかOracleに未練たらたら。
初心者の0から始めるDocker生活[mac編]

#はじめに
初心者の備忘録です．
Dockerで世界が変わったっていう友達がいたのでつられて初めてみることにしました．
一応，Docker と SQLとかいろいろ使ってシステムを構築して掲載していく予定なので，
初心者がどのくらいできるか見てやってください．

それでは，れっつごー

#環境
- MacbookAir(2019)
- CPU: intel i5-8550U
- RAM: 8GB


##dockerのインストール＆起動
[Homebrew]("https://brew.sh/index_ja")で入れています．
```cask```は，GUIアプリ(画面上でクリックするやつ，chromeとか)をインストールするときに使うものです．
みんな大好きchromeや，zoomをブラウザで調べてダウンロードするのめんどくさいですよね？
これをコマンド一撃でできるのが```cask```です．
```brew search --cask インストールしたいアプリの名前```で見つかれば入れられます．
なかったらAppStoreやブラウザで取ってきましょう．(Microsoft Remote Desktopとか)
cui(ターミナルで完結するやつ，emacsとかhtop)で取得する場合は，`cask`はいらないです．

brewで取ることによって管理や消すときも綺麗にできます．
とにかくエロい．


```
brew install —-cask docker
open /Applications/Docker.app
```

dockerをguiで取ってきてね．
それ開いてねってコマンドです．
open とするとDocker for Desktopが起動します．(くじらみたいなやつ)

##遊んでみる
```
docker run hello-world
```
ぷろぐらまー御用達のHello-worldですね．

```
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:

....
```
こんなのが出てくるとうまくいってるらしいです．

とりあえず，ここまでで，Dockerの入りができました．

## 悲報
Docker起動しただけでRAM2GB持ってかれました....
Windows,WSL2でDocker立てたので，そちらで更新していきます．


##参考記事
https://docs.docker.jp/docker-for-mac/index.html

https://qiita.com/horit/items/03e6ae6599253afcd75c

https://qiita.com/im_miolab/items/65a16637b80ea6245006
Raspberry Pi 4のUbuntu 20.10 (64bit)にTensorflowをインストールする

ラズパイ4にubuntu(64bit)を入れてTensorFlowを動かしたときのメモ。

まずはともかく`apt update`しておく。
あとは`python3 --version`して、`Python 3.8.6`と、`uname -m`して`aarch64`を確認しておく。

必要になるらしいパッケージを一気に入れる。

`apt-get install python3-protobuf python3-termcolor python3-yaml python3-pydot python3-pyasn1 python3-pyasn1-modules python3-rsa python3-markdown python3-cachetools python3-future python3-dill python3-tqdm python3-pil python3-pip python3-wheel python3-setuptools python3-matplotlib python3-h5py python3-scipy python3-grpcio python3-requests-oauthlib python3-werkzeug`

参考にした
https://qiita.com/kakinaguru_zo/items/fbbee0026025fd1e9bd3
には`python3-wrapt`もあったけど、これはあとでエラーの元になるかもなので、入れないほうがいいかも。
（自分は入れたけど、あとでエラーが出たので、削除した）

ここでサクッと`pip3 install tensorflow`で入れば楽なんだけど、エラーが出てダメだった。

次にこちらのページを参考にTensorflowを入れていく。
https://github.com/PINTO0309/Tensorflow-bin

Python 3.8でubuntu64なので、下のような感じで。

- ダウンロード1<br>
`wget "https://raw.githubusercontent.com/PINTO0309/Tensorflow-bin/master/tensorflow-2.4.0-cp38-none-linux_aarch64_download.sh"`
- ダウンロード2<br>
`./tensorflow-2.4.0-cp38-none-linux_aarch64_download.sh`
- インストール<br>
`pip3 install tensorflow-2.4.0-cp38-none-linux_aarch64.whl`

インストールは時間がかかるが、Successfullyと出ればOK。

```
python3
import tensorflow as tf
print(tf.__version__)
```
で、バージョンが出れば成功。

あとついでにOpenCVも必要になると思うので、
`pip3 install opencv-python`
もしておけばOK。

おしまい。
初心者の0から始めるDocker生活[pythonコンテナ編 feat.Windows WSL2]

#はじめに
こんちはー．
[前回](https://qiita.com/rasuk/private/e18d352a2704c6b25db6)はmacにDockerを入れて遊んでみました．
RAMが8GBしかないせいでdocker遊び障害者になったので，
Windows,WSL2にpythonのコンテナを作って動作確認までします．

unixコマンドの説明もしていくので，参考になれば幸いです．

それでは，れっつごー．

#環境
- OS: Windows10 Pro
- CPU: intel Corei9-9900k 
- GPU: Nvidia GeForce RTX 2080Super
- RAM: 32GB

#Dockerでpythonのコンテナを作る

ホームディレクトリ（cmd,PowerShellで開いた最初に出てくるディレクトリ）で以下のコマンドをやります．

```
mkdir dock
cd dock
emacs Dockerfile
```

1行目```mkdir```は，ディレクトリ(簡単に言うフォルダ)を作るコマンドです．
こいつで```dock```というフォルダを作ります．

2行目```cd```は，簡単に言うフォルダ移動です．
こいつでさっき作ったdockのフォルダ内に移動します．

3行目```emacs```はエディタです．僕が愛用しています．
デフォルトで入っていない場合は，```nano```を使いましょう．
（GUIでのやり方はわからないので，やりたい方がいれば検索してみてください．）

ちょこちょこファイルをいじる分にはnanoで十分です．(最近までnanoでいじいじしてた)


Dockerfileには，下のものをコピペしましょう．
全人類emacsを使いましょう.(圧力)

```Dockerfile                    
FROM python:3
USER root

RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    ENV LC_ALL ja_JP.UTF-8
    ENV TZ JST-9
    ENV TERM xterm

RUN apt install -y emacs
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools                  
```
Dockerfileというやつは，設計図と考えてもらって大丈夫です．
こいつを元に，機械が型を作ります．

emacsのインストールの引数 -y は，
インストールの時にYes/Noと聞かれるものに自動的にyesと回答して進めてくれます．
ないとyes/noで止まってしまうので注意！

じゃあビルド(型を作る)していきましょう．

```
 docker build -f ./Dockerfile -t python .
```
これ最後にピリオドついてるの罠すぎる
気づいた瞬間キレた（）
このピリオドは，現在のディレクトリにビルドするよーって意味だと思います．（たぶんそう）

ビルドできたら```docker images```で確認しましょう．

```
REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
python                   latest    2f672f8444e0   47 seconds ago   1.24GB
```

できたので，実際に動かしていきませう．
さっきビルドしたイメージ(型)を元にコンテナ(製品)を作ります．

引数 
- t : 新しいコンテナの中にターミナルを作ってくれる
- i : コンテナの中と外に双方向に接続できる
- d : コンテナをバックグラウンドで動かしてくれる
- p : ポートの指定ができる

```
docker run -itd --name py python
```
もしubuntuなどのOSのコンテナを立てる場合は，
- u : コンテナ接続時のユーザーを指定する
rasuk(user)のところは，自分がDockerfileで指定したユーザ名を書きましょう．

```
 docker run -itd -u user --name py python
```

runしていきましょー

```
e3fed0039b07ec9f3832d4cca51300e5192347d2e494661a84817859f34d34b5
```
ってのがでると(みんな違う数になると思います．一緒だったら縁ですね．連絡ください)
本当に起動してるか```docker ps```で確認しよう

```
CONTAINER ID   IMAGE     COMMAND   　CREATED    　　　　　STATUS    　　PORTS       NAMES
ed06f8a425ec   python   "python3" 　27 seconds ago   Up 26 seconds               　py
```

なんか起動したっぽい？


そいじゃ作ったコンテナに接続してみましょー
bash は，bashのシェルで起動してくれる，というものらしいです．
なので，zsh派もここで色々できるかな？

```
docker exec -it py bash
```

これで接続できました．

#最後に
エラーが出たら，一回そこのエラー文全文コピペしてググってみましょう．
なんかいきてるなぁって感じがすると思います．

次は，SQL編でお会いしましょう．ばいちゃー

#エラー処理編(今回のpython編じゃ全く関係ない話)
```docker run~~~~```で，
こんなエラーを吐きもうしたら，，，，，

```
3071f5980f66766d05e6605dbf2446642d1f974ead3425c540d96810ab78479f
docker: Error response from daemon: unable to find user username: no matching entries in passwd file.
```
userの設定がうまくいってないかもしれません．
DockerFileを確認してユーザ名チェックしてみてください．
そんで実は，エラーは吐いてるけど裏でコンテナが動いています．
確認は，

```
docker ps -a
```
でみると，あると思います（適当）．
なかったらググってみてください(調べて追記しときます)．
で，裏で動いてるコンテナを消さないと，runしてもエラーでコンテナが立ちません．

```
docker rm コンテナ名
```
で消せます．


#追記
pythonのコンテナ建てるくらいじゃつまんないと思うので，Ubuntuのコンテナも建てました．
sshでリモート先に目的のファイルが存在するかの確認

- sshで、リモート先に目的のファイル、あるいはディレクトリが存在するのか確認したい。
- sshでログインはしたくない。
- ローカル側のスクリプト内で実行したい。

ファイルを確認したい
ファイルだったら 戻り値0
ファイル以外だったら 戻り値1

```bash
$ ssh user@host.local 'test -f  ~/data/testfile'
echo $?
0
```

ディレクトリを確認したい場合

```bash
$ ssh user@host.local 'test -d  ~/data/testdir'
echo $?
0
```




----
間違ってはいないけど無駄だった方法
 
```bash
$ ssh user@host.local 'test -f  ~/data/testfile;echo $?'
0
```

ディレクトリを確認したい場合

```bash
$ ssh user@host.local 'test -d  ~/data/testdir;echo $?'
0
```


スクリプト内で戻り値を取る

```bash
RC=$(ssh user@host.local 'test -d  ~/data/testdir;echo $?')
```

$RC を　if文等で評価すれば良し
【VBA】シートに改ページを設定しようとしたらエラーが起きる

#区切り線の位置が取得できないとき

```vb
Dim r As Long
r = Worksheets(1).HPageBreaks(i).Location.Row
```

などとして区切り線の位置を取得しようとすると、実行時エラーがおきることがあります。
これは、画面に表示されていない範囲にある区切り線の位置が取得できないことがあることが原因かもしれません。

詳細はこちら↓
[HPageBreaks または VPageBreaks.Location 使用時の "インデックスが有効範囲にありません" エラーについて](https://support.microsoft.com/ja-jp/topic/-xl2002-hpagebreaks-または-vpagebreaks-location-使用時の-インデックスが有効範囲にありません-エラーについて-ec4a8e22-9b58-349d-b160-f7a4f561c809)

回避策としては、最終セルの選択を行います。

```vb
Worksheets(1).Cells.SpecialCells(xlCellTypeLastCell).Select

Dim r As Long
r = Worksheets(1).HPageBreaks(i).Location.Row
```

このとき、高速化のために`Application.ScreenUpdating = False`としていると、最終セル選択時の描画が行われず、エラーが回避できないので注意してください。
#区切り線の位置が変更できないとき

```vb
Set Worksheets(1).HPageBreaks(i).Location = Range("A3")
```

などとして区切り線の位置を変更しようとすると、実行時エラーがおきることがあります。
これは、表示モードが改ページプレビューでないことが原因かもしれません。
回避策としては、改ページプレビューにしてから区切り位置を変更してください。

```vb
ActiveWindow.View = xlPageBreakPreview

Set Worksheets(1).HPageBreaks(i).Location = Range("A3")

ActiveWindow.View = xlNormalView
```
ちなみにWorkbookオブジェクトからウィンドウを取得する場合は、`Workbooks(1).Wondows(1)`などとします。
本番サーバーでやらかした話（rm -rf /）

2020年秋、ちょっと手術で入院してまして、その間の運用・保守は他人に引き継いだものの、大きな問い合わせはなく、クライアントも問い合わせを止めていたようでした。
で、職場復帰して数日後にサーバーのログからでないと調査が難しい案件を指示されたので、スクリプトを組んで調査しようと思ったのです。

# どんなコードを書いたのか

もう覚えてないのですが、以下のような感じのコードです。

```sh
#!/bin/sh

cd $(dirname $0)
TMP_DIR="tmp"
rm -rf ${tmp}/*

# do something
```

意図としては、tmpディレクトリを作って、中間作業ファイルをそこに入れて、結合やgrepやAWKして、最終的な結果を出力するという私的には鉄板のやり方でした。

でもおかしくないですか。5行目が。

`tmp`なんて変数は定義していない。`TMP_DIR`変数と間違えていたみたいです。
結果、`rm -rf /*`という終末のラッパのようなコマンドが走っていました。

# 異変に気づく

スクリプト実行後やけに時間がかかるのと、想定外にPermission deniedが多いなと思って、スクリプトをキャンセルして`ls`してみるとカレントディレクトリのファイルが無くなっている。。。
スクリプトファイルはローカルマシンで組んでいたので、見返してみると、「あっ・・・」って感じでした。

# 焦ってはいけない

まずいところはいくつかあるのですが、まずこれを実行したのが、本番サーバーのうちの1台だったのです。（同じような構成のサーバーが数十台以上あります）

SSHクライアントとWinSCPでSSH接続は維持している状態でした。
__焦ってはいけない。__
まずは他のサーバーの同じユーザーから`.ssh`ディレクトリを持ってきて、パーミッションを設定。新規にSSHできるように復旧しました。
リモートできなくっては元も子もありません。

ウェブ系を始めとするアプリケーションファイルは`/var`以下に設置していたので、アルファベット順的に最後の方なので、被害は免れているみたいでした。
念の為、再同期、再デプロイしておきましたが。

また実行したのは`root`ユーザーでもなく、`sudo`していたわけでもなかったので、被害はログインユーザーのホームディレクトリだけとなっていました。

# 報告と謝罪

新規SSHができるところまで確認したらとにかく報告と謝罪です。
共有アカウントだったので、調査用に仕込んでいたログが消失していたのだとか。
それ以外のスクリプトなり何なりは他のサーバーから復旧できるということでした。
サービス上実害がなかったこともあり、私が打たれ弱いのを知ってか、お咎めはなく、「まぁ誰でもやることだから」と始末だけして、許してもらえました。
アプリケーションが止まったわけでもないので、クライアントへの報告もなし。内々で処理しました。

ただ、調査用に設置していたスクリプトは復旧できてもログやその他ファイルは復旧できない。
社内には平謝りです。

# 反省点

色々反省点はあります。

- なぜ本番で実行してしまったのか。
    - ログファイルは大体本番にしかない。
    - やっていたログ調査自体がトライ・アンド・エラー的な要素を持っていた。
    - ログファイル自体が巨大で、ファイル転送に時間がかかるし、本番サーバーのパワー有り余ってるし。（ちょっとした言い訳）
    - みんなも本番でやっていることだし、今までも大丈夫だったし。。。（正常性バイアスみたいな？）
- 意図しないコードを実行させない工夫をしなかったのか
    - いっぱいコードを書いてきましたけど、独学ゆえ知らなかっただけです。。。
        - [シェルスクリプトを書くときはset -euしておく](https://qiita.com/youcune/items/fcfb4ad3d7c1edf9dc96)

# 最後に

これからも本番でしていまうでしょう。
気をつけたいと思います。
みなさんもお気をつけください。
【Rails】Herokuのエラー「cannot load such file -- bootsnap/setup (LoadError)」を解決する

#課題

Herokuにデプロイした際に下記エラーが出てデプロイができませんでした。

```ruby:
!     Could not detect rake tasks
!     ensure you can run `$ bundle exec rake -P` against your app
!     and using the production group of your Gemfile.
!     /tmp/build_68e54361/config/boot.rb:4:in `require': cannot load such file -- bootsnap/setup (LoadError)
```

#原因

Herokuではbundlerがバージョン2.1.4までしか使えず、ローカル環境とherokuの環境でbundlerのバージョンが違うことが原因であると考えました。

実際に自身のGemfile.lockは以下のようになっており、2.2.2が設定されていました。

```ruby:Gemfile.lock
RUBY VERSION
   ruby 2.6.5p114

BUNDLED WITH
   2.2.2
```

#解決策

上記原因を解決するために、bundler2.1.4でもう1度bundle installを行えば解決できると考えました。

**① bundlerのインストール状況を確認する**

```ruby
$ gem list bundler

*** LOCAL GEMS ***
bundler (default: 2.2.2, 2.1.4)
```

**② バージョン2.1.4があるのでバージョンを指定してインストールする**

```ruby
$ bundle _2.1.4_ install
```

この後、変更内容をpushしてHerokuでデプロイを行ったら掲題課題を解決することができました！！
Gitで履歴からファイルを消す


# 概要

誤って個人情報の入ったファイルをcommitしてしまった際に、履歴を遡ってファイルごと削除するコマンドのメモ。

# コマンド

コマンドはGit管理しているディレクトリのトップで実行し、ファイル名はフルパスで指定する。

```shell
git filter-branch --index-filter 'git rm --cached --ignore-unmatch aaa/bbb/password.txt' HEAD
```

これで削除できないケースもあったが、「-f」オプションを付けて実行することでうまくいった。

```shell
git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch aaa/bbb/password.txt' HEAD
```

いくつかのファイルを消した場合、念の為「git grep」で確認すると安心。

```shell
git grep MyPassword
```
Heroku上で、一部ページを開こうとするとStatus=500のエラー

#結論
Heroku上で、ユーザー一覧を開こうとするとStatus=500のエラーが出ましたので
以下の2つのコマンドを実行することでエラーを解決しました。

```
$ heroku run rails db:rollback
```
↓

```
$ heroku run rails db:migrate
```

※heroku run rails db:rollbackは一度テーブルを差し戻すため、カラムに保存されているデータは削除されます。実行には注意ください。


#バージョン
rubyのバージョン　ruby-2.6.5
Railsのバージョン Rails:6.0.0

#Status=500のエラーが起こるまでの経緯
エラーが起こる前の、Hrokuにデプロイを行ってからの作業はviewの調整でした。
viewの調整後、デプロイしHeroku上で、ユーザー一覧を開こうとすると以下のエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/ce5f1830-453f-6b12-fcfa-75977ce12904.png)

localで確認すると、問題なく開かれました。

なのでlogを確認しました。

```
heroku logs --tail --app アプリ名
```

すると文末にstatus=500とのエラーが出ました。

#そもそもstatus=500とは？
status=500はウェブサーバーに何らかの問題が発生しているという信号です。
具体的なエラーや根本原因が明確ではなく、複数の原因が考えられます。


#エラー原因の仮定
普段からユーザーにアプリを使ってもらってレビューしてもらっているので
何かしらの形でユーザー情報が壊れてしまったのだと仮定しました。
（壊れる仕組みについてはまだ断定できていないです（怖））


#行ったこと①
まず、一度ユーザーデータが壊れていると仮定しているので、heroku run rails db:migrate:resetで、DBのリセットとmigrateを同時に行い、migrationの中身をキレイにしようと思いました。

```
$ heroku run rails db:migrate:reset
```

しかし、以下のエラーが出ました。。。

```
〜省略〜

rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1

〜省略〜

```

拒否られましたね。

Rails6ではDBを破壊する系のコマンドを防止する機能があるため起こったと考えられます。

エラー通りに環境変数 DISABLE_DATABASE_ENVIRONMENT_CHECK=1指定すれば問題ないかと思うのですが、私は違う方法を取りました。


#行ったこと②
DBの情報をリセットする方法として、heroku run rails db:rollbackを行えば良いのではないかと考えました。
heroku run rails db:rollbackは一度テーブルを差し戻すことができるためです。

実際に差し戻しdb:rollbackと更新db:migrateを行いました。

```
$ heroku run rails db:rollback STEP=○
```
※現在地を含めた○個前までなかったことにしてくれます。
つまり○+1個前のファイルまで実行された状態となります。

↓

```
$ heroku run rails db:migrate
```

無事Heroku上でユーザー一覧を開くことができました。
ユーザー情報が壊れてしまう仕組みがあるかもしれないので、今後はその原因究明に努めます。

#記事の紹介
前回もstatus=500のエラーが出てデバックした時の記事です。
よろしければご参考ください。

内容は全く違うエラーの内容となっております。
https://qiita.com/narimiya/items/39b896f2a1bee9db99d7

以上です。
【Blender初心者】ノートPCでBlenderを使う際、テンキーを模倣する方法


__動作環境__
・ Blender 2.91.0


Blenderで視点変更（正面から見る、左側から見る、等）をするには、テンキーを使うと便利です。
ですが、私も含め「とりあえず手持ちのノートPCでBlenderを始めてみた」という人も多いかと思います。
そんな場合は、Blenderの機能で__文字キーの上部にある数字キーでテンキーを模倣する__方法がありますので、設定を行うと便利です！


#設定方法

1.　【編集】→【プリファレンス】
![0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1122815/9d0d11a6-a9a6-cd88-1d8b-e4bd552c40c1.png)


2.　【入力】→【テンキーを模倣】のチェックを入れる
![0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1122815/331f4fe2-6793-0ada-6502-eda57ba7971a.png)


たったこれだけです！
私は最初、テンキーの代替ができることを知らなくて、マウス操作で【ビュー】→【視点】→【上】等と選択していました・・・。
それが今は【7】キーを押すだけで良いので、作業が捗ります！
【Laravel初心者】投稿削除機能の実装

Laravel初学者です。
オリジナルアプリを作成しているのでその過程を記事にしています。

理解が曖昧なところも多いため、ご指摘等ありましたらご連絡いただければ幸いです。

今回は投稿の削除機能の実装について備忘録のため記録として残します。
関連記事：
[【Laravel初心者】一覧表示の実装](https://qiita.com/mumucochimu/items/b0221657a3981f4a4f49)
[【Laravel初心者】投稿保存の実装]
(https://qiita.com/mumucochimu/items/12bd2d46b73891e737e2)
[【Laravel初心者】投稿編集機能の実装]
(https://qiita.com/mumucochimu/items/943fb5c8838ae6e586bb)


## 環境

|                | Version     |
|:---------------|------------:|
| PHP            | 7.4.14      |
| Laravel        | 8.24.0      |
| mysql          | 8.0.23      |
| docker         | 20.10.2     |
| docker-compose | 1.27.4      |


## ルーティング

```PHP:routes/web.php
Route::resource('/game', App\Http\Controllers\GameController::class)->only(['create','store','show','update','destroy']);
```

`resource`で`destroy`を追加します。


## コントローラー

```PHP:app/Http/Controllers/GameController.php
/**
* Remove the specified resource from storage.
*
* @param  int  $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
  Game::where('id', $id)->delete();
  return redirect('/')->with('success', '削除しました');
}
```

`where`で該当のidを探し`delete`してます。

## ビュー

```PHP:
<form
  style="display: inline-block;"
  method="POST"
  action="{{ route('game.destroy', $game->id) }}"
>
@csrf
@method('DELETE')
<button class="btn btn-danger">削除する</button>
</form>
```

`action="{{ route('game.destroy', $game->id) }}"`で`destroy`アクションを指定してます。`$game->id`がないとどれを削除すればいいか分からずエラーになるので忘れずに。

`@method('DELETE')`で指示してあげています。

参考記事：[【Laravel】掲示板を作成する（5）投稿編集機能、投稿の物理削除](https://nodoame.net/archives/11628)

以上です。
laravel 認証機能を指定のフォルダに格納

#はじめに
`php artisan ui vue --auth`で認証機能を実装した際、`User.php`を指定のフォルダに格納して見えやすくしたい!!という思いがあったので実際に改良してみました。

#投稿者の環境
MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
macOS Big Sur バージョン11.0.1
PHP 7.3.23
Laravel Framework 6.20.7

###STEP 1
今回はModelsというフォルダに格納したいと思います。User.phpをModelsフォルダに手動で移動させて下さい 

###STEP 2 registarController.phpを編集しよう
`use`を使用して、クラスの呼び出しを変更します。下記のように2箇所編集します。

```registarController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User; //こちらを左のように変更
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
//以下省略

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return App\Models\User //こちらを左のように変更
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
}

```

###STEP 3 configフォルダを編集しよう

そのままログインすると`Class '\App\User' not found`というエラーが発生します。ここでどハマりして中々解決できませんでしたが、こちらの[Qiita](https://qiita.com/niiyz/items/5b83ef5255a1ec64d9d6)を参考にして解決しました。

###エラー文 Class '\User' not found
名前空間を指定しようとしてデフォルトで存在しているModels/User.phpなんかに名前空間指定するといろんなところでエラーになると思います。 下記の様に編集します。

```
app/config/auth.php
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
```

![“スクリーンショット” 2021-01-30 19.03.43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/57d563d1-2f6f-47b1-9163-6d2ad97127f6.jpeg)

### 最後に
如何でしょうか?
今回、あまり触らないファイルを編集したので少し不安でしたが何とか反映することができました。何か突っ込む所があれば突っ込んでいただきます様お願いします。
iOS13以降のSegmentedControlで下線を端まで伸ばす

## はじめに

よくある上タブ実装でタップしているタブの下に下線をCALayerで引くというのをやったんですが、iOS13以降だと角が丸まってしまいました。

![スクリーンショット 2021-02-19 15.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/23d80e9b-dbef-780a-5888-0020f0ec1ba1.png)


その際に[こちら](https://medium.com/flawless-app-stories/ios-13-uisegmentedcontrol-3-important-changes-d3a94fdd6763)を参考にして対応しました。

## Sampleコード

```swift

/// iOS13以降だとSegmentedの角が自動で丸まってしまうので、Radiusを上書きしたclassを用意
class SquareSegmentedControl: UISegmentedControl {
    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = 0
    }
}

```

![スクリーンショット 2021-02-19 14.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/5d758954-1843-7612-34ca-4c8c340628e2.png)
EC2からDocumentDBに接続してみた

業務でDocumentDBを利用する場面があったので、慣れるために一旦EC2からDocumentDBに接続してみました。
どうやらDocumentDBはMongoDB互換のデータベースらしいです。
私はMongoDB自体も初めてだったので、なんのこっちゃという感じでした。
この記事が、私と同じように困っている方の参考になれば幸いです。

# 前提
* DocumentDBに`mongo`コマンドでアクセスしたい場合は`mongo-org-shell`をインストールする必要がある
* Linuxに`mongo-org-shell`をインストールするにはリポジトリを追加する必要がある
    * 普通に`yum install`のではダメ。リポを追加しないと
* 今回のOSには「Amazon Linux2」を利用する
    * Amazon Linux2のパッケージ管理ツールは`yum`


# 事前準備
* VPC（サブネットなどの周辺リソースも）とEC2インスタンスを作成
* 上記で作成したVPCでDocumentDBを作成
* セキュリティグループを適切にEC2インスタンス・DocumentDBに設定


# ゼロから接続する手順
#### mongodbのyumリポジトリを追加する

`/etc/yum.depos.d/`下に`mongodb-org-4.4.repo`というファイルを作成

```:mongodb-org-4.4.repo
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc
```

注意）利用したいmongodbのバージョンによって、ファイル名やコードは変更してください。
　例えば、4.0を利用したいなら`mongodb-org-4.4.repo`ではなく`mongodb-org-4.0.repo`


#### mongo-org-shellをインストールする

```bash
$ yum install -y mongo-org-shell
```


#### DocumentDBへのSSL接続に必要な鍵をダウンロード
```bash
$ wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
```

#### mongoコマンドでDocumentDBにSSL接続
以下のコマンドを実行するとDocumentDBに接続でき、mongo-shellの対話画面が始まる。

```bash
$ mongo --ssl --host <host_name>:27017 <db_name> --sslCAFile rds-combined-ca-bundle.pem --username <username> --password <password>
```

# おまけ
#### mongoimportを使いたい場合
`mongo-org-tools`をインストールする

```bash
$ yum install -y mongo-org-tools
```

以下のようにコマンドを実行すればjsonデータを挿入できる

```bash
$ mongoimport --ssl --host <host:port> --db mydb --collection mycollection --file myfile.json --sslCAFile rds-combined-ca-bundle.pem --username <username> --password <password>
```


# 参考
* [Amazon EC2 を使用して接続 - Amazon DocumentDB](https://docs.aws.amazon.com/ja_jp/documentdb/latest/developerguide/connect-ec2.html)
* [NLB経由でAmazon DocumentDBに接続する方法を検証しました | DevelopersIO](https://dev.classmethod.jp/articles/docdb-via-nlb/)
* [Install MongoDB Community Edition on Amazon Linux — MongoDB Manual](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-amazon/)