OmniAICreator/Qiita-1.07M huggingface dataset:
Rocky Linux 8にOpenJDK 8(1.8)をインストール（AppStream）

# はじめに

Application Stream(AppStream)を利用してRocky Linux 8にOpenJDK8(1.8)をインストール
親記事：[OpenJDKの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/b179202216aab50b7090)
参考：[RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログ]( https://rheb.hatenablog.com/entry/rhel8_baseos_and_appstream)

## サポート

本手法で導入した場合、[Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portal](https://access.redhat.com/node/4079021)より、2026-05がEOLだと思われる。
[OpenJDK ライフサイクルおよびサポートポリシー - Red Hat Customer Portal] (https://access.redhat.com/ja/articles/1457743)の内容とも合致する期日になっている。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## note

- openjdkはmoduleではなく、バージョン+パッケージ名で別れているだけの模様

## LOG

### インストール

```shell-session
# cat /etc/redhat-release
Rocky Linux release 8.5 (Green Obsidian)

# yum install -y java-1.8.0-openjdk
... 略
```

### 各種確認

```shell-session
# which java
/usr/bin/java

# java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
```
deno deployのplaygroundをGitHubに移す

deno deploy playgroundのGitHubエクスポート機能を試してみたいと思います。

## deno deployとは

deno deploy とは、cloudflare workersのようにエッジサーバーでDeno向けのコードを実行してくれるサービスです。Deno社が開発・運営しています。

https://deno.com/deploy

deno deployには、1クリックで簡単にプロジェクトをスタートできる**playground**機能が備わっています。今回はこのplayground機能についての話です。

## playgroundの作成

GitHubアカウントにログインした後、プロジェクトのダッシュボードから「New Playground」をクリックします。以上です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/f40b9855-cd4b-49e4-9aa2-00dc0f5eab7d.png)

playgroundにはHello Worldサーバーのコードが既に入っており、画面右側にはサーバーのライブサンプルが表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/4bc37927-df9e-e381-0406-e293473b5a4e.png)

playgroundは色々弄りながら動作確認するのに便利なのですが、複数ファイルはサポートされていないのでコード量が増えた時に困ります。そういう時のために、**GitHubへのエクスポート機能**が存在しています。

## エクスポート機能を使ってコードをGitHubに移す

playgroundのエクスポート機能の使い方について解説します。
まず、playgroundのプロジェクトページに移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/60830254-b1d0-44a3-a67b-ad4a1b6b8838.png)

下にスクロールすると「Export to GitHub」欄があるので、コードの移動先となるGitHubリポジトリ名を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/326b29e0-53ea-6f09-62d0-3970e7d6bc28.png)

Exportボタンを押すと、GitHubへのエクスポートが完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/7c7d3032-ca00-a830-4b1f-bf4e8e5b2d1d.png)

エクスポート先のGitHubリポジトリは、自分のplayground自体がプライベートの設定になっていたためか、プライベートリポジトリになっていました。

注意点として、一度GitHubにエクスポートしたplaygroundは、もう一度playgroundに戻すことはできないようです。

## まとめ

playgroundにはコード共有機能など、便利そうな機能が備わっているので、色々使っていきたいです。
【Vue3+GAS】今日の気分で献立を決めてくれるマッチングアプリ作ってみた

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283492/f1a382e1-6ccd-dd64-3b4b-939fc20d0444.png" width="300">

ミニWEBサービス「おすすめごはん」を作りました。
５つの簡単な質問に回答するだけで、あなたにおすすめのごはんを提案するサービスです。
まずはやってみましょう。
https://an-248.github.io/suggest_dish/

コードはこちら。
https://github.com/AN-248/suggest_dish

## 作った動機
面白いものを作りながら技術力をアップしたいという思想のもと、
職場の複数のエンジニアで、アイデア出しをしたり、ごはんデータ入力したり、コードを書ける人が書いたり、数学できる人がアルゴリズムを考えたりして、ゆるーく完成しました。

## 使用技術

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283492/ca87d46a-6436-60aa-bca3-8ba52e98cc4e.png" width="100"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283492/f3850139-867c-d29b-94b2-509a70cfc09f.png" width="100">

フロントエンドはvue3
バックエンドはありませんが、ごはんは全165品目のデータがあり、googleのスプレッドシートに登録しています。
Google App Script（GAS）を利用してスプレッドシートの情報をAPIで取得し、js側で利用しています。
![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283492/a3b3f6e2-0e12-0b67-c64d-e434ffa4a946.png)



jsだけの実装なので、公開はgithub pagesで行いました。（すべて無料！）

## レコメンドの仕組み
ごはん165品には、以下の５つの指標で1〜10の点数をつけています。
・油っぽさ
・熱さ
・塩味
・甘味
・固体

ユーザーに５ステップの質問をすることで、ユーザーに対しても上記５つの指標の点数付けを行います。
これでユーザのペンタゴンと、ごはん165品のペンタゴンができますので、ペンタゴンの一致率が最も高いごはんをレコメンドするという仕組みです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283492/d5ead0ec-75fe-7c7c-95c4-b0df275d301c.png" width="400">


グラフ同士の一致率は「ユークリッド距離」という計算方法を利用しました。小難しそうですが、落ち着いて公式に当てはめれば以外とできます。

```math
{d = \sqrt{(a_1 - b_1)^2 + (a_2 -b_2)^2 + (a_3 -b_3)^2 + ...+(a_i-b_i)^2}
}
```

以下はユーザーのペンタゴンとごはん全品のペンタゴンを比較し、一致度の高い順に並び替え、最も一致しているごはんをどっかに登録している部分のコードです。コード全体はgithubでご確認ください。

```js
const suggest = async () => {
    let points = {};

    dishes.value.forEach(d => {
        let n = 0;
        Object.keys(tastes.value).forEach(k => {
            n += Math.pow(Number(d[k]) - Number(tastes.value[k]), 2);
        });
        n = Math.sqrt(n)

        points[d['id']] = n;
    });

    let sortedDishes = dishes.value.sort((a, b) => {
        return points[a['id']] > points[b['id']] ? 1 : -1
    });

    result.value = sortedDishes[0];
    store.commit('setDishes', sortedDishes);
}
```

`Math.pow`が累乗で、`Math.sqrt`が平方根です。

## 不思議な質問の正体
５つの質問はユーザーのペンタゴンを作成するためのものです。
色、乗り物、方角など、ごはんとは関係なさそうな質問からレコメンドしますが、
ユーザーのペンタゴンを作れれば、質問はなんでも良いので、よりおもしろいものを選びました。

ユーザーのペンタゴンは、デフォルトではすべて平均値となっており、
質問の回答次第で点数をプラスしたりマイナスしたりしています。

たとえば乗り物の質問では、以下のように点数が増減します。

```js
  {
    "id": 33,
    "name": "車",
    "tastes": {
      "heat": 0.5,
      "oily": -0.5,
      "salty": 0,
      "solid": 1,
      "sweetness": 0.5
    }
  },
  {
    "id": 34,
    "name": "電車",
    "tastes": {
      "heat": -0.5,
      "oily": -0.5,
      "salty": 0.5,
      "solid": 0,
      "sweetness": 0.5
    }
  },
  {
    "id": 35,
    "name": "船",
    "tastes": {
      "heat": 0.5,
      "oily": 0.5,
      "salty": 0.5,
      "solid": -1,
      "sweetness": -0.5
    }
  },
  {
    "id": 36,
    "name": "飛行機",
    "tastes": {
      "heat": 1,
      "oily": -1,
      "salty": 0.5,
      "solid": 1,
      "sweetness": -0.5
    }
  },
```
これが適切なのかどうかは不明ですが、そこがおもしろいかなと思います。車と電車は甘くて、飛行機は熱いんでしょうか。不思議です。
周波数伝達関数のs=jwの意味

#はじめに

初めて制御工学を習ったとき、伝達関数$G(s)$に$s=jw$を代入すれば、周波数伝達関数だ！と教えられました。その時は、あまり深く考えずそんなもんかと思っていましたが、ふと最近考えてみてその理由が分かった気がするので書いておきます。

#s=jwの理由
伝達関数$G(s)$の$s$に$jw$を代入すると考えるから、理解が出来ていなかった気がします。この$s$が$G(s)$$=Y(s)/U(s)$の入力$U(s)$の$s$に代入されたものと考えればすっきりしました。

周波数伝達関数はそのシステムの周波数特性、ボード線図を知るために用いられます。そのとき、入力としてある周波数$w$の正弦波を入れます。この入力の正弦波の作成用に$\ddot{u}+w^2u=0$という単振動の系を考えたとき、その固有値$s$が$jw$だったのです。こう考えると、$U(s)$に$s=jw$を代入することによって、入力として周波数$w$の正弦波が生成されます。そして線形性により、出力も周波数$w$の正弦波となります。つまり、$Y(s)$にも$jw$が代入されたことになります。それらをまとめると結局は$G(s)$に$s=jw$を代入すれば周波数特性が分かる。つまり$G(jw)$が周波数伝達関数だ、ということで腑に落ちました。
Kotlinで地図アプリ（ゴミ拾いアプリ）作成。（6日目）

Kotlinで制作している、GoogleMapを使った、自作のゴミ拾いアプリ。制作6日目。

#これまでの経過
1日目：Android Studio + Kotlin で開発環境作成。GoogleMapAPIアクセスキー取得。エミュで動作。
2日目：地図にマーカー表示・カスタム方法。マップ表示形式の変更。
3日目：現在地を取得し、地図上に表示。クリックイベント。
4日目：移動する際にマップがスクロールしなかった問題を修正。
5日目：volleyを使いGETリクエスト送信と、サーバー側で受信＋記録。

#今日やった事

・LocalDateで、現在の日時を取得
・ボタンにアイコン画像を付ける
・サーバー側でBASIC認証を設定
・クライアント側はVolleyでBASIC認証

#LocalDateで、現在の日時を取得

参考サイト

https://codechacha.com/ja/kotlin-examples-current-date-and-time/

    val current = LocalDateTime.now()
    val date_time = current.format( DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") )



#ボタンにアイコン画像を付ける

以下のサイトを参考にactivity_maps.xmlを変更

https://codeforfun.jp/android-studio-how-to-use-image-button-widget/

ButtonをImageButtonに変更。

setOnClickListenerの方も、ButtonをImageButtonに変更。

エミュレーターの動作画面：
![イメージ7366.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/b40e69dd-5308-bdc3-449d-d35b7fa6392e.jpeg)


#サーバー側でBASIC認証を設定

ディレクトリに「.htaccess」と「.htpasswd」を作成・編集

```txt:.htaccess
AuthUserFile /home/users/2/xxxxxxxx/web/.htpasswd
AuthGroupFile /dev/null
AuthName "Please enter your ID and password"
AuthType Basic
require valid-user
```

```txt:.htpasswd
id:pass
```


#VolleyでBASIC認証

今日は、ここで少しハマりました…。

具体的には、getHeadersをオーバーライドすればいいようです。

```kotlin:MapsActivity.kt
            @Throws(AuthFailureError::class)
            override fun getHeaders(): Map<String, String> {
                val params = HashMap<String, String>()
                val creds = String.format("%s:%s", "ユーザーID", "パスワード")
                val auth = "Basic " + Base64.encodeToString(creds.toByteArray(), Base64.DEFAULT)
                params["Authorization"] = auth
                return params
            }
```

参考サイト：

https://stackoverflow.com/questions/16817980/how-does-one-use-basic-authentication-with-volley-on-android

ベーシック認証が出来るようになったところで、今日はここまで。
kaliを日本語設定にする方法

# kaliを日本語設定にする方法

kaliを日本語にする際にいろいろ困ったので，最終的な解決策のみを記録する．

## 前提となるインストール方法
以下のURLからkaliのVirtualBoxのイメージをダウンロードし、インポートした．
https://www.kali.org/get-kali/#kali-virtual-machines

## 解決策

参考にしたURL(末尾に記載したURL)のWebサイトを見て，ターミナル（端末）に以下のコマンドを入力して実行した

```zsh
setxkbmap -layout jp
```
上記は一般ユーザで動作する．

これで動くことを確認した．しかし，このコマンドは再起動すると英語配列に戻ってしまう．
このため，起動したときに自動的にこのコマンドが実行されるように仕掛ける

```zsh
$ cat /etc/passwd | grep kali             
kali:x:1000:1000:Kali,,,:/home/kali:/usr/bin/zsh
```
上記の結果からzshであることが分かった．

`~/.zshrc`の末尾に以下を追加

```zsh
setxkbmap -layout jp
```

これにより，再起動しても日本語配列で利用可能になった．

## 日本語に対応させる

```zsh
sudo apt-get install -y task-japanese task-japanese-desktop
reboot
sudo dpkg-reconfigure locales
sudo update-locale LANG=ja_jp.UTF-8
reboot
locale #確認
```

## 日本時間にする

```zsh
sudo dpkg-reconfigure tzdata
reboot
```

# 参考
以下のURLを参考にした．
- https://what-a-day.net/vm-keyboard-layout#%E5%85%88%E3%81%AB%E8%A7%A3%E6%B1%BA%E7%AD%96%E3%81%8B%E3%82%89
- https://cocolofun.co.jp/linux-upgrade/
- https://tex2e.github.io/blog/keyboard/keyboard-layout-jp
kivyMD開発其の壱 初期公開篇

ハロー、Qiita!いかがお過ごしでしょうか。

すっかり街はというか街でなくてもクリスマスムード。なんだか胸騒ぎしそうでしなくもない
でもなんかソワソワする、そういった時期なのではないかと思ってしまいます(意味不明)。

:::note
先週日曜くらいに投稿しようと思ってたのですが、まんまと忘れていました:sweat_smile:
少し時差がありますがおゆるしのほどを:bow_tone1:
:::

今日はというと、先週お伝えした通りとタイトルの通り(こちらは分かりにくい)ですが、投稿
者自身のサンプルアプリケーションをリリースするということで投稿しています。

先に言っておくと、完成度はそれほどというか全然高くありません:sweat_smile:

ですが、以前から~~口走っていて~~お伝えしていたので、現段階の状態でリリースすること
としました。ではさっそくですが、ここからは本題とします。

## TodoApp

いつかのときに言っていたと思いますが、まずは簡単なものからということで副タイトルの
通りでアプリのことをお伝えしていきます。

どんなものなのかは見てみるに越したことはないので、さっそくどんなものか見ていただき
ましょう。

![todoapp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/b7ac30c9-c008-b23a-75a4-240a693c9ef8.gif)

少し重く、見づらいかもしれませんがご了承のほどを。

まず最初に見れる画面は、タブがありCreateタブが見れるかと思います。名前の通り、
こちらはタスクを作るタブとなっています。少しやりたいこととは異なっていたのです
が、力不足でした。。

こちらでタスクを作ったあとは、まずTodoタブに移動してタスクの左にあるアイコンを
クリックしてステータス移動ダイアログを表示させます。あとは移動するかどうか聞かれた
あと(このときNoを押下しても何も起きないことは大きな声ではいえないことです...)、
移動するのであればYESをクリックしてステータスを移動します。

Doingに移ったあとは、Doneに移動することも同じことであり、遷移の仕方は現状1方向
であります(おかしいだろ!とか言わないでくださいbrbr...)。

ということで、簡単な説明になりましたが、このようなアプリとなっています。まぁ見た
方はほとんど思われるかもしれませんが、完成度は今ひとつといった状況です。日本語化
もできてないし、ステータスを1方向に絞るのは使いづらいこと極まりありません。。あと、
もう言っているところもありますが、不具合も共存したりして。。

ですが、結構モバイル版のTODOアプリってなかなか使いやすいものってなかったり(少し
前にインストールしたもので最近のものはわかりませんが、、)して作り込めると結構よく
できたアプリになるのではないかと目論んでいます。まぁそれでユーザー集めるの?とか
言われるとぐうの音もでませんが。。

## まとめ

というわけで、少し早いですがこれまでとしようと思います。コードは?説明ないの?と
思われる方もいらっしゃるかもしれませんが、まぁまぁそう興奮しないでください(いつ
ぞやの前首相風)。

そんな興奮する方はいらっしゃらないとは思いますが、コードの方は以下になります。
いつものリポジトリではなく、別のリポジトリを作ってそちらに格納しています。

https://github.com/Quiet396/TodoApp

こちらの説明については、次回に回そうと思います。理由は単純明快で力尽きたことに
よります:joy:次回はいつになるかは見通しはありませんが、来年早めに投稿は努めたい
と思います。

ということで、今年は最後の投稿になりましたが今まで見ていただきありがとうござい
ました(終わらないよ!)。全然締められてはいませんが、来年もまたよろしくお願いします:bow:

それでは、ごきげんよう。

## 参照

> KivyMD
> https://kivymd.readthedocs.io/en/latest/
VSCodeのターミナルをちょっとした計算機（電卓風）に使う

## 想定読者
- ※ 普段からVSCodeを嗜んでいる方
- 電卓＝Web電卓とかWindows電卓(Calc）を使っている方
- 四則計算の履歴を見たい方
  - ふるさと納税の計算で課税所得を計算している方
  - 今年の収入と経費をざっくり把握しておきたい方
  - 確定申告の計算で課税所得を計算している方
- VSCodeは好きだけど、ターミナルは画面が黒くて怖いというブロガー/ライターの方

内容が内容なのでプログラミングの話は若干外れますが、フリーランスエンジニアの方には何気に需要があると思います。

## やり方
計算したい内容が閃いたら、おもむろにターミナルを開き

``` cmd.bat
set /a 【計算】
```

``` wsl.sh
# $((【計算】))で良いですが、「command not found」エラーメッセージも表示されるので、echoを入れてます
echo $((【計算】))
```

とすると計算できます。

これでいちいちVSCode用の拡張機能で電卓探したり、Web電卓を使わなくても良くなりました。

## 補足: ターミナルをWSLなどLinux系にすると履歴が見れます
cmdでもF7キーを押す事で履歴を見る事はできますが、今回実行した結果しか見れません。
たかが計算処理ぐらいならこれでも良いですが、経理業務をやっていたらウッカリcmdを落としてしまう事はよくあります。
その場合、過去の履歴を参照する事ができないので不便です。

WSLを使うと、計算内容がhistoryに残るので、上キーをポチポチやるとすぐに結果を見れるのでおすすめです。
Docker Hubに置いているDockerイメージを使用してElastic Beanstalkにデプロイする方法

Elastic Beanstalk(以下EB)で、**Docker Hubのプライベートリポジトリ**にホストしているDockerイメージを使用してデプロイするための設定方法をざっくりまとめ

## 1. リポジトリを指定する
Dockerrun.aws.jsonに`Image`キーを追記する

```json:Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "organization/image-name",
    "Update": "true"
  }
}
```

- `Name`キーにはDockerリポジトリを指定する
- `Update`キーにはイメージのキャッシュを上書きするかどうか指定します。デフォルトはtrue

🚫 注意点🚫
`Dockerfile`がソースバンドルに**含まれている**場合、Dockerrun.aws.jsonのImageを無視し`Dockerfile`を使用してコンテナ構築が行われるため、Dockerfileは含めないようにしましょう

## 2. リポジトリの認証を設定する
インスタンスからプライベートリポジトリにアクセスできるように、docker loginを行う設定をします。主に2種類の設定方法がありますが、ここではそれぞれ概要をまとめる程度にします。詳しくは[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/single-container-docker-configuration.html#docker-configuration.remote-repo)を参照ください

1. AWS Systems Manager (SSM) パラメータストア
SSMに認証情報を保存し、デプロイプロセスのビルド前フェーズでイベントを発生される[フックスクリプト](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html)を使用して、認証情報の取得・docker loginを行う方法

2. Dockerrun.aws.jsonファイル
docker login時に作成される認証ファイルをS3に置き、そのバケット情報をDockerrun.aws.jsonに記載する方法

ちなみに私のローカル環境下(MacBook Pro 13-inch 2018、Docker for Mac)では期待する認証ファイルが作成されなかったため、1番を参考にセットアップを行いました

## 3. その他Docker設定を記載する
- Port (必須)
Docker コンテナで公開するポートを指定します。基本的にはカスタムイメージを作成したときのEXPOSEと同じ値で問題ないと思われます。こちらを指定しないとコンテナが起動しません

```json:Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "organization/image-name",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "3000"
    }
  ]
}
```

- Volumes, Logging, Entrypoint, Command (オプショナル)
お好みに応じてDocker周りの設定を記載します。詳しい設定方法は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/single-container-docker-configuration.html#awsui-expandable-section-80-trigger)を参照ください

## 4. デプロイに使用するソースバンドルの中身を調整
上記の`🚫 注意点🚫`でも書いているように、`Dockerfile`をソースバンドルに含めないように、`.ebignore`で必要のないファイルを対象外にします

```plaintext:.ebignore
# 全ファイルを対象から外す
.

# EB設定ファイル
# ファイル名に!をつけて対象にする
!.ebextensions/*.config
!.platform/**/*.*

# Dockerビルド用ファイル
!Dockerrun.aws.json
```

## 参考
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/single-container-docker-configuration.html
【Rails】production環境でCSS等が反映されないとき（ActionController::RoutingError (No route matches [GET] ....


## 環境
Ruby 3.0.2
Rails 6.1

## 問題
CSSなどをプリコンパイルの対象に指定し，コンパイル実行後にproduction環境にてページを表示してみたらCSS等の設定が全く反映されていなかった．また，ログ（`log/production.log`）を確認してみると

```
ActionController::RoutingError (No route matches [GET] "/assets/ ... .css"):
```

のようなメッセージが残っていた．

## 解決方法
まず，コンパイルするときに環境を指定していなかったのが問題だった．以下のように，環境を指定してコンパイルをする．

```sh
$ RAILS_ENV=production bundle exec rails assets:precompile
```

なお，`bundle exec rails`の部分は環境構築のしかたによって適宜変えて実行すべきところだろう．

次に，`config/environments/production.rb`を開き，`config.public_file_server_enabled`に直接`true`を指定する（コメントアウトしてある部分は，もともとあった記述）．

```rb
# config.public_file_server_enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server_enabled = true
```

以上で，自分の場合は問題が解決した．

## 参考
＜問題の解決に役立ったサイト＞
[プリコンパイルの方法について（2015年の記事．古い）]
https://blog.naichilab.com/entry/2015/11/08/005606
[No route matches [GET] /assets について（質問と回答）]
https://coderedirect.com/questions/99092/no-route-matches-get-assets

＜より深く理解するために＞
[アセットパイプライン]
https://railsguides.jp/asset_pipeline.html
RJBでハマったこと

## RJBとは

Ruby Java Bridge。
簡単に言うと「Ruby から Java のライブラリを使用する」もの。

## 開発環境

* WSL2（Ubuntu 20.04LTS）
* Docker
* Ruby 1.8.7
* Rails 2.1.0 
* rjb-1.4.6
* JDK1.8.9

## ハマったこと

### クラスパスの記述方法

任意のクラスパスを読み込む。
今回はExcelを扱おうとしてるのでpoi等以下のような感じ。

```ruby
Rjb::load("#{RAILS_ROOT}/lib/poi-3.5-FINAL-20090928.jar;#{RAILS_ROOT}/lib/poi-ooxml-3.5-FINAL-20090928.jar;#{RAILS_ROOT}/lib/ooxml-schemas-1.0.jar;#{RAILS_ROOT}/lib/poi-scratchpad-3.5-FINAL-20090928.jar;#{RAILS_ROOT}/lib/dom4j-1.6.1.jar;#{RAILS_ROOT}/lib/geronimo-stax-api_1.0_spec-1.0.jar;#{RAILS_ROOT}/lib/xmlbeans-2.3.0.jar", jvmargs=[])
```

複数の場合、Linuxの場合はコロン（:）、Windowsの場合はセミコロン（;）になる。
本番環境のセミコロンになっていて、正しく読み込まれていない状態だった。
（前任者の開発環境がウィンドウズだったのか？）
今まで正常に動いてたのが奇跡。

### Rjb::load は一度まで

loadは「JVM インスタンスの作成」をしている模様。
（一度loadすると2回目は無効になる？）

なので、Railsサーバーの再起動も必要っぽい。
サーバーレスアプリケーションを作成する

# 事前の準備
WebStormを使って、AWSのサーバレスアプレケーションを作成するための準備作業になります。
[nvmを使って、Node.jsをインストールする](https://qiita.com/hikotaro_san/items/f5ae1962920dcdf847b0)
[AWS SAM CLI をインストールする](https://qiita.com/hikotaro_san/items/ccfbf876aa6b68e322be)
[Dockerをインストールする](https://qiita.com/hikotaro_san/items/fac9d7f215fdf47a3ba6)
[AWS Toolkitをインストールする](https://qiita.com/hikotaro_san/items/b1334b477e19951f7ccc)

# 新規プロジェクトを作成する
WebStormを起動します。
「New Project」をクリックします。
「AWS Serverless Application」をクリックします。
お好きなプロジェクト名を入力し、「Create」をクリックします。
![スクリーンショット 2021-12-28 18.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/2bf5d0c5-9de8-baff-0291-e2bd43876a37.png)

# ローカル環境で、Lambdaプログラムを実行する
Dockerを起動しておきます。

WebStormで、実行(緑の矢印)をクリックします。
![スクリーンショット 2021-12-28 18.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/766cf7dc-1b15-7984-dab3-0180b4860514.png)

実行の編集画面が表示されます。
API Gateway AWS Proxyを選び、「Run」をクリックします。
![スクリーンショット 2021-12-28 18.19.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/2e25cb8e-3ffa-4d51-6369-b1ca29463b97.png)

実行結果が表示されます。
![スクリーンショット 2021-12-28 18.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/3d66042d-6798-8af4-f2be-f358c5e20ac9.png)

【参考】
[JetBrains 用 AWS Toolkit for JetBrains を使用した AWS Lambda](https://docs.aws.amazon.com/ja_jp/toolkit-for-jetbrains/latest/userguide/building-lambda.html)
Unity2019でプレイモードにした際にオブジェクトに生成されたライトマップが外れる現象の対処法

#はじめに
現在，手軽にメタバースを体験できる「[VRChat](https://hello.vrchat.com/)」に注目が集まっています。
VRChatとは、「ワールド」と呼ばれる仮想空間で、「アバター」と呼ばれる仮想の身体を介して他のユーザーと交流が出来るソーシャルVRプラットフォームの一つです。Steam、Oculus Store、Viveportからインストールできます。「VR」の文字が入っていますが、VRゴーグルがなくともデスクトップでプレイすることも可能です。
ワールドやアバターはユーザーが制作してアップロードすることが可能で、それらの表現は多岐にわたります。

VRChatの導入の仕方については、以下の記事で丁寧に説明されています。
・[VRChat初心者向けガイド](https://vrc.wiki/)
・[VRChat 日本Wiki](https://vrchatjp.playing.wiki/)

ワールド制作については、以下の記事で詳細が共有されています。
・[VRChat 技術メモ帳 - VRChat tech notes - ワールド作成入門](https://vrcworld.wiki.fc2.com/wiki/%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E4%BD%9C%E6%88%90%E5%85%A5%E9%96%80)
（なお現在のVRChatのコンテンツ制作を行うためのUnityのバージョンは**2019.4.31fのみ**です！）

この記事では、VRChatのワールド制作の中で遭遇したバグについて、対処方法と共に共有したいと思います。


#確認環境
・Windows10
・Unity2019.4.31f
・VRCSDK3

#バグの内容
Unityでベイクをしたのちにプレイモードにすると、オブジェクトからライトマップが消えてしまうバグです（ちなみに生成されたライトマップ自体はsceneフォルダに残っています）。

ベイク後の画面。inspectorを見るとライトマップがアタッチされている。
![スクリーンショット 2021-12-27 171411.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415104/9d86fd8a-498b-9e1c-bb42-0b08d2768962.jpeg)
プレイモードにした直後の画面。inspectorを見るとライトマップが外れているのがわかる。
![スクリーンショット 2021-12-27 171522.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415104/608b0386-e2f4-00e3-489e-2e03d939971c.jpeg)

ベイクをやり直したり、Unityの再起動を試みたのですが、自分の環境では何度やってもこのバグは直りませんでした。

#対処法
このバグの対処法は、

1. 新たなsceneを作る
2. バグが起きているsceneから1.のsceneにHierarchyの中身を全て移す


以上の工程を経た後に、1.のsceneでベイクを行い、プレイモードにするとオブジェクトからライトマップが外れることなく動作しました。

#さいごに
自分の環境では上記の方法で解決しました。
ほかの方法があれば教えていただけると幸いです。
FlutterからHelloWorld

## はじめに
モバイル開発がしてみたいと思い、Flutterに入門しました。
FLutterは公式チュートリアルでHelloWorldしていないので、ここに備忘します。

## 使用技術
- Flutter 2.8.1
- 環境はiOS,Android,Webのどれでも可

## 開発環境構築
ここではflutter doctorが正常に完了したとします。

Flutterの公式Documentが素晴らしいです。

　→ https://docs.flutter.dev/get-started/install


## デフォルトアプリを見渡す
Flutterは初期状態ではカウンターアプリが用意されています。
そのデフォルトアプリが以下のコマンドで起動するか確認しましょう。

```
flutter run
```

### main.dart を紐解く
lib フォルダ下にある main.dart が Flutter アプリケーションを開発するためのスタート地点です。

main.dart には冒頭に以下の記述があります。

```main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}
``` 
import 文ではそのプロジェクトで利用可能なパッケージを各ファイルで参照可能にするために使用します。パッケージだけではなく、別のファイルに記述した実装を参照するためにも使用します。

### main メソッドと runApp メソッド
mainメソッドは Flutter の実行時にプログラムのエントリーポイントとして扱われるもので、全ての処理（実装した分）についてはmainメソッドを起点に動き始めます。

runApp()はFlutterのプロジェクト上で最初に展開して欲しい Widget を指定します。Widgetはここでは「FlutterのUIを構築しているパーツ」と認識してください。runApp()がなければ、Widgetはただの Dart プログラムとして動作します。

Flutter アプリ開発においては、とりあえず "main から始まって、runApp を呼んだところから Widget が必要になるんだね" ということを覚えておいてください。


### Flutter では全てが Widget である
Flutterが公式に「Flutter では全てが Widget である」と言っているので、MaterialAppにしてもCupertinoAppにしても、とりあえずは「なんか部品があってそれを組み合わせて作るんだ」とざっくり考えましょう。

テンプレートのMyApp Widgetについて考えましょう。

```main.dart
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
```
さて、Flutter は全てが Widget だと言いましたが、Widget もクラスです。Flutter を動かす上で必要な機能がモリモリのったクラスです。次に StatelessWidget ですね。これについてはStatefulWidgetと並べて別の記事で取り上げます。
とりあえず、よく使う Widget のひとつです。


- ```const MyApp({Key? key}) : super(key: key); ```
- ```@override```

これらについてはまた別の記事でまとめます。

## アプリの大掃除
- コメント類を消す
- FAB(Floating Action Button)を消す
- AppBar を消す
- StatefulWidget を消して StatelessWidget へ変更する
- 画面中央に HelloWorld を表示する

ここまでで以下の状態だと思います。

```main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pokemon Flutter',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Hello World',
          style: TextStyle(
            fontSize: 36,
          ),
        ),
      ),
    );
  }
}
```

## ここまでで覚えたいこと
- Flutter は Widget でできている
- Widget は Dart のクラスである
- 基本の Widget に StatelessWidget と StatefulWidget がある

## 感想
言葉にできない楽しさがFlutter開発にはある。
Next.jsでFirebase9のリアルタイム更新機能を使う

Next.jsでFirebase9のリアルタイム更新機能を使います。

###サンプルコード

１００から始まり、＋を押すと１を加え、ーを押すと１減らすプログラムです。
このコードをベースにします。

```javascript
import React from 'react';
import {useState, useEffect} from "react";

export const UserCount = React.createContext();

function  Test() {

  const[count, setCount] = useState(100);

  return (
    <>
      <div style={{ textAlign: 'center' }}>
        <h1>Test</h1>
          <p>{count}</p>
          <button onClick={() => setCount(count - 1)}>-</button>
          <button onClick={() => setCount(count + 1)}>+</button>
      </div>
    </>
  );
}

export default Test;
```

![スクリーンショット 2021-12-28 17.50.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1942691/028ce1d9-adc2-17bb-55ca-ad7dfcb8afc9.png)


###サンプルデータベース

サンプルのデータベースはこちらです。
counterというコレクションに、countというフィールドを設定しています。

![スクリーンショット 2021-12-28 17.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1942691/a1bbb90d-7ef7-5191-32f5-8fdaffbf4d5b.png)


###リアルタイム更新を行うソースコード

onSnapshotを使用します。

```Javascript
import React from 'react';
import {useState, useEffect} from "react";
import {collection, doc, query, onSnapshot} from "firebase/firestore";
import {db} from '/lib/firebase';

export const UserCount = React.createContext();

function  Test() {

  const[count, setCount] = useState(100);

  //データを表示する処理（初回のみ）
  useEffect(async()=> {

    //DBリアルタイム更新設定
    const q = query(collection(db, "counter"));
    const unsub = onSnapshot(q, (queryCounterSS) => {

      let l_count = 0;
      queryCounterSS.forEach((doc) => {
        if (doc.exists()) {
          console.log("Current data: ", doc.data().count);
          l_count = doc.data().count;
        }
      });

      setCount(l_count);
    });
  },[]);


  return (
    <>
      <div style={{ textAlign: 'center' }}>
        <h1>Test</h1>
          <p>{count}</p>
          <button onClick={() => setCount(count - 1)}>-</button>
          <button onClick={() => setCount(count + 1)}>+</button>
      </div>
    </>
  );
}

export default Test;

```

この状態でデータベースの値を変更すると、ブラウザ上の値にも即反映されます。

![スクリーンショット 2021-12-28 17.54.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1942691/34dbaced-6908-8422-188e-4c5d2522ac9d.png)

![スクリーンショット 2021-12-28 17.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1942691/27d78684-9406-11c2-a722-3d224bfa4771.png)


さらにsetDocでデータベースへの書き込み処理を追加すれば
ブラウザとデータベースのどちら側で値を変更しても、即反映されます。

以上です。

###参考サイト

https://firebase.google.cn/docs/firestore/query-data/listen?hl=ja
IoTの素晴らしさと未来2

#　一問一答形式「Flask」
【Q1】Flaskって何？
【A1】Flask（フラスコ/フラスク）はPythonのウェブアプリケーションフレームワークで、小規模向けの簡単なウェブアプリケーションを作るのに適しています。

【Q2】ウェブフレームワークって？
【A2】ウェブフレームワークとは、ウェブサイトやウェブアプリケーションを作るための機能を提供し、ウェブフレームワークを使わない時よりもより容易にウェブアプリケーションを作ることができるものです。

【Q3】pythonみたいなプログラム言語となんか関係する？
【A3】pythonはデータ解析用の言語として使われているのですが、実はウェブアプリケーションを開発するサーバーサイド言語としても使えます。要するに、pythonは結構いろいろなプログラムを作れる、とても優秀な言語だということです。Flaskはpythonのモジュールです。
　pythonの他にもPHPやRudyなどの言語がありますが、高度な数値計算やウェブアプリケーション開発が同時に出来てしまうのがPythonの特徴です。

【Q4】Flaskのメリットは？
【A4】まず一つ目、Flaskは軽いです。Flaskは「マイクロ」ウェブアプリケーションフレームワークの名前通り、必要最低限の機能しか搭載されていないため、他のウェブアプリケーションフレームワークに比べて動きが軽くなります。そのため、多くの機能は必要としない単純なウェブアプリケーションなどに適しています。
　二つ目は、機能が単純で学習が簡単なことです。搭載されている機能が多ければ、それぞれの機能について時間をかけて学んでいく必要があります。一方、Flaskは搭載されている機能が少ないためシンプルで学習が簡単です。
　最後に、Flaskは自由でがとても高いことが挙げられます。一般的なウェブアプリケーションフレームワークでは、大体搭載されている機能をもとにアプリケーション設計をしていくため、あまりカスタマイズをすることはありません。
　一方、Flaskは多くの機能を自分で実装していく必要があるため、要件に応じた細かなカスタマイズをすることが可能です。
　デメリットとしては、Flaskは大規模なウェブアプリケーションを開発することに向いていないことが挙げられます。

【Q5】Flaskはどうやってつかうの？
【A5】Flaskは簡単にインストールできます。コマンドプロンプトを起動し、

    ```pip3 install Flask　
    ```

を実行します。例えば、Hello worldを出力するためには

    ```from flask import Flask
       app = Flask(__name__)

       @app.route(‘/’)
       def hello():
       hello = “Hello world”
       return hello

       if __name__ == “__main__”:
       app.run()
    ```


このプログラムを実行すると、


       
       
    ``` $ python3 hello.py
       * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
       
    ```
「http://127.io0.0.1:5000/」 のURLにアクセスをすると 「Hellow World」の表示を確認することができます。

【Q6】FlaskとIoTの関係は？
【A6】IoTにおいてFlaskはデータサーバーとして機能させることができます。サーバとクライアント間のデータのやり取りは、CSVやJSONフォーマットを使用します。

【Q7】JSONフォーマットとCSVどちらのほうがデータの受け取りに適しているのですか？
【A7】JSONフォーマットです。ほとんどの言語においてJSONのライブラリが提供されており、構造に柔軟性があるためCSVよりもJSONのほうが圧倒的に使いやすいからです。

以上のことから、Flaskが如何にウェブアプリケーションのフレームワークとして優れているのか、ということを理解できたかと思います。IoTとFlaskは切っても切り離せない関係だということもよくわかりました。IoTについての理解が一段と深まったように思えます。
  参考文献
[【Python】Flaskとは？FlaskでWeb開発の基礎を学ぼう！](https://aiacademy.jp/media/?p=57)
[【Flask入門】Python初心者でもわかるフレームワークを解説！](https://udemy.benesse.co.jp/development/system/flask.html)
[PythonのFlaskで簡単なWebアプリケーションを作ってみよう！](https://toukei-lab.com/python-flask)
Top WordPress Tips you Need to Know Today

![Top-WordPress-Tips-you-Need-to-Know-Today-850x508 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327999/d86d1f77-f430-e15a-0734-5135ed86a027.jpeg)
From beginners to experts, everyone can do with some handy tips while working WordPress. Here is a list of such WordPress hacks that can help you do much more with your content.

1. Choosing a Nice Theme
You need to set a nice theme for ,your website in order to intrigue your site visitors and hold their attention. You can use various platforms to buy templates and themes according to your choice and necessity.

ThemeForest is a popular option to buy themes for your WordPress blog. They come with page builders that are very simple to use. Some themes also provide demo sites for various types of industries. You can easily import these demos and change the color, background, font according to your taste. Once your theme is set, you’re good to start your site. You can save a good amount on web designing costs as you won’t have to <a href="https://www.icecubedigital.com/hire-wordpress-developers-designers/">hire WordPress expert.</a>

2. Download a Search Optimization Plug-in
If you’re a beginner on WordPress, the initial step would be to download a search optimization plug-in that will help you every step of the way by inspecting posts, photos, products, and surveys to improve your rank in search results. Plug-ins are available for free and are very easy to install. Yoast, SEMrush, and Google Keyword Planner are few names to achieve the best SEO results. They also help improve your performance and rank based on your chosen keywords and meta tags. Readability scores help you tweak the content according to the age of your readers and their comprehension level. To go further and achieve new heights, you can always go selecting the best SEO service provider.

Read more: https://www.icecubedigital.com/blog/top-wordpress-tips-you-need-to-know-today/
neosでlogix その43

#概要

niosでlogixやってみる。
Impulse Multiplexerノード使ってみた。

#写真

![2021-12-28 06.28.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f6569e3e-1771-c031-42fe-72a0f3e839d1.jpeg)


#Impulse Multiplexer

```
Inputs
 	Impulse	Trigger
 	Int	Index
Outputs
 	Impulse	[0]
 	Impulse	[1]
```


以上。
ExceptionsManager.js:184 Error: If you want to use Reanimated 2 then go through our installation steps...というエラーが出たら

React Native開発をしているときにこんなエラーが出た

```
ExceptionsManager.js:184 Error: If you want to use Reanimated 2 then go through our installation steps http...
```

![Simulator Screen Shot - iPhone 13 - 2021-12-28 at 17.54.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1789530/8d62dfdb-d4fc-485c-d721-bfb624d95755.png)


結構頻繁に出てくる上に本当に初期の頃はこれで3時間くらい溶かしてしまったのを思い出したので（お恥ずかしい...）解決法をメモ。

単純にchromeのdebuggerを起動していたかららしい。それを閉じて再度シミュレータを起動したら解消しました。
[React]React.memoを使用して不要な再レンダリングを防ぐ

# はじめに
Reactの特徴である親コンポーネントのstateやpropsが更新されると子コンポーネントも一緒に再レンダリングされます。

その子コンポーネントが重い処理を持っており、子コンポーネントにのみ変更があった際にレンダリングされるようにしたく色々試行錯誤してみました。

# TL;DL
結論から言うと```React.memo```を使用すると実現できました。

```tsx:tsx
export const ReactmemoChild: VFC<Props> = memo(({ open }) => {
  console.log('再レンダリング!!!');
  return <>{open && <p>child</p>}</>;
});

```


# 開発環境
| ライブラリ |   バージョン     |   
|---:|-------------|
| React  |    17.0.2         |          
| typescript |4.5.4|    

# 詳細
結論の内容を説明する詳細な内容を説明
番号付き見出しのまとめ

## 1. React.memoとは
> React.memo は高階コンポーネントです。
もしあるコンポーネントが同じ props を与えられたときに同じ結果をレンダーするなら、結果を記憶してパフォーマンスを向上させるためにそれを React.memo でラップすることができます。つまり、React はコンポーネントのレンダーをスキップし、最後のレンダー結果を再利用します。
React.memo は props の変更のみをチェックします。React.memo でラップしているあなたのコンポーネントがその実装内で useState、useReducer や useContext フックを使っている場合、state やコンテクストの変化に応じた再レンダーは発生します。
デフォルトでは props オブジェクト内の複雑なオブジェクトは浅い比較のみが行われます。比較を制御したい場合は 2 番目の引数でカスタム比較関数を指定できます。
これはパフォーマンス最適化のためだけの方法です。バグを引き起こす可能性があるため、レンダーを「抑止する」ために使用しないでください。

>引用:[React の最上位 API](https://ja.reactjs.org/docs/react-api.html#reactmemo)

簡単にまとめるとReact.memoはpropsの変更のみをチェックしてパフォーマンスを最適化するための方法ということになります。


## 2. React.memo実装前

![画面収録-2021-12-28-17.52.46.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481470/50c9356f-274e-71f7-b2c4-d63176dfc4b6.gif)


```tsx:親コンポーネント
import { useState } from 'react';
import { ReactmemoChild } from './ReactmemoChild';

export const Reactmemo = () => {
  const [open, setOpen] = useState(false);

  const [notOpen, setNotOpen] = useState(false);
  const onClickButton1 = () => setOpen(!open);
  const onClickButton2 = () => setNotOpen(!notOpen);

  return (
    <div style={{ textAlign: 'center' }}>
      <button onClick={onClickButton1}>Childを表示</button>
      <button onClick={onClickButton2}>Childとは関係ない</button>
      <ReactmemoChild open={open} />
    </div>
  );
};

```


```tsx:子コンポーネント
import { VFC } from 'react';

type Props = {
  open: boolean;
};

export const ReactmemoChild: VFC<Props> = ({ open }) => {
  console.log('再レンダリング!!!');
  return <>{open && <p>child</p>}</>;
};

```

## 3. React.memo実装後


![画面収録-2021-12-28-17.21.48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481470/c4a4c75c-4bbe-71f4-fc01-c9ebc229eff3.gif)

```tsx:子コンポーネント
import { memo, VFC } from 'react';

type Props = {
  open?: boolean;
};

export const ReactmemoChild: VFC<Props> = memo(({ open }) => {
  console.log('再レンダリング!!!');
  return <>{open && <p>child</p>}</>;
});
```
※親コンポーネントは一緒のため省略


## まとめ
今回は子コンポーネントのpropsに変更があった時のみ際レンダリングするようにReact.memoを使用しました。

次回は**メモ化（Memoization）という概念**を深掘ってReact.memoの仕組みを深めたいと思います。
フォトリフレクタをラズパイで使ってみた

Arduinoでフォトリフレクタを扱う記事は、ネットよくに載っています。今回はラズパイでやってみました。まとめておきます。

#フォトリフレクタについて
赤外線LEDとフォトトランジスタが1つになったものです。
黒いものは赤外線を吸収します。しかし白いものは反射するので、それがベース電流となって電流が流れます。
回転速度やライントレースなどに使われています。
#動作環境
Raspberry Pi 4 Model B
Python3.7.3

#準備するもの
- フォトリフレクタ<br>
[LBR-127HLD](https://akizukidenshi.com/catalog/g/gP-04500/) や [TPR-105](https://akizukidenshi.com/catalog/g/gI-03812/)が有名です。
- 抵抗 ( 220Ωと1kΩ )
- ブレッドボード
- ジャンパ線

#配線
型番ごとに、それぞれのピンの役割が違います。データシートを見ながら行ってください。<br>
1. 5V (GPIO2,4番) からアノードとコレクタへ繋ぐ
2. カソードから220Ω抵抗を入れて、GND (GPIO6,9番など)へ接続
3. エミッタから1kΩ抵抗を入れて、GPIO11番へ繋ぐ

![スクリーンショット 2021-12-28 17.48.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549741/2ff39189-92c4-eb34-b51e-47fe4b125dc5.png)


#プログラム
白い紙や指を近づけると、値が"1"に変化する内容です。

```python:photo.py
import RPi.GPIO as GPIO
import time

pin = 11 #GPIOのピン番号は、変更可

GPIO.setmode(GPIO.BCM)
GPIO.setup(PNO, GPIO.IN)

while True:
    try:
        print(GPIO.input(PNO)) #センサーの値を出力
        time.sleep(0.8) #0.8秒間隔で
    except KeyboardInterrupt:
        pass

GPIO.cleanup()
```

#注意点
製品ごとに異なりますが、フォトリフレクタと検出物(白い紙など)との距離がかなり近くないと精度は良くありません。使ってみて、屋外など他の光に影響されない場所での方が安定する気がしました。
【Automation Anywhere】デバイスを接続する　- はじめてのAA

#はじめに

Automation Anywhere の [Automation360](https://qiita.com/IQ_Bocchi/items/e5c95bd74cae45d1c586) で作ったBotを動かすためには、「デバイスの接続」という作業が必要になります。

この記事では、実際にデバイスを接続する方法を説明します。

#デバイス接続の手順

[Automation360](https://qiita.com/IQ_Bocchi/items/e5c95bd74cae45d1c586)にログインし、以下の手順で操作を行います。

## Step1. デバイスの資格情報を設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8f101a0f-b7f1-de42-019c-4a45b84ad7c4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/a4c40fa5-581a-d7fe-c9d2-d7a09486384b.png)

**【注意！】以下の⑤の手順で、入力内容を間違える人がかなり多いです！**
**[こちらの手順](https://qiita.com/IQ_Bocchi/items/0b75e2e3aabc74c5084b) を参考に、「コンピューター名&yen;ユーザー名」を入力してください。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/95d5426b-c4e2-a9ac-9f06-bbf6307ef2b9.png)

## Step2. Bot Agent をインストールする

Step1で起動した画面から、以下の手順で Bot Agent をインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f6fa3739-a279-aa01-022f-9e6dd58d75c1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f4bdb4f8-cc1c-1b49-49d6-c73f37b0ee5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/a647ab01-0318-dc9b-a7d4-43a152e2ead7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/56e8fb94-6548-f543-12a5-eb0fb2ce5c91.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/2c419199-52dc-64d3-14fd-9d376737b059.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/11f384de-eed0-1b30-4813-44a6122cb33d.png)

## Step3. Chrome の拡張機能を有効化する

Step2 が完了すると、以下の画面がポップアップされ、Chromeの拡張機能を有効化するよう促されます。

下記の手順に従って、拡張機能を有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/3e3583a4-f723-4bc8-adf4-59906f77e57b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/48893655-bcb7-5f66-ee08-83e2a981b2ee.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/09fe6b45-0e61-aa34-c574-c4a69bbd34bd.png)

## Step4. 結果の確認

Step3までの手順が完了すると、画面上のステータスやアイコンが次のように変わります。
（反映までに数秒かかる場合があります）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/0fceb3ff-a1b1-f783-f9fd-829aade1add2.png)

上記のとおりになっていれば、デバイスの接続は完了です。おつかれさまでした！

## うまくいかないときは

デバイス接続がうまくいかない場合は、こちらの記事も確認してみてください。

https://qiita.com/IQ_Bocchi/items/911c1c46133d57446a85

# 次のステップ

デバイスが接続できたら、さっそくBotを作って動かしてみましょう！

最初のBotを動かすための手順ページは、現在準備中です。完成次第、リンクを貼ります。


#最後に

この記事は、「はじめてのAA」シリーズからリンクされています。

Automation Anywhere を初めて使っている方は、ぜひ以下のリンクもチェックしてみてください。

https://qiita.com/IQ_Bocchi/items/8d28f12256037b5f9058
Learn What’s New for App Builders in Winter ’22(App Builder資格更新)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/c94876c2-84ca-975a-44e2-4ad8d40419fd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/ccb68932-41ce-7446-1049-03ffa5de5f56.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/54b784db-0c8c-f8d6-ad88-075d5d6e94f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/d6223b3e-d8f2-fd4d-ad52-0de2e9097551.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/82d12681-f95f-830b-d3db-bdb59879ed36.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/29e5652f-a5e1-699a-22bc-d638fcc5987f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/3823e399-16b3-7fe8-89bf-db47e394b40f.png)
【Java】StreamAPIと拡張for文の違い・使い分け

現在、参画しているプロジェクトではjavaを用いて開発しています。
その際、StreamAPIと拡張for文を使う場面が多く、それぞれの違いや、場面によっての使い分けを例をあげてまとめてみました。

#Stream API とは
Stream APIとはJava SE 8から追加されたイテレーションの拡張APIです。
ListなどのCollectionを扱う為のもので、値の集計やデータを使った処理などが出来る便利なAPIです。

**基本的な流れ**
1. コレクションからstreamを取得
2. streamに対して「中間操作」を実行
3. 「終端操作」で変換したコレクションの中身に対して処理を適用

###中間操作の例
|   メソッド  | 内容                          |
|:-----------|:------------------------------|
|filter()    | ( )内の式がtrueの要素だけを集める| 
|map()       | 要素を変換                     | 
|distinct()  | ストリーム内の重複要素を削除    | 
|sorted()    |Comparableの実装クラスに対する、自然順序でのソート| 


###終端操作の例
|   メソッド  |戻り値型   | 内容                          |
|:-----------|:----------|:------------------------------|
|forEach(Consumer action)| void|各要素に対してactionを実行。順序を保証しない| 
|collect(Supplier factory, BiConsumer acc, BiConsumer combiner) |結果コンテナ|factoryで生成した可変コンテナに対し、accで要素を追加し、combinerで各コンテナを結合| 
|count()    | long    |ストリーム内の重複要素を削除| 
|findFirst()|Optional|最初の要素を返す。順番を保持しないストリームでは任意の要素を返却| 
|findAny()  |Optional|	任意の要素を返却| 
※`collect`の一例として、中間操作された要素をリストにして返す`collect(Collectors.toList())`などがある。


#StreamAPIと拡張for文を使った例
**サンプル：「name(名前)とage(年齢)をフィールドに持つPersonクラス」**

```java:Person.java
public class Person {
  private String  name;
  private int     age;

  public String  getName()  { return this.name; }
  public int     getAge()   { return this.age; }

  /* コンストラクタやsetterは省略 */
```

**■Personクラスのリストから年齢が20歳以上の人の、名前のリストを返却するメソッドを各構文で比較**

●拡張for文を使用

```java
  public List<String> getAdultPersonNameList(List<Person> personList) {
    List<String> adultPersonNameList = new ArrayList<>();
    for (Person person : personList) {
      if (person.getAge() >= 20) {
       adultPersonNameList.add(person.getName());
      }
    }
    return adultPersonNameList;
  }
```

●StreamAPIを使用

```java
 public List<String> getAdultPersonNameList(List<Person> personList) {
    return personList.stream() // streamの取得
                     .filter(person -> person.getAge() >= 20) // 中間操作(filter)
                     .map(Person::getName) // 中間操作(map)
                     .collect(Collectors.toList()); //終端操作(collect)
  }
```

拡張for文を使用するパターンでは「20歳以上の人であればリストに追加」という構造になっています。
StreamAPIを使用するパターンでは「20歳以上の人を集める」→「集めた要素をそれぞれの名前に変換」→「リストにして返却」という構造になっています。

StreamAPIを使用することで可読性が上がるほか、部品性やコードの抽象度も高まっています。
また、中間操作は繋げて書くことができるため、より複雑な操作を行う際に、さらにその効果は発揮されそうです。



#StreamAPIが使えないパターン
Streamが使えないパターンというのも残念ながら存在しています。
Streamの処理は一般的なforループとは違って、continueやbreak、returnなどで一部の処理をスキップしたり途中で処理を止めることができません。基本的にStreamは全要素に対して処理をすることを前提にして設計されたからです。
使えないパターンではfor文で処理しましょう。

実際のパターンは以下の通りです。

###●複数の変数をまとめて扱いたい場合
1つのCollectionを扱うStreamはこの操作が苦手です。
複数の変数をStreamで扱おうとしてデータを作成するぐらいなら素直にfor文で処理させた方が良いことも多いです。
現在、私が参画しているプロジェクトでもこの場面は非常に多いです。


###●CollectionにIndexが欲しい場合
残念ながらJavaにおいて、Stream操作内でIndexを付与して処理されることは出来ません。
ランキング処理のような順位を付けたい場合など、Indexを付与したい場面ではfor文で処理しましょう。


###●検査例外を扱いたい場合
StreamというよりはJavaのラムダ式の制限になります。
ラムダ内で発生した検査例外についてはラムダ内部で処理する必要があります。
catchして無理矢理どうにかするという方式をとれば使えなくないのですが、あまりクールではありません。
以下の記事が分かりやすいので、気になる方は見てみてください。
[[Java] Streamと例外処理は相性が悪いという話](https://www.maytry.net/java-cant-use-stream-easily/)
SAP ABAP初心者の便利と感じた機能のメモ

SAP、ABAPを1ヶ月触り、便利と感じた機能の使い方を含めたメモ

# RS_ABAP_SOURCE_SCAN
SAP SE38内に存在する汎用プログラムで、内部に実装されているプログラム内から
任意のソースコードと一致するものや条件に満たすプログラム検索できる機能です。

##### 検索ソースコード
SE38でRS_ABAP_SOURCE_SCANを直接実行し、
検索したいソースコードを入力して実行を押すだけで調べてくれます。
とは言っても無数のプログラムから検索するので時間がかかってしまいますので
そのために存在するのが検索条件です。
#####プログラム名
基本的に作成したアドオンプログラムが検索することが多いと思いますから
Zから始まるプログラム「Z*」で網羅出来ます。
#####プログラムタイプ
実行可能プログラム、インクルード等の指定が行えます。

# ABAP ON/ABAP OFF
```abap
IF CHEK1 = ABAP_ON.
* CHEK1のチェックボックスが入力されている
ENDIF.
IF CHEK2 = ABAP_OFF.
* CHEK2のチェックボックスが空である
ENDIF.
```
例えばチェックボックスを使用したプログラムの際、
チェックが入っているかいないかを実行時に取得する入力値で判断します
判断基準は同値を＝で置くか、あらかじめ変数に格納して使用する方法等です。
ですがABAPでは既にグローバル変数として存在していますので、
そのまま使う方が不要な文を書かなくて済みます。

###余談
#####SAPに関する話
今回の使用ツール:SAP S/4HANA
複合ツールであり、内部にDBとしてSAP HANAを保持している。
保持しているデータをファイルとして出力する機能があり、
ソースコードやDBテーブルを外部ファイル化して確認することが出来る。
ツール内部でも可能だが使用目的等で分けて使用すると良いかもしれない。
Python#1_入出力とデータ型


#Python入門その１
###Pythonとは
・インタプリタ型言語。
プログラミングにはインタプリタ型とコンパイル型がある。
インタプリタ型は、書かれたコードを逐次解釈しながら実行する言語。
一方、コンパイル型は一旦ソースコードをコンパイルして実行する。
コンパイルとは、例えばC言語で書かれた人間が理解できる文字を、10010110...のように機械が理解できるモノに変換すること。

今は、
インタプリタ->プログラムの開発がやりやすいが、実行速度が遅い
コンパイラ->開発に手間がかかるが、実行速度が速い
程度に覚えておけばOK
インタプリタ型言語：pythonなど
コンパイル型言語:Cなど

Instagramなどの開発に使われている。
本来、多くのイベントを同時に処理するアプリケーションの開発には不向きなはずだが、その開発速度の速さが好まれて使われている。

あと、pythonはライブラリが多くて、とにかくいろいろなことができます。


##実際に書いてみよう
まずは
１VSCodeを開く
↓
２ファイルを作成し名前を`HelloWorld.py`にする
↓
３以下のコードをかく

```php
print('HelloWorld')
```

↓
４上タブにある`RUN`→`Run Without Debbuging`を押す

おそらくこれで下の方にターミナルが出現し、実行できたはずです。


***Unity（C#)と違うところは、文末の;がいらないところです。***


###動的な型付け
pythonの大きな機能の一つが「動的な型付けです」。
まずは書いてみましょう。

```php
message = "Good morning"
num = 85
pi = 3.141592

print(message)
print(num)
print(pi)
```

これで実行してみましょう。こうなるはずです。

```
Good morning
85
3.141592
```

***unityでこれをやるとエラーが起きます。
なぜなら、変数の型を宣言してあげていないからです***

じゃあ次を続けて実行してみましょう

```php
print(type(message))
print(type(num))
print(type(pi))
```

こうなるはずです

```php
#`type(変数)`でその変数の型を出してくれる。
#あ、ちなみにpythonのコメントアウトは//ではなく#です。
<type 'str'>
<type 'int'>
<type 'float'>
```

誰も何も言っていないのに、勝手に型を決めてくれています。
***これが動的な型付け***です。便利ですね。

>ex1-1
・自分の名前を表示してみよう。


###四則演算###
四則演算とは、足し算とか、引き算とか、掛け算とか、割り算のことです。
***これはunityと全く一緒です***
+ -> 足し算
- -> 引き算
* -> 掛け算
/ -> 割り算
演算子はまた今度やります。次を実行してみましょう。

```php
a = 10
b = 20
print(a+b)
print(b-a)
print(a*b)
print(b/a)
```
次のようになるはずです.

```
30
10
200
2
```

>ex1-2
・一日は何秒なのか、pythonを書いて求めてみましょう。
・1,296,000秒は何日でしょうか

###データ型
pythonには、複数のデータを一括で管理するための***データ型***というものが存在します。
データ型、とかリスト、とか聞くと難しく聞こえてしまいますが、unity(c#)でいうところの***配列***です。（ただし厳密には違う).

pythonには、データ型として、
・リスト
・タプル
・辞書
・集合
の４種類があります。
今回はリスト(以下list)を見ていきます。
実際に見るのが早いので↓を見てください。

```php
a = []
b = [2,5,62,1]
c = [5,232,'Bob']
```

このように、listは好きな型を格納できます。入れた順に、0番目、1番目、2番目,,と順序が割り振られます。
list内の値は変更したり、後から追加したりすることができます。一番便利なので、もっともよく使われます。

また、異なる型の値を入れることができます。
例えば、cは整数型と文字型が入っています。
では、次を書いてみましょう

```php
mylist = ["tom","john","bob","kenji"]
print(mylist[1])
```

この場合、誰が出力されるでしょうか？
答えはjohnです。
list名[番号]というのは、そのlistに入れられている値を指します。mylist[1]なので、mylistの一番目であるjohnが出力されます。
書き忘れていましたが、listは0からカウントされます。
こういうのを***zero-based index***とか言います。

また、次のような代入方法も可能です。

```php
mylist = [0,1,2,3]
mylist[0] = "tom"
mylist[1] = "john"
mylist[2] = "bob"
mylist[3] = "kenji"
```

ちなみに、listにはいろいろな機能があります。
さすがに、僕も全部は覚えていません。下のを参考にしてみましょう。
>[リストの使い方](https://atmarkit.itmedia.co.jp/ait/articles/2012/25/news023.html)

例えば、0~9までの数字が入ったリストを作って、偶数だけ出力してみます。

```php
mylist = list(range(10))
s = mylist[0:10:2]
print(s)
```

```php
[0, 2, 4, 6, 8]
```

このように、listに数字を加えたり、一定の数だけ取り出したり、消したりする機能があります。
上のサイトを参考に次の問題達をやってみてください。

>ex1-3
・まずは0~9のリストを作ってみましょう
・その中で５番目のみ消してください。
・そのlistの末尾に消えてしまった数字を挿入してください。
・listの先頭に95を挿入してみましょう。
・その要素を昇順にソートしてください。ソートとは並び替えるという意味で、昇順というのはだんだん大きくなるということです。


データ型には、他にもタプルやDictionaryなどがあります。
例えば、タプルは、値が変更できないなどの特徴があります。listは変更できます。
その他をここで学ぶと非常にややこしいことになるので、また今度。


##参考
[https://developer.rhino3d.com/guides/rhinopython/]
Windows・Jupyter・pytorchでGPUを使う

# 結局何が必要なのよ
必要なもの

+ cuda

色々調べて結局これがあれば良いというわけでした

# cudaのダウンロード

こちらの[ダウンロード先](https://developer.nvidia.com/cuda-downloads)にてcudaをダウンロードする


# ターミナルにてcudaインストール
Jupyterを開いてターミナルでcudaをインストールする。
ターミナルに入力するコマンドは[pytorch公式サイト](https://pytorch.org/)にて自分の対応する環境にあったコマンドが得られる。

自分の場合はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340152/765b5236-c1db-48f0-b3ee-4542894fa089.png)

ターミナルに入力して何もエラーが出なければJupyter・PytorchでGPUが使えるようになっているはず。

# 確認

```ruby:python
import torch
print(torch.cuda.is_available())
```
これでTrueとなっていればよい

```ruby:実行結果
True
```
GPUが何個使用できるか

```ruby:python
print(torch.cuda.device_count())
```

一応GPUの名前を確認

```ruby:python
print(torch.cuda.get_device_name(0))
```

```実行結果
'NVIDIA GeForce RTX 3080 Laptop GPU'
```

# タスクマネージャー
タスクマネージャーを確認すると
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340152/129ec01d-46a1-a11f-be38-d40351652355.png">
デフォルトのままだと見れないのでcudaに変更
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340152/ded5086b-5dea-fe90-9fee-c409acd4becd.png">
きちんとGPUが使われていることが確認できた
【Homebrew】インストール方法と便利なコマンドまとめ

# はじめに
プログラミング学習を進めているうちにMac環境ではHomebrewを使って環境構築している方が多いと知り、早速インストールしました。
Homebrewを聞いたことはあるけどまだインストールしていない方や、インストールしたばかりで基本コマンドを知らない方の参考になればと思い、本記事を書きました。

## インストールした環境
ハードウェア ：MacBook Pro(13インチ、2020年 Intelモデル)
OS：macOS Big Sur Version11.4
Shell：zsh

# Homebrewとは？
macOSのためのパッケージ管理ツールです。
Homebrewなどのパッケージ管理ツールを使う利点としては、

- ターミナル上からコマンドラインで実行できるため、楽にアプリケーションをインストール/アップデートできる
- パッケージ間の依存関係を自動で解消してくれる
- インストールしたアプリケーションを一元管理できる

などがあります。注意点としてHomebrewが管理していないアプリケーションについては、ホームページから直接ダウンロード/インストールする必要があります。

# インストール方法
下記のHomebrewホームページに記載されているコマンドラインをターミナル上で実行。
https://brew.sh/index_ja
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428148/c1996438-144d-96d0-c64b-4aed82942d6d.png)
実行後にパスワードが聞かれるので、PCにログインする際に使用しているパスワードを入力してEnterを押して下さい。
※ここで入力するパスワードはターミナル上に表示されませんが、入力はされています。

```:zsh
Press RETURN to continue or any other key to abort:
```

と表示されるのでEnterキーを押して続行して下さい。しばらく経ってから

```:zsh
Installation successful!
```

上記が表示されれば、インストールが完了です。

```:zsh
brew -v
```
上記コードを実行して、Homebrewのバージョンが表示されれば無事にインストールされています。

# 便利なコマンド
## brew install(uninstall) package-name
パッケージのインストール（アンインストール）を実行

## brew update
Homebrewを更新する

## brew upgrade
パッケージを全て更新する。
brew upgrade package-name
のようにupgradeの後にパッケージ名を入れると、そのパッケージのみ更新する

## brew list
Homebrewでインストールしたパッケージ一覧を表示

## brew doctor
Homebrew上で問題が起きていないか確認する

## brew info package-name
Homebrewでインストールしたパッケージのバージョンを調べる

# おわりに
今回がQiita初投稿で、不安もありましたが何とか書き終えることができました。「数日前の自分に教える」つもりで分かりやすく書いたつもりですが、不備やアドバイス、その他何でもコメントをいただけると嬉しいです！

# 参考記事
以下の記事を参考にさせていただきました。

- [homebrewとは何者か。仕組みについて調べてみた](https://qiita.com/omega999/items/6f65217b81ad3fffe7e6)
- [MySQLの開発環境を用意しよう（macOS）](https://prog-8.com/docs/mysql-env)※「2. Homebrewのインストール」まで
- [【完全版】Homebrewとはなんぞや](https://zenn.dev/sawao/articles/e7e90d43f2c7f9)
- [Homebrewのインストール](https://qiita.com/zaburo/items/29fe23c1ceb6056109fd)
【AWS】S3からアクセス拒否されてElastic Beanstalkのデプロイが失敗する

## 何が起こった？
Elastic Beanstalk(以下EB)のプラットフォームを[Linux 2ベースへアップグレードするためにGreen環境を用意](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.migration-al.html)し、ローカルから`eb deploy`を行ったところデプロイが反映されないという事象が発生しました。
EC2インスタンスに出力されるログを確認したところ、デプロイ途中で**S3へのアクセスが拒否**されてデプロイが失敗していることがわかりました。

```/var/log/eb-engine.log
2021/10/29 15:51:57.334639 [ERROR] failed to populate deployment meta data with error failed to generate App version manifest file with error AccessDenied: Access Denied
status code: 403, request id: XXXXXXXXXX, host id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

もとのAmazon Linux AMIベースのプラットフォーム(Green環境)では問題なくデプロイが行えており、またEB経由でアタッチしているインスタンスプロファイルにもS3へのアクセスを許可している状態のためすぐには原因がわかりませんでした。

## 原因は？
**🚨 ECインスタンスのrootユーザーにAWS認証情報ファイルを設定していたため🚨**

上記のようにすぐには原因がわからず[クラスメソッドメンバーズ技術サポート](https://classmethod.jp/services/members/aws-support/)経由でAWSサポートに問い合わせたところ、以下の回答が来ました。
>インスタンスの root ユーザーに認証情報ファイルが作成されておりますと、デプロイ時にもこの認証情報が使用されます。

自分の環境では以下のように設定ファイル (.ebextensions)を使用して、aws cliを設定するノリでEC2インスタンスに.aws/credentialsに認証情報ファイルを設定していました。

```
echo "[default]" > ~/.aws/credentials
/opt/elasticbeanstalk/bin/get-config environment -k IAM_ACCESS_KEY_ID | xargs -I ACCESS_KEY
echo "aws_access_key_id = ACCESS_KEY" >> ~/.aws/credentials
/opt/elasticbeanstalk/bin/get-config environment -k IAM_SECRET_ACCESS_KEY | xargs -I SEC_KEY
echo "aws_secret_access_key = SEC_KEY" >> ~/.aws/credentials
```

実際にこちらのIAM権限ではS3アクセス権限がなかったため、認証情報ファイルをインスタンスから取り除いたところ`eb deploy`が成功するようになりました！！

## まとめ
インスタンスからAWSリソースの操作する場合は

- **インスタンスに認証情報ファイルに置かない**
- **EB経由でアタッチするインスタンスプロファイルを利用する**