OmniAICreator/Qiita-1.07M huggingface dataset:
Lambda Layersの設定　Layer設定するだけでrequestsが使える

lambdaで必要なライブラリはzipであげないといけないんですが...
### 皆んながよく使うやつは、Layerってとこに設定すればよいんです

で、有志でこんなもが。
https://api.klayers.cloud//api/v2/p3.8/layers/latest/ap-northeast-1/html
https://api.klayers.cloud//api/v2/p3.9/layers/latest/ap-northeast-1/html

https://github.com/keithrozario/Klayers#list-of-arns
### このARNをLayerに設定するだけ、すてき！

# requestsの設定の仕方
コード　の下

コードソース
↓
コードのプロパティ
↓
ランタイム設定
↓
レイヤー
の右「レイヤーの追加」

1. レイヤーソース > 「ARNを指定」を選択
2. ARNを指定のテキストフィールドに
3. ここから入れたいものをさがして、そのarn欄をコピペ
https://api.klayers.cloud//api/v2/p3.8/layers/latest/ap-northeast-1/html
https://api.klayers.cloud//api/v2/p3.9/layers/latest/ap-northeast-1/html
今回は「requests」の latest　の arn
![スクリーンショット 2022-06-24 11.33.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/8a2d363d-5f9b-ce69-db37-c18a03975f59.png)
4. 「保存」

で設定完了！！
![スクリーンショット 2022-06-24 11.40.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/da60ec3f-ecfa-da06-9eab-4155c4ec4986.png)
Python-SPIKE プライムで非同期処理

今回はLEGO SPIKEPrimeのPython環境でマルチタスク(非同期処理)を実装してみたので備忘録として残す。  

SPIKE アプリケーション内のPythonエディターでコーディングしていくのだが、アプリケーション内のナレッジベースにはSPIKEPrimeを制御するために使うことができるメソッドについての解説は網羅されているが、MicroPythonから提供されているライブラリに関する情報はほとんど掲載されていないため、MicroPython環境で利用できそうな非同期処理用のライブラリを検索した。(かつpipなどによるインストールが不要なものである必要がある)  


<img width="400" alt="00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/9a8af070-3bd9-726a-5171-0912cd2860cc.png">


## 機体  
今回のソースコードを動かすために用意した機体は以下のような簡易的なもの。
画像では車型になっているが、ここではフォースセンサーと距離センサーが使えればいいのでそれら２つが固定されていれば問題ない。
<img width="400" alt="02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/1237c905-f828-1160-6851-8758eef8978e.jpeg">


## 非同期処理について
今回非同期処理のために`uasyncio`というライブラリを利用した。
公式のドキュメントは[こちら](https://micropython-docs-ja.readthedocs.io/ja/latest/library/uasyncio.html)から確認できる。

また、参考にした記事は[こちら](https://qiita.com/KChai/items/37c6e7ad02b8a21c02cf)

## ソースコード
以下が今回実装したソースコード。
フォースセンサーが押されたかどうかと、距離センサーが10cm以内に物体を検知したかどうかを同時に監視している。

<img width="400" alt="01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/02c047d3-5ed8-261b-550b-58a46836acc6.png">

~~~
from spike import PrimeHub, LightMatrix, Button, StatusLight, ForceSensor, MotionSensor, Speaker, ColorSensor, App, DistanceSensor, Motor, MotorPair
from spike.control import wait_for_seconds, wait_until, Timer
from math import *
import uasyncio


hub = PrimeHub()

f_sensor = ForceSensor('A')
d_sensor= DistanceSensor('D')

async def touch():
    if f_sensor.is_pressed():
        hub.light_matrix.show_image('HAPPY')
        print('touched')

async def dis():
    distance = d_sensor.get_distance_cm()
    if distance == None:
        distance = 200
    elif distance < 10:
        hub.light_matrix.show_image('SMILE')
        print('detected')

async def main():
    hub.light_matrix.show_image('ANGRY')
    uasyncio.create_task(touch())
    uasyncio.create_task(dis())
    await uasyncio.sleep(0.2)

while True:
    uasyncio.run(main())

~~~

## 実行結果
プログラムを実行すると、ライトマトリクスが`ANGRY`の表示になり、フォースセンサーの監視をするタスクと距離センサーの監視をするタスクが非同期で動いている状態になる。
<img width="400" alt="03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/37ff87c4-d3b1-75d7-39ad-a251fc7acc8c.jpeg">

非同期処理なので、フォースセンサーと距離センサーのどちらに関するアクションを行っても問題ないが、フォースセンサーを押すとライトマトリクスの表示が`HAPPY`に変わる。
<img width="400" alt="04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/7ce3b62d-67a3-4aa8-369c-3227066917a4.jpeg">

距離センサーに手をかざすなどして10cm以内の検知を行わせると、ライトマトリクスの表示が`SMILE`に変わる。
<img width="400" alt="05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/126a11f6-8ab2-f33f-2996-f1fb681912ec.jpeg">

SPIKEのPython環境では`uasyncio`が問題なく利用できることがわかった。
先頭の文字を判定して必要に応じて削除する方法（JavaScript/Vue）

javaScriptで先頭の文字を判定して、それが特定の文字の場合削除する方法です。

例えばAPIから送られてくる値が
```userName: ",山田,鈴木,吉村"```
だとします。

この値をそのまま画面上に表示してしまうと先頭にカンマが表示されてしまい、よろしくありません。
画面表示の際に先頭のカンマを削除して表示するのが好ましいです。
それを実現するためにはstartsWith()メソッドとslice()メソッドを用います。

# 方法
まず、先頭の文字がカンマかどうかの判定を行います。
いきなり先頭の文字を削除せず。一度判定を挟むのはAPIの仕様が変わり先頭にカンマが入らなくなった場合に山田の山を削除してしまうことになるからです。
先頭の文字がカンマであるかの判定はstartsWith() メソッドを用います。

startsWith() メソッドは文字列が引数で指定された文字列で始まるかを判定して true か false を返します。
startsWith() メソッドがfalse、つまり先頭の文字がカンマでない場合はそのまま表示、startsWith() メソッドがtrueの場合、つまり先頭がカンマの場合は先頭の文字列を削除して表示する　という処理を行います。
文字を削除するという処理はslice()メソッドを用います。


vue で記述すると下記のようになります。
```
<div v-if="this.userName.startsWith(',')">{{ this.userName.slice(1) }}</div>
<div v-else>{{ this.userName }}</div>
```

上記の処理で　
```山田,鈴木,吉村```
という表示がされるようになります。
　
# 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
Lambda 最初に呼ばれる関数 ハンドラの設定

コード　の下

コードソース
↓
コードのプロパティ
↓
ランタイム設定
の中の　ハンドラ
右の「編集」から

[ファイル名].[関数名]
![スクリーンショット 2022-06-24 11.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/a4a001de-546f-a033-f725-f9c03c12c75b.png)
PV実装する際に使えるサイト

★簡潔でわかりやすいです！

https://qiita.com/ryouzi/items/727063547da2432beda9

★少しだけ実装を多くしたパターンのやつでした！わかりやすいです！

https://qiita.com/ryo___eng/items/a525f80398210d0486b7
Data & AIサミットで発表されるDatabricksノートブックの新機能

[Join Us for Updates to Databricks Notebooks at Data and AI Summit 2022 \- The Databricks Blog](https://databricks.com/blog/2022/06/23/whats-new-with-databricks-notebooks-at-the-data-ai-summit.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Databricksにおいては、データから洞察に至る道のりを加速するために、開発体験を継続的に進化させ続けています。本日、6/27-30に開催されるData + AIサミット([登録はこちらから！](https://databricks.com/jp/dataaisummit/))に先立ちDatabricksノートブックの更なる改善を発表できることを嬉しく思っています。SQLとPython間のディープな連携、簡素化された計算処理、Jupyterエコシステムの取り込み、新たなローコードのデータ探索ツール、監査ログによるトラッキングへの容易なアクセスなど、どのように[我々が開発体験を改善しているのか](https://databricks.com/it/dataaisummit/session/databricks-notebook-front-door-lakehouse)を見るために是非サミットに参加してください。

# ノートブックにインテグレーションされた計算資源管理

皆様が適切なリソースを検索するのに要する時間を削減し作業自体に時間を費やせるように設計することで、我々は計算資源を選択するノートブックのUIを徹底的に再構築しました。最近使った計算資源をすぐに利用することができ、新たなリソースを必要とした場合には、ノートブックの画面を去ることなしに数クリックでクラスターを作成することができます。
![](https://databricks.com/wp-content/uploads/2022/06/db-238-blog-img-1.png)
*お手軽に計算資源を作成できることで、自身のタスクにフォーカスできます*

# PythonからSQLの結果に容易にアクセス

PythonとSQLはDatabricksノートブックにおいて最も人気のある2つの言語となっており、多くの場合ユーザーはPythonで詳細分析を行う前にSQLでデータをロードします。今では、Pythonノートブック上のSQLセルの結果を探索するのにPythonを使うことができます。手動で二つの言語間で変換を行うことなしに、PythonデータフレームとしてSQLセルの結果を取得することができます。
![](https://databricks.com/wp-content/uploads/2022/06/db-238-blog-img-2.png)
*SQLの結果をは自動でPythonデータフレームに変換され、追加のコードを書く必要がなくなります*

# PythonノートブックへのIpywidgetの導入

IPythonカーネル上でのipywidgetのサポート(現在パブリックプレビュー)によって、ノートブック上で30以上の様々なUIエレメントと豊富なコントロールとインタラクションできるようになります。これによって、DatabricksノートブックにJupyterエコシステムのパワーをもたらすことができます。

**以下のリンクをクリックすると動画が別タブで開きます**

https://player.vimeo.com/video/723422661?h=15a739ac85&version=hd1080%E2%80%9D%20frameborder=

*お使いのノートブックに30以上のフレキシブルなウィジェットによる偉大なビジュアルとインタラクティブ性を追加*

# BamboolibによるUIベースのデータ探索

シンプルかつユーザーフレンドリーなインタフェースを用いて、データの準備、変換、可視化、探索を行えるようになります！ノートブックにインテグレーションされる拡張可能なGUIであるBamboolibを用いることで、ノーコードのデータ探索で時間を節約しつつも、結果を再現、カスタマイズするために生成されたコードにアクセスすることもできます。これによって、シチズンデータサイエンティストの方やドメイン専門家がPythonを用いて簡単にデータを操作できるようになります。

**以下のリンクをクリックすると動画が別タブで開きます**

https://player.vimeo.com/video/723422626?h=337ee8cf79&version=hd1080%E2%80%9D%20frameborder=

*ユーザーフレンドリーですがパワフルなUIを用いてローコードのデータ探索を楽しんでください*

# ノートブックセルの実行に対する監査ログによるコンプライアンスの改善

すべてのノートブックへのアクセスやユーザーによる改訂はユーザーのIDを関連づけられるので、セキュリティ管理者は容易に自分のワークスペースで行われたアクションを監査できるようになります。Databricksノートブック内の個々のセルの実行をロギングすることで透明性の確保をさらに推し進めました。これによって、管理者は誰が何を、いつ、どこで行ったのかを常に知ることができ、アクセス管理とID管理を改善します。
![](https://databricks.com/wp-content/uploads/2022/06/db-238-blog-img-3.png)
*Databricksノートブックのセル実行レベルまで追跡することで監査能力を改善します*

# より詳細は

- Data + AIサミット2022に登録ください: [https://databricks\.com/jp/dataaisummit/](https://databricks.com/jp/dataaisummit/)
- ノートブックに対する一般的な情報: https://docs.databricks.com/notebooks/index.html
- ノートブックのベストプラクティス: https://docs.databricks.com/notebooks/best-practices.html


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
PowerVS IBM i 日記(44): IBM i 7.5 利用可能

# IBM i 7.5 が PowerVS 環境でも利用可能になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/119d0c9d-c2b5-bdc2-7a11-0deb98eb7038.png)

## パスワードの変更がちょっと面倒

7.5 ではよりセキュリテイが厳しくなっています。
7.4 までに感覚で QSECOFR のパスワードを変更しようとしたら「理由コード 19」で怒られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/955159df-fc02-8bb6-5143-8b97ae117eb0.png)

文字が不十分といっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/e5563173-396a-46d4-fa0a-f15309a5eb16.png)

パスワード変更の画面から F9 でパスワードルールが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/d8d02217-c560-144d-a5a5-dece4a9b068a.png)

なるほど、15 文字以上必要なのですね。

## 無事にパスワードを変更してライセンス認証をすれば 7.5 として利用可能

無事にパスワードを変更してライセンス認証をすれば 7.5 として利用可能でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/d4aada9f-6f7d-94af-69b4-a6c1d5b4e215.png)

## 2次言語は導入されていません。導入メディア専用サーバー IBMi_COR-74-05-1 にも含まれません。

「 [ブートイメージ 言語コード 2924/2984 の区別と導入メディア専用サーバーの用意](https://qiita.com/6onoda/items/1476ee1fda758ecc67e1)」のイメージと同様に、2次言語は導入されていません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/3b0081e7-4994-82ee-40fd-a50e155ddd7d.png)

また、現在の導入メディア専用サーバー「IBMi_COR-74-05-1」には、7.5 のイメージは含まれていません。
(イメージ名が前回から変わっていないから当然ですが)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/a7267b0d-aec2-7f70-dd11-56766b6e66bc.png)

そのため、すぐに日本語環境が必要な場合は、自分でメディアイメージを転送する必要があります。

---
2022/06/24 作成

---
当日記のIndexは[こちら](https://qiita.com/6onoda/items/f146c78c0c1bbe905a42)です。

---
許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
IDSカメラをPythonで制御するためのパラメータ

諸事情でIDS ueyeカメラ（UI3250）をPythonから制御したい。
ライブ画像を表示するスクリプトは[公式](https://jp.ids-imaging.com/programming-examples-details/simple-live-image-acquisition-with-the-python-interface-pyueye.html)からダウンロードできる（ログイン必要）。
露光時間・フレームレートを調整しようとして詰まったが、下記を書き加えるとどうやら制御できた。

```Python:Python
from pyueye import ueye
import ctypes

pixel_clock = ueye.uint(30) #10-128
nRet = ueye.is_PixelClock(hCam, ueye.IS_PIXELCLOCK_CMD_SET, pixel_clock, ueye.sizeof(pixel_clock))

time_exposure = ueye.double(20) #ms
nRet = ueye.is_Exposure(hCam, ueye.IS_EXPOSURE_CMD_SET_EXPOSURE, time_exposure, ueye.sizeof(time_exposure))

targetFPS = float(10) #fps
actualFPS = ueye.double()
nRet = ueye.is_SetFrameRate(hCam, targetFPS, actualFPS)

#露光時間・フレームレートを表示
print("Exposure time:\t", time_exposure)
print("Frame rate:\t", actualFPS)
```

# 参考
- [公式ドキュメント](https://www.1stvision.com/cameras/IDS/IDS-manuals/uEye_Manual/is_setframerate.html)
- [How to use function ueye.is_IO(hCam, nCommand, pParam, SizeOfParam) pyueye library GPIO camera IDS](https://stackoverflow.com/questions/68368308/how-to-use-function-ueye-is-iohcam-ncommand-pparam-sizeofparam-pyueye-libra)
- [FSTImplementation](https://github.com/FSTDriverless/FSTImplementation/blob/master/inference.py)
- [Source code for pymanip.video.ids](https://pymanip.readthedocs.io/en/latest/_modules/pymanip/video/ids.html)

# 追記
なぜかimport ctypesを消すと制御できない？
単純にOpenCVでaviを保存すると意図したフレームレートよりもっと多くのフレームが取得されている。要検討。
SSHキーを作成！

## GitHubにSSHキーを登録しました。
SSHキー作成コード↓
`$ cd`
`$ ls -al`
`$ mkdir .ssh`
`$ cd .ssh`
`$ ssh-keygen -t rsa`
`$ pbcopy < ~/.ssh/id_rsa.pub`
ここまではSSHキーを作成する時に使用したコード

GitHubに上げるために打ったコード
`$ git init`→リポジトリを新規作成
`$ git add .`→作業ディレクトリ内の変更をステージングエリアに追加
`$ git commit -m 'コメント'`→コメントを追加
`$ git remote add origin https://github.com/[GitHubのユーザー名]/[GitHub側のリポジトリ名].git`

## 次に行ったこと→token作成（7日間）
GitHubのマイページに入り、自身のトークンを発行
pushするときに間違えてSSHをpasswordに入れていました・・・
完全にアホなことして今いたけど、トラブルシューティングや参考ページをみながらやったらできました。
## なんだかんだでここまでやったらできました。
最後に打ったコードというか・・・途中何度も打ってましたけれど、エラーの連続で最後になりました。他の方達のコマンドを見ていると
`$ git push origin main`という打っている方と
`$ git push origin master`と打っている方がいましたね。自分は後者の方を打ちましたけれど、問題なく上げることができました。



[参考にしたページその1](https://zenn.dev/oimo_revolution/articles/4c7d48907e19e5)
[参考にしたページその2](https://www.sejuku.net/plus/question/detail/15100)
[GitHubトラブルシューティング](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
git 省略

# alias設定
alias gaA='git add -A'
alias gst='git status'
alias gl='git log'
alias gcm='git commit -m'
alias gps='git push'
alias gpl='git pull'
alias gb='git branch'
alias gdf="git diff"
alias gch='git checkout'
alias gm='git merge'
alias gam='git commit -a -m'
備忘録 － Flutterで使用したパッケージ

# はじめに
<!-- 発端や概要を記載 -->
開発するうえで、色んなパッケージを使いますが、
何が何だったかこんがらがってきたのと、
知見として貯めたいと思い、この記事を執筆します。

とりあえず、パッケージ名と簡単な説明(できれば使い方）を羅列。
ある程度溜まったら、カテゴライズできればなぁという感じです。
一気にはやらず、少しずつの更新となります。

# 対象読者
・Flutter初心者
・どんなパッケージがあるか知りたい方

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [羅列](#Chapter1)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 羅列
・[go_router](https://gorouter.dev/)
  ページ遷移の複雑さを解消するパッケージ

・[sembast](https://pub.dev/packages/sembast)
NoSQL データベースで、暗号化やトランザクション、マイグレーションなどデータベースに求められる基本的な機能が提供されている。sqfliteの作者の方がAuthorで開発している。ローカルのDBについては他にもいろいろあるが、NoSQLなら`sembast`、sqliteなら`sqflite`でよさそう。
NetFlow とは

## 勉強前イメージ

流量とか見る感じはしてる・・・
そういうアプリケーション？

## 調査

### NetFlow とは

NetFlowはCisco独自のプロトコルで
ネットワーク機器を通過する通信のネットワーク、セキュリティの監視やトラフィックの分析などを監視する目的で開発されました。
これらの情報はNetFlowを有効にした機器から統計情報を取得することができます。
ネットワークの負荷の把握やDoS攻撃など外部からの検知など確認することが出来ます。
フロー情報はIOSメモリ上に格納されます。
NetFlowはいくつかバージョンが有り、それによって取得できるデータも変わります。

NetFlowはCisco独自規格ですが
標準規格としてsFlowが策定されました。
仕組みはNetFlowと同様ですが、様々な製品を組み合わせて使用できます。

実際の設定ではインターフェースごとに設定でき
さらに受信パケットと送信パケットそれぞれ独自に設定することが可能です。

## 勉強後イメージ

cisco独自規格！
初めて知った・・・一回設定してみようかな

## 参考

- [NetFlow](https://e-words.jp/w/NetFlow.html)
- [NetFlow - Command](https://www.infraexpert.com/study/netflow2.html)
CICD

circleciとは


ワークフローとは
一つ一つのタスク(処理単位)を定義しているもの

 1031  vi ~/.ssh/config
 1032  ssh -T github.com
 1033  cd
 1034  cd work
 1035  git clone git@github.com:jojo232/sample-ci-raitech-live.git
 1036  ls
 1037  cd sample-ci-raitech-live
 1038  ls -l
 1039  pwd
 1040  git branch
 1041  ls -l
 1042   git pull
 1043  ls -la

コマンドノットと出た理由は、macOSにインストールされていなかったのでかきサイトからコマンドを実行したら修正できた。
zsh: command not found: circleci

https://circleci.com/docs/2.0/local-cli

git add
メモ　VisualStudio2022 Prism インストールメモ

Prismインストールしようとした時、　拡張機能からインストールを実行してVSを再起動すると
エラーが発生する。　全て無視して「新しいプロジェクトの作成」を実行すると、テンプレートの全てが消えている

違うパソコンで実施すると発生しない為、環境依存と考える

VS2022 VS2019 VS2017 を全て削除してから入れなおしたがだめだった。

VS2019ではPrismが、未対応となりインストールできない状況になった。

とりあえず、VSの状況により使えたり使えなくなったりする為、採用を控える
結局 python でパッケージ分割したプロジェクトにするにはどういうディレクトリ構成にすればいいのか

# tl;dr

https://rinatz.github.io/python-book/ch04-07-project-structures/

で普段他の言語でやってる感じのディレクトリ構成がことごとくアンチパターンになっていたし実際動かないので色々調べてどうやらこの構成ならうまくいきそうだというのの健忘です。

# 結論

```
project/
+ project/
| + __init__.py
| + __main__.py
| + module.py
| + subpackage1/
| | + __init__.py
| | + submodule1.py
| + subpackage2/
|   + __init__.py
|   + submodule2_1.py
|   + sunmodule2_2.py
+ tests/
  + __init__.py
  + test_module.py
  + test_submodule1.py
  + ...
```

## `__init__.py`

`tests` 以外のこれは全部中身を書く。

```py:project/__init__.py
from . import module
from . import subpackage1
from . import subpackage2
```

```py:poject/subpackage2/__init__.py
from . import submodule2_1
from . import submodule2_2
```

## 各モジュールからのインポートのしかた

基本的には相対インポートを使う。

### `__main__.py`

```py:__main__.py
from . import module

moduile.function()
```

テストのために `__main__.py` の中身はできるだけ簡素にしておくのが良さそう。

### `module.py`

```py:module.py
from . import subpackage1

subpackage1.submodule1.function()
```

### 隣のサブバッケージの呼び方

```py:submodule2_1
from .. import subpackage1

subpackage1.submodule1.function()
```

呼び出しの度にパッケージ名書くのが面倒ならこれでもいける

```py:submodule2_1
from ..subpackage1 import submodule1

submodule1.function()
```


### テストコード

import 元に自身のパッケージを指定する. **ただしトップレベルのモジュールが VSCode ではコード補完が効かない**。 何故かサブバッケージにはコード補完が効くのでこの構成にするならもう全部サブバッケージにいれるのがいいかもしれない。

```py:tests/test_module.py
import project

def test_module():
    assert project.module.function() == 'hoge'
```

```py:tests/test_submodule1.py
from project.subpackage1 import submodule1

def test_submodule1():
    assert submodule1.function() == 'huga'
```

## `__main__.py` 実行時

```bash
cd /path/to/project
python3 -m project
```

## テスト実行時

```bash
cd /path/to/project
pytest tests
```
現在時間を表示させる

js:
     function set2(num) {
      // 桁数が1桁だったら先頭に0を加えて2桁に調整する
      let ret;
      if (num < 10) { ret = "0" + num; }
      else { ret = num; }
      return ret;
    }
    function showClock() {
      const nowTime = new Date(); //現在日時
      const nowHour = set2(nowTime.getHours()); //時間
      const nowMin = set2(nowTime.getMinutes()); //分
      const nowSec = set2(nowTime.getSeconds()); //秒
      const msg = "現在時刻は、" + nowHour + ":" + nowMin + ":" + nowSec + " です。";
      document.getElementById("showTime").innerHTML = msg;
    }
    setInterval('showClock()', 1000);

html:
      <div id = "showTime"></div>
【Windows10】Hyper-Vを一時的に無効化する

# はじめに
Windows10のHyper-Vが有効化されている場合、他の仮想化ソフトウェアである、**VMware Workstation Player**や**Virtualbox**が利用できません。そのため、Hyper-Vを一時的に無効化する方法を記載します。
(Dockerを利用する場合は、有効化してください)

# Hyper-Vの無効化

:::note info
コマンドプロンプトまたはPowerShellを管理者として起動し、下記コマンドで変更していきます。
:::

:::note info
設定変更後は、PCの再起動をすることで、変更内容が適用されます。
:::

* **確認方法**
```java:
Microsoft Windows [Version 10.0.22621.160]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\System32>bcdedit

Windows ブート マネージャー
--------------------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  ja-JP
inherit                 {globalsettings}
flightsigning           Yes
default                 {current}
resumeobject            {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows ブート ローダー
--------------------------------
identifier              {current}
device                  partition=C:
path                    \WINDOWS\system32\winload.efi
description             Windows 11
locale                  ja-JP
inherit                 {bootloadersettings}
recoverysequence        {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
flightsigning           Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \WINDOWS
resumeobject            {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}
nx                      OptIn
bootmenupolicy          Standard
hypervisorlaunchtype    Off         ★ここの値を確認します

C:\Windows\System32>
```

* **無効化**
```java:
bcdedit /set hypervisorlaunchtype off
```

* **有効化**
```java:
bcdedit /set hypervisorlaunchtype auto
```
ProxmoxでVMをWake on LAN

## はじめに
通常Wake On Lanは物理マシンに対して行うが、ProxmoxVEの仮想マシンを今回は起こしたい。
以下の記事を見つけたのだが、そのままでは動作しないため手直しを行った。

https://forum.proxmox.com/threads/wake-on-lan-script-for-vm-on-proxmox-host.60986/

## ※追記
ProxmoxVE 7.3から公式に仮想ゲストのWakeOnLanが追加されたので、そちらを使ったほうが良いです…
https://pve.proxmox.com/wiki/Roadmap#Proxmox_VE_7.3

## Bashスクリプトの作成

Wake on Lanによって送信するMagicPacketを受信し、そのMACアドレスがVMと一致する場合にVMの起動を行う内容。VMのIDとMACアドレスを引数に取る汎用的なものにした。

修正点
* ncのオプションを実在するものに変更
* 受信ポートを指定できるように変更
* 既にVMが起動中の場合は再度起動をかけないように変更
* while readにパイプで投げ込むとncが終わらなくなるため、別の方法で渡すように変更

`/root/wol_vm.sh`

```bash
#!/bin/bash

if [ $# -ne 3 ] ; then
  echo "Usage: $0 VM_ID MAC_ADDRESS";
  exit 1
fi

PORT=$1
VM_ID=$2
MAC_ADDRESS=$3

while read ; do
  MAC=${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2};
  echo Received Address: $MAC
  if [ "$MAC" == "$MAC_ADDRESS" ] && [ ! "$(qm status $VM_ID | awk '{ print $2 }')" == "running"  ] ; then
    qm start $VM_ID
    exit
  fi
done < <(nc -v --listen --udp --port=$PORT |
  stdbuf -o0 xxd -c 6 -p |
  stdbuf -o0 uniq |
  stdbuf -o0 grep -v 'ffffffffffff')

```

![Screenshot 2022-06-24 at 08-35-20 kiyoura - Proxmox Virtual Environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65278/3e9ea6a6-60c8-c744-328f-5f4206c06439.png)
![Screenshot 2022-06-24 at 08-40-06 kiyoura - Proxmox Virtual Environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65278/5cf0e9c4-1f92-8abc-a0fb-ec9732aa3ee8.png)

VMの番号が`107`でMACアドレスが`22:e1:08:90:ec:9e`の場合、以下のように実行
Wake on Lanを投げるプログラムによって7番ポートの場合と9番ポートの場合がある。下記は9番ポートの例。

```bash
./wol_vm.sh 9 107 22:e1:08:90:ec:9e
```

スクリプトが稼働し続けるので、その状態でWake on Lanを投げる。Successfullyの表示と共にVMが自動起動する

```bash
root@hoge:~# ./wol_vm.sh 9 107 22:e1:08:90:ec:9e
nc: listening on :: 9 ...
nc: listening on 0.0.0.0 9 ...
nc: connect to 0.0.0.0 9 from 192.168.0.244 (192.168.0.244) 36711 [36711]
Received Address: 22:e1:08:90:ec:9e
GUEST HOOK: 107 pre-start
107 is starting, doing preparations.
GUEST HOOK: 107 post-start
107 started successfully.
```

## サービス化

このままでは扱いにくいため、systemdのサービスにする。
以下のファイルを作成する。

`/etc/systemd/system/wol-vm@.service`

```bash
[Unit]
Description=Wake on Lan for VM service Port %I

[Service]
Type=simple
User=root
Group=root
Restart=always
Environment="SCRIPT_ARGS=%I"
ExecStart=/root/wol_vm.sh $SCRIPT_ARGS

[Install]
WantedBy=multi-user.target
```

以下のコマンドで制御できるようになる。7番ポートと9番ポートをそれぞれ用意すると良い

```bash
# wol-vmサービスの有効化
root@hoge:~# systemctl enable wol-vm@"7 107 22:e1:08:90:ec:9e"

# wol-vmサービス開始
root@hoge:~# systemctl start wol-vm@"7 107 22:e1:08:90:ec:9e"

# wol-vmの状態確認
root@hoge:~# status wol-vm@"7 107 22:e1:08:90:ec:9e"

# wol-vmサービスの終了
root@hoge:~# stop wol-vm@"7 107 22:e1:08:90:ec:9e"
```

おわり
【第4回】HULFT8 動的配信・動的集信(Linux)

# はじめに
[前回](https://qiita.com/asds0025/items/5373ae5248964c4cb4cc)はHULFT8の暗号化配信・ファイルトリガー配信を行いました。
今回は動的配信・動的集信について解説していきます。

# 環境
* Oracle Linux 8.5
* HULFT8 Cipher OP(AES) Linux / 8.5.1

# 構成
![タイトルなし2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709815/8c1d1082-4882-7966-e858-9b61bbb707a0.png)

# 1. 動的配信設定 (配信ホストで設定)

配信ホストは、hulenv.confのdynparamを"1"にすることで有効化されます。

## 1.1 配信時の動的指定

既に有効化されていました

```java:
[root@ln01 ~]# cat $HULPATH/hulenv.conf |grep dynparam
dynparam = 1
```

# 2. 動的集信設定 (集信ホストで設定)

集信ホストは、HULFTの環境変数である"$SNDFILE"とすることで、配信されたファイル名で集信することができます。

## 2.1 集信時の動的指定

```java:
[root@ln02 Send]# utladmin
```

```java:
6.システム管理 > 2.集信管理情報 > FILE ID
```

下記画面のファイル名で、HULFT環境変数を指定します。
設定後、Enterを押下し保存して下さい。

```java:

 集信管理情報 更新                    Ctr+p：管理情報複写   ESC ：キャンセル
                                      Ctr+d：管理情報削除   TAB ：項目移動
                                      Ctr+s：次画面
 ファイルＩＤ      :  FILE1

 ファイル名        :  /opt/HULFT/Collection/$SNDFILE  ★ここで変数を設定
 オーナー名        :  root              グループ名        : root
 パーミッション    :  読 み   書 き   実 行    0:権限無し  1:権限有り
        オーナー        1       1       0
        グループ        1       1       0
        その他          1       1       0
 登録モード        :  N (N:新規作成  R:置き換え  M:追加)
 異常時の処置      :  D (D:削除      K:保存      R:復元)
 集信形態          :  S (S:単一集信  M:複数集信)
 世代管理          :  N (N:無 Y:有)  世代管理数        :
 EBCDICセット      :  0 (0:AUT A:KN B:AL C:AC D:AP E:LOW F:EX G:NEC H:KX
                         I:CNX V:U1 W:U2 X:U3)
 正常時ジョブＩＤ  :
 異常時ジョブＩＤ  :

 コメント :
```

# 3. 動的配信テスト

今回は下記でやってみようと思います。
* 配信ディレクトリ：/tmp　※どこでも可能です
* 配信ファイル：sendtest　※何でもいいです

## 3.1 動的配信

```java:
[root@ln01 ~]# touch /tmp/sendtest
[root@ln01 ~]# utlsend -f FILE1 -file /tmp/sendtest -sync
```

## 3.1 配信確認

```java:
[root@ln01 ~]# utllist -s

FILEID    HOST NAME START DAY   START TIME END TIME   RECORDS  STATUS   CONNECT
FILE1     ln02      2022/06/23  05:47:26   05:47:26          0 0000-0000   LAN
```

## 3.2集信ホストからの確認

```java:
[root@ln02 Collection]# pwd
/opt/HULFT/Collection
[root@ln02 Collection]#
[root@ln02 Collection]# ll
合計 0
-rw-rw-rw- 1 root root 0  6月 23 05:47 sendtest
[root@ln02 Collection]#
[root@ln02 Collection]# utllist -r

HOST NAME FILEID    START DAY   START TIME END TIME   RECORDS  STATUS   CONNECT
ln01      FILE1     2022/06/23  05:47:23   05:47:23          0 0000-0000   LAN
[root@ln02 Collection]#
```

配信されたsendtestというファイル名で集信してますね。

# まとめ

配信ホストの設定
・動的パラメータを有効化にする

集信ホストの設定
・HULFT環境変数を設定する

配信時
・-fでFILEIDを指定し、-fileで実際に配信するファイル名までのフルパスを指定する。(-fileを指定することで、配信ホストの配信管理情報で設定されているファイル名よりも優先されます)

# おわりに
動的集信は結構使われると思うので、覚えといて損はないですね。
今回でHULFTの解説は終了です。ありがとうございました。
Dockerとは？

## Dockerとは？
✳︎✳︎Docker(ドッカー)✳︎✳︎とは軽量なコンテナ型アプリケーション実行環境。 簡単に言うと、Dockerを利用することで、OS内部に独立したアプリケーションの実行環境(コンテナ)を生成することが出来、異なったOS環境(Macや Windows等)いつでもその環境を立ち上げることが可能になる。

### Dockerは何がいいのか？
1. コード化されたファイルを共有することで、どこでも誰でも同じ環境が作れる。
1. 作成した環境を配布しやすい。
1. スクラップ＆ビルドが容易にできる。

開発環境(Windows上)では動いていたけどLinuxで動かなかった、といったケースも、開発工程からDockerを活用していくことで防ぎやすくなる。
開発工程の中で使っていた環境をそのまま本番環境に持っていくことも可能なため、環境差分が少なく、環境による問題を減らすことができる。

作成したDockerイメージを他の人にも渡して使ってもらうことで、それぞれの環境のバージョンずれ防止や、開発環境準備の短縮化にもつながる。開発環境の準備で、無駄に丸一日かかったとなってしまうのはもったいない。私自身も、初心者だが、開発環境からDockerを使うことを心がけている。

また、クラスタ構成を構築する場合も、Dockerイメージがあれば、それを起動する名前（コンテナ名）などを変えるだけで、複数の環境（コンテナ）を起動できるので、一から手順に沿って環境を作る作業もなくなり、クラスタ構成を構築するのも容易になります。これは、コンテナを管理するオーケストレーションツールを使うことで、より運用が楽になります。

このように、Dockerを使うことで安定した開発を進めたり、リリースサイクルの改善にも役立つので、ぜひ使ってみて下さい。
メッセージをお嬢様風にしてcommitしてくれるCLIツールを作った

# ojosama-commit

始めまして。しぐまと申します。
こんなツイートを見かけました。

https://twitter.com/jiro_saburomaru/status/1538044512861585409?s=20&t=UlsquA4tbY5NdKZvFsTI1g

何か作ってみたくなりました。

ということで
今回は、Rustという言語の勉強がてら、指定した文字列をお嬢様風にしてcommitしてくれるCLIツールを作りました。
とはいうものの実際にお嬢様風に変換する処理は[jiro4989](https://github.com/jiro4989)さまの[ojosama](https://github.com/jiro4989/ojosama)というものを叩いているだけです。

### GitHub
完成品のリンクです。
https://github.com/Sigumaa/ojosama-commit

予告なしに非公開にする可能性があります。

### 使い方

#### インストール
リポジトリをクローンして、次のコマンドを実行してください。
```bash
$ cargo install --path .
```

#### コミット
```bash
$ ojo "コミットメッセージです！"
[hoge huga000] コミットメッセージですわ～～！
 ∞ file changed, ∞ insertions(+)
```

### 作るうえで大変だったこと

今回の完成品はコード自体は短いのですが、Rustでこのようなツールを作るのは初めてだったということもありところどころ詰まる箇所がありました。

APIへのリクエストはreqwestを使っています。
https://docs.rs/reqwest/latest/reqwest/
返ってきたデータをHashMapにぶち込んでいじくっています。もっと良い方法があれば教えてください。

```rust
    let res_text: HashMap<String, String> =
        serde_json::from_str(&res).expect("かえってきたデータの処理に失敗してしまいましたわ。");

    let commit_message = res_text
        .get("Result")
        .expect("メッセージを取り出すのに失敗してしまいましたわ。");
```

外部コマンドの実行にはstd::process::Commandを使用しました。
https://doc.rust-lang.org/std/process/struct.Command.html

### 最後に
簡単なプロジェクトかもしれませんが、結構勉強になり楽しかったです。
これからもRustでいろいろ作ってみたいと思いました。

**PR**お待ちしてます！
よろしくお願いします！
A4000という選択

# 0.Intro
ちょっとポエムチックになりますが。
2022/6/16に個人売買のサイトにてNVIDIA RTX A4000ポチりました。ハードに疎いのとノークレーム・ノーリターンに8万円以上出すのは大変度胸要りました。届いて取り付けた最初は画面がつかずハズレ引いたかとヒヤヒヤしましたが、何とか無事にBIOS画面が見られて、WindowsでもUbuntuでも認識してくれて、今は元気に動いてくれています。グラボって問題なくついているかどうかって画面すら見られないので大変心臓に悪いです。

# 1.Contents
僕のグラボの用途は機械学習です。ゲームは全くしません。
これまでは Geforce 2080TIを使っていました。当初は全く以て不満はなかったのですがあれこれやり出すと欲が出てくるものでよりバッチサイズを載せたいとか思い出すようになります。そこでより大きなメモリサイズをと探してA4000に行き着きました。
NVIDIA RTXシリーズは昔のQuadro系列とのことですが、そもそもGeforceと何か違うのかというが今ひとつわかりませんでした。調べた範囲でまとめると

・Geforceはいつでも動き出せるようにスタンバイしているが、Quadro系列は言われたら動くスタンス
・GeforceよりQuadra系列の方が省電力
・Quadra系列の方が長時間安定稼働に向いている。
・APIがGeforceはDirectXメイン,Quadra系列はOpenGLメイン

という感じでした。
機会学習用とだとコード書いたり調べたりしている時間が長いので学習の時だけ動いていてくれたらよく指示待ちスタイルでも全く問題なく、それ故に消費電力が少なくて済んでいるのかなと思いました。全く以て好都合です。長時間稼働にも適しているということで3,4日回しっぱなしというのもありかと思われます。
APIの違いでゲームへの向き不向きが出てくるのでしょう。一応Quadro系列でもDirectXいけるみたいですが。ゲームは全くしないと書きましたが、それでもたまに気になるタイトルがあったりします。そこで通常のグラボとしての性能を調べるとGeforce3060とGeforce3070の間ぐらいのようです。最新でゴリゴリというものでなければいけそうですね。

値段と性能のバランスという観点からだと以下のようになります。

|  | A2000  |ELSA GeForce RTX 3060 S.A.C /L GD3060-12GERSH  |
|---|---|---|
|CUDAコアプロセッサ  |3,328コア  | 3584コア  |
|メモリ |6GB GDDR6搭載(12GBモデルもあり) | 12GB|
|値段 |¥74,280(6GB)¥96,745(12GB) | ¥59,800|

|  | A4000  |ELSA GeForce RTX 3080 ERAZOR X GD3080-10GEREZX [PCIExp 10GB]  |
|---|---|---|
|CUDAコアプロセッサ  |6,144コア  | 8704コア  |
|メモリ |16GB GDDR6搭載 | 10GB|
|値段 |¥131,669 | ¥126,800|

|  | A5000  |ELSA　ELSA GeForce RTX 3090 ERAZOR X GD3090-24GEREZX [PCIExp 24GB]  |
|---|---|---|
|CUDAコアプロセッサ  |8,192コア  | 10496コア  |
|メモリ | 24GB GDDR6搭載 | 24GB|
|値段 |¥314,599 | ¥229,744|

おおよそ近しい性能のGeforceと比べたときに、お安いラインだとお得感余りありません。ハイエンドだと寧ろ無いなぁという感じ。ただミドルレンジ辺りだとアリと思えると思います。なんと言ってもメモリが16Gであるというのが大きい。16GメモリのグラボなんてColabでしか使えないと思っていましたので。


# 2.Conclude
Qiita読んでいる人の中には僕のようにゲームはしないけど機会学習用にグラボ積んでいる人は多いと思います。ガチ勢の方は自己投資で大枚はたいても回収できると思うのでハイエンドにいかれると思いますが、僕のように半分趣味、半分仕事ぐらいの感じでやっている人はミドルレンジ辺りに位置すると思うので、そういう方にはNVIDIA RTXシリーズは割と魅力的だと思います。機械学習界隈でも多くの方はGeforce使われていますが、もう一つの選択肢として。


最後に僕の環境を動作報告を兼ねて記しておきます。

【メーカー】Diginnos
【モデル名】GALLERIA ZZ
【CPU】Intel Core i9-9900K 3.60GHz
【メモリ】128GB
【ストレージ】SSD 1TB * 2 + HDD 4TB
【光学ドライブ】BD-RE
【LAN】Gigabit LAN
【MB】ASROCK Z390 Phantom Gaming 4
【電源】SILVERSTONE 750W 静音電源（80PLUS PLATINUM）

公式にもきちんと対応していると記載されてはいますが、PCI Express 3.0 x16　で動いてくれるかがやはり不安でしたね。
【Jest】commit時にJestを実行する


### パッケージのインストール
以下のコマンドを実行して`husky`および`lint-staged`をインストールします。
```:ターミナル
$ yarn add -D husky lint-staged
```

### `lint-staged`の設定
lint-stagedの設定をします。
`package.json` に以下のように記述することでステージングしたファイルに対しコマンドを実行できます。
```package.json
{

  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "jest --bail --findRelatedTests"
    ]
  },

}
```

### `Git hooks`を有効化
以下コマンドを実行して`Git hooks`を有効化します。

```:ターミナル
yarn husky install
```

以下のように`.husky`ディレクトリが作成されます。
![スクリーンショット 2022-05-12 午前2.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e805ff5f-3178-31a2-18d7-b33fa0f9e9b4.png)


`git clone`してパッケージをインストールした際に`Git hooks`を有効化するため、`package.json`に`prepare`を記述します。

yarn2以降を使用している場合には`prepare`は使用でないので`postinstall`を記述します。

```package.json
  "scripts": {
    "prepare": "husky install"
  },
```

```package.json
  "scripts": {
    "postinstall": "husky install"
  },
```


### `hooks`を作成
以下のコマンドを実行して`hooks`を作成します。
```:ターミナル
$ yarn husky add .husky/pre-commit "npx lint-staged"
```
実行すると`.husky`ディレクトリに`pre-commit`ファイルが作成されます。

![スクリーンショット 2022-05-12 午前2.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e34af6af-0665-9086-f13b-15a5405e3811.png)


```pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
```


```
セッションマネージャを使ってECインスタンスへアクセスする

セッションマネージャはAWS Systems Managerというサービスの機能です。
EC2にSystems Managerへのアクセス権限を設定することで使えるようになります。

# EC2へのアクセス権限を設定する
マネジメントコンソールでIAMダッシュボードを表示してください。
左メニューから「ロール」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/c839e7dc-caa1-c6bc-d67b-f89b64244468.png)

「ロールを作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/7d05af76-9aa5-e00e-b12a-37c160a66ada.png)

信頼されたエンティティの種類で、「AWSのサービス」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/28f6e56c-ecfd-f2ad-1d1e-1aed99708dd7.png)

ユースケースは、「EC2」を選択し、「次へ」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/32641922-6f3a-a6e6-17af-80db2b9af80e.png)

許可ポリシーで、「AmazonSSMManagedInstanceCore」を選択し、「次へ」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/02471683-0568-2772-821d-6e8201a21812.png)

ロール名を入力し、画面下の「ロールを作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/f4e2fd7e-8e6d-911c-5e9d-c409402aee16.png)

# EC2にIAMロールをアタッチする
作成したIAMロールをEC2に割り当てます。
マネジメントコンソールでEC2ダッシュボードを表示してください。

IAMロールを割り当てるEC2を選択し、「アクション」-「セキュリティ」-「IAMロールを変更」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/dd34a718-7954-649b-16b9-2c7d474d4005.png)

IAMロールで、作成したIAMロールを選択し、「Update IAM role」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/cc195178-e237-9b72-eae9-27fc3148d271.png)

「インスタンスの状態」-「インスタンスの再起動」をクリックします。

# セキュリティグループを変更する
HTTPとHTTPSでアクセスできるようにセキュリティグループを変更します。
マネジメントコンソールの左メニューから「セキュリティグループ」をクリックしてください。

![スクリーンショット 2022-06-24 6.35.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/ff875d03-4211-36bb-073a-d8fffbd6893f.png)

HTTPとHTTPSを追加し、「ルールを保存」をクリックしてください。
![スクリーンショット 2022-06-24 6.37.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/d006b754-1064-a970-04ee-36817e3c3215.png)

# セッションマネージャを使ってEC2インスタンスにアクセスする
EC2ダッシュボードで、接続するEC2のインスタンスをチェックし、「接続」をクリックします。

セッションマネージャータブの「接続」をクリックします。
![スクリーンショット 2022-06-24 6.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/f2f1c07e-eb72-58ba-f94d-709457b1f430.png)

以上です。
リスコフの置換原則でカレー作り

カレー作り、特に好評ではなかったけど第3弾

### こんにちは、Javaおじさんのシキムです。


40才目前で、プログラム工学に興味を持ったので本や記事で読んだ難しい話を
咀嚼して簡単な言葉で語りたいと思います。

-----

今回は、**リスコフの置換原則（Liskov substitution principle**というものについてです。

ざっくりと、、、

拡張したクラスは、元のクラスと同じように使えないといけない。

詳しくは偉い人の話を読んでください。

ここでは、この原則をカレー作成装置に見立てて解説したいと思います。

では、さっそくカレー作成装置を作りましょう。


今回は真カレー装置(夏)に、さらにとんかつをトッピングしてしまいましょう。
----
(真カレー装置(夏)の詳細は第２弾をご確認ください。)

**野菜BOX作成キット**
　　容器
　　剥き方ノート(白紙)
　　切り方ノート(白紙)

**人参BOX**
　　容器：人参
　　剥き方ノート：ピーラーで皮を剥く
　　切り方ノート：輪切りに切る

**ジャガイモBOX**
　　～省略～

**玉ねぎBOX**
　　～省略～

**野菜BOXコンテナ**
　　人参BOX
　　ジャガイモBOX
　　玉ねぎBOX

**野菜下ごしらえ装置**
　入れるもの：
　　　野菜BOX

　作業：
　　　①容器の野菜を剥き方ノートと同じように剥く
　　　②皮を剥いた野菜を切り方ノートと同じように切る

　出てくるもの：
　　　下ごしらえ野菜

**肉下ごしらえ装置**
　入れるもの：
　　　肉

　作業：
　　　①肉を切る

　出てくるもの：
　　　下ごしらえ肉

**とんかつ装置**
　入れるもの：
　　　ロース肉

　作業：
　　　①カラットあげる

　出てくるもの：
　　　とんかつ

**とんかつカレー作成装置**
　入れるもの：
　　　野菜BOXコンテナ、肉、ロース肉

　作業：
　　　①野菜下ごしらえ装置に野菜BOXコンテナのBOXを１つづつ入れて下ごしらえする
　　　②肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　③具材を鍋に入れて煮込む
　　　④カレールーを入れる
　　　⑤ご飯にかける
　　　⑥とんかつ装置に、ロース肉をいれとんかつを作る
　　　⑦とんかつを８等分にする
　　　⑧カレーにとんかつをトッピングする

　出てくるもの：
　　　カレー(とんかつトッピング)

とんかつカレー装置の完成です。
----
やっぱり、カレーにとんかつは最強だと思います。
え？もうちょっとさっぱりしたものがいいって？（誰も言っていない）
しょうがない！大根おろしを乗せて、おろしとんかつカレーにしてあげましょう。

とんかつ装置を拡張して、大根おろしを乗っけてしまいましょう。
----
～通常具材省略～

**とんかつ装置(おろし乗せ)**
　入れるもの：
　　　ロース肉

　作業：
　　　①カラットあげる
　　　②たっぷりと大根おろしを乗せる

　出てくるもの：
　　　おろしとんかつ

**とんかつカレー作成装置**
　入れるもの：
　　　野菜BOXコンテナ、肉、ロース肉

　作業：
　　　①野菜下ごしらえ装置に野菜BOXコンテナのBOXを１つづつ入れて下ごしらえする
　　　②肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　③具材を鍋に入れて煮込む
　　　④カレールーを入れる
　　　⑤ご飯にかける
　　　⑥とんかつ装置(おろし乗せ)に、ロース肉をいれおろしとんかつを作る
　　　⑦とんかつを８等分にする
　　　⑧カレーにとんかつをトッピングする

　出てくるもの：
　　　カレー(おろしとんかつトッピング)

今回は成功しております。
----
今までのカレー作りだと、だいたいここで失敗します。

しかし、今回は失敗しませんでした。
とんかつ装置を拡張しましたが、とんかつ装置がとんかつ装置(おろし乗せ)に置き換えても
そのまま８等分してトッピングすることができるので、そのままとんかつカレー装置で作ることができました。
もし、とんかつに戻したくてもこれなら装置を入れ替えるだけで問題がありません。

　


急に話が変わりますがトッピングのとんかつって、スプーンで切らなきゃいけなのでとても食べにくいですよね。

そんなあなたに、１口とんかつカレーはいかがでしょうか？
----
～通常具材省略～

**とんかつ装置(１口サイズ)**
　入れるもの：
　　　ロース肉

　作業：
　　　①ロース肉を一口サイズまで小さくする
　　　②カラットあげる

　出てくるもの：
　　　１口とんかつ

**とんかつカレー作成装置**
　入れるもの：
　　　野菜BOXコンテナ、肉、ロース肉

　作業：
　　　①野菜下ごしらえ装置に野菜BOXコンテナのBOXを１つづつ入れて下ごしらえする
　　　②肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　③具材を鍋に入れて煮込む
　　　④カレールーを入れる
　　　⑤ご飯にかける
　　　⑥とんかつ装置(１口サイズ)に、ロース肉をいれ一口とんかつを作る
　　　⑦とんかつを８等分にする
　　　⑧カレーにとんかつをトッピングする

一口とんかつカレー完成です。
----
さっそく、一口とんかつカレーを作ってみました。
そうすると、コマ切れになったとんかつの乗ったカレーが出てきました。。。。

とんかつカレー装置は、出てきたとんかつを８等分してしまうため、無残な姿になっていたのです。
とんかつ装置と同じ装置なのに、同じ処理ができないものが出てくるようになってしまいました。

これでは、リスコフの置換原則に違反しています。

以上が、おじさんなりのリスコフの置換原則の理解です。


　
　
　
　







**カレー作りシリーズ**

https://qiita.com/sikimuOji/items/a99fdc2de406a0f42fac
JavaScript 乱数使ってカラーコード生成

JavaScript で乱数 `Math.random()` 使ってカラーコード生成

```JavaScript
// RGB
let rgbArray = [...Array(3)].map(i => Math.floor(Math.random() * 256));
let colorCode = 'rgb(' + rgbArray.join(',') + ')';

// Hex
let hex = '#' + Math.random().toString(16).slice(-6);
```
rsyncのPermissionエラーの件

rsyncのPermissionエラーの件下記のこと意外と触れていないので、あえて投稿
rsync -av -e ssh /var/www/html/xxxx user@999.999.999.999:/home/user/
で下記エラー
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(600) [sender=3.0.6]
vi /etc/ssh/sshd_config
にて
PasswordAuthentication no
を
PasswordAuthentication yes
に変更
Centos6
/etc/rc.d/init.d/sshd restart
Centos7
systemctl restart sshd
にてsshd再起動
【Kotlin】引数がデフォルト引数か否かを判定する

# やりたいこと
以下のように、デフォルト引数を設定した関数で、引数が外部から渡されたものか、内部的に設定されているデフォルト引数か判定します。

```kotlin
fun foo(v: Int? = ...)
```

# やり方
以下のようにすればできます。
サンプルコードでは、外部から値を渡した場合その値が、渡さなかった場合`default`が出力されます。
また、`Int.MIN_VALUE`（= `ABSENT_VALUE`に設定した値）を渡した場合も正常に判定が行えます。

```kotlin
val ABSENT_VALUE: Int? = Integer.valueOf(Int.MIN_VALUE)

fun foo(v: Int? = ABSENT_VALUE) {
    if (v === ABSENT_VALUE) println("default") else println(v)
}

// -> default
foo()

// -> 1
foo(1)

// -> -2147483648
foo(Int.MIN_VALUE)
```

## 原理
`Kotlin`では`===`/`!==`でインスタンスの比較が行えます。
このため、特定のインスタンスをデフォルト値に設定すると、値が指定されているかのチェックをすることができます。

```kotlin:比較部分（抜粋）
if (v === ABSENT_VALUE) println("default") else println("not default")
```

ここで、以下2点については注意が必要です。

- `ABSENT_VALUE`は確実に固有のインスタンスになるよう指定する
  - 特にプリミティブ型に対するラッパー型などはインスタンスがキャッシュされている場合が有る
- 引数がプリミティブ型（`non-null`な`Int`など）の場合、この方法は使えない
  - 回避方法は「この値は`null`とみなす」ようなマジックナンバーを導入するしか無い

# 感想
~~こんなトリッキーなことはしないようにしましょう~~ニッチなテクニックですが、`Java`向けのライブラリに関連するコードを`Kotlin`化したい時なんかに使えることが有るかなと思います。

# 追記
`Integer`型等のインスタンス比較に関する挙動は今後変更の可能性が有るようです。
少なくとも`Java 18`では紹介したコードで成功していましたが、今後成功しなくなる可能性が有ります。

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/doc-files/ValueBased.html

対応方法も考えてみましたが、流石に現実的な感じにはなりませんでした。

https://qiita.com/wrongwrong/items/105a40219070c8828ad1
リファレンスリファレンス

# はじめに
なかなか読みこなせるようにならないリファレンスの読み方についてまとめました。
前半ではリファレンスを読みこなすためのコツについてのお話を、~~後半ではリファレンスだけを用いてAPIを駆使する実践を行います。~~(追記予定)
# なぜリファレンスは読みにくいのか
そもそもなぜリファレンスは読みにくいのでしょうか？
理由は色々あるでしょうが、筆者はそもそもまとめ記事や入門書とリファレンスが作られた目的の違いに起因すると考えています。
## リファレンスは辞書
辞書にあるすべての英単語を丸暗記したとしても、実生活で使う単語はごく一部だと思います。一方で単語帳に乗っているような英単語は頻出で、暗記価値が高いことが多いです。

まとめ記事とリファレンスもこれに対応していて、まとめ記事は単語帳、リファレンスは辞書に相当します。
すなわち、前者は**よく使う技術、あるいは最低限知っているべき技術をさらうため**に作成されたものですが、後者は**それに関するすべての情報を網羅するため**に作成されたものであるという違いがあります。
## メリットとデメリット
リファレンスは上述の通り特殊な性格をしているため、リファレンスにしかないメリットやデメリットが存在します。
### メリット
+ すべての情報が網羅されている
+ 情報が常に正確で新しい
### デメリット
+ 情報量が尋常じゃないほど多い
+ 情報が玉石混交
+ シンプルに文章が難しい(特に公式は正確性を要求されるため用語や言い回しが難解になりやすい)

特にデメリットの部分は、ちょうどまとめ記事と対置しているため、**同じノリで気楽に情報収集しようとすると爆殺されます**。おそらくここがリファレンスが読みにくいと感じる所でしょうが、逆に言えば**アプローチの仕方さえ心得ていればそれほど怖くない**のも事実です。
# いつ使うべきか
道具は適切なタイミングで使用することが肝要です。では、リファレンスを使うべき時というのはどんな時でしょうか？

辞書と考えればいいわけですから、1つ目は当然**わからないことが出てきた時**です。しかし、見落としがちなのは2つ目の**全体像を把握したい時**です。
上述したようにリファレンスは正確かつ最新の情報が完璧に網羅されているため、システム全体についての把握をするにはうってつけというわけです。
# どう使うべきか
いつ使うべきかの話と重複しますが、リファレンスを使うのはわからないことが出てきた時と全体像を把握したい時です。
しかし、前者に関して言えば正直まとめ記事のほうに分があることが多いです。というのも、まとめ記事は一つのテーマについて詳しく説明できる分、~~お粗末でお役所的なリファレンスよりも~~優れていることが多いからです。

結局のところリファレンスを積極的に使用する理由があるのは、まとめ記事にも載っていないようなマイナーな機能を使ってみたいと考えるときということになります。しかし、そういう機能に限ってだいたい煩雑なので、やはり**関連する機能についての知識の習得は必須になります**。

以上をまとめると、リファレンスを使用する意義は**機能同士の関連性を習得すること**(広義にはAPIの全体像を捉えることも含まれる)にあるということができます。
# 攻略のためのTips
理解すべきものが単体ではなく関連になるわけですから、読み解いていくときには「ここはこれを使う。」「こういう時にはこうする。」以上の理解が必要になります。

コツは大きく分けると2点です。
## 抽象から具体へ
全体像や関連という大きなものを対象とする場合には、まず**ざっくりとでいいのでどれが何をしているか**を把握してから細々としたことを理解していくことが重要です。
この場合、システム全体のピラミッドの上から下へと走査していくのが理想になるため、
1. API
1. パッケージやコンポーネント
1. クラスやインターフェース
1. メソッドや関数

といった順番に参照することになります。

逆に、1つのメソッド周りから並んでいる順につぶしていくという方法はご法度です。
## 処理の流れを追う
パスタを作りたければ、材料のほかに調理手順がわかっている必要があります。鍋に湯を入れて沸騰させてから塩を一つまみ入れてパスタを茹でてから、~~湯切りと称して網戸にパスタを打ち付ける芸人さん最近何してるんでしょうか？~~

APIは通常複数のクラスやインターフェースが集まって1つの機能を提供し、それらが集まって全体として大きな機能を提供します。
パスタと同様、**処理の流れが大まかにでも掴めていないとある程度の予測や勘が働かず、断片的な知識の集積となり役に立ちません**。

2つは似たようなことを言っていますが、前者は**上下の関連性を追う**のに対して、後者は**横の関連性を追う**ことになる点で異なります。
フォルダを指定してマイグレーションファイルを作成したい

マイグレーションファイルを作成する際にフォルダを指定して行う必要があり、その方法を調査したため、備忘録としてメモしておきます。

# 必要になった理由

ファイル構成は次のとおり。
```
- bootstrap/
- config/
- core/
- database/
 - migrations/ 
- develops/
- modules/
 - Test
 ...
  - database/
   - Migrations/  ← ここのフォルダを指定したい！
 ...
- public/
- resources/
- routes/
- strage/
- tests/
- vue/
```

今回のプロジェクトは上記のようなファイル構成となっており、プロジェクトのトップで通常のマイグレーションファイルを作成するコマンドを入力しても、
希望の`/module/Test/database/Migrations`配下にマイグレーションファイルを作成できません。



それなら、`/module/Test`まで移動して、通常のマイグレーションファイルを作成するコマンドを入力すれば良いんじゃない！？と思って、

```
php artisan make:migration create_tests_table
```
と入力したら、
```
Could not open input file: artisan
```
というエラーが。
「arisanファイルのあるディレクトリにいないから、実行できないよー」
とのこと。


そのため、プロジェクトのトップで`/module/Test/database/Migrations`配下にマイグレーションファイルを作成しようと思い、調べてみました。
調べると、マイグレーションコマンドの後ろに「--path」を付けて、オプションでフォルダのパスを指定すればよいとのこと。
そこで、以下のコマンドを入力
```
 $ php artisan make:migration create_tests_table --path=modules/Test/Database/Migrations 
```
作りたい場所にマイグレーションファイルを作成することができました！

# まとめ
フォルダを指定してマイグレーションファイルを作成する場合は、
**マイグレーションコマンドの後ろに「--path」を付けて、オプションでフォルダのパスを指定** しましょう！

# 参考にしたサイト
https://tech.adseed.co.jp/Laravel%20migration%20file%20migrate%20artisan
オタマトーンNeoに本体改造なしで音声出力端子を追加する

## オタマトーンすごい楽しい

[オタマトーンNeo](https://otamatone.jp/lineup/otamatone-neo/)かっちゃいました。ずっとほしかったんですが、なかなかタイミングがなく買う機会がありませんでした。そしてついに買ってしまったんですが、いじってるとあまりにも楽しくて、ついつい時間が経つのを忘れてしまいます。楽器がひけなくても結構それっぽくできるんですよね、雰囲気で触るだけで楽器が演奏できるなんて素敵すぎます。

オタマトーンNeoは2019年末にオタマトーン誕生10周年を記念して発売された新機種です。スマホと連携できるOTM Linkがあるのが特徴です。小型で持ち運びもラクなのですが、ヘッドホン端子やラインアウト端子がないので、深夜は演奏できません。さすがに夜中は近所迷惑になってしまいます。

そこで、このOTM Linkという端子がどのようなものか、ここからLINE Outできないか調べてみました。

## OTM Linkとは

OTM Linkはスマートフォンのイアホン・マイク端子に接続して利用します。基本iPhoneですので、CTIA規格に準拠しているようです。さて、ここにどのような信号が流れているかというと、スマートフォンのマイクに向けてオタマトーンの出力音が、そしてスマートフォンのイヤホンとしてオタマトーンの口から出力されるようになっています。OTM Linkアプリはスマートフォンをエフェクターにする仕組みのようです。

![CITA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100408/245d2e8c-5806-210b-3f40-8c11bff5d4e8.png)

## Mic Outを追加する

オタマトーンからの出力はスマホのマイク入力で受けるため、アッテネータなどが入っているようで信号レベルが低いです。そのため、ミキサーのマイク入力に接続します。しかし、オタマトーンのスピーカはオタマトーンの出力側のインピーダンスが低い場合、音が漏れる仕様になっているようです。そこで、100KΩの抵抗を挟みます。

配線図は以下の通りになります。

![OTM-Phone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100408/9ca4723d-62cb-e625-3c6f-7ceeeca7db13.png)

100KΩの抵抗はなくても問題ないようですが、これがないとオタマトーン側からも音が（やや小さめですが）でるようになります。しかし、ミキサー側のゲインをそれなりに上げなければならないので、ノイズが増えるかと思います。そのへんは音漏れをどれくらい許容できるかとのトレードオフになるでしょう。また、ミキサー側の入力インピーダンスでオタマトーン側の音漏れの具合が代わってくるかと思います。未確認ですが、ギターアンプやコンパクトエフェクターなどハイインピーダンス向けの装置でしたら、この抵抗が無くても音が漏れないかもしれません。

オペアンプでLINE OUTに対応できるアンプを追加するのもありだとおもいます。

## 音声出力端子の弱点

オタマトーンの音声出力には弱点があります。そう、口のパクパクによるワウが効かなくなり、オタマトーンの魅力が半減してしまいます。これは構造上仕方ありません。口のパクパクや顔の移動による表現に盛り込みたい場合は、普通にマイクで録音するのがベストだと思います。音声出力端子はオタマトーンを深夜楽しむときや、別のエフェクターを噛ませたいときに活用するのが理想的だと思います。

## オタマトーンはスピーカーになる？！

ご想像どおり、オタマトーンはスマホの外付けスピーカにもなります。TRRSの1番目(R1)が入力になります。ステレオ信号を入れた場合Rchの音がでる形になります。

## オタマアンプを作る

オタマトーンの入出力にコンパクトエフェクターを噛ませて、オタマアンプをつくることにしました。図のようにオペアンプを非反転でいれて、エフェクタにセンド・リターンを入れる用にしました。ひとまず回路図を作成して、ブレッドボードで実験してみました。エフェクターによっては出力信号が入力信号に回り込み、ハウリングを起こします。

![スクリーンショット 2022-07-01 10.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100408/fdf11a10-ddb1-8e59-1d2d-0918faab0a39.png)

## 関連情報

改めて検索したところ、OTM Linkから出力する方法について、以下のような記事もありましたので、参考になるかもしれません。

* [オタマトーンneoをイヤホン出力するには](https://note.com/otamatone_tote/n/nbc0191af0f04)
表示速度を上げるための個人的な考察　画像読み込み編

今回は私が開発したwebサービス(https://universitycommunity.herokuapp.com/) のページを読み込む速度を改善していきたいと思います。
ユーザーがサービスを利用する際に負担に感じる大部分はデザイン・表示速度の2つだと考えます。
なので今回は表示速度の改善を通じてより良いサービス開発に繋げていこうと思います。

まずGoogle社が提供しているPageSpeed Insights(https://pagespeed.web.dev/?hl=ja) を用いて表示速度を測っていきます。


![スクリーンショット 2022-06-24 2.36.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/0cb3d474-2491-a864-9e65-ae1eae0425cf.png)
モバイル版の表示速度スコア
![スクリーンショット 2022-06-24 2.37.43 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/23699ca4-23b1-6db6-2203-0b8837d6833f.png)
デスクトップ版の表示速度のスコア

モバイル版のパフォーマンスは77、デスクトップ版のパフォーマンスは92です。
どちらも改善の余地がありそうです。
改善項目を読むと
どうやらサーバー応答時間、画像の読み込みに時間がかかっているようです
サーバーの応答時間の改善についてはサーバーのプランをアップグレードするのが一番早いでしょう。なので今回は画像の読み込み時間の改善をおこなっていきます。
「次世代フォーマットでの画像の配信」と書かれていますが、
Webpなどの形式の場合、画像の圧縮率に優れており、画像ファイルサイズが小さくなりダウンロードしやすくなることから画像の読み込み時間が短縮できるようです。
なので画像形式をjpegからwebpに変えて再度試してみましょう。
結果を確認すると

![スクリーンショット 2022-06-24 2.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/01ac3210-de09-045a-9e07-b3b449fba0ae.png)

モバイル版の表示速度スコア

![スクリーンショット 2022-06-24 2.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/d5153611-e41f-cdd0-a9aa-e1a9694e4c06.png)


デスクトップ版の表示速度のスコア

モバイル版のパフォーマンスは86、デスクトップ版のパフォーマンスは94です。
少し改善されました。
このように画像形式を圧縮率の高いものにするとその分表示時間を短縮できます。

今回のページの場合、DBとの直接的なやりとりを行っていないためその分表示時間が短縮されていますが、DBとのやり取りがある、特に投稿一覧、ユーザー一覧ページなどの場合はN+1問題というのが発生し、その分表示速度が遅くなるようです。
N+1問題については次回扱います。
【React】useLocation() : Object is of type 'unknown' の対処方法

# 概要

`Object is of type 'unknown'` になる場合の対処方法をまとめる

```tsx
import {useLocation} from "react-router-dom";

export const Users: () => JSX.Element = () => {
    const location = useLocation()
    const state = location.state
    console.log(state.isAdmin)
}
```


# 対処方法

`unknown` 型にユーザー定義の型を割り当て（アサーション）する

```tsx
import {useLocation} from "react-router-dom";

type State = {
    isAdmin: boolean
}

export const Users: () => JSX.Element = () => {
    const location = useLocation()
    const state = location.state as State
    console.log(state.isAdmin)
}
```
中間テーブルへのデータの保存の仕方

今日は現役テックキャンプ生のアプリ開発Day8分を記述します。今回は中間テーブルへのデータの保存の仕方について記述します。まず、中間テーブルの説明から始めます。

# 中間テーブルとは？
テーブル間で多対多のアソシエーションが発生する時、間に交通整理員を置くようなイメージで中間テーブルというものを作成します。中間テーブルに関しては下のメチャクチャわかりやす記事を参考にしてください

https://qiita.com/Lotuswhite/items/0794b468ecc627e01ae1

# 今回のDB設計
今回は私自身のアプリ開発で利用しているUserとRoom(userが参加する場所)のテーブルを例に説明します。２つのテーブルのアソシエーションを確認します。
・userは複数のroomに参加できるので、userは複数のroomを持っていると言えます。
・roomには複数のuserが参加しているので、roomは複数のuserを持っていると言えます。
以上より、userとroomは多対多のアソシエーションなので、中間テーブルとしてuser_roomを作成します。

# マイグレーションファイル
中間テーブルのみ記述します。
```ruby:マイグレーションファイル
    def change
      create_table :user_rooms do |t|
         t.references :user, foreign_key: true
         t.references :room, foreign_key: true
         t.timestamps
      end
    end
```
# モデルへアソシエーションの記述
簡易に記述します。
```ruby:モデルファイル
#中間テーブルのUser_room
belongs_to :user
belongs_to :room

#userテーブル
has_many :user_rooms
has_many :rooms ,through: :user_rooms

#roomテーブル
has_many :user_rooms
has_many :users, through: :user_rooms
```
# 中間テーブルへデータを保存する方法
結論から言うとparamsにuser_ids:[id,id2・・・]というカラムを追加すると保存できます。railsコンソールで確認していきましょう。まず、コンソールを起動します。
```
rails c
```
次に、ユーザーを複数作った上で、roomを作成します。
```ruby
Room.create(カラム名:"test",カラム名２:"test",　user_ids:[ユーザーID,ユーザー２人目のID]) 
```
以上で、中間テーブルにデータが保存できたはずです。

参考になるかわかりませんが、実際にコントローラー内に記述したコードを下に載せます。
```ruby:controllor内部
def create
    @room = Room.new(room_params)
    @room.save
    redirect_to root_path(@room)
end

private
  def room_params
    params.require(:room).permit(:room_name).merge(maker_user: current_user.nickname, user_ids: [current_user.id])
  end
```
以上、お読みいただきありがとうございます。
DynamoDBのクリーンとコピー



# はじめに
DynamoDBのクリーンとコピーの仕方について、簡単に説明

# 目次
-  テーブルのクリーン
-  テーブルのコピー
-  最後に

## TableのCleanUp
### Scan + Delete Item
①すべてのデータをScan
②１件ずつ削除

　結果：遅い、コスト高い

```
aws dynamodb scan --table-name myTable
aws dynamodb delete-item --table-name myTable --key '{ "user_id": { "N": "1" }}'
```
※scanはデフォルトでは、1度に取得できるのは最大1MB

### Drop Table ＋ Create Table
①テーブル削除
②テーブル作成

　結果：早い、テーブルの再設定が面倒

```
aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=5,WriteCapacityUnits=5 \
    --table-class STANDARD

aws dynamodb delete-table --table-name Music 
```
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/getting-started-step-1.html

## TableのCopy

### backap＋restore
①バックアップ
②リストア※1
※1 リストア時、新しいテーブルで作成される
　　手動でTTLやメトリクス、ロール等の設定が発生

　結果：早い、キャパシティを利用しない

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/backuprestore_HowItWorksAWS.html

## Scan + Write Item
①すべてのデータをScan
②１件ずつ追加

　結果：遅い、コスト高い

```
aws dynamodb scan --table-name Music  
aws dynamodb put-item \
    --table-name Music  \
    --item \
        '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}, "Awards": {"N": "1"}}'

```
※scanはデフォルトで最大100件のため、ページング等が必要

## DataPipeLine(EMR)でexport＋import
①import：DynamoDB→EMR→S3
②export：S3→EMR→DynamoDB

　結果：早い（バックアップ用途では、AWS非推奨）


https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBPipeline.html

## 最後に
テーブルのクリアやコピーは他にもあるとは思いますが、メジャーなものを記載しました。
imtem数が少ないテーブルであれば、scanしてクリアやコピーしても問題ないと思います。
メリット、デメリットを把握した上で使用できたらと思います。