OmniAICreator/Qiita-1.07M huggingface dataset:
Vim Adventures攻略法 レベル5

## レベル5のポイント
[Vim Adventures](https://vim-adventures.com/)のレベル5では`d`オペレーターと`D`コマンドを入手して文字を削除する際の選択範囲の指定に慣れることが学習目的です。`D`コマンドは`d`オペレーターを入手すると使えるようになります。レベル5の最初のマップの文章を読むと「`x`キーを連打して削除するのは遅い」と書いてあります。

|キー|効果|
|:-:|---|
| d | 指定範囲を削除してレジスタに保持します|
| D | カーソル位置から行末までを削除します |

## レベル5開始時点で使えるようになっているキー
下記キーボードはマップの好きな場所で:keyboardと入力すると表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/0ad1bf1b-9fcc-639d-5bb9-d4b9c1749517.png)

## レベル5の攻略手順
新たなマップに表示される赤字赤枠のセルを全て置換・削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/170ad40d-9b5b-7312-2704-66d40d50d565.png)

すると`d`オペレーターが入手できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/9d6e63f7-285c-13c5-ae95-5fb25ea5f85e.png)

次に右側に位置するマップで赤枠で囲われた文字列を全て削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/6f73a2e0-8b29-8aa1-b3b0-aa13c8930b4d.png)

|行位置|削除/置換する対象|キーストローク|補足説明|
|---|:-:|:-:|---|
|先頭行|"not "|dw||
|先頭行|"the "|dw||
|第2行|"yellow "|dw||
|第3行|"out! "|dW||
|第3行|"not "|dw||
|第4行|"u"|x||
|第4行|"t"|ry||
|第4行|"stop "|dw||
|第4行|"!"|x||
|第6行||x|空白の削除|
|第6行||x|空白の削除|
|第6行|"rabb"|dB| まだ`d4l`のような回数指定ができない。カーソルをiの位置で`dB`を実行する|
|第7行|"n't"|dE| `e`だと n のみの指定になる|
|第7行|"d"|rn||
|第9行|"a"|re||
|第9行|"t"|x||
|第12行|"y"|rt||
|第12行|"u"|x||
|第12行|"board"|de||
|第13行|"p"|rh||
|第13行|"der"|de||
|第16行|"Just ~ islands."|dj|2行にまたがる文字列を削除したいので、次の行に移動する`j`を利用して削除範囲を2行と指定する。|

そしてマップ左下隅の X の文字の上で`dw`を入力するとマップ中央部に鍵が出現します。このXがある列を上から縦に読むと、"Toge tkey dwon  X" -> "To get key dw on X"と読めます。
この`dwon` は注意していないと`down`と読み飛ばしてしまいそうですが、レベル5の最初のマップにいた2人のキャラのうち茶髪のキャラがヒントで「`down`という文字があったら2文字2個の組合せなのでもう一度読んでみてね」と言っていました。最初に見た時は意味不明と思ったのですが、ここに来て納得です。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/24522b95-c214-6002-fe55-4a753caec632.png)


鍵を取得したら左側のマップに戻って赤枠で囲われた文字列を削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/c6b45a03-d685-08e4-0ba4-72e50bb81c2c.png)

|行位置|削除/置換する対象|キーストローク|
|---|:-:|:-:|
|先頭行|"are "|dw|
|先頭行|"ne"|de|
|第2行|" not"|dE|
|第2行|"s"|ra|
|第2行|"p"|rw|
|第2行|"d"|x|
|第3行|"s"|rx|
|第4行|"p"|rs|
|第5行|"r"|x|
|第5行|"ache"|dE|
|第6行|"r"|x|
|第6行|"s"|x|
|第6行|"s"|x|
|第6行|"h"|rd|
|第7行|"v"|rl|
|第8行|"not "|dW|

赤枠部分の編集が全て終わると鍵とキャラが出現します。キャラに会うには第6行または第8行で`E`モーションを入力します。そして先に進むには第4行で`e`モーションを入力して通路にある`r`のセルに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/7c3d2698-f95b-4230-afe9-f877883d145a.png)

鍵の掛かった扉を2個開けて、青い髪のキャラのセルに到着すればレベル5クリアです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/9e7238c1-19fe-694f-8a1b-9706ca8437ed.png)


[目次へ](https://qiita.com/mailstop/items/284f2a1300369b693f45)
[レベル4へ](https://qiita.com/mailstop/items/45ba38707f1baf164c6f)
[レベル6へ](https://qiita.com/mailstop/items/1cb4e1557f4a63277a65)
PHP 標準入力の方法

#標準入力の方法

１行の場合

```php

$one = trim(fgets(STDIN));
var_dump($one);
```


複数行の場合

```php

<?php

while ($line = fgets(STDIN)) {
    // 配列を生成
    $arr[] = trim($line);
}
   var_dump($arr);

　　　結果↓
    /*
    arr(2) {
  [0]=>
  string(2) "60"
  [1]=>
  string(2) "90"
}
*/
```
    
trim()で囲っているのは余分な改行や余白をなくす為にしようしている（必ず必要なものではない）
アンサンブル学習

# ノーフリーランチ定理

「あらゆる問題に対して、他の識別器よりも性能の高い万能なモデルやアルゴリズムは存在しない」

# アンサンブル学習
- 複数のモデルの予測結果を組み合わせて最終的な予測を行う
- 各モデルを弱学習器という

# バギング
- 並列
- ブートストラップ集計法（bootstrap aggregating）
- ブートストラッピング
  - 訓練データから無作為に重複ありでサンプリング（復元抽出）する
- ブートストラッピングしたデータで弱学習器を学習する
- 結果を集計する

　デ
↙︎↓↘︎
デ　デ　デ　・・・ブートストラッピング
↓ ↓ ↓
学 学 学
↘︎ ↓ ↙︎
　集計!　＝　👜最終予測!


# ブースティング
- 直列
- 弱学習器を逐次的に学習する
- 順番に学習するので時間がかかる
- 外れ値や誤差の影響を受けやすい
- Xgboostが実装するアルゴリズム

デ　デ　デ
↓　↓　↓
学→学→学→🚀最終予測！

# スタッキング
- 複数のモデルの予測結果を特徴量にして学習する
- 各モデルの重み付けも最後の学習器が学習してくれる
- 学習データの情報を使い尽くすので学習データとテストデータの分布が同じでデータ量が多いと有効にはたらく
  - 逆に時系列データなど学習データとテストデータの分布が異なる場合は過学習しやすい
- 教師なし学習による分類を２層目の特徴とする場合もある
- ３層、４層とスタッキングすることもある

デ→学→予測値!↘︎
デ→学→予測値!→学→🏫最終予測!
デ→学→予測値!↗︎
VulterにVPSサーバーを作って22番ポートをポートを開いておくと不正アクセスガンガンくるのでFirewallを設定する

# VulterにVPSサーバーを作って22番ポートをポートを開いておくと不正アクセスガンガンくるのでFirewallを設定する

![vulter_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/6fe4f363-867b-ee4c-0316-05931003552d.png)
こんな感じで、rootを試みる不正アクセスがガンガン来る。

大体３０分で２５０件くらい。
予測しにくいパスワードを設定しておけば、不正ログインされる可能性は低いが
気持ち悪い。

## Firewallを設定する

![fw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/a0b5e958-6a7b-cfb5-4212-0fecb781c77c.png)


Vulterではfirewallを使うことができる。
自分が使っているプロバイダーのIPアドレスを設定する。


自分の接続しているプロバイダのIPアドレスの範囲を調べる。
https://www.cman.jp/network/support/go_access.cgi
このサイトで接続IPアドレスを調べる。

自分のグローバルIPアドレスが分かったら
Macのターミナルを開いて
whois #IPアドレス#
を実行。

inetnumの部分にプロバイダーに割り当てられいるIPアドレス情報が出る。

例：
![ip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6384/4e34aeb6-a8a6-8ecb-b073-0a960b3d4486.png)

この例では
inetnum:        122.249.0.0 - 122.249.255.255
なので
firewallには  122.249.0.0/16  を指定する。

これで一安心。
UnityでLEAPのWebSocketサーバーjson受信

Unityで複数LEAPの可能性を探していたので、ひとつの再現方法をメモ

内容はjsonデータをUnityで見えるようにしている状態にしただけなので、活用できるかは未検証。。

返り値floatが本当に正しい値？など。。

LEAPの設定は下記

https://qiita.com/mmt/items/e7ad634f2170eb9db8b4

UnityでWEBSocketは下記を参考にしました

https://qiita.com/oishihiroaki/items/bb2977c72052f5dd5bd9

###動作状態

![SnapCrab_NoName_2021-3-16_3-51-15_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/bf782347-99fc-5a59-544d-6086363dc25d.png)


###スクリプト

```WsLeap.cs
using UnityEngine;
using WebSocketSharp;

public class WsLeap : MonoBehaviour
{
  public WebSocket ws;
  public string url = "ws://192.168.1.1:6437/";//環境ごとに変更
  public float currentFrameRate;
  public Devices[] devices;
  public Hands[] hands;
  public int id;
  public Pointables[] pointables;
  public int timestamp;
  public void RecvText(string text)
  {
    string json = text.ToString();
    LeapJson jsonData = new LeapJson();
    JsonUtility.FromJsonOverwrite(json, jsonData);

    currentFrameRate = jsonData.currentFrameRate;
    devices = jsonData.devices;
    hands = jsonData.hands;
    id = jsonData.id;
    pointables = jsonData.pointables;
    timestamp = jsonData.timestamp;
  }
  public void RecvClose()
  {
  }

  void Start()
  {
    ws = new WebSocket(url);
    ws.Connect();
    ws.OnMessage += (sender, e) => RecvText(e.Data);
    ws.OnClose += (sender, e) => RecvClose();
  }
}
```

```LeapJson.cs
using System;
using UnityEngine;

[Serializable]
public class LeapJson
{
  public float currentFrameRate;
  public Devices[] devices;
  public Hands[] hands;
  public int id;
  public Pointables[] pointables;
  public int timestamp;
}

[Serializable]
public class Devices
{

}

[Serializable]
public class Hands
{
  public float[] direction;
  public int id;
  public float[] palmNormal;
  public float[] palmPosition;
  public float[] palmVelocity;
  public float timeVisible;
}


[Serializable]
public class Pointables
{
  public string direction;
  public int handId;
  public int id;
  public int length;
  public int timeVisible;
  public float[] tipPosition;
  public float width;
}
```

###参考サイト

https://www.hanachiru-blog.com/entry/2019/04/24/211642
React 入門 (#3) ～React Components～

#１，コンポーネントとは
前回にも述べたのですが、「コンポーネント」とは
マークアップとロジックを両方含んだ一つの要素だといえます。
具体的に、ソースコードを見て確認しましょう。

#２，ソースコード
![code8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/79592e46-a649-da27-5455-fecd078f6b06.png)

コンポーネントの中に、マークアップとロジックを含んでいます。
このコンポーネントを利用する場合は、**コンポーネントタグ**と言われるものを使います。
それが、**＜App /＞**　と記述します。

#３，次回から、Reactアプリケーションを作っていきます。
次回から、[Reactアプリケーション](https://qiita.com/iwasaki-hub/items/1decaf281abff9df16dd)の作成を進めていきます。
Java学習　基礎編　~繰り返し処理 for文 ~

Java学習の備忘録になります。
内容は初心者なので基礎的な部分となります。
Javaに興味がある方やJava学習初心者の参考になれば幸いです。

* * *
### 繰り返し処理
簡単にいうと、
『**一定の処理を自動で繰り返し行う処理**』
のことを繰り返し処理と言う。

#### for文

前回学習した「**while文**」と同じ、繰り返し処理のひとつ。
記述方法は下記になり、**条件がtrueの間、{}内の処理を繰り返す**ことができる。

for文の方が、while文よりシンプルに書けるイメージかも。


```Main.java
for (変数の初期化; 条件式; 変数の更新) {
  繰り返す処理;
}

// while文と比較してみましょう。

while (条件) {
  繰り返す処理;
}

//-------------------------------------------------

// 例 for文
for (int i = 1; i <= 5; i++) {
  System.out.println(i);
}

// 例　while文
int i = 1;
while (i <= 5) {
  System.out.println(i);
  i++;
}

```

###### 繰り返す処理の流れ
①変数の初期化 (while文を繰り返すかどうか判断するために用いる)
※変数の初期化とは、変数定義と同時に値を代入すること。
↓
②条件
↓
③繰り返す処理
↓
④変数の更新
↓
②に戻り、条件がtureであれば繰り返す。
**条件がfalseになれば繰り返し処理が終了する。**

#### breakとは
繰り返し処理を終了するためには、条件をfalseにする以外に、「**break**」を使って強制的に終了させる方法もある。

下記のように、if文などの条件分岐と組み合わせることで、任意の箇所で繰り返し処理を終了させることができる。

```Main.java
for (int i = 1; i <= 10; i++) {
  if (i > 5) {
   break; // 変数iの値が6になった時点でfor文を終了。
  }
  System.out.println(i);
}
```

#### continueとは

繰り返し処理の終了とは違い、その周の処理だけスキップして次の周を実行することができる。
continueもif文などと組み合わせて利用するのが一般的である。

```Main.java
for (int i = 1; i <= 10; i++) {
  if (i % 3 == 0) {
   continue; // 変数iの値が3の倍数の時、その周をスキップして次の周を実行。
  }
  System.out.println(i);
}
```

* * *
#### おわりに
ほんとに基本的な部分になるかと思います。
ご指摘などございましたら、よろしくお願いいたします！！
Azure FunctionsでFastAPIを使う

Azure FunctionsでのRESTful APIの開発を楽にしたいと考えて調べたら、簡単な方法でFastAPIが使えることが分かりました。
備忘を兼ねて共有します。

# 注意

ここで紹介する方法で使用するパッケージ([Bonnette](https://github.com/jordaneremieff/bonnette))は2021年3月現在、2019年8月を最後に更新されていません。
上記の理由から公開されたサービスの本番運用には向いていないかと思います。
この記事は個人レベルの簡単なアプリをAzure Functionsでぱぱっと無料で公開することを念頭に置いています。

# 前提条件
- Azure Functionsを利用できるAzureのサブスクリプションを持っていること
    - もしなければ[ここ](https://azure.microsoft.com/ja-jp/free/)で作成できます

# 使うもの
- Pythonが動くAzure Functionsアプリ
- [Bonnette](https://github.com/jordaneremieff/bonnette)
- [その他Azure Functionsの開発に必要なもの](https://docs.microsoft.com/ja-jp/azure/azure-functions/create-first-function-vs-code-python#configure-your-environment)

# [Bonnette](https://github.com/jordaneremieff/bonnette)とは
- Azure Functions用のASGIアダプタです
- 受け取ったリクエストをASGIインスタンス向けに変換し、FastAPIが返したレスポンスをAzure Functions向けに変換します
    - 乱暴な言い方をするとUvicornの代わりです
- 繰り返しになりますが、2021年3月現在このプロジェクトのレポジトリには THIS PROJECT IS UNMAINTAINED と記載されており、2019年8月を最後に更新されていません

# Azure Functionsアプリの作成
当たり前ですが Python が動く設定でお好きなリージョンに作成してください。
バージョンは3.6以降しか選べないのでどれでも構いません。

# VS Codeでプロジェクトを作成する
[公式のチュートリアル](https://docs.microsoft.com/ja-jp/azure/azure-functions/create-first-function-vs-code-python)を参考にローカルでプロジェクトを作成してください。
もし初めてであれば、Azureへのデプロイと初期状態での動作確認を行っておくことをお勧めします。

# サンプルを見ながらコードを編集する
[azure-functions-fastapi-asgi-example](https://github.com/morzik45/azure-functions-fastapi-asgi-example)に素晴らしいサンプルがあります。
<del>このレポジトリのURLを貼るだけで十分とか言っちゃいけない。</del>

編集する点は以下の5点です。

- `host.json`
    - `"extensions"` 以下をコピーして追加してください
    - これを追加することでURLに勝手に追加される"api"という文字列を消すことができます
- `requirements.txt`
    - bonnette と fastapi を追加してください
- `[function name]/__init__.py`
    - `fastapi/__init__.py` と置き換えてください
    - `Bonnette(app)` がFastAPIインスタンスをラップするための記述です
- `[function name]/main.py`
    - `fastapi/main.py` をコピーして配置してください
    - このファイルに FastAPI アプリケーションを記述します（もちろんファイルを分割しても構いません）
- `[function name]/function.json`
    - `["bindings"][0]` に `"route": "{*route}"` を追加してください
    - この記述を追加することで、 `<アプリ名>.azurewebsites.net` 以降のすべてのパスをFastAPIで自由に使えるようになります

# デプロイと動作確認
チュートリアルと同じ手順でAzure上にデプロイします。
`<アプリ名>.azurewebsites.net` にアクセスして `{"Hello": "World"}` と返ってくれば成功です。

# まとめ
[Bonnette](https://github.com/jordaneremieff/bonnette)を使えばAzure Functions上でFastAPIが走ります。
個人で遊ぶ程度であればAzure Functionsは無料(2021年3月時点での情報)で使えますのでだいぶ捗りますね。

# ちなみに
AWSのFaaSであるLambdaでも似たような方法でFastAPIを使えるようです。
その場合には[Mangum](https://mangum.io/)というアダプタを使うようですが、AWSには詳しくないので名前を紹介するだけにします。

# 参考
- [Bonnette](https://github.com/jordaneremieff/bonnette)(Github Repo)
- [azure-functions-fastapi-asgi-example](https://github.com/morzik45/azure-functions-fastapi-asgi-example)(Github Repo)
- [クイックスタート: Visual Studio Code と Python を使用して Azure に関数を作成する](https://docs.microsoft.com/ja-jp/azure/azure-functions/create-first-function-vs-code-python)
Vim Adventures攻略法 レベル4

## レベル4のポイント
[Vim Adventures](https://vim-adventures.com/)のレベル4では`E`モーション、`W`モーション、`r`コマンドを入手します。引き続きvimのカーソル移動の流儀に慣れること、そして一文字の置換を学習することが目的です。

|キー|効果|
|:-:|---|
| E | カーソル位置よりも後ろにあるWORDの末尾に移動する |
| W | カーソル位置よりも後ろにあるWORDの先頭に移動する |
| r | カーソル位置にある一文字を置換する |

## レベル4開始時点で使えるようになっているキー
下記キーボードはマップの好きな場所で:keyboardと入力すると表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/94186c32-520c-8b50-f82e-c93dd39c47ed.png)

## レベル4の攻略手順
まずはレベル4開始時点から下に数セル分移動すると画面全体が明るくなります。そしてマップに表示されている赤枠赤字のセルの文字を全て削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/894c05c3-36f3-42bb-2b50-b8aeeeb8cd8c.png)

すると`E`と`W`モーションが出現するので入手します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/7f12b75e-7715-7fa2-8eb1-44c0caed6072.png)

マップを先に進み先頭行の`<`の箇所で`W`モーションを入力して`for`の先頭文字`f`まで移動し、`e`モーションを入力して`r`コマンドを入手します。これで一文字の置換ができるようになるので、マップ上の赤枠赤字のセル全てを置換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/f92247e3-880f-85bd-252f-f0c436ad1295.png)

以降も同じ要領で`W`モーション、`E`モーション、`r`コマンドを使えば良いのですが、一応キーストロークを下記表に示します。

|キーストローク|カーソル位置|捕捉説明|
|:-:|:-:|---|
|-|<| 文字列`<script>`の先頭|
|W|f| 文字列 for(var の先頭に移動|
|e|r| 文字列 for の末尾で r キーを取得|
|E|r| 文字列 for(var の末尾に移動|
|E|;| 文字列 i=1; の末尾に移動|
|h|1| 赤枠赤字の1に移動|
|r0|0| 1を0に置換|
|W|i| 文字列 i>10 の先頭に移動|
|l|>| > に移動|
|r<|<| >を<で置換|
|W|{| {に移動|
|W|a| 文字列 acert の先頭に移動|
|l|c| cに移動|
|rl|l| cをlで置換|
|W|b| 文字列 beat の先頭に移動|
|W|t| 文字列 the の先頭に移動|
|W|s| 文字列 swordfaster の先頭に移動|
|lを5回入力|f| lを5回入力（まだ数字は使えない）|
|rm|m| fをmで置換|
|W|}| }に移動|
|j|e| 文字列 elect の先頭に移動|
|ra|a| eをaで置換|
|lを3回入力|c| cに移動|
|rr|r| cをrで置換|
|E|t| 文字列 alert の末尾に移動|
|E|k| 文字列 ("Check の末尾に移動|
|W|o| 文字列 out の先頭に移動|
|W|m| 文字列 my の先頭に移動|
|W|T| 文字列 T-shrft!" の先頭に移動|
|lを5回入力|f| fに移動|
|rr|r| fをrで置換|
|Bを3回入力|o| 文字列 out の先頭に移動|
|h| | スペースに移動|
|kを2回入力|b| 文字列 beat の先頭に移動|
|lを8回入力|青い髪のキャラのセル|ステージクリア|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/3e449bbc-d40d-9f8f-3165-3e2e9c4a8802.png)

 


[目次へ](https://qiita.com/mailstop/items/284f2a1300369b693f45)
[レベル3へ](https://qiita.com/mailstop/items/9741bb28c16c8719c95d)
[レベル5へ](https://qiita.com/mailstop/items/56444c01ea619affbd38)
Elixir/PhoenixでjQueryを使う。


```bash

docker-compose run app npm install jquery --save
```

* 前提
  * `app`というコンテナ名で開発している。
  * Phoenix:`1.4.0`以降


# 補足
Phoenix:1.4.0より前のバージョンは下記の手順が必要かと思います。

https://qiita.com/mexelout/items/706da38e57f4454c710b

PhoenixのVersion`1.4.0`からビルドツールがbrunchからwebpackに移行しています。
Python:Flask DBのmodelsはJson形式の文字列で返そうよってお話し

#初めに
大学２年の春休みの課題（ゼミ）中で色々データの受け渡しに困ったのでこんな記事を描こうと思い至った次第。
地味にqiita初投稿の記事でちょっと緊張。

なんか変だよとかあったらなんでもご教授ください。

環境
Python3.9.2
flask1.1.2
Vue2.6.12
その他ライブラリ等割愛

#何が起こったのか
flaskとVueでSPAを作ってたらDBからのデータ受け渡しで困った。

#原因
過去コード何にも考えずにを使いまわしたこと。

[FastAPIのチュートリアル](https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment)でtodoappをゼミの勉強会で作ったのですが、その時のmodelsを考えなしにほぼそのまま使いました。はい。アホです。

#コード
```python:flask-getdata
@app.route('/chat_api/')
def get_chat():
    talks = db.session.query(Talk).all()
    db.session.close()
    res = dict()
    for i in range(len(talks)):
        res[i] = str(talks[i]) 

    return res
```
上記のコードでdbからtalkのリストを取得してフロントvue.jsから表示しようとしました。

``` python:models(before)
class Talk(Base):
    """
    toDoタスク
    id       : 主キー
    user_id  : 外部キー
    content  : 内容
    date     : 作成日
    """
    __tablename__ = 'talk'
    id = Column(
        'id',
        INTEGER(unsigned=True),
        primary_key=True,
        autoincrement=True,
    )
 
    user_id = Column('user_id', ForeignKey('user.id'))
    content = Column('content', String(256))
    date = Column(
        'date',
        DateTime,
        default=datetime.now(),
        nullable=False,
        server_default=current_timestamp(),
    )
 
    def __init__(self, user_id: int, content: str, date: datetime = datetime.now()):
        self.user_id = user_id
        self.content = content
        self.date = date

 
    def __str__(self):
        return str(self.id) + \
               ': user_id -> ' + str(self.user_id) + \
               ', content -> ' + self.content + \
               ', date -> ' + self.date.strftime('%Y/%m/%d - %H:%M:%S')
```

"->"が良くなかった。

```python:models(after)
def __str__(self):
        parms =  {
                "id" : self.id,
                "user_id" : self.user_id,
                "content" : self.content,
                "date" : self.date.strftime('%Y/%m/%d - %H:%M:%S') 
            }
        json_str = json.dumps(parms,ensure_ascii=False, indent=2)
        return json_str

```

```vue:getTalk
const path = `http://localhost:5000/chat_api`
axios.get(path)
          .then((response) => {
            var len = Object.keys(response.data).length
            for(var n = 0 ; n < len ; n++ ){
                var cont = JSON.parse(response.data[n])
                this.message.push({user_id:cont['user_id'],message:cont["content"]})
            }
```
フロントではこんな感じでtalkを取得してます。

#結果
実際これでもvueで受け取る時のデータは文字列なのですが、
json.parse()でjson認識できる(しやすい)ので格段にデータの扱いやすさが変わりました。
データ構造まじ大事
【JavaScript】要素ノードの取得方法

#はじめに
この記事は以下の書籍を参考に作成しました。

https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=27USW7I2418F8&dchild=1&keywords=javascript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80+%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7&qid=1615819432&sprefix=JAVASCRIPThonn%2Caps%2C230&sr=8-1

#目次

#クライアントサイドJavaScript(DOM)
クライアントサイドJavaScript(DOM)で開発をする場合、以下の３つを抑えなければなりません。

####・要素ノードの取得(今回の内容)
#####・文書ツリー間の行き来
#####・イベントドリブンモデル

#要素ノードを取得する
JavaScript(以下JS)からHTMLなどの「要素を値を取り出す」「処理した結果を要素に反映させる」「新規に要素を作成し、既存の要素の配下に追加する」といった処理をするためには、操作の対象となる要素を取りださなければなりません。
JSで要素を取得するには、いくつかの方法がありますが、特に使用頻度の高い方法を紹介します!

#要素ノードの取得方法
##1.id値から取得-getElementByIdメソッド-
もっともシンプルな取得方法で、指定されたidを持つ要素を取得します。

######構文
```
document.getElementById(取得したいid名);
```
######使用例
```index.html
<p id="test"></p> <!--idを指定-->
```

```main.js
let test = document.getElementById('test'); //id=testが含まれている要素を取得
test.textContent = 'これはテストです' //取得した要素にテキストを埋め込む

//ページに反映する　→　「これはテストです」
```

getElementByIdメソッド他にも、

######・getElementsByTagNameメソッド (name属性から要素を取得)
######・getElementsByNameメソッド (要素名から要素を取得)
######・getElementsByClassNameメソッド (name属性から要素を取得)

など、getXxxxxメソッドで異なる方法で要素を取得することができます。
使い方は、メソッドによって少しことなるので、気になったら調べてみてください。

##2.セレクター式に合致した要素を取得-querySelector / querySelectorAllメソッド-
getXxxxxメソッドに比べ、より複雑な条件で要素を取得することができるメソッドです。
**セレクター式**で文章を検索し、合致した要素を取得できます。

######構文
```
document.querySelector(セレクター式);
document.querySelectorAll(セレクター式);
```
######使用例
```index.html
<ul id="testList">
  <li class="testItem"></li>
  <li></li>  <!--クラス指定していない-->
  <li class="testItem"></li>
</ul>
```

```main.js
let testItems = document.querySelectorAll('#testList .testItem'); 
//「id="testListである要素」の配下から「class=testItemのあるアンカータグ」を取得

for(let i = 0; i < testItems.length; i++){
testItems[i].textContent = 'これはテストです';
//リストから順にアンカータグを取り出し、そテキストを挿入
}

//ページに反映
//→・これはテストです　
//・
// ・これはテストです
```

セレクター式を使うことで、複雑な要素の指定をしたいという状況でも、複雑なコードを書く必要がなくなります。
取得したい要素が１つとわかっている場合は**querySelecotorメソッド**を使用してましょう。

######getXxxxメソッドとqueryXxxxメソッドの使い分け
queySelector/querySelectorAllメソッドを用いれば、どんな要素でも取得することができます。
しかし、getXxxxメソッドに比べて動作が低速になってしまうというデメリットがあります。
なので、私は以下のように使い分けています。

・id,class名で取得できる場合→getXxxxメソッド
・複雑な条件で取得したい場合→queryXxxxメソッド

#さいごに
以上にあげた方法以外にも、ノードウォーキングで取得する方法（childrenNodesプロパティ）など様々な方法で要素を取得することができます。
先頭でも記述したように、JSからHTMLを編集するためにかかせない作業になります。
まずは、ここに記述した方法を使ってみましょう！使い方に慣れてきたら違う取得方法にも挑戦しましょう！
A - Frog 1, B - Frog 2, H - ハードル走

##[A - Frog 1](https://atcoder.jp/contests/dp/tasks/dp_a)

O(N)
受け取るDPが一番作りやすいです。

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

# main
def main():
    N = int(input())
    H = list(map(int, input().split()))

    dp = [1000000007] * (N)
    dp[0] = 0

    for i in range(1, N):
        dp[i] = min(dp[i], dp[i-1] + abs(H[i] - H[i-1]))
        if i>1:
            dp[i] = min(dp[i], dp[i-2] + abs(H[i] - H[i-2]))

    print(dp[N-1])
            
# エントリポイント
if __name__ == '__main__':
    main()
```

メモ化再帰

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

H = []
dp = []

def dfs(n)->int:
    global dp
    
    if n<0:
        return 0
    if dp[n]<1000000007:
        return dp[n]
    
    dp[n] = min(dp[n], dfs(n-1) + abs(H[n] - H[n-1]))
    if n>1:
        dp[n] = min(dp[n], dfs(n-2) + abs(H[n] - H[n-2]))

    return dp[n]


# main
def main():
    sys.setrecursionlimit(1000000)
    global H, dp
    
    N = int(input())
    H = list(map(int, input().split()))

    dp = [1000000007] * (N)
    dp[0] = 0

    dfs(N-1)

    print(dp[N-1])
            
# エントリポイント
if __name__ == '__main__':
    main()
```

##[B - Frog 2](https://atcoder.jp/contests/dp/tasks/dp_b)

O(N)
受け取るDPが一番作りやすいです。
[A - Frog 1](https://atcoder.jp/contests/dp/tasks/dp_a)の応用ですね。
任意のKまでDPを受け取ります。

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

# main
def main():
    N, K = list(map(int, input().split()))
    H = list(map(int, input().split()))

    dp = [1000000007] * (N)
    dp[0] = 0

    for i in range(1, N):
        for j in range(1, K+1):
            if i-j>=0:
                dp[i] = min(dp[i], dp[i-j] + abs(H[i] - H[i-j]))

    print(dp[N-1])
            
# エントリポイント
if __name__ == '__main__':
    main()
```

##[H - ハードル走](https://atcoder.jp/contests/past202005-open/tasks/past202005_h)

O(N)

```python:python
import sys
import math
import heapq
import itertools
from collections import deque
from functools import reduce

# main
def main():
    N, L = list(map(int, input().split()))
    X = list(map(int, input().split()))
    T = list(map(int, input().split()))

    hurdle = [False] * (L+1)
    for index in X:
        hurdle[index] = True

    dp = [1000000007] * (L+1)
    dp[0] = 0
    for i in range(1, L+1):
        dp[i] = min(dp[i], dp[i-1] + T[0])
        if i-2>=0:
            dp[i] = min(dp[i], dp[i-2] + T[0] + T[1])
        if i-4>=0:
            dp[i] = min(dp[i], dp[i-4] + T[0] + (T[1] * 3))
        if hurdle[i]:
            dp[i] += T[2]
    
    ans = dp[L]
    for i in [L-3, L-2, L-1]:
        if i>=0:
            ans = min(ans, dp[i] + T[0]//2 + T[1]*(2*(L-i)-1)//2)

    print(ans)
            
# エントリポイント
if __name__ == '__main__':
    main()
```
メールを使わずスマホだけでPDFをKindleに送る

PDFをKindleで読みたい時にメールにPDFを添付することでKindleに送信する方法がある。
この方法には色々制限があり、メールで送ること自体が面倒なので、スマホだけでPDFをKindleに送る方法を調べた。

# メールでPDFをKindleに送る方法

Send to Kindle という方法が用意されている。
最大で50MBまでのドキュメントしか送れないという制限があり不便。
ググっても大体この方法しかでてこない。

https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=G7NECT4B4ZWHQ8WV

# スマホのKindleアプリでPDFを送る方法

ここではGoogleドライブにアップロードしたPDFを、スマホでKindleアプリに共有することで書庫に入れる。

## 用意するもの

- PDF
- スマホ
- Googleドライブアプリ(Dropboxアプリでも何でもいい)
- Kindleアプリ

## PDFをGoogleドライブにアップロード

スマホからPDFを開きたいので、Googleドライブなどのクラウドストレージを利用する。
Googleドライブアプリでなくても、PDFを他アプリに共有できれば何でもいい。
まず、Kindleに送りたいPDFを、Googleドライブの適当な場所にアップロードする。

![1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379/5b50a9d6-2946-ea90-0094-63acef7e6541.jpeg)

## GoogleドライブアプリでPDFを共有

スマホでGoogleドライブアプリを開く。
先ほどアップロードしたPDFのメニューから「アプリで開く」を選択する。

![2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379/8514f74b-0ffa-40ee-0a39-38c2ee9ecb00.jpeg)

## Kindleアプリを共有先として選択

共有先のアプリを選択する画面がでるので、Kindleアプリを選択する。
候補になかったら「…」その他、から選択する。

![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379/d86fcee0-9678-ad66-c7ef-94f69df1fd84.jpeg)

## タイトルや著者の入力

エクスポートの準備に少し時間がかかる。

![4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379/50b9b91f-ed76-7aa1-376f-78f32375bd99.jpeg)

タイトルと著者名が必須なので入力する。
するとPDF→Kindleフォーマットへの変換確認が表示されるが、上手くいった試しがないので「いいえ」を選択する。

![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379/e3e4e06c-6a76-4f77-cc0e-0b6dd70926ed.jpeg)

## KindleアプリでPDFを開く

しばらくすると、KindleアプリにPDFが表示されるようになっているはず。
Swiftで使う基本的な型について

swiftを使ってく上で出てくるコードの１つが型。
何も知識がなくUdemyの先生に言われるままやっていっても必ずどこかに出てきてる気がする。

基本的な型は３つ
▼文字列型（String型）
・基本形式　var ○○ = string()

string型は文字列
var ○○ = "あいうえお"
　

▼数字型（Int型、Double型、Float型）
・基本形式　var ○○ = Int()、Double()、Float()

・Int型は数字
var ○○ = 10

・Double型は小数点を表せられる（64bit）
var ○○ = 12.5

・Float型も小数点を表せられる（32bit）
var ○○ = 12.5

:thinking:じゃあDoubleとFloatは何が違うの？？
表せる範囲が違う！
Doubleは64bitで10の308乗まで表すことができるが、Floatは32bitで10の38乗まで表す
　

▼真偽型（Bool型）
・基本形式　var ○○ = Bool

Bool型は、そうであるかそうでないかを表す
var ○○ = true
         if  ○○ == true {
           △△
         }else{
           ××
         }

　

基本の３つではないが、辞書型（Dictionary型）というのもある
これは勉強して一番意味がわからなかった。

内容を聞いてわからないということは別の考え方をしなければいけないと思ったので、何かに変換できないかなと思っていたらすごくかんたんに変換できる方法があった！

まず、Dictionary型の基本形式（他にもあるそう・・・）
var dic = ["あいう" : 500,"えお" : 5000]
var dic2 : [String : Int] = [ : ]

はい、もうわからないw

Dictionary型には別名があり、「Key-Value型」と呼ばれる。
内容的に、文字列として記載されている「"あいう"」は「key」の部分をさし、
数字（Int）として記載されている「500」は「value」の部分をさす。

var dic2 : [String : Int] = [ : ]

これについても同じで、Stringが「key」、Intが「value」となる

この形式を以下のように指定して取り出そうとする

let value = dic["あいう"]
print(value!)

これもさっぱりでした。w
どういうこと？？？ってハテナがたくさんとんだw

理解できるように変換する上でわたしは、key＝鍵（そのまんまw）
value＝扉の先と考えました。

valueを呼び出すには、dic["あいう"]を使って呼び出すやり方ですが
つまり、
扉の先(value)へいくためには、開くための鍵(key)が必要で、
このコードは["あいう"]という鍵を使って、valueを呼び出している(扉の先を見ている)ということ。

つまり、最初に記載しているvar dic = ["あいう" : 500,"えお" : 5000]の「500」を呼び出しているよーってこと:raised_hands:


以上！！
不偏分散ってなんなのか

不偏分散がよくわからなかったので詳しく教科書を読みました
1. はじめに知っておくこと
2. 平均値と期待値の違い
3. 不偏分散は推定値


##はじめに知っておくこと
**平均値と期待値の違い**
**推定と自由度**について
**推定のために使われる**ということ


##平均値と期待値の違い

平均値
・取得した標本の値によって変化する

期待値
・取得した標本には関係なく一定の値
##推定と自由度について
ここで母平均の推定値の標本平均を例にあげます

```math
\bar{X}=\frac{1}{n}((X_1)+(X_2)+\cdots+(X_n))  \\
```
この式を変形すると

```math
((X_1-\bar{X})+(X_2-\bar{X})+\cdots)+(X_n-\bar{X})=0  \\
```
となります
ここでこの式がいつでも成立するようにするように$X_1～X_n$の値を考えると，1つの値(ここでは$X_n$)を調整用として残しておく
つまり

```math
\sum_{i=1}^{n-1}(X_i-\bar{X})=-(X_n-X)
```
と変形すると左辺の$X_1$から$X_{n-1}$までが任意の値を取れる変数になります．
これの個数を自由度と呼びます
推定を行う際には基本的に自由度が1減ります

## 不偏分散は推定値
標本分散(n=標本数で割ったもの)は

```math
S^2=\frac{1}{n}((X_1-\bar{X})^2+(X_2-\bar{X})^2+\cdots+(X_n-\bar{X})^2)  \\
```
で表すことができます

しかし
標本分散(k=自由度で割ったもの)は

```math
s^2=\frac{1}{k}((X_1-\bar{X})^2+(X_2-\bar{X})+\cdots+(X_n-\bar{X})^2)  \\
```

```math
s^2=\frac{1}{n-1}((X_1-\bar{X})^2+(X_2-\bar{X})^2+\cdots+(X_n-\bar{X})^2)  \\
```
となります

推定値とは推定したい値となるべく一致するよう(過大過小でなく平均的に)に取られた値
つまり不偏分散とは**母分散の期待値と一致するために生まれた値**ということです

参考文献
統計学入門 (基礎統計学Ⅰ)
お手軽に Laravel ローカル開発環境を構築(Laradock 編)

# 今回作成する環境構成

|名前     |バージョン|
|--       |--|
|PHP      |7.3.27|
|Laravel  |8.32.1|
|Laradock |v11.0 (2020/06/18)|

* VSCode のプラグイン
  * PHP Debug
  * PHP IntelliSense

![laradock.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/c693ace2-0f5b-79a8-e3aa-d3c1ebe587a3.png)

# まずは Web サーバーを準備

ここで登場するのが `Laradock` です。公式には以下のように記載があります。
> Laradockは、Docker用の完全なPHP開発環境です。
> さまざまな一般的なサービスをサポートし、すべてがすぐに使用できるPHP開発環境を提供するように事前構成されています。

本当に[いろいろなコンテナ](https://laradock.io/introduction/#supported-software-images)が `Laradock` には入っているのですが、今回使うのは `nginx` と `mysql` になります。

* http://laradock.io/

アプリケーション用のディレクトリを作成します。

```bash
mkdir -p ~/Desktop/workspace && cd ~/Desktop/workspace
```

今回準備するディレクトリ構成は以下の通りを想定しています。

```bash
└── workspace
    ├── laradock  ← Laradock本体
    └── myproject1 ← コンテナ(Laradock)とディレクトリ共有しているLaravelアプリケーション
```

Laradock を Clone します。

```bash
git clone https://github.com/laradock/laradock.git
```

`.env` を編集します。

```bash:.env
cd laradock
cp env-example .env
```

以下の項目を編集してください。

```bash:.env
NGINX_HOST_HTTP_PORT=80
↓ 80番ボートは何かと被ることが多いので未使用ポートに変更する
NGINX_HOST_HTTP_PORT=8100
```

Laradock は起動したいコンテナを引数に渡してあげれば起動できる仕組みになっていて、今回は冒頭で説明した通り nginx と mysql を指定します。

```bash
docker-compose up -d nginx mysql
```

http://localhost:8100 にアクセスします。
まだアプリケーションが空なので、404ページが表示されますが、これで正常にWebサーバーが構築できたことは確認できました。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/cbef41f4-2098-4e35-2770-e6cb65ffeacb.png width=500px></img>

# Laravel をインストール

コンテナにアタッチしてから `Laravel` をインストールします。

```
docker exec -it laradock_workspace_1 bash
composer create-project laravel/laravel myproject1
```

* https://laradock.io/documentation/#install-laravel-from-container

`.env` を編集します。
以下の項目を編集してください。

```bash:.env
APP_CODE_PATH_HOST=../
↓
APP_CODE_PATH_HOST=../myproject1/
```

設定を反映します。

```bash
docker-compose down
docker-compose up -d nginx mysql
```

http://localhost:8100 にアクセスし、以下の画面が開けばインストールは完了です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/f7c140c2-a88d-05a5-9d50-b25cf66cbfa9.png" width=500px></img>
 

# デバッグ(xdebug)の設定

`.env` を以下の通り編集してください。

```bash:.env
WORKSPACE_INSTALL_XDEBUG=false
PHP_FPM_INSTALL_XDEBUG=false
↓
WORKSPACE_INSTALL_XDEBUG=true
PHP_FPM_INSTALL_XDEBUG=true
```

* https://laradock.io/documentation/#install-xdebug

以下の `xdebug.ini` を編集します。(2ファイルあります。)

* workspace/xdebug.ini
* php-fpm/xdebug.ini

```bash:xdebug.ini
xdebug.idekey=PHPSTORM
xdebug.remote_autostart=0
xdebug.remote_enable=0
↓
xdebug.idekey=Listen for XDebug
xdebug.remote_autostart=1
xdebug.remote_enable=1
```

インストールした `Laravel` に `launch.json` を設定します。

* myproject1/.vscode/launch.json

```json:launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000,
      "pathMappings": {
        "/var/www":"${workspaceFolder}"
      }
    }
  ]
}
```

設定を反映します。

```bash
docker-compose down
docker-compose up -d nginx mysql
```

## デバッグしてみます

できました。

![xdebug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/0419329e-944c-3430-23ad-3bbb7be514be.png)
Chartkickを使用したグラフ作成

#はじめに
体重管理アプリを作成しようと思い、入力した値をグラフ化する際にchartkickを使用したので、
導入方法からデータ入力、表示方法を忘れないように記録します！！
Rails 6を使用しています！！

※使用するバージョンによって記述内容が異なるので、詳しくはリンクを参照してください。
[Chartkick公式](https://chartkick.com/)

#ChartKickの導入
まずgemにファイルに以下を記述します。
groupdateは今回作成するアプリで日時を表示したいため、一緒に導入しました。

```ruby:qiita.rb
gem "chartkick"
gem 'groupdate'

```

記述ができたらbundle installを行います。


続いてchart.jsを追加するため、ターミナルで以下も実行。

・yarn add chartkick chart.js

```javascript:qiita.js
require("chartkick")
require("chart.js")

```

#入力したデータをグラフにする

以下はコントローラー内容です

```ruby:qiita.rb
def create
    @weight = Weight.new(weight_params)
    if @weight.save
      redirect_to action: 'index'
    else
      render :new
    end
  end

  private
  def weight_params
    params.require(:weight).permit(:weight, :date).merge(user_id: current_user.id)
  end
```

以下はビューファイルの記述です。

```ruby:qiita.rb

<%= line_chart @weight.group_by_day(:date, series: false).average(:weight),height: "400px",xtitle: "日", ytitle: "体重",min: 30, max: 80, curve: false %>

```

これでweightモデルのdateカラムをX軸にグラフが作成できます。
・series: falseを記述しないと、データが無い日付に０がカウントされてしまいます
・curve: falseでは、折れ線グラフの線が直線になります

以下が今回作成したグラフの画像です。

![グラフ](https://i.gyazo.com/1a9c5653b456c82dee56ab5cb4695513.png)

#まとめ

Chartkickでは、折れ線グラフの他にも円グラフなど様々なグラフを作る事ができます。

今後はX軸、Y軸の値を入力された値によって変化させたり、グラフの点の部分にリンクつけて細かい記録を見たりとか、色々つけたい機能がたくさんあるので、実装できたらまた記事にします！！（それが実現できるかについてもまた調べます）
Overleafのpdflatexで日本語・中国語・韓国語を使う

#対象とする読者
**Overleaf**にてCompilerが**pdfLaTeX**の状態で**日本語・中国語・韓国語**を利用したい方。
（その他の言語を利用したい方も参考になる可能性があります。）



#解決法

プリアンブルにて以下のようなコマンドを定義し、各言語の文章を表示したい際に利用します。

```latex
% 中国語・韓国語用パッケージ
\usepackage{CJKutf8}

% 日本語用パッケージ
\usepackage[whole]{bxcjkjatype}

% 中国語用コマンド
\newcommand{\Chinese}[1]{{\begin{CJK*}{UTF8}{gbsn}#1\end{CJK*}}}

% 韓国語用コマンド
\newcommand{\Korean}[1]{{\begin{CJK}{UTF8}{}\CJKfamily{mj}#1\end{CJK}}}


\begin{document}
東京
\Korean{도쿄}
\Chinese{东京}
Tokyo
\end{document}

% 東京
% 도쿄
% 东京
% Tokyo
```

その他の言語に関しても[Overleafの公式Documentation](https://ja.overleaf.com/learn)から表示方法が確認できます。


Overleafのサンプルは[コチラ](https://www.overleaf.com/project/604f4963b413c0433014281f)

#おわりに
もっと簡単に利用できる方法があれば教えていただけると嬉しいです🙇‍♂️


#参考

- [Overleaf Documentation](https://ja.overleaf.com/learn)
- [Overleafのpdflatexで日本語を使う] (https://qiita.com/fumi1/items/73cbdd78db8fe12a5904)
- [完全攻略！ LaTeX のマクロ定義](https://qiita.com/zr_tex8r/items/5067307890d36c0e4882)
【p5.js】background() を使う時の注意点

### 開発環境
p5.js Web Editor
https://editor.p5js.org/

## background()はdraw()の中に書くこと

1. リファレンスの通りhttps://p5js.org/reference/#/p5/background
2. setup()にも置けるが初回の１回のみ
3. draw()の中でbackground()を使用することが想定されている


```javascript

let alien;
let imgAlien;
let imgBackground;

function preload(){
  imgAlien = loadImage('assets/invader1.png');
  imgBackground = loadImage('assets/bg_space1.png');
}

function setup() {
  createCanvas(400, 400);
  alien = new Alien(50,50,imgAlien);
  // setup()にも置けるが最初だけ。
  // background(imgBackground);
}

function draw() {
  // ここ!!　draw()の中に置くことが公式リファレンスで説明している基本的な使い方
  background(imgBackground);
  alien.draw();
  alien.update();
}

// ------base setting end ------

class Alien {
  constructor(x, y, image) {
      this.x = x;
      this.y = y;
      this.image = image;
  }

  draw() {
      image(this.image, this.x, this.y, this.image.width/30, this.image.height/30);
  }
  
  update(){
    this.x += 0.2;
  }
}

```


## setup()だけにbackground()を置くと、、

残像が残ってしまう。しかもpreload()した一部の画像のみがそうなる。内部処理でおそらく画像の優先度があるのだろうが具体的にはわからなかった。

![Screen Shot 2021-03-16 at 10.06.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394058/32f7ec33-5e76-6990-30a9-ce86829270e8.png)




## まとめ
詳細は腹括って公式リファレンスを読もう。
https://p5js.org/reference/#/p5/loadImage

参考にしている資料は下記
How to code Space Invaders (1978) – 7　/ Published by lukegarrigan
https://codeheir.com/2019/03/17/how-to-code-space-invaders-1978-7/
Github で Origin の修正をマージする

# 完全なる自分メモです..

Github で Fork した後に Origin をマージするのわからん！...
の解になるかも..

## Pull Request の画面で New Pull Request

compare access forks の link をクリックする

![スクリーンショット 2021-03-16 0.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/5ece7066-f269-e9a1-f8d5-409f11166543.png)

base を自分のブランチ、マージ元をマージしたい本流のブランチにする。
だけ..

![スクリーンショット 2021-03-16 0.25.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/ec2cf397-bfed-8f0c-9987-d2d8f9b4eb3d.png)

自分用メモですが、誰かの助けになればいいなと..
（あと、書くと思い出せるか検索できるので..）
Gatsby公式チュートリアルでややハマったこと



Vue一家に所属していたわけですが、reactファミリーも少し覗いてみようと思い門を叩きました。

※macでの操作になります。

```Terminal:Terminal
node -v
v15.11.0
```

#目次
[1.CSSをimportする時に読み込めないエラー発生](#1-cssをimportする時に読み込めないエラー発生)
[2.ところどころでnpm installの時にエラー](#2-ところどころでnpm-installの時にエラー)
[3.チュートリアル４のパンダで発生](#3-チュートリアル４のパンダで発生)
[4.チュートリアル「セクション７」](#4-チュートリアルセクション７)
[5.まとめ](#5-まとめ)

#1. CSSをimportする時に読み込めないエラー発生

セクション２で`tutorial-part-two/src/components/container.js`で「containerなんてねえぞ」と怒られる。

```
// localhost:8000/about-css-modules/

Cannot read property 'container' of undefined
  3 |
  4 | export default function Container({ children }) {
> 5 |   return <div className={containerStyles.container}>{children}</div>
    |                          ^
  6 | }

```
どうやらCSSがimportできていない模様。
import側

```
// components/container.js

import Container from "../components/container"
```

を

```
// components/container.js

import * as Container from “../components/container”
```

としたら通った。
**「*」で全て受けとめてから「as」で別名指定。**
CCSが読み込めなくて困ったことがよくあったがだいたいコレでした。


#2 ところどころでnpm installの時にエラー

> このエラーは、npmのバージョン7.xから発生します。
>
> --legacy-peer-depsオプションで再試行してください。
> [引用元](https://stackoverflow.com/questions/64718633/unable-to-resolve-dependency-tree-reactjs)

バージョンのバグ？らしく、npm installのオプションに

--legacy-peer-deps

これを付与しろとのこと

```Terminal:セクション３
npm install --save gatsby-plugin-typography react-typography typography typography-theme-fairy-gates --legacy-peer-deps
```

#3. チュートリアル４のパンダで発生

モジュールが足りないと怒られる。
@emotion/reactが解決できない・・・

```

 ERROR #98124  WEBPACK

Generating development SSR bundle failed

Can't resolve '@emotion/react' in
'tutorial_gatsby/tutorial-part-four/src/components'

If you're trying to use a package make sure that '@emotion/react' is installed.
If you're trying to use a local file make sure that the path is correct.

```

調べてみると、@emotion/coreではなく@emotion/reactが必要だということ

@emotion/reactをインストールしてimport部分も@emotion/reactに変更

```Terminal:Terminal
npm install @emotion/react
```

[引用元](https://stackoverflow.com/questions/65486256/module-not-found-cant-resolve-emotion-react)  

#4. チュートリアル「セクション７」

gatsby-node.jsでGatsby APIのところ。

```js:gatsby-node.js

exports.onCreateNode = ({ node }) => {
  console.log(node.internal.type)
}
```

見るのはターミナルなので注意w（自分はブラウザからコンソールを見ていて日が暮れそうになりました）


![tutorial1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264884/f73843fe-e4c4-de37-5b69-60edc1a00712.jpeg)


---

#5. まとめ

サイト制作後、客先のサーバーがPHP5系であり「FTP以外使わないでほしい」という希望に絶望し、フォームはGoogleフォーム、メールもGoogleメールでまかなって、ペラサイトにしてFTPでアップロードする作戦に切り替え。

Nuxt.jsで作ってみるも納期に余裕があったのでGatsbyに挑戦。

その備忘録として。

Gatsbyかなり良いですね！

reactにも慣れていきたいと思います。
PHPをherokuでデプロイする！(4)Composerのインストールとデプロイの実行

#はじめに
PHPをherokuでデプロイする方法、前回まででデータベースを整えたので、今回はいよいよデプロイするために最終準備にうつっていきます！

#Composerのインストール
デプロイするための最後の準備として、Composerのインストールが必要となります。このComposerというのはPHPのパッケージ管理を行うツールであり、フレームワークを利用せずにPHPのみで作成している場合には、デプロイするために必要なソフトウェアが入っているため、新たにインストールする必要があります。

それではインストールの方法について説明します。ターミナルでデプロイしたいアプリのディレクトリにアクセスしましょう。
そして以下のように入力しましょう。

```
$ touch composer.json
```

このように入力すると、composer.jsonのファイルが作成されます。もちろん、composer.jsonというファイルを直接デプロイしたいアプリのディレクトリ内に作成しても構いません。その後エディタでcomposer.jsonを開きましょう。

```
{
    "require": {
      "php": "~7.412",
      "ext-mbstring": "*"
    }
 }
```

phpの後はバージョンを表す数字になるので、自分のバージョンに合わせて編集しましょう。続いては再びターミナルでの操作に戻ります。

```
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
```

この入力をしたら、一度ターミナルを閉じて、再びデプロイしたいアプリのディレクトリを開きましょう。
そして以下のように入力すればcomposerがインストールされます。

```
$ composer -v
$ composer install
```

これを行うと、venderというディレクトリと、composer.lockというファイルが作成されます。
herokuにデプロイするときは、gitを用いるので必ずgitにコミットをしておきましょう！

いよいよ最終段階、デプロイに入ります。データベース情報は必ず書き換えているか、パスワードなど漏れてはいけないものが書かれていないか確認しておきましょう。
またgitに全ての編集がコミットされているか確認しておいてください。

#いよいよデプロイ！
確認が終わればいよいよデプロイします。デプロイしたいアプリのディレクトリにターミナルでアクセスしましょう。

```
$ heroku login
```

念のためログインの確認をしておきましょう。そして、以下をコマンドを入れればデプロイできます！

```
$ git push heroku master
```

もしいつも更新しているブランチがmasterという名前でなければ、そのブランチの名前でプッシュしてください。赤字でのエラーが出ていなければデプロイ成功です！

```
$ heroku open
```

ターミナルでこちらを入力すると、デプロイされたURLにアクセスすることができます。動作確認し、正しくトップページが表示されていればデプロイ完了です！もしエラーが出る場合は、データベースなどが正しく動いていない可能性があります。コードの見直しと、前回インストールしたWorkbenchで確認して見ましょう。

#おわりに
4回に渡ってPHPのデプロイについて書いてきました。初学者なのでもし間違いや、改善点があればコメントいただけると嬉しいです！
AWS X-Ray とは

## 勉強前イメージ

全然わからん・・・

## 調査

### AWS X-Ray とは

アプリケーションが処理するリクエストに関するデータを収集するサービスで、
レスポンスタイムやレスポンスステータス、アプリケーションに対するリクエストに関するデータを収集し、コンソール上で表示したり分析することで問題を特定することが出来ます。

### X-Ray のメリット

- リクエストの動作確認・流れを把握・問題の検出

エンドツーエンドで流れを表示し、詳細情報を確認することが出来ます。
それによってボトルネックを確認し改善ができます。

- アプリケーションのパフォーマンスの向上

X-Rayのサービスマップににより、サービスやリソースの関係性をリアルタイムで表示できるので
高いレイテンシーが発生している場所を簡単に検出出来ます。

- AWSの他のサービスとの連携

EC2、ECS、Lambda,Elastic Beanstalkと連携することが出来ます。

### X-Rayの概念

- サービスマップ

アプリケーションから生成されたトレースしたデータを可視化したもの。
クライアントが始点で、各サービスのノードが終点になります。
各ノードをクリックするとトレース画面へ進みます。

![1AWS X-Ray とは何ですか。 - AWS X-Ray - Google Chrome 2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/48069a66-1d80-b7fb-9da4-f8f8fb086e40.png)


- トレース

このリクエストに何秒かかってるのか、ということがわかります。
時間・ステータスコードなどリクエスト毎に一覧で確認することが出来ます。
IDが割り振られていて、詳細はIDをクリックすると確認することが出来ます。

### CloudWatchとの違い

AWSには似たようなサービスでCloudWatchがあります。
CloudWatchの詳細は [こちら](https://qiita.com/miyuki_samitani/items/4799428602c7ad7001f3)
CloudWatchとは、AWSで稼働している各サービスを監視するモニタリングサービスです。
違いとしては、以下になります。

- X-Ray : サービスマップと呼ばれるグラフから全体のパフォーマンスを確認することができ、リソースのレイテンシーや障害の発生率の特定など特定することが出来ます。
- CloudWatch : AWS サービスのログの管理メトリクス監視を通じて、アプリを監視することが出来ます。

イメージとしては、X-Rayはサービス監視。CloudWatchはサーバ監視 ってイメージ(間違ってたらごめんなさい)

## 勉強後イメージ

アプリケーション全体を見る感じ？
ワイヤーシャークのアプリケーション版みたいなイメージを持った。

## 参考

- [AWS X-Ray とは何ですか。](https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/aws-xray.html)
- [AWS X-Ray を使ってみる 基本編](https://blog.serverworks.co.jp/tech/2017/03/02/aws-xray-1/)
- [AWS X-Ray： クラウドでのマイクロサービスのデバッグ](https://blog.ipswitch.com/jp/aws-xray-debugging-microservices-in-the-cloud)
Adjacent JSX elements must be wrapped in an enclosing tag.

初学者あるあるらしい?

# 前提
React 17.0.1

# 起こったこと

こういうコンポーネントを作成して

```jsx

const LogoutButton = ({username, handleLogout}) => {
	return (
		<p>{username} logged in</p>
		<button onClick={handleLogout}>logout</button>
	)
}

export default LogoutButton
```

こういうふうに使いました。

```jsx
<div>
	<Title user={user} />
	{user && <LogoutButton username={user.name} handleLogout={logoutHandler} />}
	{user === null && loginForm()}

(以下略)
</div>
```

そしたらこのように言われました。

```
SyntaxError: /Users/xxx/projects/bloglist_frontend/src/components/LogoutButton.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? 
```

# 修正

```
Adjacent JSX elements must be wrapped in an enclosing tag.
```

↑一旦言われた通りにやってみます。
とりあえずdivで囲んでみます。

```jsx
const LogoutButton = ({username, handleLogout}) => {
	return (
		<div>
			<p>{username} logged in</p>
			<button onClick={handleLogout}>logout</button>
		</div>
	)
}

export default LogoutButton

```

これでエラーは解消されました。が、後続の

```
Did you want a JSX fragment <>...</>? 
```

が気になったので確認してみました。

# Fragments

https://reactjs.org/docs/fragments.html

```jsx
<React.Fragment></React.Fragment>

```
で囲めば余分なノードをDOMに追加せずに複数要素を返すことができるとのこと。つまり、上記のような余分なdivを付け加えなくてもいいということらしいです。
こういうふうに書ける↓

```jsx

import React from 'react'

const LogoutButton = ({username, handleLogout}) => {
	return (
	<React.Fragment>
		<p>{username} logged in</p>
		<button onClick={handleLogout}>logout</button>
	</React.Fragment>
	)
}

export default LogoutButton
```

ショートシンタックスもあるようで、こちらの方が読みやすく書きやすいのでこちらを積極的に使ったほうがよさそうに思います。ただ、ショートシンタックスはkeyプロパティに対応していないなど若干の違いがあるようです。

```jsx
//Fragment short syntax
const LogoutButton = ({username, handleLogout}) => {
	return (
	<>
		<p>{username} logged in</p>
		<button onClick={handleLogout}>logout</button>
	</>
	)
}

export default LogoutButton
```
【C#を使ってOutlookにメール送信】メールを送信するコンソールアプリ作ってみた！

【実行環境】
開発環境：Visual Studio2019 Community

Outlookへメール送信する際、いくつか躓いたのでその備忘録を作成します。

①まずOutlookのライブラリをCOM参照で取得します。
[プロジェクト]⇒[COM参照の追加]
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/f9ee8bdc-3a93-4fa2-f6d7-cb483a946fa8.png)


②参照マネージャからOutlookのライブラリにチェックを入れて「OK」ボタンを押します。
![参照マネージャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/ddff7b77-e655-9abb-7408-cc606d2a5993.png)

③[コレ大事！] interop.Microsoft.Office.Outlookをクリックしてプロパティウィンドウを開きます。※赤枠の箇所に注目してください！
「ローカルにコピー」欄に「はい」を選択します。
「相互運用型の埋め込み」欄に「はい」を選択します。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/5d41f586-5ccc-5d06-1e70-b8d33c927401.png)

あとは下記のコードをコピペするだけです！

【ソースコード】

```Program.cs
using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace OutlookMail
{
    class Program
    {
        static void Main(string[] args)
        {
            var ol = new Outlook.Application();
            Outlook.MailItem mail = ol.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
            mail.Subject = "メールタイトル";
            Outlook.AddressEntry currentUser = ol.Session.CurrentUser.AddressEntry;
            //メール本文の内容を記載する(例："C#でOutlookを操作する")。
            mail.Body = "C#でOutlookを操作する";
            mail.Recipients.Add("abcd123xyz@outlook.jp");
            mail.Recipients.ResolveAll();
            mail.Send();

        }
    }
}

```

コンソールアプリを実行！すると...
無事に送信メールを受信することが出来ました。
![OutlookMail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/b03a1ee0-ccb4-67fa-ff44-e2ba888e6080.png)

【お世話になった引用元】
.NET 5プロジェクトでのCOM参照の追加
URL: https://opcdiary.net/net-5%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%A7%E3%81%AEcom%E5%8F%82%E7%85%A7%E3%81%AE%E8%BF%BD%E5%8A%A0/
Swiftで.envを使った環境変数の管理方法

最近Swiftを触りました。

https://qiita.com/sskmy1024y/items/cd698501debe4bf32a83

今回はSwiftで開発するプロジェクトで、`.env`ファイルを使って環境変数をビルド時に埋め込む方法を書いていきます。
Swift+Xcode初心者なので間違いなどあれば教えてください。

# ビルド時の流れ

やってること自体は単純で、swiftファイルごと作成しています。

1. Run Scriptでシェルスクリプトを呼び出す
2. スクリプト内で`.env`を読み込み、`Environment.swift`を作成する
3. Environment.swiftを使ってビルド実行

# とりあえずやってみる

## 1. `.gitignore`に追記

間違ってcommitしないように、先に追記しておきましょう。
ここで`.env`と一緒に`Environment.swift`も追加しておきます。

```shell:.gitignore
#（省略）

.env
Environment.swift
```

## 2. `.env`を用意する

お馴染みのファイルを用意。場所はプロジェクトのルート直下が良いと思います。

```env:.env
TWITTER_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GYAZO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
HOGEHOGE=xxxxxxxxxxxxxxxxxxxxxx
```

## 3. シェルスクリプトを作成

`.env`を読み取って、`Environment.swift`を生成するshellscriptです。
引数を２つ取り、１つ目が.envのpath、２つ目が出力先です。

保存先は、こちらもプロジェクトルート直下が良いと思います。

```sh:buildEnv.sh
#!/bin/sh
# Copyright (c) 2021 Sho YAMASHITA

code=$(cat <<EOS

import Cocoa

let Env: [String: String] = [

EOS
)

if [ $# -ne 2 ]; then
  echo "require 2 arguments." 1>&2
  echo "./buildEnv.sh /path/to/.env /output/path" 1>&2
  exit 1
fi

if [ -f "$1" ]; then
    while IFS='' read -r line || [[ -n "$line" ]]; do
        line="${line//[$'\r\n']}"
        trimline="${line//[$'\t\r\n ']}"
        if [ -n "$trimline" ]; then
            KEY="${line%%=*}"
            VALUE="${line##*=}"
            code=$(cat <<EOS
        $code
        "$KEY": "$VALUE",
EOS
)
        fi
    done < "$1"
fi

code=$(cat <<EOS
$code
]
EOS
)

echo "${code}" > "$2/Environment.swift"

exit 0
```

`import Cocoa`部分は必要に応じて変更してください。

## 4. Run Scriptを追加

Xcodeの`TARGETS < Build Phases`を開き、左上の`+`ボタンから*Run Script*を追加してください。
この時、並び順を`Compile Souces`より前に来るように配置してください。

追加したら、以下のようにコマンドを記入します。

```sh
"${SRCROOT}/buildEnv.sh" "${SRCROOT}/.env" "${SRCROOT}/${PROJECT}"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265811/ef7ee2a5-1ccf-ceff-be62-deb911ee7a3e.png)

ここでまず1回BuildもしくはRunしてみましょう。
上手くいけばプロジェクトディレクトリ配下に、`Environment.swift`が生成されているはずです。

## 5. 環境変数（.env）の値を使用する

生成された `Environment.swift`をプロジェクトに追加すれば、あとは変数として使うだけです。
`Env["<.envに書いたキー>"]`で呼び出せます。

```swift:Example.swift
    // ...省略
    let twitterToken = Env["TWITTER_TOKEN"]
    let clientId = Env["GYAZO_CLIENT_ID"]
```

生成された環境変数は全てString型になっているので、整数型として使いたい場合などはキャストして下さい。
以上で終わりです。

# この方法のメリット

- `.env`を成果物に含める必要がない
- `Info.plist`に書く必要がない（成果物の中身見ればデータが見れてしまう）
- 管理対象のコードを上書きする事がないので、git管理がしやすい

# 今回採用しなかった、他の方法

Info.plistに持たせるのが一般的なのでしょうか？
成果物の中身をみられにくい場合（特にiOSアプリなど）や、漏れてもそこまで気にしなくて良い場合は良いのかもしれません。

https://qiita.com/nnsnodnb/items/9344a1955c5cf50e61af

https://qiita.com/kazuph/items/109c6cc6c2b5c2074120

# 終わりに

普段Web系の言語に触れていると当たり前のようにある `.env` なのですが、これといってベストな解決策が見当たらなかった事に驚きました。
そもそもあまり情報がなかったのは、iOSアプリなどをgit管理してOSSで公開する事が想定されていないからなのか……？

何かご意見等あれば、コメントお待ちしております🙇‍♂️
【Android】Viewのサイズを動的に変える時、dp指定かpx指定か忘れがち【Layout】

# はじめに

無限回忘れるから備忘録として残す。

## 結論

結論から言うと、layoutParamsをいじってViewのサイズを動的に変更する時は、**px**で指定します。  

## おまけ

だけだとあまりにも味気ないので、Viewのサイズ変更に使えるコードを紹介。

### px⇆dp変換

デザイナーから提供される数値はdpだったりする。
計算してサイズを出す場合はdp/pxどちらかに合わせないといけないから、変換の処理が必要。

```kotlin
// px→dp
fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
// dp→px
fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
```

### 画面サイズ取得

そもそも動的にサイズを変更したい理由が**「画面サイズに応じてViewを拡縮したいから」**ってこと、多いと思う。

```kotlin
// 幅取得
fun Activity.getWindowWidth(): Int {
    val wm = getSystemService(Context.WINDOW_SERVICE) as WindowManager
    val disp = wm.defaultDisplay
    val windowWidth = Point()
    disp.getSize(windowWidth)

    return windowWidth.x
}

// 高さ取得
fun Activity.getWindowHeight(): Int {
    val wm = getSystemService(Context.WINDOW_SERVICE) as WindowManager
    val disp = wm.defaultDisplay
    val windowHeight = Point()
    disp.getSize(windowHeight)

    return windowHeight.y
}
```

ちなみに、このやり方で取得できるのは画面のpx数。
dpと計算する場合は前述の`toDp()`を使って変換してあげて。

※個人的には、`WindowSize`みたいなdata classをつくってwidthとheightを持たせちゃった方がいい気がしてる。

### DataBindingを使ってサイズを指定

`layoutParams`をいじるんじゃなくて、`binding`にサイズを渡しちゃいたい！ってワガママさん、いるよね。
わかる。そっちのが簡単だからね。

まずはwidthとheightを渡せるBindingAdapterを作る。
ちなみにここで渡すのは**px**想定。

```kotlin
@BindingAdapter("width", "height", requireAll = true)
@JvmStatic
fun View.setLayoutParams(width: Int?, height?) {
    width ?: return
    height ?: return
    layoutParams = View.LayoutParams(width, height)
}
```

あとはBindingAdapterをViewに適用して計算した値をわたすだけ。

```xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="width" type="java.lang.Integer"/>
        <variable name="height" type="java.lang.Integer"/>
    </data>

    <View
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            width="@{width}"
            height="@{height}"/>
</layout>
```

# 最後に

アスペクト比計算...。
端末のサイズに合わせて画像サイズを変更...。
うっ...頭痛が...。

おわり。