OmniAICreator/Qiita-1.07M huggingface dataset:
【Android】AndroidセンサーAPIの種類

#プログラミング勉強日記
2021年1月18日
Android端末には様々なセンサーが搭載されている。具体的には温度や方位、方角、明るさ、傾き、加速度センサーなどがある。そういったセンサーを使うために必要なセンサーAPIについてまとめる。

#AndroidのセンサーAPI
　Androidでは、センサーによって変換された電気信号を取得するためのセンサーAPIが提供されている。このAPIによってセンサーを用いたアプリを簡単に開発できる。
　android.hardwareパッケージには、<b>SensorManager、Sensor、SensorEvent、SensorEventListener</b>の4つのセンサーAPIが提供されている。

##SensorManager
　センサーにアクセスするためのクラス。各センサーのイベントリスナーの登録や解除、センサーの情報の取得を行う。

```java:SensorManagerクラスのメソッド
// イベントリスナーを登録するメソッド
registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler)
registerListener(SensorEventListener listener, Sensor sensor, int rate)

// イベントリスナーを解除するメソッド
unregisterListener(SensorEventListener listener, Sensor sensor)
unregisterListener(SensorEventListener listener)

// 使用可能なセンサーをリストで取得するメソッド
getSensorList(int type)
```

| 定数名 | 説明 |
|:--:|:--:|
| SENSOR_DELAY_FASTEST | 最速通知頻度（デバイスのスペック次第）|
| SENSOR_DELAY_NORMAL | 通常のサンプリング |
| SENSOR_DELAY_GAME | ゲームに適した早い反応速度 |
| SENSOR_DELAY_UI | UI向けの遅い反応速度(ゲームではないアプリ向け) |

##Sensor 
　各センサーに関する情報を管理するクラス。

```java:Sensorクラスのメソッド
// センサーが検出できる最大値を取得するメソッド
getMaximumRange() 
// センサーの名前を取得するメソッド
getName() 
// センサーからの電気信号をmAで取得するメソッド
getPower() 
// センサーの精度を取得するメソッド
getResolution() 
// センサーの種類を取得するメソッド
getType() 
// センサーのベンダー名を取得するメソッド
getVendor() 
// センサーのバージョンを取得するメソッド
getVersion() 
```

センサーの種類

| 名前 | 説明 |
|:--:|:--:|
| TYPE_ACCELEROMETER | 加速度センサー |
| TYPE_MAGNETIC_FIELD | 磁界（磁気）センサー |
| TYPE_ORIENTATION | 方位（傾き）センサー |
| TYPE_GYROSCOPE | ジャイロスコープセンサー |
| TYPE_LIGHT | 照度センサー |
| TYPE_PRESSURE | 圧力センサー |
| TYPE_TEMPERATURE | 温度センサー |
| TYPE_PROXIMITY | 近接センサー |
| TYPE_GRAVITY | 重力センサー |
| TYPE_LINEAR_ACCELERATION | 直線加速度センサー |
| TYPE_ROTATION_VECTOR | 回転角度センサー |
| TYPE_ALL | 指定したセンサーの全ての値が取得できる |

##SensorEvent
　センサーが取得できる情報を1つにまとめて管理するクラス。

```java:SensorEventクラスのフィールド
// センサーの精度を格納するフィールド
int accuracy 
// Sensorオブジェクトを保持するフィールド
Sensor sensor
// タイムスタンプを格納するフィールド
long timestamp 
// センサーの値を格納するフィールド
float[] values 
```

##SensorEventListener
　センサー関連のイベントを取得するためのイベントリスナー。SensorManagerのメソッドでこのイベントリスナーの登録や解除をすると、センサーからの情報を取得できる。

```java:SensorEventListenerのメソッド
// センサーの精度が変わったときに呼び出されるメソッド
onAccuracyChanged(Sensor sensor, int accuracy)
// センサーの値が変わったときに呼び出されるメソッド
onSensorChanged(SensorEvent event)
```

#参考文献
[センサーの概要](https://developer.android.com/guide/topics/sensors/sensors_overview)
Unity Input System


# 環境
Unity2019.4.16
OS : windows10 pro
IDE : VS2019 free
# 概要
InputSystemを使用するにはUnity 2019.1以降+および.NET 4ランタイムが必要

# 参考
https://forpro.unity3d.jp/unity_pro_tips/2021/05/20/1957/
http://tsubakit1.hateblo.jp/entry/2019/01/09/001510


# [Unityの新しい入力システムInputSystemを使ってみる](https://gametukurikata.com/basic/inputsystem)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/ee19c9c9-8dc1-451e-b7de-b46ed9921128.png)

# メモ１

・Package ManagerでInputSystemをインストール
・Net4.0にする
・上記の[Player]-[Active Input Handling]をBothまたはInput System Package(New)にする
・Createボタンを押す

Unity再起動します。次の画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/7f6ff9df-2c71-7e8c-71e6-4323257a58f0.png)

対応したいキーボード、マウス、VR(Oculus)などのデバイスを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/39615166-de93-8c53-ac8d-3357a29b6723.png)

# アクション設定ファイル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/b3b6da17-aaad-09d4-8ca9-14de384fbb6c.png)

# マウスの認識

Unity2020.2.0f1 だとマウス認識されない、Mouse.current==NULLになる。つかえない？


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/89e40e91-df35-ea4f-0dc2-a477134fa3f4.png)

```
    if (Mouse.current!=null){
            if( Mouse.current.leftButton.wasPressedThisFrame){
                Debug.Log("マウスの左ボタンが押された");

            }
        }
```

# コード
OnArrow,OnFireに着目。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/b3fc1588-ffbd-5611-282e-1d08667993d7.png)

```
public class UnityEventScript : MonoBehaviour
{
    public void OnFire(InputAction.CallbackContext context)
    {
        Debug.Log(context);
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        var value = context.ReadValue<Vector2>();
        Debug.Log(value);
    }
}
```
VSCode+Pythonでmicro:bitを触ってみる

micro:bitのプログラムをVSCodeとPythonで書いてみたメモです。
ビジュアルプログラミング環境で作れるのがmicro:bitの特長であって、わざわざPythonで書きたい人がいるかは怪しいですが...。
使用環境はこんな感じ。

* MacOS Catalina 10.15.7
* VSCode 1.52.1
* Python 3.9.0

VSCodeにはPythonの拡張機能がすでに入っている前提での解説です。

# 1. uflashのインストール
micro:bitにPythonプログラムを書き込むためのツールです。

```
$ pip install uflash
```

このあと導入するVSCodeの拡張機能が"uflash"コマンドを使用するようなので、ちゃんと使えるか確認しておきます。

```
$ uflash --version
uflash 1.3.0
```
バージョンが出ればOKです。

# 2. VSCode拡張機能のインストール
micro:bitに対応した拡張機能をVSCodeに入れます。
拡張機能の検索欄で「micro:bit」と検索し、↓の拡張機能をインストールします。
![スクリーンショット 2021-01-15 20.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365868/e863f5bd-518d-bb6c-a674-d1f80b1231d3.png)
インストールしたあとは一応VSCodeを再起動しておきましょう。
これで環境の構築は完了です。

# 3. Pythonファイルの作成
適当な場所に新しいディレクトリを作成し、その中にPythonファイルを作成します。
ここではディレクトリ名を「microbit」、Pythonファイル名を「main.py」としました。
作成したディレクトリをVSCodeにドラック&ドロップし、VSCode上でPythonファイルを開きます。
![スクリーンショット 2021-01-15 20.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365868/7ea2385d-a563-7bf8-79cd-079c8c73358c.png)
拡張機能がうまく入っていれば右上に「Build current file to Micro:Bit」というボタンが出てきます。

それではmicro:bit用のコードを書いてみます。

```py
from microbit import *

while True:
    if button_a.is_pressed():
        display.show(Image.HAPPY)
    else:
        display.show(Image.ANGRY)
```

# 4. 補完が効かない問題
ここまででも最低限micro:bitへ書き込みができるのですが、まだVSCode上でmicro:bit用の関数に赤線が出てくる上に補完も効きません。
補完を働かせるにはVSCodeのコマンドパレット(Cmd+Shift+P)を開き、以下のコマンドを実行します。

```
Fetch micro:bit modules
```

コマンド実行直後はまだ赤線が消えませんがソースファイルを一度保存すると反映されて赤線が消えます。

# 5. micro:bitへの書き込み
micro:bitをPCに接続し、「Build current file to Micro:Bit」ボタンを押すとmicro:bit本体のオレンジ色LEDが点滅し始め、点滅が終わると書き込み完了です。
書き込み完了後、本体のAボタンを押したり離したりすると5×5LEDマトリクスに表示される顔の表情が変わります。

# 余談
micro:bitは単体でもLED/ボタン/センサが内蔵されていて、複数台揃えれば無線通信も可能なので工夫次第で面白いものが作れそうです。
大学の学祭で体験会をやったことがありますが、ビジュアルプログラミング環境MakeCodeを使えばプログラミング未経験の小学生でも楽しく使うことができる印象でした。
Pythonを使う場合でも[日本語のドキュメント](https://microbit-micropython.readthedocs.io/ja/latest/index.html)がしっかりしているので比較的始めやすいのではないでしょうか。
だいたいの子供向けプログラミング教材が1万円以上することを考えると、本体だけなら3000円前後で買える上にビジュアル開発環境もテキスト開発環境もサポートしているmicro:bitは有力な選択肢になりそうです。

# 参考文献
* uflash - PyPI<br>
https://pypi.org/project/uflash/
* micro:bit - Visual Studio Marketplace<br>
https://marketplace.visualstudio.com/items?itemName=PhonicCanine.micro-bit
* BBC micro:bit MicroPython ドキュメンテーション<br>
https://microbit-micropython.readthedocs.io/ja/latest/
AWS EC2 nginx SSHポート番号変更の方法

AWS EC2 nginxサーバーのSSHポート変更してみた
---

やること
①AWSセキュリティグループ(インバウンドルール変更)
②/etc/ssh/sshd_configのport変更
③sshd再起動
④configファイルのポート変更

①AWSセキュリティグループ(インバウンドルール変更)
---
EC2→セキュリティグループ→任意のセキュリティグループを選択→インバウンドルールの変更
![スクリーンショット 2021-01-18 17.41.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697150/8d0d7918-5ac9-e700-5401-04baeb91b1a3.png)
▷青枠のところに任意のSSHポートを記入
▷真ん中の枠にはIPアドレス関連の情報を記入
▷右の枠には説明を記入

②/etc/ssh/sshd_configのport変更
---
①で設定した任意のSSHポートを記入

```
#Port 22
Port 任意のもの
```

③sshd再起動
---
```
sudo systemctl restart sshd
```

④configファイルのポート変更
---
port22→port任意のものに変更


終わり
---
久しぶりのqiita投稿は初歩的なセキュリティでしたー
最近セキュリティで痛い目見たから根本から見直しだ！！！！
AWS athenaでのテーブルのプレビュー結果がzero recordになった時

# はじめに
Glue catalogに作成されたテーブルをAthenaで確認する際、テーブルの中身は表示されず以下のようなメッセージが出力される場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004329/f7726606-02c5-0d5c-cfda-a36444ec491a.png)
Crawlerのパスもうまく設定したのに、中身がないと表示されるだけで原因について教えてくれないため、この現象を解決するのに時間がかかり苦労するケースがあります。

この記事では

- なぜzero record状態が起こるのか
- 解決方法は何か

について説明したいと思います。


# なぜzero record状態が起こるのか
Crawlerを回す際、Crawlerはパス内のデータの隙間の類似性を下に1つのテーブルを作成して返します。
この場合、Crawlerの実行のリソースとして作られるテーブルがzero recordになる原因は、**_パスの中の複数のファイルが持つスキーマがそれぞれ違う_**っていうことになります。 

### スキーマとは？
スキーマとは、データの構造、性質や他のデータとの関連、データベースを操作する時のルールや表現法などを定義したもののことです。
(詳細は**[こちら](http://db-study.com/archives/36 )**をご参照ください。)
つまり、「スキーマが違う」というのは、それぞれのデータが持っている内容が違うことを意味します。

1つのパスの中に違うスキーマのデータがある時、
Cralwerは**どこを基準に1つに合わせたらいいかの判断ができない**ため、空のテーブルを返すと思われます。

# まずチェックするもの
![ea29b66a249dd5d07c73809255ae97c2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004329/1803a6e5-f78e-ef67-d13b-29cd9d631a79.png)
Cralwerの設定画面で、「S3パスごとに単一の」スキーマを作成する」にチェックが外されているかを確認してください。
後ほど説明いたしますが、この項目にチェックされていると、実際作りたいテーブルと違うスキーマを持つテーブルが作られるため、基本的にはチェックを外して使用することをおすすめします。


# 解決方法
ここからは、zero recordの現象を解決するための方法をいくつか紹介したいと思います。

###方法①
- 同一パスにい入っているデータソースファイルを加工してS3バケットに入れ直す方法になります
  - データのスキーマが一致することが重要
  - スキーマの完全一致とは「データの構造が同じ」な状態を意味する
			カラム名、カラムの数、カラムのデータ型が全部一致


例えば、

**order_list1.csv**

|customer|item|price|count|date|
|:--|:--|--:|--:|:--|
|Tom|aa|1000|20|2020-02-01|
|John|bb|2000|45|2020-02-01|
|Jane|cc|3000|3|2020-02-01|
|Amy|dd|5000|16|2020-02-01|


**order_list2.csv**

|customer|item|price|count|date|
|:--|:--|--:|--:|:--|
|Tom|dd|4000|25|2020-03-01|
|David|ee|6000|30|2020-03-01|
|Judy|bb|2000|5|2020-03-01|
|Smith|ff|1500|50|2020-03-01|
|Amy|cc|3000|35|2020-03-01|

上記のようにスキーマが完全一致する場合、Glue crawlerが自動で1つのテーブル化してcatalogに追加してくれますので、zero recordはもう発生しなくなります。


### 方法②
「カラム名＆カラムの数が一致するか？」の基準にs3パスを分ける方法です
例えば、

**order_list.csv**
    
|customer|item|price|count|date|
|:--|:--|--:|--:|:--|
|Tom|aa|1000|20|2020-02-01|
|John|bb|2000|45|2020-02-01|
|Jane|cc|3000|3|2020-02-01|
|Amy|dd|5000|16|2020-02-01|

**stock_list.csv**

|item|count|
|:--|--:|
|aa|25|
|bb|10|
|cc|5|
|dd|50|
|ee|35|

order_listとstock_list単一のテーブルに併合させる必要がないため、
S3パスを分けて登録することで、それぞれ別のパスで指定すると、2つのテーブルを分けて作成できます。

今回の場合、

```
s3://(bucket名)/(folder名)/order_list.csv
s3://(bucket名)/(folder名)/stock_list.csv
```
をそれぞれ追加すると、order_listとstock_listは別々のテーブルとして作成されます。


### 方法③

cralwerの設定を変更して無理やり合わせる方法もあります。
![e535e60271cbd1849396ea4d7cf1f46d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004329/2ab2e5e7-b053-c727-d2cf-4112fedbb576.png)
この方法は、さっきチェックを外した 「S3パスごとに単一のスキーマを作成する」を再度チェックだけでOKです。

#### 注意事項
このオプションで作られたテーブルは**元のファイルとは違うカラム情報を持ってる可能性が非常に高い**です。

- 同一カラムにも違う内容が入ったり
- 意図したように統合されない可能性も高いです

ので、基本オプションは**「チェックを外すこと」**をおすすめします。

# 結論
Glue CrawlerでGlue catalogにテーブルを追加する際は
***1つのS3パスに入ってるパスは同じスキーマを持つ入るように設定する***ことに気をつけましょう。
Overleafでタイムアウトを回避してコンパイルを通す

私自身が修士論文を書いているときに起こった問題なのですが、プロジェクトが重くなりすぎてコンパイルが通らなくなってしまいました。
有料版にするという解決策もあると思いますが今回は**無料版でなんとか解決します。**

手順としては以下の通りです。

```
1. コンパイルモード「Fast(draft)」でコンパイル
2. コンパイルモードを「Normal」に戻してコンパイル
```

一回Fastのコンパイル（画像を表示しないモード）を挟む二段階のコンパイルにするとコンパイル成功率が大幅に上がりました。
綺麗なやり方ではありませんがお試しください。
EC-CUBE3 ログアウト時にカート内の商品を維持する方法

ログアウト時にカート内の商品を維持する方法
EC-CUBE3 Application.php セッション
EC-CUBE3ではログアウト時にカート内の商品が消えてしまいます。これはログアウト時にinvalidateメソッドによりセッションの破棄を行っているためです。


カートの商品を維持するにはinvalidate_sessionの設定をfalseに設定する方法があります。invalidate_sessionがtrueのままですとログアウト時にセッションが破棄されてしまい、カート内の商品が破棄されることになります。一方、invalidate_sessionをfalseにするとセッションは維持されます。

Application.phpにて下記コードのように、ショップ・管理画面共にログアウト時のinvalidate_sessionをfalseに指定してやります。

```
$this['security.firewalls'] = array(
            'admin' => array(
                'pattern' => "^/{$this['config']['admin_route']}/",
                'form' => array(
                    'login_path' => "/{$this['config']['admin_route']}/login",
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
                    'username_parameter' => 'login_id',
                    'password_parameter' => 'password',
                    'with_csrf' => true,
                    'use_forward' => true,
                ),
                'logout' => array(
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
                    'target_url' => "/{$this['config']['admin_route']}/",
                    'invalidate_session' => false,
                ),
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
                'anonymous' => true,
            ),
            'customer' => array(
                'pattern' => '^/',
                'form' => array(
                    'login_path' => '/mypage/login',
                    'check_path' => '/login_check',
                    'username_parameter' => 'login_email',
                    'password_parameter' => 'login_pass',
                    'with_csrf' => true,
                    'use_forward' => true,
                ),
                'logout' => array(
                    'logout_path' => '/logout',
                    'target_url' => '/',
                    'invalidate_session' => false, // これ
                ),
                'remember_me' => array(
                    'key' => sha1($this['config']['auth_magic']),
                    'name' => $this['config']['cookie_name'].'_rememberme',
                    // lifetimeはデフォルトの1年間にする
                    // 'lifetime' => $this['config']['cookie_lifetime'],
                    'path' => $this['config']['root_urlpath'] ?: '/',
                    'secure' => $this['config']['force_ssl'],
                    'httponly' => true,
                    'always_remember_me' => false,
                    'remember_me_parameter' => 'login_memory',
                ),
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
                'anonymous' => true,
            ),
        );
 ```

このカスタマイズを行うことでセッションを利用している機能やプラグインで予期せぬ動作が起こる可能性がございますので、慎重にご使用ください。

単純にinvalidate_session=falseに設定する以外にも、独自のSessionLogoutHandlerを実装してやるという方法もあります。
sudoセッションをそのTTYで長時間維持するためのBashプログラム

フルコードは以下。
[TTY内にてsudoセッションを長時間維持するBashプログラム - sun610.web.fc2.com](https://sun610.web.fc2.com/program/c0005.html)

ポイントは

- sudo の挙動を把握に沿って、sudo を定間隔で実行し続ける
プロセス（群）のCPU使用率を制御する (cgroup使用)

フルコードは以下。
[cgroup によって、プロセス（群）のCPU使用率を制御するBashプログラム - sun610.web.fc2.com](https://sun610.web.fc2.com/program/c0004.html)

ポイントは

- プロセス群にも対応できる（総体としてのCPU使用率制御が可能）
ディレクトリ内 RAWファイルからJPEGファイルを並列実行しつつ取得するスクリプト

フルコードは以下。
[ディレクトリ内 RAW画像ファイルのメタデータからJPEGファイルを並列実行で取得するBashプログラム - sun610.web.fc2.com](https://sun610.web.fc2.com/program/c0003.html)

ポイントは

- & による並列実行
- 子プロセスでの二重実行防止の仕組み
- exiftool では RAW画像ファイルのメタデータから、JPEG画像ファイル（カメラが変換したもの）を抜き出すことができる
【JavaScript】英単語数をカウントする

わりと簡単に作れると思っていましたが、
スペースがあったときに1カウントとすると、スペースが2つ続いたときも1単語としてカウントされてしまうことに頭を悩ませました。

# 解決策

### HTML
```html
<textarea id="count-area"></textarea>
<span id="output"></span>
```
### JavaScript
```javascript
const input = document.getElementById('count-area');
input.addEventListener('keyup', countWords);

function countWords() {
  // \S+の意味は「空白、タブ、改行以外が1回以上続く」
  const spaces = input.value.match(/\S+/g);

  let words;
  if (spaces) {
    words = spaces.length;
  } else {
    words = 0;
  }

  document.getElementById('output').textContent = words + " words";
}
```

## 参考
[Count words as user type - Textarea and Javascript (Youtube)](https://www.youtube.com/watch?v=Pcsy93pk7_Q)
[正規表現入門 レッスン7 Space (Youtube)](https://www.youtube.com/watch?v=0_jLwrd177Q&list=PLXOP1_-wmgsB0oFGsgQtAKltkLFPL7F9d&index=7)
Docker上でVSCodeを立ち上げ、ホストアプリのように使う

## 目的

下記のような使用方法を想定しています。

- 複数の開発プロジェクトを持っている人の開発環境（プロジェクトごとに違う設定を使う）
- VSCodeの拡張機能の評価検証


## 動作イメージ

今回解説する方法で立ち上げた場合、使い方と画面イメージの概要を記載します。

1. docker-compose ファイルを作成
1. `sudo docker-compose up` コマンドでコンテナ立ち上げ
1. コンテナ立ち上げと同時にVSCode起動
1. VSCode上での日本語入力や拡張機能の導入も可能
1. VSCodeを終了と同時にコンテナも終了
1. コンテナを再起動すると前回の状態を引き継いでVSCode起動

■実際に実行した際の画面イメージ

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRUQ0nQs1DjZ508-JSxPdECd3WdrPqFrkyZz_3la7a0N40CnDV-Popx1ent0lchhTavk10SIP8aIfCi/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>


## コンテナの起動方法

### ファイル構成

[適当な名前のディレクトリ]
　├ code
　├ Dockerfile
　└ docker-compose.yml


### ファイルの内容


#### code（ディレクトリ）

ホスト・コンテナで共有したいファイルを格納するディレクトリ
必ずホスト側で作成する

#### Dockerfile

任意のユーザーを作成してコンテナイメージを作成するためのコードを記載しています。
ユーザー情報を指定せず作成した場合は、グループ名・ユーザー名・パスワードともvscodeで作成します。

```dockerfile:Dockerfile
FROM sabotagecla6/vscode_base

# ***********************************************
# install packages
# ***********************************************
ARG group_id
ARG user_id
ARG group
ARG user
ARG passwd
ENV default_group="vscode"
ENV default_group_id=1000
ENV default_user_id=1000
ENV default_user="vscode"
ENV default_passwd="vscode"

RUN { \
    group_id=${group_id:=$default_group_id}; \
    user_id=${user_id:=$default_user_id}; \
    group=${group:=$default_group}; \
    user=${user:=$default_user}; \
    passwd=${passwd:=$default_passwd}; \
    user_home="/home/"${user}; \
    groupadd -g ${group_id} ${group}; \
    export HOME=${user_home}; \
    useradd -d ${user_home} -m -s /bin/bash -u ${user_id} -g ${group_id} -G 27 ${user}; \
    echo ${user}:${passwd} | sudo  chpasswd; \
    chown ${user} ${user_home} ; \
}

USER ${user}
```

#### docker-compose.yml

上記のDockerfileをもとにコンテナイメージを作成して、
コンテナ起動時にVSCodeをcodeディレクトリを開いて立ち上げます。

``` docker-compose:docker-compose.yml
version: "3.3"
services:
  vscode:
    build: 
        context: ./
        dockerfile: Dockerfile
        args:
          user: mint
          passwd: mint
    volumes:
      - $HOME/.Xauthority:/root/.Xauthority
      - ./code:/home/mint/code
    user: "1000:1000"
    shm_size: '2G'
    network_mode: "host"
    privileged: true
    environment:
      DISPLAY: $DISPLAY
    command: code -w code
```

## コンテナの起動

```shell
sudo docker-compose up
```


## ホストに入れる場合との違い

### 開くディレクトリを切り替えられない

VSCodeでディレクトリを開く場合、一度プロセスが終了してから再度立ち上がるようにです。
本コンテナは一度VSCodeが終了すると、コンテナも終了するように作っていますので、
コンテナ起動後VSCodeのアプリの機能としてフォルダを開くを利用することができません。
（そのような使い方が必要な場合を想定していないため）

### 日本語入力の際の画面の動きが違う

通常VSCodeで日本語入力する場合は、リアルタイムでVSCode上に文字が表示されます。
しかし、本コンテナで立ち上げる場合は、mozc上で確定するまでVSCodeには反映されません。
Chefの概要を分かりやすく書いてみました

最近の現場で初めて、chefを使用しました。

あまり情報が少ないため、概要を書いてみました。

# Chefとはいったい？？
![200px-Chef_logo.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355517/44db6e08-dcfc-e265-f329-b901e9ec8eb3.png)



ウィキペディアにはこう書かれていました。

#### RubyとErlangで記述された構成管理ツールである

ん？？どういうこと？？
　

すごく簡単に言えば、

#### chefはインフラ構築を自動化できるプラットフォームなのです。

# Chefを使用するメリット
Chefでインフラの構成を自動化すれば、環境構築時にすべて自分で用意する必要はありません。
繰り返し作業を集約でき、無駄な時間を減らせます。
大規模のプロジェクトによく使われるようです。


# ChefはRubyで書かれる

ChefはRubyで書けるため、Rubyの基礎知識が必要となります。

# Chefの主な構成要素
### Recipe
実行する内容の定義を書く場所
### Attribute
変数などをまとめている場所
### Template
設定ファイルを作るためのテンプレート書く場所
### File
バイナリファイルなどを置く場所
### Cookbook
上記などをまとめたディレクトリ

### Knife
コマンドラインツールで、Cookbook や Recipe を操作します


# Chefの名前について
シェフと聞いて、
まず思い浮かぶのは
料理人ですよね！？

ここのchefはそのイメージで名前がつけられた
ようです。

だから
レシピとかクックブックとかの名前になっているんですね
なんかおしゃれーですね

# まとめ
chefはインフラ構築を自動化できるのもので
Rubyで書けるんですねーーー！！！



実際の書き方はまた別でまとめます。ありがとうございました。
【JavaScript】Mapbox入門【API】

#Mapboxを使って地図を表示

###CDN

```html
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v/mapbox-gl.css' rel='stylesheet' />
```
###[Mapbox GL JS](https://account.mapbox.com/) / [マイアカウント](https://account.mapbox.com/)でアクセストークンを取得


```js
mapboxgl.accessToken = 'hoge';
```

##mapboxglのMapオブジェクトを生成（インスタンス化）

```js
const map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://hoge',
        center: [lon, lat],
        zoom: 14
    });
```

##オプション


__container__
マウントするdiv要素（__not ネスト__）

```html
<div id="map"></div>
```
 
__[style](https://docs.mapbox.com/api/maps/styles/)__
マップのスタイル


__center__

```js
[longitude, latitude]
```
中心地の緯度経度

__zoom__
ズーム度




#現在地を追跡

```js

map.addControl(
        new mapboxgl.GeolocateControl({
            positionOptions: {
            enableHighAccuracy: true
        },
            trackUserLocation: true
        })
    );
```

##オプション
__addControl__
UIでmapを操作

__GeolocateControl__
位置情報を操作(類似:[Geolocation API](https://developer.mozilla.org/ja/docs/Web/API/Geolocation_API))

__ジオロケーション__
ユーザーの位置情報を扱う技術



__enableHighAccuracy__
・false:デフォルト
・true:高精度で現在地を取得

__trackUserLocation__
詳細不明
trueにするとアニメーションがつく

ギアマークをクリックで__現在地まで追跡__

#next
リアルタイムに自分の居場所を保存し取り出せる
Webページにいる人それぞれの位置をマップに表示
クエリ・コマンドの考え方

#### クエリ
画面の都合で変わるデータ（Read、副作用なし、Getのイメージ）

#### コマンド
コマンド：ドメインに対しての操作・システムの変更（Write、副作用あり、Postのイメージ）

---
**リポジトリのメソッドはドメインの形でRead/Writeする場合に使用する**
JavaScriptのreduce()がしていること

配列の合計値を出したいときなどに便利な`reduce()`。
基本的な使い方は以下。

```javascript
const arr = [1, 2, 3, 4, 5];

console.log(arr.reduce((n, m) => n + m));
// 15
```

勉強をしていて、「なんとなく合計値を出せるもの」という理解をもう一歩深められましたのでシェアします。

## reduce()の構文と処理内容
僕がいつもお世話になっているMDNによると、構文は次の通りです。

> ```javascript
> arr.reduce(callback( accumulator, currentValue[, index[, array]] ) {
>   // return result from executing something for accumulator or currentValue
> }[, initialValue]);
> ```
> 参考：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

`callback`：配列のすべての要素に対して実行される関数
`accumulator`：reduce()の返り値を記憶する一時的な変数（繰り返しにおける前回の実行結果）
`currentValue`：現在処理される配列要素

最初の例だとそれぞれが次のように対応しています。
`callback`：`(n, m) => n + m`
`accumulator`：`n`
`currentValue`：`m`

そして、反復処理の実行手順をひとつひとつ見ていくと以下のようになります。

| 実行回数 | n | m | 実行結果（次のn） |
|:-:|:-:|:-:|:-:|
|1回目   |1   |2   |3   |
|2回目   |3   |3   |6   |
|3回目   |6   |4   |10   |
|4回目   |10   |5   |15   |

こうして簡単に配列の合計値を出すことができました。
昔C言語で`int sum = 0;`で合計値を保持する変数を用意してforループを回していた時代はなんだったのか…。

### どうして要素が5個なのに処理が4回なのか
要素が5つなのに処理が4回である理由は、上で紹介した構文中の`initialValue`が指定されていない場合、最初の要素を飛ばしてインデックス番号1から実行されるためです。
配列の要素の合計値を求める場合は`0`を初期値として指定しておく、といった具合ですね。

MDNのドキュメントでも、通常は初期値を指定するほうが安全だと書いてあります。
より詳しく知りたい方は、ぜひドキュメントを参照してみてください。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#description

## なぜ名前が"reduce"なのか
多くの人が英単語のreduceの意味を「減らす」で覚えていますよね。
それ自体は正しいのですが、この関数`reduce()`のイメージとはちょっと合致しないな～と感じます。

そこで、いまいちどreduceの意味を調べてみると、次のような意味が出てきました。

> 3〔+目的語+to+(代)名詞〕〈ものを〉(整理して)〔簡単な形に〕変える，まとめる.
> 7【数学】〈…を〉換算する，通分する，約する.
> 参考：https://ejje.weblio.jp/content/reduce

JavaScriptの関数で使われる`reduce()`としての意味は上記のものがふさわしそうです。

`reduce()`に関数を渡し、配列要素に対してその関数を実行していき、最終的に出た結果のみを返す。ふむふむ。
要素ひとつひとつをギュッとまとめてひとつの値のみにするというイメージですかね。

英単語の意味を押さえると、グッとわかりやすくなりました。
railsでほぼ静的なページの作り方

>引用先
>[Railsチュートリアル](https://railstutorial.jp/)

※ rails new appをしている状況で新しくページを追加するところからです

#ターミナルでコマンド実行

まずは作業ディレクトリへ移動

```
cd ~
```

移動後コマンド実行

```
$ rails generate controller <コントローラ名> <アクション名> <アクション名> ・・・

# 例
$ rails generate controller StaticPages home help
```
上記コマンドを実行すれば

・コントローラの作成
・ルーティングの設定
・ビューファイルの作成
を自動で作成してくれるので非常に便利かつ簡単ですね！

実際これだけでページは作れちゃいます。

#新たにページを追加したいとなった時
例えば、新たにaboutページを作成したいとなった時に、手動でファイルを作成したりコードを書けば追加もできます。

##手順
①ルーティングの設定
②コントローラにアクション追加
③ビューファイルの作成

###①ルーティングの設定

```ruby:config/routes.rb
Rails.application.routes.draw do
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about' ←追加
end
```

###②コントローラにアクション追加

```ruby:app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

  def home
  end

  def help
  end

  def about ←追加
  end       ←追加
end
```

③ビューファイルの作成
app/views/static_pagesにabout.html.erbを右クリックで新規作成

```ruby:app/views/static_pages/about.html.erb
<h1>About作成</h1>
・・・
・・・
・・・
```
これだけでページの追加は完了です。

URLは末にstatic_pages/aboutをつければwebで開きます。
　
(https://~~~/static_pages/about)
EnjinCarftちょっと遊んでみた

#はじめに

Enjin社がminecraftと連携したと聞いて、以前から試していたのですが、
昨年、内部的に大きな修正が入るとのことで、Walletとの接続のコマンド(./Link)が一時期利用不能となってい他ので放置していましたが、

![スクリーンショット 2021-01-18 15.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/daedee5e-3436-eb16-d117-a8119b42cee4.png)

久しぶりに見てみたら、再び稼働しているようだったので再トライしてみました。

#ドキュメントなど

Introducing EnjinCraft: Minecraft Blockchain Plugin
https://www.youtube.com/watch?v=_6FDPuvxaKA

EnjinCraft: Receiving & Using Blockchain Assets in Minecraft
Walletとの紐付け方法
https://www.youtube.com/watch?v=jAhsKTYp9Xk


#やってみる

0.MyMetaverse.ioのアカウントを作成する

1.MineCraftのマルチプレイでServerに接続する
![スクリーンショット 2021-01-18 17.04.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/c3c8dde5-66f4-a61a-c14f-994228e350a4.png)

2.linkコマンドでwalletと接続する
![スクリーンショット 2021-01-18 14.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/a355a3d8-d5b4-63c6-1621-f2c6f04212bc.png)

3.紐付け完了
![スクリーンショット 2021-01-18 15.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/0983fad0-a4b4-6758-e7fd-426730614d33.png)

#metaverse wallet

ゲーム内のMetaverseWalletでmetaverse間でアイテムを相互に出入りさせれるようですが、
今の所所有アイテムがないため、試すことはできませんでした。

![スクリーンショット 2021-01-18 16.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/17693d78-ce9d-4de1-9767-2743ee7c995c.png)

#Conclusion
今回は、Walletのリンクのみですが、引き続き、ゲーム内でconvert可能なアイテムが入手できたら
引き続き記載したいと思います。
AWS Aurora（MySQL）のスロークエリログめも


## 概要
Aurora（MySQL）でスロークエリをテーブル（`mysql.slow_log`）に記録し確認できる

## スロークエリログがテーブルに記録されるようにする

DBパラメータグループで以下を設定

| パラメータ名    | 設定値 | 説明                                       |
| --------------- | ------ | ------------------------------------------ |
| slow_query_log      | 1      | スロークエリログを有効にするかどうか       |
| long_query_time | 5      | ログに記録されるクエリの最短実行時間（秒）。任意の値を設定する |
| log_output      | TABLE  | ログの出力先（TABLE or FILE）              |

参考: [MySQL データベースログファイル - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html)

## スロークエリログを確認する

```sql
SELECT * FROM mysql.slow_log;
```

## スロークエリログをローテーションする

放っておくと無限にスロークエリログがテーブルに溜まっていくので、ログが多くなってきたらローテーションすると良い。

↓のプロシージャを実行するとログがローテーションされる

```sql
CALL mysql.rds_rotate_slow_log;
```

- 現在のログテーブル（`slow_log`）がバックアップのログテーブル（`slow_log_backup`）にコピーされ、現在のログテーブルは空っぽになる。
- バックアップのログテーブル（`slow_log_backup`）がすでに存在する場合は、現在のログテーブルをバックアップにコピーする前に、削除される。


参考: [mysql.rds_rotate_slow_log - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/mysql_rds_rotate_slow_log.html)
Docker コンテナ上でGUIアプリケーションを動かす（日本語入力）

![LinuxMint-21.1](https://img.shields.io/badge/LinuxMint-21.1-brightgreen)  ![Docker-20.10.12](https://img.shields.io/badge/Docker-20.10.12-brightgreen) ![ubuntu(docker)(20.04)](https://img.shields.io/badge/ubuntu(docker)-20.04-brightgreen)

# 目的

Docker上でGUIアプリケーションを日本語入力可能な状態で動かします。
画面の表示にX11を使うため、Linuxのみで実行可能です。

# 実行

今回解説するDockerイメージを使って。VSCodeとfirefoxを動かしてみています。

<iframe width="560" height="315" src="https://www.youtube.com/embed/3Vy_0X96ISk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# 実行方法

firefoxを実行する場合を例に解説します。

## Dockerfileの作成

下記の内容をDockerfileという名前のテキストファイルとして保存します。
[firefoxを実行するためのDockerファイル](https://gist.github.com/12675ba2167dc0b36bfc86d9b501f395.git)
やっていることは、firefoxと関連パッケージのインストール、起動時に実行するコマンドの変更だけです。

作成したら、コンテナイメージを作成します。
（作成済みのコンテナイメージはDockerHubに`sabotagecla6/firefox`という名前でPushしています。
　firefoxを利用したい場合は、そのコンテナイメージをそのまま利用して貰えばよいです。）

## コンテナイメージの作成

Dockerfileをおいているディレクトリをカレントディレクトリに設定して下記のコマンドを実行します。

``` bash:ビルドコマンド
sudo docker build ./ -t tmp-firefox
```

## コンテナの起動

``` bash:コンテナの起動
sudo docker run --net=bridge --shm-size=4096m \
-u $(id -u):$(id -g) \
-v /run/user/1000/pulse/native:/tmp/pulse/native \
-v ~/.config/pulse/cookie:/tmp/pulse/cookie:ro \
-e PULSE_COOKIE=/tmp/pulse/cookie -e PULSE_SERVER=unix:/tmp/pulse/native \
-v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 -e DISPLAY \
-e USER=firefox -e PASSWD=firefox
--rm tmp-firefox
```

上記コマンドの３行目〜５行目は音を出すためのホストマシンとコンテナ間のファイルの共有とコンテナ環境変数の設定
６行目はコンテナの画面をホスト側に表示するための設定
７行目はコンテナ内のユーザーのユーザーとパスワードを指定します。
省略するとユーザー:パスワードはubuntu:ubuntuになります。
８行目はコンテナの終了の度にコンテナを破棄するための設定です。
ユーザーはホストと同じユーザーID・グループIDを使用しないと音を出さないため、合わせています。

# aliasの利用

実行するコマンドかなり長いので、aliasを切っておくと扱いやすいです。

~/.bashrcに下記のコードを追加するとよいです。

``` bash:~/.bashrc
alias docker-firefox='docker-display --rm sabotagecla6/firefox'
alias docker-display='docker-sound -v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 -e DISPLAY'
alias docker-sound='sudo docker run --net=bridge --shm-size=4096m -u $(id -u):$(id -g) -v /run/user/1000/pulse/native:/tmp/pulse/native  -v ~/.config/pulse/cookie:/tmp/pulse/cookie:ro -e PULSE_COOKIE=/tmp/pulse/cookie -e PULSE_SERVER=unix:/tmp/pulse/native'
```

# 参考記事

[Docker コンテナ内のアプリで日本語入力をする方法](https://zukucode.com/2019/07/docker-japanese-input.html)
Emacs使いがmacOSで行う初期設定メモ

# はじめに

指が勝手にemacsキーバインド操作を行うような人間が、必要に迫られて、MacBookノートを使わざるを得なくなった時に、少しでも快適に使うための試行錯誤をメモしていきます。
新しいMacBookを手に入れたので追記修正。

バージョンは　MacOS VentureVenture 13.0 (22A380)
旧バージョンは macOS Big Sur バージョン 11.1 (20C69)

## ターミナルの起動

まず、以下のいずれかの方法でコマンドを入力できるターミナルを起動します。

* DockにあるLaunchpadのアイコン（3x３みたいなの）をクリックして、「その他」の中ににある「ターミナル」をクリック 
* Launchpad内にアイコンが見つからないなら、検索フィールドに「ターミナル」と入力し表示される「ターミナル」をクリック
* Finderを起動し、「/アプリケーション/ユーティリティ」フォルダにある「ターミナル」をダブルクリック

移動したら、Dockに表示されるターミナルのアイコンを右クリック（二本クリック）して、Dockに追加しておくと便利。

## emacsのインストール

### Homebrewのインストール

[Homebrew](https://brew.sh/)にあるインストールスクリプトをコピーし、ターミナルにペーストして実行する。パスワードを聞かれるので入力する。

```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> Checking for `sudo` access (which may request your password)...
Password:
[snip]
% brew --version
Homebrew 4.4.22
[snip]
```

いつの間にかcaskも同時にインストールされるようになっているようだ。

### パスの設定

zshの場合、ホームディレクトリの　.zshrc にbrewのパスを追加。ついでに諸々も追加。

```
#   .zshrc
HISTFILE=~/.zsh_history
HISTSIZE=2000
SAVEHIST=2000

# 日本語を使用
export LANG=ja_JP.UTF-8

# brewのパスに追加　（ココ）
export PATH="/opt/homebrew/bin:$PATH"

# ヒストリーの重複を表示しない
setopt histignorealldups

# ヒストリーのサーチ
bindkey '^P' history-beginning-search-backward
bindkey '^N' history-beginning-search-forward
```

### emacsのインストール

[homebrew-emacsmacport](https://bitbucket.org/mituharu/emacs-mac/src/master/)を参考に、Emacs Mac Portをインストールする。
このEmacs Mitsuharu Yamamoto version (emacs-mac)は、Native Comp 対応で、MacOSのGUI似合っていると思ってます。

```
% brew tap railwaycat/emacsmacport
[snip]  (少し待つ）
% brew install emacs-mac
[snip]  (それなりに待つ）
% emacs --version
GNU Emacs 29.1
```

もし先に他のemacsがインストール済みであれば、brew unlink emacs する必要がある。

terminarl版でよければ、こちらでもインストール可能です。Native Comp には非対応（ざっくり書くと遅い）らしいですが、気したことはありません。

```
% brew install emacs
[snip]
% emacs --version
GNU Emacs 27.1
```

## おまけ

### マウスホイール

Windowsとはホイール操作でのスクロール方向が逆なので変更。
「システム設定」→「マウス」→「ナチュラルなスクロール」のチェックを外す。

### 日本語かな漢字のショートカット

CTRL-xでの日本語変換に慣れているため、「システム設定」→「キーボード」→「キーボードショートカット」→「入力ソース」を選び、「前の入力ソースを選択」を CTRL-x とする。通常は、半角英数と全角かなのトグルなのでこれで十分。

### キーボード設定ツール Karabiner-Elements 

純正でないキーボードを使うときにはとても便利。[公式ページ](https://karabiner-elements.pqrs.org/)からdmgをダウンロードしインストール。外部キーボードを使うときのみキーの入れ替えを設定する。

### 日本語入力でエンター1回で確定させる。

デフォルトではエンター２回なので、１回にする。
「システム設定」→「キーボード」→「入力ソース」にある「日本語　ー　ローマ字入力」を選択し「Windows風のキー操作」にチェック。

### Brave ブラウザ

プライバシーを確保すると言われるブラウザ。
[Brave.com](https://brave.com/ja/)からダウンロードしインストーラーを実行。複数デバイス間の同期は、アカウントを作って同期するのではなく、同期コードを設定することで行う。

### SRware Ironブラウザ

[SRware IRON](https://www.srware.net/iron/)のページからダウンロードし、ダウンロードしたファイルをダブルクリップで展開。設定→セキュリティとブライバシーの一般タブを表示し、下の鍵をクリックして外してから、SRWare Iron.appを実行。
アップデート時は、SRWare Iron.appを /Applications にコピーする。

2021年3月頃のgoogleの制限により使えなくなっていた同期は、同期したいGoogleアカウントで
[こちらのグループ]({https://groups.google.com/a/chromium.org/g/google-browser-signin-testaccounts)に参加することで回避できます。ちなみに参加しても「このコンテンツにアクセスする権限がありません」と表示されますが、同期はできます。とはいえ、いつまで使えるかはわかりませんが。

## 参考URL

* karabinerのimport https://decoy284.net/karabiner-input-switch/
* SRWaraIron の同期　https://lemu.blue/698
Docker コンテナ上でGUIアプリケーションを動かす

![LinuxMint-21.0](https://img.shields.io/badge/LinuxMint-21.0-brightgreen)  ![Docker-20.10.12](https://img.shields.io/badge/Docker-20.10.12-brightgreen) ![ubuntu(22.04)](https://img.shields.io/badge/ubuntu-22.04-brightgreen)

# 目的

Docker上でテキストエディタなどのGUIアプリケーションを動かせ事のできる環境を構築します。

下記に関しては記載しません。

- docker, docker-compose を導入する

# Docker imageの作成

1. [GitHub](https://github.com/sabotage-cla6/docker-ubuntu) から、ダウンロード
1. build.sh を実行

## 作成されるイメージ

- sabotagecla6/ubuntu_ui:jp
    - x11 forward可能な、日本語の使えるイメージ
- sabotagecla6/ubuntu_ui:latest
    - x11 forward可能イメージ
- sabotagecla6/ubuntu_base:latest
    - ubuntuイメージにbash-completionの設定を変更し、apt install などの補完が有効になるようにしたイメージ

# 実行する

例として、geditを実行するためのイメージを作成して実行します。

TODO:後ほど記載する


# 関連記事
[Docker上でVSCodeを動かす](https://qiita.com/SabotageCLA6/items/21b67158a4ae1cbe1e6e)
Kubernetesの知識がなくともKubernetesを用いたwebサイト環境を構築できるソフトウェアを考えてみる

# 始めに
この記事はKubernetesの環境構築の簡易化について考えたものです。実際にソフトウェアを作成したわけではないので悪しからず。

# Kubernetesとは
KubernetesはGoogleが2014年にオープンソース化したプロジェクトです。コンテナを管理するソフトウェアで、コンテナは基盤となるホストインフラからアプリケーションを切り離したものです。これにより、さまざまなクラウドやOS環境下でのデプロイが容易になります。

# Kubernetesの問題点
問題点として、学習コストが高いことが挙げられます。Kubernetesは拡張性が高く、サポートするアプリケーションの種類を制限しません。アプリケーションがコンテナで実行できるのであれば、Kubernetes上で問題なく実行できると思います。しかし、拡張性が高いということは選択肢が多いことになります。選択肢が多すぎて自分が作成したい環境を構築するために、何をすれば良いのか判断に困ることもあるでしょう。
さらにKubernetesは環境構築をする際にyamlファイルという構成ファイルを記述する必要があります。yamlファイルをコピー＆ペーストして作成したとしても、構成ファイルに書いてある記述は1年間のサポートしかされていません。Kubernetesは3ヶ月に1回アップデートしています。更新速度が早いので、サポートが切れるのも早いのです。

# 解決案
## 解決案第一版
yamlファイルを自動生成するソフトウェアを作成すれば良いのでは？
使用したいソフトウェアを選択したらyamlファイルが作成されるソフトウェアがあれば実現できる！

## 解決案の改善案
ソフトウェアに関する知識が無い人が使用できない。
Kubernetesは拡張性が高いあまり、ソフトウェアの選択肢も多大にある。Kubernetesに置ける使用するソフトウェアの選択はKubernetesの環境構築を難解にしている原因のひとつだろう。ソフトウェアの絞り込みを行える機能の追加が求められる。

## 解決案第二版
木構造で保存した質問による絞り込みを行い、お勧めのソフトウェア構成を提案する。
その後に提案されたソフトウェアを使用した環境構築を行えるようyamlファイルを生成する。

## 解決案第二版の改善案
Kubernetesは更新速度が早く、例えyamlファイルのテンプレートを作れるようになったとしても、1年たてば構成ファイルの更新が必要になるだろう。質問内容も更新して改善していく必要があります。質問を追加するとき木構造だと、前後関係も更新する必要が出てくる。

## 解決案第三版（現在）
webサイト作成の際に使用する機能ごとに分類した質問に答えてもらう。webサイトを機能ごとに分類して必要かどうか質問をユーザに答えてもらう。必要となるソフトウェアのリストを作成して、お勧めとして提案する。提案されたソフトウェアリストに則ってyamlファイルを生成する。

# 設計
目的はwebページ作成とする。

## 質問
質問を機能ごとに分類する。

- UI
- DB
- 通信

### UI
1. デザインやシステムを一から作るか？テンプレートを用いて作るか？
 1. （CMSを用いたいかどうか）
1. テンプレートを用いる
 1. CMSの選択
1. 一から作る
 1. サーバーサイドプログラムの言語選択

### DB
1. DBを使用するかどうか
 1. 大量のデータから知りたいデータを取り出すため
1. データを高速に検索、追加、削除、変更できるようにしますか？
 1. 並列的な制御を可能にするため
1. データを変更する際に矛盾がないようにする機能は必要ですか？多数の人がアクセスしますか？
 1. 使うならDBの選択に移る

### 通信
 1. 動的なものならapache（cmsならこっちか？）
  2. アニメーションを多用するページを作りますか？
 1. 静的なものならNginx

CMSとサーバーサイドプログラム、DBの選択肢はユーザが追加更新できるものとする。

## yamlファイル作成
1. ソフトウェア別にyamlファイルの内容をDBに保存しておく。
1. 使用したいソフトウェアリストに則ってDBからyamlファイルの内容を持ってくる。
1. yamlファイルを一部変数を使用してソフトウェアの連携をできる状態にしておく。
1. 作成したyamlファイルを用いてPodを作成して、環境構築完了

# おわりに
設計に関する内容が具体的ではなく、詳しく詰めていく必要があると感じた。
【Laravel】画面に画像を表示する方法。assetsの使い方とurlヘルパ関数との違いについて。

Laravelでブラウザに画像を表示する方法。

##1. publicディレクトリに画像をおく
ブラウザが直接読み取るデータなのでpublicディレクトリに設置する。

imgディレクトリを作成しその中に設置。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/54ff2518-941e-8a8e-6acf-4ac6a742d38a.png)


##2. assetヘルパーで呼び出す
imgタグのsrc属性で、assetsヘルパー関数を使って指定の画像を呼び出す。

```php:
<img src="{{ asset('img/cat3.png') }}" alt="">
```

以上で完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/40c76f5f-2df5-5aac-e290-2b973aa6b24b.png)



<br>
##assetヘルパー関数とは？
publicディレクトリ配下の素材へのURLを生成する。

・`assets('ファイルパス')`

ディレクトリの中にある場合は、`ディレクトリ名.`でつなぐ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2b7bdea7-8a28-60e3-af9a-caffdb4a6152.png)

###ビューで呼び出す
ビュー（拡張子 .blade.php）の中で呼び出す場合は、`{{ }}`をつける。

```php:.blade.php
{{ asset('img/cat3.png') }}
<br>
{{ asset('robots.txt') }}
```

**▼ブラウザの表示**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d4c971be-580f-b1dc-3f88-89a670e0438e.png)|
|:--|

自分のサイトのpublicフォルダのパスが表示される。

あとは、aタグやimgタグのsrcで指定すれば、各アセットにアクセスできる。

[公式ページ](https://readouble.com/laravel/7.x/ja/helpers.html#method-secure-url)には以下のように説明されている。（違いはよくわからない）

<br>
##urlヘルパとassetヘルパの違い
URLを表示するヘルパには、`url()`という関数もある。

・`asset()`
asset関数は、現在のリクエストのスキーマ(HTTPかHTTPS)を使い、**アセットへのURLを生成**。

・`url()`
url関数は指定したパスへの**完全なURL**を生成。


結論からいうと、`url`も`asset`もほぼ同じ。ただし、`url`は引数でパスを渡せるので動的にURLを生成しやすい。


<br>
###urlヘルパとassetヘルパは同じ使い方ができる

```php:.blade.php
asset: {{ asset('img/cat3.png') }} <br>
<img src="{{ asset('img/cat3.png') }}" alt="">

<hr>

url: {{ url('img/cat3.png') }} <br>
<img src="{{ url('img/cat3.png') }}" alt="">
```

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a53b826b-c43e-5cba-a7f9-6aee923ba577.png)|
|:--|

全く同じURLが表示される。


<br>
###`url`に特化した使い方

・`url('prefixのパス', ['後ろに続くパス'])`

```php:例１
{{ url('img', ['cat3.png']) }}
```

↓

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/1d825142-0a00-2e3a-20a3-353f33f22538.png)|
|:--|

<br>

```php:例２
{{ url('column', ['technology', 2020, 1, 10, 'monday']) }}
```

↓

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/58d22da9-f501-b187-6b28-fd9081b6e08a.png)|
|:--|

動的にURLを指定する際に何かと便利。




<br>
##参考
[Laravel公式 ヘルパ一覧](https://readouble.com/laravel/7.x/ja/helpers.html#method-secure-url)
PIFuで１枚の画像から３Dモデルを作ってみた！

#目的
PIFuで１枚の画像から３Dモデルを作成し、その精度を確認する。

#使用環境
MacbookPro(13-inch 2017)
Big Sur(ver11.1)
python3.9.1


#PIFuとは

>一枚もしくは複数枚の画像から人物の３Dモデルを生成するための深層学習の手法
その3次元形状やテクスチャを推定し、写真に写っていない裏側なども推定して生成する。

#環境構築
##[こちら](https://github.com/shunsukesaito/PIFu)からgitclone
`git clone https://github.com/shunsukesaito/PIFu.git`

##学習済みデータのインストール
`cd scripts/PIFu`
`sh ./scripts/download_trained_model.sh`

##依存関係のあるパッケージをインストール
`pip install -r requirements.txt`

※reauirements.txtはしばらく更新されていないようだったので、最新版に変更

```cycler
decorator
imageio
kiwisolver
matplotlib
networkx
numpy
opencv-python
pathlib
Pillow
PyOpenGL
pyparsing
python-dateutil
PyWavelets
scikit-image
scipy
Shapely
six
torch
torchvision
tqdm
trimesh
xxhash
```

###shapelyのインストールのために、Geosが必要であったためエラー発生

`brew install geos`で解決

##実行
`sh ./scripts/test.sh `

sampe_imagesフォルダに入っている画像を元に３Dモデルを生成されます。
![スクリーンショット 2021-01-18 16.21.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/457cf741-4eec-3c4f-b56f-21b371b0a923.png)



##実行後
resultsフォルダにOBJファイルが生成されています。
![スクリーンショット 2021-01-18 16.22.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/fd0f6626-120e-17be-57e0-0ee3a132f484.png)

フードは消えていますが、背中も生成できてる！（髪の毛の癖が強いですねw）
![スクリーンショット 2021-01-18 16.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/622a2148-dd34-7aa7-c725-d8352f26a9bb.png)

##自分で生成してみる

sample_imageフォルダに、背景除去した写真と、マスク画像を入れてておく。
そうすれば、それらを元に３Dモデルを生成してくれる。

ちなみに、背景除去は、[Removing](https://www.remove.bg)で簡単に作れた。
マスク画像は、[GIMP](https://www.gimp.org/downloads/)からDLし、
色域選択＞画像を覆うようにドラッグ＞背景色を白に変更＞背景色（白）で塗りつぶす。で簡単に作れた。

##あとがき
猫さまで３Dモデルを生成した際に、写真の背面にあたる部分に目が生成されたりと、まだ精度は甘いよう。
（人であれば背面に目は生成されなさそう）

コードを読みながら処理や、精度を上げるための学習方法などを学んでいこうと思う。
ASP.NET_Coreで接続元のIPを取る方法 

ログインのロックとかで、アクセス元のIPを知りたいときってあるじゃないですか。
で、ASP.NET_Coreってなんていうか、ちょっとググっても全然欲しい情報に出会えなかっったりするので、備忘として。

##環境
AWSで、ELB=>nginx=>app

##nginxの設定
最低限、XFFは設定しとく

```config:nginx.conf
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
```

##C#側
で、大体`.netcore RemoteIp `とかでググるとStackOverflowとかで

```c#:何かのcontroller
var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
```
使えだとか、
いやいや、ミドルウェアに

```c#:Startup.cs
  app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor |
            ForwardedHeaders.XForwardedProto
        });  
```
が必要だよとか言われるんだけど、それでもうまくいかなかったんだよね。
で、fargeteで構築してたので、いちいちちょっとした修正してみて、codecommitにpushしてパイプライン回してとかやっているととても手間だったので、ローカルでこんな環境を作って確認
nginx(elbの代わり)=>nginx=>app

```dockerfile:docker-compose.yml
version: '2'
services:
  nginxelb:
    build:
      context: nginx
    ports:
      - "50001:80"
    links:
      - nginx
  nginx:
    build:
      context: nginx
    ports:
      - "50002:80"
    links:
      - app
  app:
    build:
      context: .
    ports:
      - "50003:5000"
```
以下のようなIpになってると仮定する
host : 172.18.0.1
nginxelb: 172.18.0.2
nginx:172.18.0.3
app:172.18.0.4

で、この状況でappのどっかでlogにrequest.HttpContext.Connection.RemoteIpAddressを吐くと、
1. nginxelbからアクセス(localhost:50001)
  remoteip:172.18.0.3

2.nginxからアクセス(localhost:50002)
  remoteip:172.18.0.3

3.appに直接アクセス(localhost:50003)
  remoteip:172.18.0.1

ってなるじゃん。
172.18.0.1が欲しいわけじゃん。でないじゃん。

requestのXFFがどうなってるか見ると
1. [172.18.0.0.1,172.18.0.0.2,172.18.0.0.3]
2. [172.18.0.0.1,172.18.0.0.3]
3. null
ってなってるじゃん。
気付くよね。あ、そうか一番右の値使ってるんだって。公式ドキュメントにもそう書いてるし
とすると後はもう単純な話なんですけど、middlewareにknownとして指定すればいいって結論になるわけです。

```c#:Startup.cs
services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                     ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.All;
                options.ForwardLimit = 5;
                options.KnownProxies.Add(IPAddress.Parse("172.18.0.2"));
                options.KnownProxies.Add(IPAddress.Parse("172.18.0.3"));
            });
```

こうするとようやくmiddlewareがちゃんと？機能してくれるわけで、remoteIp取りに行くとちゃんと172.18.0.1が出ます。
ちゃんとっていうか、僕が無能というか。

あとは、AWS上でやる場合はこんなポイント絞ったプロキシなんてありえないので、ネットワークとして

```c#:Startup.cs
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("XXX.XX.XXX.XXX"), XX));
```
とかやって。自分のVPCのCIDRをセットしてあげると、うれしい。となります。
やったね！
Unity2020でPackageManagerからVector Graphicsをインストールできない（見つからない）場合の対処法

2020にアップデートしたら、Packageがみつからない現象に合い焦りました。

# 対処法

1.Window->PackageManager で PackageManagerを開く
2.赤丸で囲んだ歯車アイコンをクリック->AdvancedProjectSettingsを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119898/a5f05dda-59d1-5bb4-7089-4ccf7ee46618.png)
3.EnablePreviewSettingsをOn
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119898/cd64a8ed-258f-fe01-835b-29c0bd6d8298.png)
4.PackageManagerの画面に戻り、左上の＋ボタンからAdd package from git URLを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119898/40428604-88f1-8779-87ed-1fc446795e35.png)
5.「com.unity.vectorgraphics」を入力

これでインストールが行えるはずです。
サウンド検出センサ(FC-04)の音の検出

今回はFC-04の音の検出の仕方を紹介します。

sound()を呼び出すと音の検知をする度に１を出力し、音の検知が無い時は0を出力します。

```soundsenser.py
from machine import Pin
from utime import sleep

# LED出力
p5 = Pin(5, Pin.OUT)

# 音の検知
p23 = Pin(23, Pin.IN)

p5.off()

def sound():
    
    while True:
        if p23.value() == 1:
            p5.on()
        else:
            p5.off()
        print(p23.value())
        sleep(0.01)
        #count +=1

```
macOSでopensslコマンド打つとエラーになる

macで openssl コマンド使うとエラーになった。

```zsh
% openssl x509 -in test.crt -text -noout
unable to load certificate
...
```

一応バージョンは 
macOS Catalina 10.15.7

他のバージョンで発生するかは不明。

brewで入れてみる。

```zsh
% brew install openssl
Updating Homebrew...

・
・
・

Error: Failed to link all completions, docs and manpages:
  Permission denied @ dir_s_mkdir - /usr/local/share/fish
Error: The following directories are not writable by your user:
/usr/local/lib/pkgconfig
/usr/local/share
/usr/local/share/man
/usr/local/share/man/man1

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/lib/pkgconfig /usr/local/share /usr/local/share/man /usr/local/share/man/man1

And make sure that your user has write permission.
  chmod u+w /usr/local/lib/pkgconfig /usr/local/share /usr/local/share/man /usr/local/share/man/man1
```

なんかエラーが出たので言われたとおり実行。


```zsh
% sudo chown -R $(whoami) /usr/local/lib/pkgconfig /usr/local/share /usr/local/share/man /usr/local/share/man/man1
Password:

% chmod u+w /usr/local/lib/pkgconfig /usr/local/share /usr/local/share/man /usr/local/share/man/man1
```

で、brew で openssl が入った。

が解消しない。

```zsh
% which openssl
/usr/bin/openssl
```

これは brew で入ったものではない。

```zsh
% brew link openssl
Warning: Refusing to link macOS provided/shadowed software: openssl@1.1
If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
```

言われた通り、

```zsh
% echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
```

でターミナル新しく起動するとコマンドが通った。
EBSボリュームタイプの変更(gp2→gp3)

#はじめに
* EBSのボリュームタイプの変更を実施したので備忘録として残します。
※EC2インスタンスの停止させることなく、オンライン状態でのEBSボリュームタイプ変更作業です。
* AWS-CLIを用いて作業をおこないます。

#実施手順

##環境
```
OS情報
[root@localhost ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

AWS-CLIバージョン
[root@localhost ~]# aws --version
aws-cli/2.1.19 Python/3.7.3 Linux/3.10.0-1160.11.1.el7.x86_64 exe/x86_64.centos.7 prompt/off
```

##EBSボリュームタイプ変更作業


▼EBSのボリューム IDを変数「EBS_VOLUME_ID」に格納

```
# EBS_VOLUME_ID="vol-1111111111111111"
```

▼現在のEBSのボリュームタイプを確認

```
[root@localhost ~]# aws ec2 describe-volumes   --volume-ids ${EBS_VOLUME_ID}   --query Volumes[].VolumeType   --output text
gp2
```

▼ボリュームタイプを「gp3」に変更

```
[root@localhost ~]# aws ec2 modify-volume   --volume-id ${EBS_VOLUME_ID}   --volume-type gp3
{
    "VolumeModification": {
        "VolumeId": "vol-1111111111111111",
        "ModificationState": "modifying",
        "TargetSize": 1000,
        "TargetIops": 3000,
        "TargetVolumeType": "gp3",
        "TargetThroughput": 125,
        "OriginalSize": 1000,
        "OriginalIops": 3000,
        "OriginalVolumeType": "gp2",
        "Progress": 0,
        "StartTime": "2021-01-17T01:31:11+00:00"　
    }
}
```

※今回は、1TBのEBSボリュームで、ボリュームタイプの変更をおこないます。

▼EBSボリュームタイプ変更の進捗を確認

```
[root@localhost ~]#  aws ec2 describe-volumes-modifications   --volume-id ${EBS_VOLUME_ID}
{
    "VolumesModifications": [
        {
            "VolumeId": "vol-1111111111111111",
            "ModificationState": "completed",
            "TargetSize": 1000,
            "TargetIops": 3000,
            "TargetVolumeType": "gp3",
            "TargetThroughput": 125,
            "OriginalSize": 1000,
            "OriginalIops": 3000,
            "OriginalVolumeType": "gp2",
            "Progress": 100,　　　　　※ここの値が100になれば、処理が完了
            "StartTime": "2021-01-17T01:31:11+00:00",　
            "EndTime": "2021-01-17T01:52:13+00:00"　
        }
    ]
}
```
ボリュームタイプ変更の実施時間：2021/01/17 10:31(日本時間)
ボリュームタイプ変更の終了時間：2021/01/17 10:52(日本時間)　処理時間→21分

▼現在のEBSのボリュームタイプを確認

```
[root@localhost ~]# aws ec2 describe-volumes   --volume-ids ${EBS_VOLUME_ID}   --query Volumes[].VolumeType   --output text
gp3
```

#まとめ
今回は、何もデータが入っていないEBSボリュームで実施いたしました。そのため、データがたくさん入っている場合だと、もっと時間がかかるかもしれません。
また、旧世代(C1, C3, G2, I2, M1, M2, M3, R3, T1)のファミリーの場合は、処理が失敗するようなので、注意が必要のようです。



#参考URL
https://blog.serverworks.co.jp/reinvent2020-modify-ebs-gp2-to-gp3
Excel VBAからMeCabで形態素解析したい時

誰にでも形態素解析したい時があります。それは、Excel VBAを使っている時でもあってもです。Excel VBAから形態素解析を使う方法はいろいろあります。でも、もっと簡単にやりたいのです。メソッド一発でシートにMeCabの結果をバーンと入れたいんです。

そこで、[MeCab for Excel VBA](https://github.com/kujirahand/mecab-vba/)を作りましたので、これを使って手軽に形態素解析しましょう。これを使うと、以下のような簡単なコードでセルに形態素解析の結果が得られます。

```形態素解析.bas
Sub 形態素解析のテスト()
    ' テスト用の文字列を指定
    TestStr = "探すのに時があり、諦めるのに時がある。"
        
    ' シートに結果を入れる
    MeCabExecToSheet TestStr, Sheet1, 1

    ' 文字列として結果を得る
    MsgBox MeCabExec(TestStr)
End Sub
```

![mecab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/e88c29c4-0117-794e-852e-cfa5b7db61bf.png)


# (1) MeCabのインストール

最初に、MeCabをインストールします。Windows版のMeCabは以下よりダウンロードできます。

 - [MeCab for Windows](https://taku910.github.io/mecab/#install-windows)

親切なインストーラーがあるので、次へ次へと押していけば入ります。気をつける点ですが、Excelから使う時は、Shift_JISを使うのが便利です。途中で辞書の文字コードを指定する必要がありますので、Shift_JISにしてください。

# (2) MeCab for Excel VBAを取得

以下で公開しています。Releaseでアーカイブをダウンロードしてください。ダウンロードしたらZIPファイルを解凍して、中に「mecab.bas」があるのを確認してください。

 - [MeCab for Excel VBA](https://github.com/kujirahand/mecab-vba/)
  - [アーカイブのダウンロード](https://github.com/kujirahand/mecab-vba/releases)

なお、サンプルのsample.xlsmを開いて、VBエディタのサンプルを実行することもできます。

# (3) Excel VBAにmecab.basを取り込む

 - (3-1) Excelで新規マクロ有効ブックを作ります。
 - (3-2) [Alt]+[F11]を押してVBエディタを起動します。
 - (3-3) メニューの[ファイル > ファイルのインポート] をクリック
 - (3-4) 手順2の「mecab.bas」を選択

# (4) Sheet1にVBAのコードを書く

VBエディタで、Sheet1などを選んで、以下のコードを書きましょう。そして、Sub ... End Subの間にカーソルを置いて、[F5]キーを押せばプログラムが実行されます。

```
Sub 形態素解析のテスト()
    ' テスト用の文字列を指定
    TestStr = "探すのに時があり、諦めるのに時がある。"
        
    ' シートに結果を入れる
    MeCabExecToSheet TestStr, Sheet1, 1

    ' 文字列として結果を得る
    MsgBox MeCabExec(TestStr)
End Sub
```

簡単ですよね！良かったら使ってみてください！

# 参考

 - [MeCab for Windows](https://taku910.github.io/mecab/#install-windows)
 - [MeCab for Excel VBA](https://github.com/kujirahand/mecab-vba/)
【Android】Code Reformatに関するメモ

# XML

- タグの一番初めの行を改行していてもReformatされないようにする：<br />Code Style→XML→Other→Keep line breaksにチェックを付ける

- スラッシュの手前にスペースを入れない：<br />Code Style→XML→Other→In empty tagのチェックを外す

![スクリーンショット 2021-01-18 15.33.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/3dc51e78-cdae-4fe6-b8c1-fcc19397bf82.png)


# Kotlin

- コメントの前の行を勝手に改行させない：<br />Code Style→Kotlin→Blank Lines→Before declaration with comment or annoationを0にする![スクリーンショット 2021-01-18 15.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/a0bb8825-9b0e-3fdb-d4a8-9455ab971174.png)

- `when`の`}`後に空行を生成させない
  Code Style→Kotlin→Wrapping and Braces→when statements→New line after multiple entryのチェックを外す

  ![settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/71a63e9f-1544-129d-62a5-2f6e2ffa2b41.png)