OmniAICreator/Qiita-1.07M huggingface dataset:
データベースからデータを取り出す PHP/MYSQL

#■はじめに
PHPでデータベースと接続しておく
以前に記事を書いたのでそちらを参照ください。
https://qiita.com/pito555/items/77d2f141846a40d8c659

#■①SQL文の準備
$sqlとしてSQL文を入れる変数を用意

●下記SQL文の意味
左から読むとわかりやすい!
テーブル名　FROM(から)　*(全部) SELECT(選択)


``` php
$sql = 'SELECT * FROM テーブル名';
```

#■②SQLの実行
$SQL文を実行するために記述します。

▼　$dbh 以前データベースに接続するために書いたPDOを格納しているもの
▼　query 問い合わせる
▼　$sql  実行するSQL文
▼ $stmt PDOStatementとして実行される。


``` php
$stmt = $dbh->query($sql);
```

#■③SQLの結果を受け取る。
▼fetchAll
全ての行を返す。

フェッチモードを使いデータの結果を受け取る。
PDOでデータベースからデータを取り出した時に配列の形式を指定するモード

今回はベーシックなPDO::FETCH_ASSOCを使用します。

▼fetchAllの引数としてフェッチモードを使う。
PDO::FETCH_ASSOCはカラム名の配列を返す。

詳しくは下記URLを参照してみてください。
https://blog.senseshare.jp/fetch-mode.html

``` php
$result = $stmt->fetchAll(PDO::FETCH_ASSOC)
```

#■HTMLの中でPHPを使いデータを表示する。
▼foreachで配列の中身を取り出す。

``` php
//ポイントforeachの最後に:で閉じる。;ではエラーになる。
<table>
<?php foreach($result as $column):?>
<tr>
<td><?php echo $column['カラム名']?></td>
<td><?php echo $column['カラム名']?></td>
<td><?php echo $column['カラム名']?></td>
<tr>
//最後にforeachを終わらせる。
<?php endforeach; ?>
</table>
```
URP非対応のアセット・マテリアルを使用する場合のシェーダー設定や変換関連

手順を忘れると、URP対応時に時間を取られるのでメモとして記録します。
もっと簡単に設定できる方法があれば、コメントを頂けると助かります。

※Unity2021.2以降の自動アップグレード方法が変更になっています。

# URPに対応していないシェーダーがある場合
テクスチャが割り当てられていない状態の表示になります。
![screenshot.306.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/31ec812f-0d67-525e-1587-497dfbb90c12.png)

# URP対応する場合の基本的な方法
### Unity2021.1以前の方法

以下をクリックすると一般的なシェーダーはURPに対応したシェーダーに一括で変換することができる。

Edit > RenderPipeline > UniversalRenderPipeline > UpgradeProjectMatelialsToUniversalRPMaterials
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/4df2e3b3-f1c8-295f-5812-b4dde0f21db1.png)

### Unity2021.2以降の方法

"Edit > RenderPipeline"の項目が無くなり、別ツールとして追加されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/fc0022fb-83c0-3bd1-ff6b-75aa1a93a904.png)

Built-in to URPを選択してConvertを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/5dc35179-be88-2284-22f1-628a05898de9.png)


fbxとかに埋め込まれているようなReadOnlyになっていたマテリアルの場合、これまでは一度エクスポートしないと変換ができなかったのですが（その認識であってます？）、新コンバートツールではエクスポート無しで変換できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/05b67299-7424-0fd6-f590-804ab19c5bc3.png)

#### 新RenderPipelineConverterの注意点
2021.2.7f1の時点では、従来の機能でURPマテリアルに変換した方が、変換できるシェーダーの種類に違いがあるようで、UIだけでは無く、内部の変換処理も変わっていると思われます。

ちなみに私の変換したかったマテリアルは従来の機能で変換した方が変換成功率が高かったため、若干劣化している様に感じました。

自分の使いたいマテリアルが2021版だけ変換できなった！というケースでは、一旦2020のプロジェクトでURP用のマテリアルに変換してから、コピーする方法が良いと思います。

#### 2022/02/24追記：UnityStationで本機能の解説動画が公開されました

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

# 上手くシェーダーが変換されない条件

* カスタムシェーダーを使用している場合（URPに変換できない機能が含まれている場合）
*  Prefabにマテリアルが組み込まれている場合

# カスタムシェーダーを使用していた場合の対応

* 一つづつピンクに表示されているマテリアルを選択し、標準のシェーダーに変更する。
※複数同時にシェーダーを変更しようとすると、テクスチャが剥がれてしまうので、元のテクスチャを探すのが面倒になります。

![screenshot.317.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/53459ee2-5f1a-e914-abc1-3f225d9e8805.png)

* UpgradeProjectMatelialsToUniversalRPMaterialsを実行する。ここでテクスチャが表示されているはず。
![screenshot.320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/48eb9709-af88-f52b-7c05-73d2952c4070.png)

* テクスチャに透過する部分がある場合、透過しない状態になっているので、AlpahaClippingにチェックを入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/1c550fbf-0ea1-5f8d-48d6-4096e218864b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/0592a962-ae6d-93d3-b7e1-740274924ccc.png)

# Prefabに組み込まれているReadOnlyなマテリアルの対応

* Unity2021.2以降は組み込みマテリアルも自動変換できるので不要です。
* 本ケースの場合、シェーダーの編集自体ができなくなっているため、PrefabのInspecterからExtractMaterialsをクリックし、マテリアルをPrefab外に出力すると、編集が可能になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/e10fd57a-04e4-6924-2a52-d6c1a5d66a16.png)

* UpgradeProjectMatelialsToUniversalRPMaterialsを実行する。
kustomizeのversionを指定してインストール

# インストール

```bash
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s <version>
```

# 例

```bash
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s 3.6.1
{Version:kustomize/v3.6.1 GitCommit:c97fa946d576eb6ed559f17f2ac43b3b5a8d5dbd BuildDate:2020-05-27T20:47:35Z GoOs:darwin GoArch:amd64}
kustomize installed to /Users/masato-naka/repos/nakamasato/kustomize
```

```bash
./kustomize version
{Version:kustomize/v3.6.1 GitCommit:c97fa946d576eb6ed559f17f2ac43b3b5a8d5dbd BuildDate:2020-05-27T20:47:35Z GoOs:darwin GoArch:amd64}
```

# 例外: v3.2.1

[v3.2.1](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.2.1) 以前は、ファイルがtarでないので　[install_kustomize.sh](https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh)内の `tar xzf ./kustomize_v*_${opsys}_${arch}.tar.gz` で失敗してしまう。

```
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash -s 3.2.1
tar: Error opening archive: Failed to open './kustomize_v*_darwin_amd64.tar.gz'
```

## v3.2.1のインストール方法

1. 以下のように、スクリプトと同じようにrelease_urlをセット

    ```bash
    release_url=https://api.github.com/repos/kubernetes-sigs/kustomize/releases/tags/kustomize%2Fv3.2.1
    ```

1. OSTYPEによって`opsys`を決める

    ```bash
    opsys=windows                                
    arch=amd64
    if [[ "$OSTYPE" == linux* ]]; then
      opsys=linux
    elif [[ "$OSTYPE" == darwin* ]]; then
      opsys=darwin
    fi
    ```

1. `RELEASE_URL` を githubのAPIを使って取得する

    ```bash
    RELEASE_URL=$(curl -s $release_url |\
      grep -E "browser_download.*${opsys}_${arch}" |\
      cut -d '"' -f 4 |\
      sort -V | tail -n 1)
    ```

1. Download

    ```bash
    curl -sLO $RELEASE_URL
    ```

1. executableに変換

    ```bash
    chmod +x kustomize_kustomize.v3.2.1_darwin_amd64
    ```
1. チェック

    ```bash
    ./kustomize_kustomize.v3.2.1_darwin_amd64 version
    Version: {Version:kustomize/v3.2.1 GitCommit:d89b448c745937f0cf1936162f26a5aac688f840 BuildDate:2019-09-27T00:10:52Z GoOs:darwin GoArch:amd64}
    ```


# Reference

- https://kubectl.docs.kubernetes.io/installation/kustomize/binaries/
- https://stackoverflow.com/questions/66836979/how-to-install-a-specific-kustomize-version
- https://stackoverflow.com/questions/66843181/cant-install-a-specific-kustomize-version
- https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv3.2.1
Docker Compose V2がやってくる

すみません、よく分かってません。

ただ一つ言えることは、ちょっと前まで実行できていたコマンド

`docker-compose --log-level CRITICAL`

を実行すると、

`Unable to parse logging level: compose`

というエラーが表示されるようになった。

設定(Experimental Features)で「Use Docker Compose V2」のチェックを外すと良いらしいぜ、とのことでしたが、チェックを外しても効果がなかったような……？？

「DockerのUpdateが出た！」と表示されるたびに、ほいほいアップグレードするのも考えものですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/50597df1-6178-6803-ef4d-f24ca16e51d4.png)

いつの間にかバージョンが `v2.0.0-beta.6` になってました。

前述のログレベルオプションについては、[GitHubの方](https://github.com/docker/compose-cli/issues/1891)でさきほどまで熱い議論？が交わされていたようですが、 `--log-level` オプションは正式に復活しないことに決定した（ように見える）。

そうなのね。という感じで。そもそも、 `Docker Compose V2`って言われても未来のバージョンなのか過去のバージョンなのか分からないよ、って感じがしませんか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/f22b4998-ff44-7d7c-a3d0-43d43a70ca33.png)

なんとなくバージョン3とかじゃなかったっけ、と思ったらそれは `Docker Desktop` のバージョンだったり。

docker-compose.ymlの先頭にもバージョン書くやつ、あれも `3` じゃなかったっけ、とか。
それは `Compose ファイルフォーマット` の[バージョン](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/compose-file-v3/)らしいです。現行は `3.9` 。

とりあえず[GitHubリポジトリ](https://github.com/docker/compose-cli/tags)を見ればバージョンが分かる、という感じですかね。では。
……あれ？ `compose-cli` の話なの……？（混乱）
[Flutter] TextやButtonを逆さにする方法


こんにちわ

今回は、TextやButtonを逆さにする方法を紹介します。

## テキストを180度回転したい場合

```dart
ElevatedButton(
  onPressed: () {},
  child: const RotationTransition(
    turns: AlwaysStoppedAnimation(180 / 360),
    child: Text('Stop'),
  ),
),
```

## ボタンを180度回転したい。
```dart
 RotationTransition(
   turns: AlwaysStoppedAnimation(180 / 360),
   child: ElevatedButton(
     onPressed: () {},
     child: Text('Stop'),
   ),
 ),
```


ぜひお試しあれ〜〜〜
比較演算の連続

1 < x < 10 などの記述ができるんだよ，という記事は多いけど，別に2つの比較演算を単純に記述できるだけじゃないんだね。

1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5

の結果はどうなる？

順番にやっていけばわかるけど，True だ。
HTMLの＜nav＞まとめ

#HTMLの＜nav＞まとめ

html触ってて、＜nav＞? ん？＜nav＞ってなんぞや！！！ってなったので、備忘録ついでにまとめました。

nav要素、navタグってよばれているこれ＜nav＞.....＜nav＞は、ナビゲーションメニューを設定するときに用います。
ナビゲーションメニューってなんぞやって思うかもしれませんので、実際に書いてみました。コレです↓
<nav>
     <ul>
        <li><a href="#コードの書き方">コードの書き方</a></li>
        <li><a href="#navとかulとかli要素の説明">navとかulとかli要素の説明</a></li>
        <li><a href="#まとめ">まとめ</a></li>
     <ul>
<nav>

"コードの書き方"とか"まとめ"とか押すと、ビュンって下行って、その（"コードの書き方"とか"まとめ"の）場所へ飛んでってくれます。
押してみましたか？　これがナビゲーションメニュー（リンク先指定付きバージョン）です！
めっちゃ便利ですよね。私もこの便利機能使いこなしたいので、navについて私が知ってる情報を洗いざらいまとめました。
ぜひ、皆さんも使いこなしてサイトに訪れた者共をその人が欲している情報のもとへ飛ばしてやりましょう！

<h2 id="コードの書き方">コードの書き方</h2>

では、早速コードの書き方へ突入します！

```html:html
<nav>
  <ul> <!-- <ol>でもいいよ! -->
    <li>じゃがいも</li>
    <li>にんじん</li>
    <li>たまねぎ</li>
  <ul> <!-- ol使ったんだったら</ol>で閉じてね -->
<nav>
```
...って書くとこう表示されます。↓
<nav>
  <ul>
    <li>じゃがいも</li>
    <li>にんじん</li>
    <li>たまねぎ</li>
  <ul>
<nav>

このコードが基盤となります。
URLつけたらその場所までビュンって行くし、classタグで名付けたらCSSでいじり放題になります。

```html:htmlリンク付けて名前もつけた場合
<nav>
  <ul class="makings"> <!-- classタグで好きな名前つけなされ -->
    <li class="make-stuff"> <!-- 必要なところに必要な名前をつけなされ -->
      <a href="https://www.zyagaimo-hokuhoku">じゃがいも</a> <!-- ""の中にリンク先を指定しなされ。これは絶対パスと呼ばれる書き方。（このリンク先は存在しないぞ）　-->
    </li>
    <li class="make-stuff">
　　　　　　　　　　　　　<a href="">にんじん</a> <!-- ""のままだと、ページがリロードされるし、"#!"って書くと遷移しないリンクになるし、hrefは奥深いから暇なとき調べてみてね　-->
　　　　　　　　</li>
    <li class="make-stuff">
      <a href="#たまねぎ">たまねぎ</a>　<!--「#+設定id」でidで名付けたところの言葉へ飛んでいくぜ！一番最初に書いたやつがこれ。同ページ内のリンク先へってときに使えるさ　-->
    </li>
  <ul>
<nav>
<!-- ほんとマジでhrefの書き方は色々あるからさ、自分に合った書き方を調べて書くことをお勧めする。　-->
```

なんかコメントアウトコメントが凄いことになってしまった。
＜nav＞とか＜ul＞とかの説明できてないから次の章で書くからちょっとこの先まで付き合ってください。

<h2 id="navとかulとかli要素の説明">navとかulとかli要素の説明</h2>

###nav
ここにナビゲーションメニューを設定するぜ！って領域を作成するためのnav要素
ここがナビゲーションメニューだ！！！

###ul
箇条書きリストを表示するぜ！
（リストの先頭に・が付きます）

###ol
番号付きリストを表示するぜ！！
（1からリストの先頭に番号が振られます）

###li
リストの内容を指定。じゃがいもとか、Homeとかまとめとか、その記事のメニューや見出し内容を書くところ。


<h2 id="まとめ">まとめ</h2>

* __ナビゲーションメニューとはその名の通り目的地を示す項目のこと__

* __nav + ul + li か、 nav + ol + li のセットメニューとなる__


<h2>おまけ</h2>
ちなみに、一番最初に例として書いたナビゲーションメニューのコードはこんな感じ。

```html:ナビゲーションメニュー
<nav>
     <ul>
        <li><a href="#コードの書き方">コードの書き方</a></li>
        <li><a href="#navとかulとかli要素の説明">navとかulとかli要素の説明</a></li>
        <li><a href="#まとめ">まとめ</a></li>
     <ul>
<nav>
```

```html:遷移先の見出し
<h2 id="コードの書き方">コードの書き方</h2>
<h2 id="navとかulとかli要素の説明">navとかulとかli要素の説明</h2>
<h2 id="まとめ">まとめ</h2>
```


以上。終わり！！！
Lamda上のmatplotlibで日本語対応する

　　Lambda上でmatplotlibを使ってグラフを作成したいとき、Lambdaには日本語フォントが含まれていないため日本語が豆腐になってしまいます。この記事では、日本語対応するための方法について説明します。

## 前提
matplotlibは別途利用できるようにレイヤーなどで用意する必要があります。

## やり方

1. Lambdaレイヤーに日本語フォント用のレイヤーを登録
2. Lambda関数に日本語フォント用のレイヤーを追加
3. matplotlibでフォント読み込み



## 1.Lambdaレイヤーに日本語フォント用のレイヤーを作成

　日本語フォントなら基本的に何でもOKと思いますが、今回は[IPAexゴシック](https://moji.or.jp/ipafont/ipaex00401/)（ipaexg.ttf）をダウンロードして使いました。
　ダウンロードしたttfファイルを適宜ディレクトリ（例えばfontsなど）に入れてzip圧縮します。
　Lambdaのレイヤーページから「レイヤーの作成」にて作成画面に移動し、アップロードにて先程圧縮したzipファイルを選択してレイヤーを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22648/59549833-6471-8cd4-fc08-f0de1d05ae14.png)

## 2. Lambda関数に日本語フォント用のレイヤーを追加

　グラフを作成するメインLambda関数に、先程作成した日本語フォント用のレイヤーを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22648/4812d247-c46e-696e-862d-5f24caefaf3f.png)


## 3. matplotlibでフォント読み込み

　font_managerのFontPropertiesにてレイヤーで登録したttfファイルを指定すれば日本語が使えるようになります。レイヤーは`/opt`にバインドされますので適宜指定してください。

```python
import matplotlib.font_manager as fm

# 日本語フォント設定
prop = fm.FontProperties(fname='/opt/fonts/ipaexg.ttf')

・・・略・・・

ax.set_xticklabels(labels, rotation=45,　fontproperties=prop)

```


## その他
- ttfファイル自体をLamba関数に含めることでも実現可能ですが、容量が大きいためWebIDE上でコードの編集ができなくなる可能性があります。
- 他の方法として、japanize-matplotlibのレイヤーを作ってもよいかもしれませんが、試してません。
Javaの超基礎（条件分岐）

##はじめに
前にJavaの基礎をやって中途半端だったので、少しずつだけですが学習しています。条件分岐の文法について記事にまとめました。

よろしくお願いします。

##if文
javaのif文は「if」の後に()の中に条件式を記述し、その後{}に処理を書きます。

```java
int a = 10;
if (a < 20) {
  System.out.println("aは20未満");
```

True以外の処理は{}を閉じた後にelseを記述し、さらに{}に処理を書きます。

```java
int a = 30;
if (a < 20) {
  System.out.println("aは20未満");
 } else {
  System.out.println("aは20以上");
}
```

ifの他に条件式を追加したい場合は{}を閉じた後「else if」を記述し、ifと同じように()に条件式、{}に処理を書きます。

```java
int a = 20;
if (a < 20) {
  System.out.println("aは20未満");
 } else if (a > 20){
  System.out.println("aは20より大きい");
}　else {
  System.out.println("aと20は等しい");
```
##switch文
条件分岐はifの他にswitch文があります。
switchの後の()に条件の値を記述し、{}の中に「case 値:」を書いて、その下に処理を書きます。

caseの後の値と条件の値が合致していればTrueを返し、違えばFalseを返します。
それぞれのcaseの後には必ず「break;」が必要となります。

```java
int a = 5;
switch (a % 2) {
  case 0:
    System.out.println("偶数")
    break;
  case 1:
    System.out.println("奇数")
    break;
}
```

上記の例だと、()の値が1になるので二個目のcaseに該当します。ですので「奇数」が実行されます。

また、どのcaseにも該当しなかったときの処理を書きたいときはcaseの代わりに「default:」を書きます。if文のelseみたいなものですね。

```java
switch(champion) {
  case 1:
    System.out.println("山田たろう");
    break;
  case 2:
    System.out.println("田中じろう")
    break;
  case 3:
    System.out.println("吉田さぶろう")
  default:
    System.out.println("表彰されるのは3位までです")
    break;
}
```
[OutSystems]PWAにおけるプラグインの仕組み

OutSystemsのモバイルアプリケーションにおいて、プラグインとは、Cordova Pluginをラップしてハードウェアにアクセスする機能を提供するもの。

特定のプラグインは、PWAでも動作するように作られています。

PWAもモバイルアプリケーションとして開発するわけですが、実質WebアプリケーションであるPWA内でどのようにして同じプラグインが動作するのか、実装を追って確認してみました。

現時点（2021/8/6）のプラグイン実装からの確認なので、あとで公式のガイドが出たら、別の作り方が推奨されるかも。

対象は、2021/8/6時点で、公式（[PWAでプラグインを使用する](https://success.outsystems.com/ja-jp/Documentation/11/Delivering_Mobile_Apps/Distribute_as_a_progressive_web_app#PWA.E3.81.A7.E3.83.97.E3.83.A9.E3.82.B0.E3.82.A4.E3.83.B3.E3.82.92.E4.BD.BF.E7.94.A8.E3.81.99.E3.82.8B.7B.23plugins.7D)）でPWAに対応しているCamera Plugin。

# 確認環境
Personal Environment(Version 11.12.0 (Build 30002))
Service Studio (Version 11.11.11)
Camera Plugin (Version 7.0.7)

# Check Actionの書き方
プラグインを作るときには、そのプラグインを使えるかどうかを判定するためのCheckプラグイン名 Actionを提供することになっています。

実装は以下の通り。PWAのときは黄色に塗ったフローを通ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/4c2832b2-6412-83a3-27c5-398ff3c7fe74.png)

この例を見ると、

1. CommonPluginに含まれるIsCordovaDefinedでCordovaが有効（＝つまりネイティブ環境で動くモバイルアプリケーション）かを判定する
1. Cordovaが定義されていないときは常にIsAvailable=Trueを返す
1. 定義されているときは、これまで通りネイテイブ環境のモバイルアプリケーションに必要な動作をする

という仕組み。

# PWAでもネイテイブでも動作させる処理（TakePicture）
実装は以下の通り。PWAのときは黄色に塗ったフローを通ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a8c174a7-fde6-99eb-ad64-2e1e4f00ddf4.png)

Cordovaが定義されている（＝ネイティブアプリ環境）かどうかで処理を分岐しています。

## Cordovaが定義されている（＝ネイティブアプリ環境の）場合
従来のプラグイン向けのロジックを「Native_処理名」を名前とするActionに切り出す。
例：TakePictureのネイティブ向け処理はNative_TakePicture Actionへ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/b9a6826f-8d00-b966-6769-b7f580ae43bc.png)

## Cordovaが定義されていない（＝PWAの）場合
「Web_処理名」を名前とするActionに切り出す。
例：TakePictureのPWA向け処理はWeb_TakePicture Actionへ

PWAではプラグインの機能をWeb APIを利用して実現するため、以下のようにJavaScriptで呼び出すWeb APIが処理の本体となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/2f9a2cab-417b-5c89-a51b-01fcff71c547.png)

ここでは、Camera Plugin自体の詳細は書きませんが、大まかに言うと以下のような処理。

1. 非表示のinputタグを作る（accepts=image/*、capture=camera、type=file）
2. inputタグをクリックしたら、window.focusでvideoElementを削除する処理を走らせるリスナーを追加する
2. reactContainer配下のDOMに追加
2. 追加したvideoElementをclickする（iOSならdispatchEventで）

# PWAでは動作しなくてよい or できない処理（ChooseGalleryPicture）
IsCordovaDefinedの結果がFalseであれば何もせずに終了させる。
Webアプリケーション構築の反省点

Windows１０
MySQL 8.0.20
Amazon　AWS

勉強のために、WebアプリケーションをAWSに構築しています。

AWSを使い、RDSを作成するが

サブネットグループの作成、
パラメータグループ作成
名前など間違えないように注意しないといけない。

RDSなら
DB インスタンス識別子

AWS Systems Manager
パラメータ名
/プロジェクト名/dev/app/MYSQL_DATABASE
/プロジェクト名/dev/app/MYSQL_HOST
/プロジェクト名/dev/app/MYSQL_PASSWORD（値でのパスワード入力も注意）
/プロジェクト名/dev/app/MYSQL_PORT　（値でのポート番号）
/プロジェクト名/dev/app/MYSQL_USERNAME

ここの設定はよく丁寧に確認した方が良いと思います。
設計したパラメータ名が正しく入力されていないとAPサーバー構築してからデーターベースに接続できないなどの
エラーが発生します。

その他
データーベースのセキュリティグループ名
IAMロールのチェックも念入りにチェックを推奨。

一文字間違えたおかげで、はまりました。
プログラミングと同じですね。

特にデーターベース周りはタイプミスするとWeb公開時にプラウザで確認するとこんなエラーが出ます。
````

````
Error: connect ECONNREFUSED 127.0.0.1:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
ポアソン分布の確率変数0〜∞の総和が1になることを証明してみた

#ポアソン分布の確率変数0〜∞の総和が1になることを証明してみた
##1.ポアソン分布とは
ポアソン分布は以下の式で表される。
$$P(X=x)=\frac{\lambda^x}{x!}e^{-\lambda}$$
意味としては，単位時間あたり，平均的に$\lambda$回生じる事象がある場合に，それが単位時間あたりに
$x$回生じる確率を表している。

(例)平均的に年に2回「今日はイケてるね」と言われることが分かっている場合，年に3回言われる
　　確率は，

```math
\begin{align}
P(X=3)&=\frac{2^3}{3!}e^{-2}\\
\\
&=0.1804
\end{align}


```
##2.ポアソン分布の確率変数0〜∞の総和
ポアソン分布の確率変数0〜∞の総和が1となることを証明する。

求めたいものは，

```math
\begin{align}
\sum_{x=0}^{\infty} \frac{\lambda^x}{x!}e^{-\lambda}&= e^{-\lambda} + \lambda e^{-\lambda} + \lambda^2 e^{-\lambda} \cdots\\
\\
&=e^{-\lambda}\sum_{x=0}^{\infty} \frac{\lambda^x}{x!}
\end{align}
```

ここで，

```math

e^{\lambda}=\sum_{n=0}^{\infty} \frac{\lambda^n}{n!}

```

であるから，

```math
\begin{align}
\sum_{x=0}^{\infty} \frac{\lambda^x}{x!}e^{-\lambda}
&=e^{-\lambda}\sum_{x=0}^{\infty} \frac{\lambda^x}{x!}\\
\\
&=\frac{\sum_{x=0}^{\infty} \frac{\lambda^x}{x!}}{\sum_{n=0}^{\infty} \frac{\lambda^n}{n!}}\\
\\
&=1
\end{align}
```

となる。
【JavaScript】Macrotasks？Microtasks？どういうもの？

# はじめに
JavaScriptには２種類の非同期処理のキューが存在します。
それが、、`Macrotasks`と`Microtasks`です。
それがどういったものかを見ていこうと思います！

# Macrotasksとは
Macrotasksはタスクキューとも呼ばれており、1つずつタスクを実行します。
例えば、`setTimeout`や`setInterval`などのコールバック関数が該当します。
※ジョブキューの後に実行される。

# Microtasksとは
Microtasksはジョブキューと呼ばれており、順番が回ってきたら全てのタスクを実行します。
こちらは`Promise`などが該当します。
※タスクキューのより先に実行される。

# 動きの解説
以下のコードを利用して実行順序がどうなっているかの解説を行います。

```js
// 非同期処理かつMacrotaskなのでタスクキューに追加
setTimeout(function task1() {
  console.log('task1');
});

// Promiseの即時関数を定義
new Promise(function promise(resolve) {
  // この部分は同期的に処理されるので一番早くコンソール出力する
  console.log('promise');
  resolve();
}).then(function job1() {
  // 非同期処理かつMicrotaskなのでジョブキューに追加
  console.log('job1');
});

// グローバルコンテキストが終了したのでここが実行される
console.log('global end');
```

## 実行の流れ
①まず、setTimeout関数は非同期処理のためタスクキューに追加される。(ここでは実行されない)
②次に、Promiseの中身である関数では同期的に処理されるので、一番最初に処理されます。
③thenメソッドも非同期処理のため、タスクキューに追加されるため実行されません。
④ここで、最後の行のコードである`console.log('global end');`が実行されます。
⑤setTimeout関数はMacrotaskで、thenはMicroTaskなので、thenが先に実行されます。
⑥最後にキューに残っているsetTimeout関数の処理を実行して終了です。

ちなみに実行結果は以下の通りです。

```js
"promise"
"global end"
"job1"
"task1"
```

# 終わりに
ややこしい部分ではありますが、ここを理解しておかないと実装時に意図しないエラーが発生することもあるので気をつけましょう！

# 参考
[【JavaScript】Macrotasks と Microtasks]
(https://hidekazu-blog.com/javascript-macrotasks-microtasks/)

[JavaScript初心者でもよくわかる！コードの非同期処理]
(https://tech.wwwave.jp/entry/javascript-async-execution)
AtCoderログ：0058 - ABC 139 B

# 問題

https://atcoder.jp/contests/abc139/tasks/abc139_b

## 問題文
> 高橋くんの家には電源プラグの差込口が $1$ 口しかありません。
> そこで、高橋くんは $A$ 個口の電源タップをいくつか使って未使用の差込口を $B$ 口以上に拡張したいと考えています。
> $A$ 個口の電源タップ $1$ つと未使用の差込口 $1$ 口を使って、新たに差込口を $A$ 口増やすことができます。
> 最小でいくつの電源タップが必要でしょうか。

## 制約
> ・入力は全て整数である。
> ・$2 \le A \le 20$
> ・$1 \le B \le 20$

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #001 

# 回答
## 回答1 (AC)
$A$ 個口の電源タップを増設すると差し込み口は $A-1$ 個増えます。現在の差し込み口の個数を now, 増設した電源タップの個数を add とおき、now が b より小さい間は増設を繰り返せば良いでしょう。コードは以下のようになりました。

```C++:abc139b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int a, b;
  cin >> a >> b;

  int now = 1, add = 0;
  while ( now<b ) {
    now += a-1;
    add += 1;
  }

  cout << add << endl;
}
```

## 回答1 (AC)
増設する電源タップの個数を計算式で求めることが出来ます。$A$ 個口の電源タップを増設すると差し込み口は $A-1$ 個増えます。増設した差し込み口の個数は最低で $B-1$ 個なので、必要な電源タップの個数は $\lceil \frac{B-1}{A-1} \rceil$ 個となります。割り算を小数にキャストすることが必要です。コードは以下のようになりました。

```C++:abc139b-2.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int a, b;
  cin >> a >> b;

  cout << ceil((float)(b-1)/(a-1)) << endl;
}
---

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc139/tasks/abc139_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2019/09/04/220545)
回答2と同じ方針でした。なお「切り上げする場合は、分子に分母-1を足すことで切り上げが可能」を採用すると、小数へのキャストが不要となるようです。

## [AtCoder の解説](https://atcoder.jp/contests/abc139/tasks/abc139_b/editorial) → [公式解説](https://img.atcoder.jp/abc139/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0057 - ABC 042 B](https://qiita.com/RoadLynton/items/e8b9c37c092d51aaf418)
- 次の記事 → [AtCoderログ：0059 - AGC 027 A](https://qiita.com/RoadLynton/items/15ca251f738b15e80efa)
Dockerメモ①

# Dockerfileのメモ走り書き
- Dockerfileを作成するメリットってなにか
    - 軽量化
    - 生産性・可用性
        - 環境を作成することで、複数人がローカルで開発する際の環境差異をなくすことができる.
        - しかしDockerfileからの起動手順が複雑であると、環境作成に人的ミスが発生するのではないか。
            - docker-composeで解消できる
    
# docker-composeのメモ走り書き
- docker-composeとは
    - Docker imageのbuildや、複数コンテナを一括で起動・停止などできるツールのこと。
    - Docker起動時のオプションや設定をyml形式のテキストファイルで記述する。

## 例

####Dockerfileで起動する場合のコマンド
```
docker run -v <mount元フォルダ>:<mount先フォルダ> -p <host側ポート番号>:<container側ポート番号> -it <image ID> bash
```
Dockerfileからコンテナを起動する場合は引数が多く、typoなどにより人為的ミスが発生しうる可能性ある。1つのコンテナを立ち上げるだけで上記の程度コマンドを打たなければならないため、複数台コンテナを立てなければならない場合はさらに人的ミスが発生する可能性が高まる。

####docker-composeを使用する場合
事前にymlファイルを作成する必要があるが、環境作成者がたたくコマンドが少なくなるため、Dockerfileからコンテナを起動する場合に比べて人為的ミスが減少する。
#####docker-compose.yml
```docker:docker-compose.yml
version: '3'
services:
        app:
                build: .　# Dockerfileがあるディレクトリを記述
                #image: nginx:alpine # imageをそのまま記載することも可能
                ports:
                        - '<host側ポート番号>:<container側ポート番号> '
                volumes:
                        - '<mount元フォルダ>:<mount先フォルダ>'
                tty: true #-tオプション
                stdin_open: true #-iオプション
```

#####docker-compose.ymlを使用して起動する場合のコマンド
docker-compose.ymlと同じ場所で下記コマンドを実行する

```
docker-compose up -d
```
【Python】ワードクラウドを使ってサイトの単語の使用頻度を見える化する

##目的
指定のサイトで使用頻度が高い単語をワードクラウドを使って視覚化したい

##コード

```python
import requests
from bs4 import BeautifulSoup
import MeCab
from wordcloud import WordCloud

# ワードクラウドの保存ファイル名
file_name = "hage.png"

# ワードクラウド化の対象サイトのURL
url = 'https://ja.wikipedia.org/wiki/%E3%83%8F%E3%82%B2'

# 対象サイトのURLのページを取得して解析
html = requests.get(url)
soup = BeautifulSoup(html.content, 'html.parser')

# scriptとstyleを要素から除去
for element in soup(["script", "style"]):
    element.decompose()

# テキストを抽出
text = soup.get_text()
# 行ごとに分けて両端の空白文字を削除
lines = [line.strip() for line in text.splitlines()]
# 改行文字を結合
text = "\n".join(line for line in lines if line)

# 形態素解析する
mecab = MeCab.Tagger("-Ochasen")
node = mecab.parseToNode(text)

word_list = []
# 品詞を使って単語を分ける
while node:
    # 品詞
    part = node.feature.split(",")[0]
    # 配列の追加する単語を品詞で指定する
    if part in ["動詞","副詞","形容詞","名詞"]:
        word = node.surface # 単語
        word_list.append(word)
    node = node.next

words = ' '.join(word_list)

# ワードクラウドで使用するフォント（メイリオ）のパス
fpath = "C:/Windows/Fonts/meiryo.ttc"

# ワードクラウドの作成
wordcloud = WordCloud(background_color="white",
                     font_path=fpath,
                     width=800,
                     height=600).generate(words)

# 指定の名前で保存する
wordcloud.to_file("./"+file_name)
```
PuLP で解いたモデルから Gurobi で IIS を出す方法

ソルバーの比較などのために PuLP で実装したが、モデルのデバッグのために Irreducible Inconsistent Subsystem (IIS) を Gurobi で計算させたいことがある。PuLP には IIS を出す手段は（今のところ）ないので、一度 .lp ファイル出力をして、Gurobi のコマンドで IIS 計算するのがお手軽[^1]。

PuLP でモデルを LP ファイル出力させるには、モデルの構築後に以下の行を実行すればよい。

```python
model.writeLP("model-infeasible.lp")
```

そして、Gurobi のコマンドを使って最適化を実行する。ResultFile を指定しておけば、Infeasible だった場合は IIS が model.ilp に出力される。

```bash
$ gurobi_cl ResultFile=model.ilp model-infeasible.lp
```

https://www.gurobi.com/documentation/9.1/refman/solving_a_model2.html


[^1]: 一応過去の公式フォーラムで[同様の回答](https://groups.google.com/g/pulp-or-discuss/c/eWpNZROuPVg?pli=1)がある。2016 年のものだが、現在の PuLP のドキュメントを見ても IIS 出力をするコマンドは追加されていない。
Rspecのchangeマッチャーを使う時、初期状態の設定をsubjectでやるのってありですか？

# はじめに

普段はC++とかTypeScriptのように型がある言語が好きな私。

最近業務でRubyとRailsとMySQLとRspecとかいう全部わからないし、しかもRubyって型がない。そんなものを使うことになって苦戦しつつも勉強して仕事しています、たのしい。

# 問題提起

突然ですが下のRspecのコードを見てみて下さい(疑似コード)

```ruby
# frozen_string_literal: true

require 'spec_helper'

describe "test" do
  def put_value(v)
    # なにかside effectを起こす
  end

  subject do
    put_value "before"
    lambda do
      put_value "after"
    end
  end

  it { is_expected.to change { some_value }.from("before").to("after") }
end
```

意図としては、`subject`の中で初期状態の設定を行って、変化を生じさせる操作もsubjectの中のlambdaに書くことで、`before`とか`let`を排除して直線的に何が変化するのか読めるようにするというものです。

なあにこのlambdaという人は以下の記事を。

https://qiita.com/paranishian/items/51d3742b7095aa7744ca

こういう書き方はありかどうか、これがこの記事の問題提起です。

# 評価順序の予想

1. `subject` に渡したblock
2. `is_expected` : https://github.com/rspec/rspec-core/blob/dc898adc3f98d841a43e22cdf62ae2250266c7b6/lib/rspec/core/memoized_helpers.rb#L120-L122
3. `expect`
4. `change`
5. `(change return object)#from`
6. `(change return object)#to`
7. `RSpec::Expectations::ExpectationTarget::InstanceMethods#to`

# 反論

## そもそもbefore使えばいいのでは

```ruby
# frozen_string_literal: true

require 'spec_helper'

describe "test" do
  def put_value(v)
    # なにかside effectを起こす
  end

  subject { -> { put_value_after } }

  before do
    put_value "before"
  end

  let(:put_value_after) do
    put_value "after"
  end

  it { is_expected.to change { some_value }.from("before").to("after") }
end
```

before は「最初にこれがあります」という前提条件の提示なのでbeforeは排除したくないというもの(職場の先輩の主張)。

自分は`subject`は先頭に書かれるべきだと思っているし、Rubocopで`Rspec/LeadingSubject`を有効にしています。

すると見た目は`subject`→`before`→`let`なのに実際の順序は`before`→`subject`→`let`となってしまい、上から下にコードを読めなくなってしまいます。

## そもそもsubjectは必要か？

```ruby
# frozen_string_literal: true

require 'spec_helper'

describe "test" do
  def put_value(v)
    # なにかside effectを起こす
  end

  before do
    put_value "before"
  end

  let(:put_value_after) do
    put_value "after"
  end

  it { expect { put_value_after }.to change { some_value }.from("before").to("after") }
end
```

`is_expected`にしようと`subject`つかうから話がややこしいのであって、それをやめればすっきりするのでは？というもの。

結局冒頭のコードは断念してこちらを今回は採用することにしたのでした。

# 終わりに

自分はRuby学び始めて1カ月の初心者なのでRubyのプロたちの意見をお待ちしています。

# 余談

マッチャーと書くと抹茶に変換されがちな現象ありませんか？もう🍵でよくないですか？(だめです
AtCoderログ：0057 - ABC 042 B

# 問題

https://atcoder.jp/contests/abc042/tasks/abc042_b

## 問題文
> いろはちゃんは 長さ $L$ の文字列を $N$ 個持っており、それぞれ $S_1,S_2,\ldots,S_N$ です。
> それらの文字列を好きな順番で全て結合してできる文字列のうち、もっとも辞書順で小さいものを求めてください。
> なお、ある文字列 $s=s_1s_2s_3\ldots s_n$ と $t=t_1t_2t_3 \ldots t_m$ について、以下のどちらかを満たすとき、辞書順比較で $s<t$ であるといいます。
> ・ある整数 $i~(1 \le i \le {\rm min}(n,m))$ に関して、$1 \le j < 
 i$ を満たす任意の整数 $j$ において $s_j=t_j$ が成立し、かつ $s_i <  t_i$ が成立する。
> ・任意の整数 $i~(1 \le i \le {\rm min}(n,m))$  に関して $s_i=t_i$ が成立し、かつ $n<m$ が成立する。

## 制約
> ・$1 \le N, L \le 100$
> ・全ての $i~(1 \le i \le N)$ に対し、$S_i$ の長さは $L$ に等しい。
> ・各 $i$ について, $S_i$ は全て半角英小文字のみから成る文字列である。

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第06問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-6-%E5%95%8F--abc-088-b---card-game-for-two-200-%E7%82%B9))

# 回答
## 回答1 (AC)
結合した文字列が辞書順で最も小さくなるのは、$N$ 個の文字列を小さい順に並べたときです。処理としては、それぞれの文字列を配列 s() に受け取った後、小さい順 (昇順) にソートし、小さい順に出力すれば良いでしょう。コードは以下のようになりました。

```C++:abc042b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, l;
  cin >> n >> l;

  vector<string> s(n);
  for ( int i=0; i<n; i++ ) {
    cin >> s.at(i);
  }

  sort( s.begin(), s.end() );

  for ( int i=0; i<n; i++ ) {
    cout << s.at(i);
  }
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc042/tasks/abc042_b/editorial) → [公式解説](https://img.atcoder.jp/data/arc/058/editorial.pdf)
回答と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0056 - 問題セットのまとめ](https://qiita.com/RoadLynton/items/d897a1821b861c5bb65c)
Grove IoT スターターキット for SORACOM で GPS を使う

GPS の Grove を UART に接続します。

```text:gps_test/gps_test.ino
// ---------------------------------------------------------------
/*
	gps_test.ino


					Aug/06/2021
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>
#define INTERVAL    (500)

WioLTE Wio;

// ---------------------------------------------------------------
void setup()
{
	delay(200);

	SerialUSB.println("");
	SerialUSB.println("*** START ***");
	
	SerialUSB.println("### I/O Initialize.");
	GpsBegin(&SerialUART);
	Wio.Init();
	
	SerialUSB.println("### Power supply ON.");
	Wio.PowerSupplyGrove(true);
	delay(500);
	SerialUSB.println("*** Setup *** ddd");
	delay(500); 
	SerialUSB.println("*** Setup *** eee");
	delay(500);
	SerialUSB.println("*** Setup *** fff");
	delay(500);
	SerialUSB.println("*** Setup completed ***");
}

// ---------------------------------------------------------------
void loop()
{
  	const char* data = GpsRead();

	if (data != NULL)
		{
		if (strncmp(data, "$GPGGA,", 7) == 0) {
			SerialUSB.println(data);
			}
		else if (strncmp(data, "$GPGSA,", 7) == 0) {
			SerialUSB.println(data);
			}
		else if (strncmp(data, "$GPGSV,", 7) == 0) {
			SerialUSB.println(data);
			}
		else if (strncmp(data, "$GPRMC,", 7) == 0) {
			SerialUSB.println(data);
			}
		else
			{
			SerialUSB.print("   : ");
			SerialUSB.println(data);
			}
		}
	else
		{
//		SerialUSB.println("*** error GpsRead ***");
		}


	Wio.LedSetRGB(0, 0, 1); 
	delay(INTERVAL / 2);
	Wio.LedSetRGB(0, 0, 0); 
	delay(INTERVAL / 2);
}

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

#define GPS_OVERFLOW_STRING "OVERFLOW"

HardwareSerial* GpsSerial;
// char GpsData[100];
char GpsData[256];
char GpsDataLength;

// ---------------------------------------------------------------
void GpsBegin(HardwareSerial* serial)
{
	GpsSerial = serial;
	GpsSerial->begin(9600);
	GpsDataLength = 0;
}

// ---------------------------------------------------------------
const char* GpsRead()
{
	while (GpsSerial->available()) {
		char data = GpsSerial->read();
		if (data == '\r') continue;
		if (data == '\n') {
			GpsData[GpsDataLength] = '\0';
			GpsDataLength = 0;
			return GpsData;
		}
		
		if (GpsDataLength > sizeof (GpsData) - 1) { // Overflow
			GpsDataLength = 0;
			return GPS_OVERFLOW_STRING;
		}
		GpsData[GpsDataLength++] = data;
	}

	return NULL;
}

// ---------------------------------------------------------------
```

テスト時の結線
![IMG_20210806_205248.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6c518c02-5ace-dd3d-beb7-e1f44f971ca8.jpeg)
ROS2におけるパラメータのdeclareとundeclareに関わる諸事

【[ROS2導入&レクチャー](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)】

# 概要

パラメータはyamlファイルで初期値を設定できる．さて，パラメータを

1. declare_parameterで宣言
1. undeclare_parameterで削除
1. declare_parameterで宣言

など繰り返し，二回目以降の宣言の時にyamlファイルよる初期値設定はどうなるのか？と思ったのでやってみた．

# 実験

- ROS2バージョン
    - foxy
    - 2021/08/06
- やり方
    - あるパラメータ`param`を宣言，関数としての初期値は0，yamlファイルでは1
        - declare_parameter("param", 0)を使用
        - yamlファイルでは以下と設定
            - param: 1

## 基本の確認
まずはyamlファイルの有無で変わるか確認．当たり前の結果をちゃんと見てみよう！ってところ．

1. yamlファイルなしで対象を実行
    - ros2 run <package> <target>
    - 結果は`0`
- yamlファイルありで対象を実行
    - ros2 run <package> <target> --ros-args --params-file <yamlファイル>
    - 結果は`1`

## 複数回の宣言とyamlファイルの確認
複数回の宣言とyamlファイルの設定との関係を見るために，declare/undeclareを実行中に変えられるようにプログラムした(サービスで指令を送信してdeclare/undeclareさせた)．

1. yamlファイルありで対象を実行
    1. パラメータを宣言(declare)
    - ros2 param getでparamの値を取得
        - 結果は1
    - パラメータを削除(undeclare)
    - ros2 param getでparamの値を取得
        - 結果は「そんなパラメータないよ」みたいなメッセージ
    - ros2 param getでparamの値を取得
        - 結果は1

### 結果
というわけで，declareしたときにyamlファイルの値が設定される．

## 途中でyamlファイルの中身を書き換えたら？

1. yamlファイルありで対象を実行
    1. パラメータを宣言(declare)
    - ros2 param getでparamの値を取得
        - 結果は1
    - パラメータを削除(undeclare)
    - ros2 param getでparamの値を取得
        - 結果は「そんなパラメータないよ」みたいなメッセージ
    - yamlファイルの中身を`param: 2`に書き換え
    - ros2 param getでparamの値を取得
        - 結果は1

### 結果
つまり，declareしたときにyamlファイルが読み込まれるのではなく，起動時にyamlファイルの中身が読み込まれ，保存されていて，それが使用されるっぽい．
WSL2上のVSCodeで.bash_profileや.bashrcが読み込まれない。。。(備忘録メモ)

`settings.json`に以下を記載すると解決します。`terminal.integrated.shell.linux.args`に`-l`を設定するという情報が結構ヒットしますがそれは古いバージョンのVSCodeでの話。

```json
  "terminal.integrated.profiles.linux": {
    "bash": {
      "path": "bash",
      "icon": "terminal-bash",
      "args": ["-l"]
    },
    "zsh": {
      "path": "zsh"
    },
    "fish": {
      "path": "fish"
    },
    "tmux": {
      "path": "tmux",
      "icon": "terminal-tmux"
    },
    "pwsh": {
      "path": "pwsh",
      "icon": "terminal-powershell"
    }
  },
  "terminal.integrated.defaultProfile.linux": "bash",
```

# Reference
https://code.visualstudio.com/docs/editor/integrated-terminal

https://teratail.com/questions/347788#reply-477019
App EngineにNodeバックエンドをデプロイするときのチェックリスト

# 概要
App Engine に Nodeで作ったバックエンドをデプロイするときにいつも何かしらで詰まるので、チェックリストを備忘録としてまとめました。


# 1. ポート
Nest.jsとかだとデフォルトで3000ポートでリッスンする用になっているが、`process.env.PORT`でリッスンするようにする。

```ts
app.listen(process.env.PORT ?? 3000)
```

# 2. スタートコマンド

```json-doc
"scripts": {
  // "start": "nest start",
  "start": "node dist/main",
```
App Engineでは npm scripts の startコマンドが実行される。このとき、Nest.jsなどデフォルトで設定されているstartコマンドだと、実行できないことが多々ある(App EngineではdevDependenciesはインストールされないなどが原因)

# 3. DBの接続先
Cloud SQLへPostgreSQLで接続する際には以下のようにする

```
postgresql://user:password@localhost:5432/<データベース名>?host=/cloudsql/<接続名>
```
接続名はCloudSQLのコンソールから確認できる。`プロジェクトID:リージョン:インスタンス名`の形式のやつ。

# 4. Prisma
https://qiita.com/kiyoshiro/items/878358e74a1935463b28
こちらを参照
TerraformのためにAWSのアクセスキーID、シークレットアクセスキーをわざわざダウンロードしたくない問題


##結論
Terraform用にEC2インスタンスを立てて、そこからterraformを実行しましょう。
※2021/08/07追記
この方法は悪手であるとのご指摘をいただきました。詳細はコメント欄に記載されていますが、使用しているチームやアカウントの状況によっては不向きとのことでした。
その他ご意見のある方もご意見があればご指摘お願いします。

##Terraformを学ぶ際に私が行っていたこと
1.Terrafrom用のユーザを作成
2.Terraform用のユーザのクレデンシャル情報(アクセスキーID、シークレットアクセスキー)をダウンロード
3.アクセスキー、シークレットアクセスキーをtfvarsに記載

##アクセスキーID、シークレットアクセスキーをダウンロードすることの問題性
何かしらのアクシデントでアクセスキーIDやシークレットアクセスキー漏洩した場合、不正利用される可能性がある。

例）
・githubに誤pushしてしまう。※git-secretの利用で防ぐことはできます。
・ダウンロードしたマシンがウィルスに感染して情報漏えいしてしまう。
etc.

##具体的な対処方
1.プライベートサブネットにEC2インスタンスを構築、terraformをインストール
2.IAMロールを作成、必要に応じて最小権限のポリシーを設定
3.作成したIAMロールをEC2インスタンスにアタッチ
4.これでterraformを安全に使えます

##気づきにつながったブログ　ありがとうございます。
https://dev.classmethod.jp/articles/unauthorized-use-of-aws-access-keys-due-to-leakage/
Djangoでsuperuserのみでアクセス制限を行う方法

djangoのアクセス制限に関してです。

``ログインしているユーザーのみ``といったアクセス制限の方法は日本語資料でも確認できましたが、
**``superuser``のみといったアクセス制限の方法については、あまり見かけなかったので解説します**。

誰かの役に立てば、幸いです。

## 環境
- Django 2.2.4

## 関数で開発している場合
デコレータをつけることでいけます。

```python:views.py
from django.contrib.auth.decorators import permission_required
from django.http import HttpResponse

@permission_required('admin.can_add_log_entry')
def test(request):
    return HttpResponse("Only access superuser!")

```

---

## classで開発している場合

せっかく、djangoを使っているなら、classベースで開発したいですよね。
そんな時のためのTips。

### 1. mixins.pyを定義
djangoのアプリ内で、``mixins.py``を作成します。

```python:mixins.py
from django.contrib.auth.mixins import UserPassesTestMixin

class SuperuserRequiredMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_superuser

```

### 2.views.pyで継承
ここで、定義したclassをviews.pyで使用します。

```python:views.py
from .mixins import SuperuserRequiredMixin

class TestView(SuperuserRequiredMixin,TemplateView):
    template_name = "test/home.html"
```

アクセス制限ができれば、
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407666/a9e018f2-36af-c3c0-7ca0-964f384b617d.png)

こんな感じになるはず。

参考になったら、幸いです。

## 参考文献
- [How to limit a view to superuser only? ](https://stackoverflow.com/questions/15998140/how-to-limit-a-view-to-superuser-only/47689629)
Dart/Flutterの.pub-cacheから、古いパッケージを削除する

`.pub-cache`内にあるパッケージの、最新版以外のバージョンを削除するツールを作りました。

pub.devのパッケージページはこちら → [purge_pub_cache](https://pub.dev/packages/purge_pub_cache)

# 背景

Dart/Flutterで開発していると、`.pub-cache`に古いバージョンのパッケージがどんどん溜っていくのがなんか嫌。

Dart 2.4で、`pub cache clean`というコマンドが実装されるらしいが、これは、有無を言わせず、全部パッケージを消してしまうものっぽい。

うまいこと整理する方法がありそうで見付からなかった(だいたい、全部削除して`pub get`し直せばいいじゃない、という話になる)ので、自分で作った。実はもうあったらごめんなさい。

# インストール

`% [dart|flutter] pub global activate purge_pub_cache`

# 使いかた

`% [dart|flutter] pub global run purge_pub_cache [option...]`

```
Options:
-h, --help                Show this usage.
    --version             Show app version and exit.
-d, --directory=<path>    Specify a path to handle as pub_cache directory.
-y, --yes                 Assume YES to confirm the deletion.
-q, --quiet               No outputs (--yes is assumed to be set).
-n, --dry-run             Dry-run. Show the packages to delete and exit.
```

ご存知のように、dartとflutterでは、それぞれデフォルトで使用する.pub-cacheディレクトリの場所が違います。

activeteコマンドから推奨されるように、`.../.pub-cache/bin`にパスを通して起動しても良いのだけれど、それだと、dartとflutter、それぞれにインストールした時に使いわけが面倒になりそう。

なので、dart、または素のまま`pub global run`で起動すれば、`${HOME}/.pub-cache`が、flutterから起動すれば、`${FLUTTER_ROOT}/.pub-cache`が操作対象になるということで。

もちろん、`-d`で、好きなパスを指定しても構わないです。

実行すると、下記のように、削除対象になるパッケージとバージョンのリストが表示されて、最終確認を求められるので、問題なければ`y`する、という感じです。

```
% pub global run purge_pub_cache
Using pub-cache directory: /home/foo/.pub-cache

Packages to be deleted:
fooPackage: 0.0.1, 0.0.2
barPackage: 1.8.0

Are you sure to delete these 3 packages? [y/N]: y
Deleting 3 packages... done.
```

もしかして、誰もこんなこと気にしていない?
localStorageを操作する

「お気に入り機能」や「最近見た記事（商品）」などの実装でよく使います。

# localStorageにデータを保存する

```js
localStorage.setItem(キー名);
```

ローカルストレージは各ブラウザでドメインごとに保存されるので、
同一ドメイン内で複数実装する場合は接頭辞を変える。
だいたい追加した順番にソートしたりするので、追加する際は日時を取得して一緒に格納する場合が多いです。

商品系の場合（例）　　：favProduct-商品ID
ニュース系の場合（例）：favNews-記事ID
（分かりやすければ何でも良い）

デベロッパーツール（F12）→ Application → Local Storage →　ドメイン選択
で、このドメインのLocal Storageに何が入っているか確認できます。

![localStorage1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/afb4abd2-2642-eddb-a80c-f613da840c8d.jpeg)

consoleに`localStorage`と打ち込んでも確認できます。

![localStorage2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/a7b56dad-c09d-4611-b5fa-20f6ceb7603a.jpeg)


# localStorageから取得する
```js
localStorage.getItem(キー名);
```
localStorageをforで回して任意の接頭辞が付いているデータのみ取り出したり。

```js
let favArr = [];
for(let i in localStorage) {
	if(i.indexOf('favProduct-') !== -1) {
		favArr.push(i);
	}
}
```

# localStorageからデータを削除する
```js
localStorage.removeItem(キー名);
```

##### 全データ削除する場合
```js
localStorage.clear();
```
【TIPS】Testing for State Restoration

iOS13以降からState RestorationはNSUserActivityを利用したものに変わりましたが、[サンプルコードのTest State Restoration on a Device](https://developer.apple.com/documentation/uikit/uiscenedelegate/restoring_your_app_s_state)にテスト方法が載っていたため紹介します。

文章は、サンプルコードの手引きの内容に具体的なステップを足したものです。

# テスト方法

アプリケーションを実行し、復帰したい画面でホームボタンを押す。ホーム画面に戻ったらXcodeの停止ボタン(もしくは停止のキーボードショートカット)を実行し、その後ホーム画面から開く。こうすることでState Restorationをテストすることができる。

※ Xcodeの実行ボタンから再実行させるとテストできないので注意
Elixir Phoenix でのbootstrap iconの使い方

# PhoneixでBootstrap Iconsを使う

liveviewやlivecomponentでアイコンを使いたくなったのですが、

hexに登録されているライブラリがあまり使いやすくなかったため、別のやり方を探していたら、

https://dev.to/mnishiguchi/how-to-use-bootstrap-icons-in-elixir-phoenix-1-5-app-4i78

↑phoenixでbootstrap iconsの使い方を説明している記事を見つけました。

3ステップでめちゃくちゃ簡単にbootstrap iconsが使えるようになるみたいです。

## 手順

①mixプロジェクトのままのディレクトリでbootstrap-iconsをインストール

```
npm --prefix=assets install bootstrap-icons file-loader --save-dev
```

②スタイルシートにCSSとwebfontsをインポート

```CSS:assets/css/app.scss
+ @import '../node_modules/bootstrap-icons/font/bootstrap-icons.css';
+
+ @font-face {
+   font-family: 'bootstrap-icons';
+   src: font-url('../node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff2') format('woff2'),
+     font-url('../node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff') format('woff');
+ }
```

③webfontsのfile-loaderを設定する

```javascript:assets/webpack.config.js
           test: /\.[s]?css$/,
           use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
         },
+        {
+          test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+          use: [
+            {
+              loader: 'file-loader',
+              options: {
+                name: '[name].[ext]',
+                outputPath: 'fonts/',
+              },
+            },
+          ],
+        },
       ],
     },
     plugins: [

```

あとは下記のようにすればok

```HTML
<i class="bi bi-plus-circle"></i>
```

　　
　　

他のやり方もあるみたいです↓

https://dev.to/mnishiguchi/how-to-use-bootstrap-icons-in-elixir-phoenix-1-5-app-4i78

# 注意事項

tailwindcssも使っている場合、bootstrap-iconsとの併用が原因でtailwindcssが動かなくなるエラーがありました。
tailwindcssと併用する際にはご注意ください。


# 備考

hex packageでsurface_heroiconsであれば、mix.exsのdepsに追加するだけでheroiconsの豊富なiconを使用できます。

https://hex.pm/packages/surface_heroicons
JavaScriptを基本からまとめてみた【8】【closest()メソッド】

##はじめに

####学習するに至った経緯

2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。
入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、
卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

##「closest」とは

『closest()』は、基本的に親要素を取得することができるメソッド。
ただし、検索性と高速性を兼ね備えているのが特徴で、指定した「タグ・属性」を持つ親要素を瞬時に探し出せる。

##「closest」の使い方
#### 直近の親要素を「closest」で取得する

一般的な記述方法としては、【要素.closest(セレクタ)】のように対象要素へセレクタを指定する。

```sample.html
<body>
    <div class="wrap">
    <ul>
        <li>項目１</li>
        <li>項目２</li>
        <li>項目３</li>
    </ul>
    </div>
    <script>
        var result = $('li').closest('div');
        console.log( result );
    </script>
</body>
```

このli要素に対して、「.closest(‘div’)」と記述することで親要素に「div要素」があるかどうかをチェックできる。注意点は、li要素から最も近い場所にある対象のdiv要素だけを取得するという点で、親要素としてdivタグが複数あったとしても、最初に合致したdiv要素だけを取得する。


##参考サイト
[【jQuery入門】closest()で親要素を取得する方法まとめ！]
(https://www.sejuku.net/blog/36728)
ブラウザで画像認識する安価な環境がほしい

#動機
普段はunityでアプリを作っていますが、アプリをインストールしてくれない時代になってきたので
webアプリも習得したいが、個人的な勉強なので安価な環境が欲しい
最終的には、mediapipe、opencv 使いたい　
GCP、IBMcloudでインスタンス停止し忘れた経験あるので、高額請求されるくらいなら止めて欲しい

#目指す環境
スマホカメラで撮影し、サーバーで処理し画像を返す
ubuntu18.14
flask
SSL

#コンテンツ
```python:app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run( port=8000, debug=True)
```

#自宅のPCに環境を構築 ngrokで公開してみる

https://ngrok.com/download

```shell:install.sh
./ngrok authtoken <your_auth_token>
./ngrok http 80
```

```shell:run.sh
cd  app.pyがある場所
python3 app.py
```

遅すぎるのと、アクセス回数が限られていたので断念


#vpsを借りてみる
プリペイドが使え残金がなくなると停止するconohaを使う

https://www.conoha.jp/vps/pricing/?btn_id=vps-glonavi_pricing

VPSレンタル代  530 円/月 
ドメイン代　￥2000/年


###SSL設定
caddy２という、SSLが設定できるサーバーを見つけたので
設定してみる　ネットで探すとほとんどV1で、情報がまざっていて大変でした

https://caddyserver.com/v2

https://caddyserver.com/docs/install#debian-ubuntu-raspbian

```shell:install.sh
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```

sudo nano /etc/caddy/Caddyfile

```shell:install.sh
www.sample.com:443
tls mail@gmail.com
reverse_proxy  localhost:8000
encode zstd gzip
```

```shell:run.sh
sudo ufw allow 443
sudo ufw allow 80
sudo caddy run --config /etc/caddy/Caddyfile 

```


###確認
```shell:install.sh
cd  app.pyがある場所
python3 app.py
```

ブラウザから　https://www.sample.com　で
Hello World!　と表示され
なんとか、できたので次回、画像認識をやっていきたい
In PackageManifest.php line 122: Undefined index: nameでなんか詰まった話

composer2にしたら起きている問題らしい
とりあえずやったことをメモメモ

なんかkey:generateしたらこれが出た

```
In PackageManifest.php line 122: Undefined index: name
```

composerのバージョンが1 から 2にしたときに起きたみたい。
合わせいないといけないものだったため、composerを1にする方法で解決した。

バージョン確認して

```
composer --version
```

とりあえず　下げてみる
下げるコマンド

```
composer self-update --1
```

ちなみに２にする場合はコマンドの1を2にすればいい

以上！！！！
three.jsでVRツアーを作成する


https://qiita.com/im02kai/items/31fa6cfc8e50855bebff

の続きです

Aframe や　panolens.js の方がレスポンシブルで使いやすいが
ビデオやcanvasと組み合わせ場合、複雑になるのでthree.jsから作った方が
デバッグしやすいと考えて、作成


#参考
https://threejs.org/examples/webgl_panorama_equirectangular.html 
https://threejs.org/examples/webgl_geometry_terrain_raycast.html　 の　function onPointerMove( event ) 


#raycastで座標を取得

webgl_panorama_equirectangular.html を基に
変更

```javascript:webgl_panorama_equirectangular.html 
let mesh;
let group;
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
mesh = new THREE.Mesh( geometry, material );
```


webgl_geometry_terrain_raycast.html　 の　function onPointerMove( event ) を
onMouseDownへ変更して
追加

```javascript:webgl_panorama_equirectangular.html 

window.addEventListener( 'mousedown', onMouseDown );

			function onMouseDown( event ) {

				pointer.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
				pointer.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
				raycaster.setFromCamera( pointer, camera );

				// See if the ray from the camera into the world hits one of our meshes
				const intersects = raycaster.intersectObject( mesh,true );
				//const intersects = raycaster.intersectObject( group,true );

				// Toggle rotation bool for meshes that we clicked
				if ( intersects.length > 0 ) {
					console.log( intersects[0].point.x + ", " + intersects[0].point.y + ", " + intersects[0].point.z );
					console.log(intersects[0].object.name);
				}

			}
```


#背景球を設置　少し小さくする

```javascript:webgl_panorama_equirectangular.html 
const geometry = new THREE.SphereGeometry( 500-50, 60, 40 );
```

#console.logで配置したい座標を記録
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514937/42a581ff-33f5-53f5-f244-161b5f1ce63b.jpeg" width=400 />


#記録した座標へspriteを配置
```javascript:webgl_panorama_equirectangular.html 
group = new THREE.Group();
const map = new THREE.TextureLoader().load( "info.png"  ); 
const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, depthWrite: false} );
const sprite = new THREE.Sprite( material );
sprite.name = "point1";
group.add( sprite );
sprite.position.set( 214.48695923481648, -50.46751981995689, -447.88923840211703);  
sprite.scale.set(100, 100, 1);
scene.add( group );
```


#重なっているので背景球の大きさを戻す
```javascript:webgl_panorama_equirectangular.html 
const geometry = new THREE.SphereGeometry( 500, 60, 40 );
```

#onMouseDownへクリック判定と別画像をロード 追加

```javascript:webgl_panorama_equirectangular.html 

//const intersects = raycaster.intersectObject( mesh,true );
const intersects = raycaster.intersectObject( group,true );

if (intersects[0].object.name=="point1"){
var material = mesh.material;
material.map = new THREE.TextureLoader().load( './r2.jpg' );
material.map.needsUpdate = true;
}
```

#ブラウザで確認
![gif](https://user-images.githubusercontent.com/45844502/128324590-ed64be8e-b3d5-4a04-adc5-f3dbee4bf9cf.gif)
Unityを利用してthree.js用のパノラマ画像を作成する


VRツアーをthree.jsで作成しようとサンプル素材を探したところ
１フロア各所のパノラマ画像が全然なく
Unityを利用してパノラマ画像を作成しました

#インストール
Unity2020.3
Unity Recorderをpackageから
部屋のアセットを購入、インポート


#シーン設定
ライティングやマテリアルの設定で何度も録画するため、
タグ機能を使い複数の場所を同時に出力できるようにする
タグをr1 - r7までつくり
カメラの複製、位置移動、タグ設定を繰り返す
![camera.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514937/b57c8c9a-308c-1ea3-2df5-fce4d1223b34.png)

#Unity Recorder設定
![rec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514937/15dc3f93-e09f-67a9-72a9-c4f7c1d65c48.png)

Recording Mode -> Single Frame
Capture 
Source -> 360 View
Camera -> TaggedCamera
Tag    -> r1  *
Output File
File Name -> r1  *

Add Recorderで、追加して＊部分を割当

#Recordしてファイル生成
![render.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514937/e61d0d78-8189-fd98-5369-4f2a2ae25a3d.png)


#three.jsに埋め込み
コードは、公式サンプルの　https://threejs.org/examples/webgl_panorama_equirectangular.html  を参考

テクスチャのパスだけ変えて

```javascript:webgl_panorama_equirectangular.html 
const texture = new THREE.TextureLoader().load( 'textures/r1.jpg' );

```

#ブラウザで確認
![gif](https://user-images.githubusercontent.com/45844502/128302222-a7f7b5f3-0f5c-45de-8587-28e2b4c9fc7f.gif)


つづき

https://qiita.com/im02kai/items/2b150b875bea6a3035b8
PV数実装時のsession_hashでのエラー【impressionist】【Ruby on Rails】

# {TypeError　の改善方法}
![スクリーンショット 2021-08-06 18.41.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/e5e433cb-c953-3810-2834-72fad49d416a.png)


## はじめに
impressionist gemを使用して、PV数の表示を実装しました。
その際に、エラーにぶつかったため共有します。


## エラー内容
![スクリーンショット 2021-08-06 18.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/346441c8-cba3-36e1-89c4-268b4ade04cc.png)

ここのuniqueにて、session_hashを値として、閲覧数をカウントすると規定しました。
ですが、サーバーを立ち上げてると、typeErrorが出現しました。
## 原因
調べてみると、session_hashは、string型のため、そのまま使用しようとするとエラーが出るみたいです。

## 改善方法
なので、session_hash.to_sとして、変換すれば改善します
![スクリーンショット 2021-08-06 18.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/74282227-1dbd-eebd-23fd-21d86f25d695.png)
。