OmniAICreator/Qiita-1.07M huggingface dataset:
[Kotlin]Roomのデータ構造を更新する手順(migration)

# 概要
Roomデータベースのデータ構造を更新する時に大切なポイントをまとめてみました。migrationを使えばアプリ内のデータベース情報も正常に引き継ぐことができます。

:::note info
ここで紹介するのはmigration機能を使った更新の仕方です。autoMigrationを使った更新は[ここ](https://qiita.com/kazuma_f/items/8c15e7087623e8f6706b)をご覧ください。
:::

# 列を追加したい時の手順
例として「member」という列を追加してみます。

## ＠Databaseの修正
Entityを更新した時はversionの数字を増やす必要があります。

更新前

```kotlin
@Database(entities = [ToDoTask::class], version = 1, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
   abstract fun toDoDao(): ToDoDao
}
```

更新後

```kotlin
@Database(entities = [ToDoTask::class], version = 2, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
    abstract fun toDoDao(): ToDoDao
}
```
:::note info
「exportSchema = true」を指定するとRoomがバージョン管理をするために使用するjsonファイル（スキーマ）を出力してくれます。
もしexportSchema = falseにする時は以下の「フォルダの指定」は記述しなくても大丈夫です！
:::

## スキーマの書き出しフォルダの指定
＠Databaseに「exportSchema = true」を指定した場合、スキーマの出力先フォルダを「build.gradle(:app)」に記述しておく必要があります。

```kotlin
defaultConfig {
   kapt {
       arguments {
           arg("room.schemaLocation", "$projectDir/schemas")
       }
   }
}
```

## ＠Entityの修正
memberを追加しておきます。

更新前

```kotlin
@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
)

```

更新後

```kotlin
@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
   val member: String,
)
```

## migration用のSQL文
ここでは列を追加するSQL文を記述します。
Migration（~,~）部分に更新前と更新後のバージョンを書いておきます。

```kotlin
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE todo_table ADD COLUMN member TEXT DEFAULT 0 NOT NULL")
    }
}
```

Room生成部分に.addMigrations()でSQLを指定します。

```kotlin
Room.databaseBuilder(
        context,
        ToDoDatabase::class.java,
        DATABASE_NAME
    ).addMigrations(MIGRATION_1_2).build()
```

# 補足1
新規テーブルを作る場合はこんな感じに記述します！
[参考公式HP](https://developer.android.com/training/data-storage/room/migrating-db-versions)

```kotlin
val MIGRATION_1_2 = object : Migration(1, 2) {
  override fun migrate(database: SupportSQLiteDatabase) {
    database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
      "PRIMARY KEY(`id`))")
  }
}
```
# 補足2
Androidエミュレータ内のデータベースを確認したい時はDatabase Inspectorが便利です。
AndroidStudioの標準機能です。
https://developer.android.com/studio/inspect/database?hl=ja
Multipassのdocker上で、WordPressの開発環境を作る

multipassのdockerにVSCODEをSSH接続できましたので、WordPressの開発環境を作ります。

前回までの記事は、こちらを読んでください。

https://qiita.com/masaru21/items/85fcafa2d8668473bd6a

https://qiita.com/masaru21/items/0b26d8c4559a07cefe9f



このページから、 **docker-compose.yml**の内容をコピーして、持ってきました。

https://hub.docker.com/_/wordpress

作業の流れの概略は、こちらのページを参考にしました。

https://dev.classmethod.jp/articles/beginner-docker-wordpress/



VSCODEで **docker-compose.yml**を保存すると、エラーが出ます。
そのため、VSCODEの拡張機能のVIMをインストールしましょう。
私もエラーが出て検索したところViコマンドで保存し直したら直ったという記事を見つけ、この拡張機能のVIMをインストールして保存しました。

```bash
docker-compose
```
を実行しました。
しかし、エラーが出てしまいました。
そのため、インストールしました。

```bash
sudo apt install docker-compose
```

フォルダのことは、こちらが参考になります。

https://chigusa-web.com/blog/docker-compose%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6wordpress%E3%82%92%E7%B0%A1%E5%8D%98%E6%A7%8B%E7%AF%89/


こちらのPortainerで確認しました。
![VirtualBox_Ubuntu0319_26_03_2022_20_39_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/4e1cab66-d32d-2bac-de87-4b95cf2b55f1.png)

ブラウザでアクセスしたら、無事にWordPressが起動していました。
インストールできました。
![VirtualBox_Ubuntu0319_26_03_2022_20_42_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/07a4447e-23eb-fd69-fcd1-e71a2241871e.png)


## dockerのコマンド
dockerの起動や停止のコマンドは、こちらを参考にしました。

https://kure.hatenablog.jp/entry/2020/12/03/162027

 **Portainer**でも、操作できます。
【CSS】クラス名でハイフン--やアンダースコア__が２つ並んでるのを見かけた。それはBEM記法

# きっかけ
CSSの学習をしていたら、こんな感じのクラス名が出てきました。

- `Foo__Bar`
- `Foo--Bar`


言語ごとに`スネークケース`・`キャメルケース`などの使い分けがあるかと思いますが、

初学者のわたしとしては、CSSのクラス名ってイマイチどう書くのが正解かハッキリしないな〜と感じていました。

そんな中あらわれたハイフン2つ／アンダースコア２つのクラス名。

調べると`BEM記法`という命名法を見つけました。

# BEM（ベム）記法とは
CSS設計手法の１つで、クラス名を以下の３つの概念に応じて命名します。

- Block
- Element
- Modifier（モディファイア）

3つの頭文字をとってBEMというわけです。

## Block
単体で再利用できる独立した機能のかたまり（コンポーネント）を`Block`と呼びます。

例：ヘッダー、検索パーツ

Blockの中に子としてBlockを含める場合もあります。

## Element
単体では使用せず、Blockの中で使用する部品を`Element`と呼びます。

例：検索パーツの入力フォーム

Elementは、属するBlockを明示したクラス名をつけ、アンダースコア２つ`__`で繋ぎます。

- `Block__Element`

## Modifier
BlockやElementのスタイル違い（同様の役割をもつが色や形、状態が違うもの）を`Modifier`と呼びます。

例：入力フォームの枠を丸くしたパーツ

Modifierは、元となるパーツを明示したクラス名をつけ、ハイフン2つ`--`で繋ぎます。

- `Block--Modifier`
- `Element--Modifier`

## まとめ
BEM記法では
- Elementならアンダースコア２つ`__`
- Modifierならハイフン２つ`--`

で繋ぎます。

ちなみに、これらの区切り記号を`セパレータ`と呼びます。

組み合わせによっては「`Block__Element--Modifier`」なんて形のクラス名もでてきます。

# 感想
独立した機能ごとにパーツをわけ、再利用可能にする発想はまさにオブジェクト指向ですよね。

Blockの階層が深すぎると、クラス名がとんでもなく長くなってしまう...気もします。

クラス名は様々な工夫の仕方があるようで、つくるものの性質にあわせ柔軟に使い分けたいものです。

BEMの他にも、`SMACSS`や`FLOCSS`といった記法もあるそうな。

また、CSSを拡張した言語である`SASS`も気になります。

以上、案外奥深いCSSの世界のお話でした。
【個人開発】筋トレ × 音ゲー × EDMの新感覚トレーニングアプリ「Muscle Beat」をリリースしました💪

[![Image from Gyazo](https://i.gyazo.com/e53f4d2fd2bde97ad508a7716e5ad6ed.png)](https://www.muscle-beat.com)

EDMの音ゲーに合わせて筋トレを行えるサービスをリリースいたしました！

**▼ サービスURL（スマホ専用）**
https://www.muscle-beat.com

**▼GitHub**
https://github.com/jibiking/muscle_beat



## はじめに

はじめまして！
[駆け出し筋肉エンジニアのJibiki](https://twitter.com/ji_bi__)と申します💪

- **時間がなくとも、筋トレを知らなくとも、楽しくトレーニングを行えるサービスを開発したい！**
- **普通の筋トレでは満足できない体の人でも楽しめるサービスを開発したい！**

そのような想いから、Muscle Beatの開発に至りました🔥



## トレーニング手順

**1. All Beats画面からプレイしたい曲を選択**
★ モード（ハード・ノーマル）が選べます。
★ 曲ごとのユーザーランキングを見れます。
<img src="https://user-images.githubusercontent.com/73700567/158554771-80d79a7d-1878-463b-bb6b-74f31b8e9629.gif">

**2. 流れてくるマルの色に合わせてマッチョマンのようにトレーニング**
★ 最長120秒の短時間集中トレーニング
★ ベストタイミングで動作をするとEDMの重低音が響き渡ります。
<img src="https://user-images.githubusercontent.com/73700567/158554992-5c2dba7a-f7ad-4b6f-bdf4-770a3ee8fa4f.gif">


**3. トレーニングスコアを確認**
★ ユーザー登録済みの場合、上位5名がランキング表示されます。
<img src="https://i.gyazo.com/353c8fa0037ce9b3e53ae5788549ff8b.jpg">


## 使用技術
- Ruby 3.0.1
- Ruby on Rails 6.1.4
- JavaScript
- phina.js
- Heroku
- AWS S3


## ER図
![ER図](https://i.gyazo.com/c0c5af59ed88acd67174b090c1dbf249.png)


## 各主要機能の説明

#### 1. 音ゲー機能の動的表示
DBに保存した音ゲーに必要ファイル（MP3・譜面・説明文など）を動的にゲームライブラリに入れて動作させるために、```beats#showファイル```でerbタグを使用して読み込みを行なっています。

```html:beats#show
<script>

  //ゲームの記述は省略
　　　var ASSETS = {
  sound: {
    music: "<%= @beat.music.url %>",
  },
  json: {
    beatmap: "<%= @beat.notes.url %>"
  },
  image: {
    'sprite': "<%= @beat.gif.url %>",
    'thumbnail': "<%= @beat.thumbnail.url %>",
  },
</script>
```

<br>


#### 2. 筋トレ動作検知機能
JavaScriptの```devicemotionイベント```でスマホの加速度センサー（傾きなどを検知する）の値を取得して、スマホが筋トレ動作を検知したタイミングと音ゲーのタイミングを判定します。

```javascript:beats#show
// 加速度センサーを利用した判定機能
window.addEventListener("devicemotion", function (event) {
  // 加速度センサーの値を変数に格納
  var x = Math.floor(event.accelerationIncludingGravity.x)
  var y = Math.floor(event.accelerationIncludingGravity.y)
  var z = Math.floor(event.accelerationIncludingGravity.z)

  if (Math.abs(x) > 15 || Math.abs(y) > 15 || Math.abs(z) > 15) {
    self.judge(icon);
  }
})
```

<br>

#### 3. スコアデータの受け渡し
プレイ画面からスコア画面に遷移する際、ユーザー登録をしている場合は筋トレスコアをフロントのphina.jsからバックのRailsに受け渡しています。
（スコア履歴はマイページから確認できます。）
```javascript:beats#show
// ゲーム終了（Scoreページへ）
if (this.elapsedTime > "<%= @beat.url%>") {
  SoundManager.stopMusic();

  // データ受け渡し
  const data = { score: this.totalScore, user_id: "<%= current_user.id if logged_in? %>", beat_id: "<%= @beat.id %>" }
  axios.post('/scores', data);

  self.exit({score: this.totalScore,});
};
```


<br>


## おわりに
最後までご覧いただきありがとうございました！！！
**ぜひ筋肉のビートを刻んでみてください💪**


▼ Muscle Beat
https://www.muscle-beat.com

▼ Twiiterアカウント
https://twitter.com/ji_bi__
【プリンシプルオブプログラミング】 第3章（3.1~3.10）「思想」要点抜粋

この記事は「プリンシプルオブプログラミング」という書籍の、特に重要だと感じた部分を紹介します。この書籍は全部で7章あります。1記事につき1章（項目が多い章は分割）を取り上げていき、今回は第3章（プログラミングセオリー）の部分です。
### 第3章 「思想」 〜プログラミングのイデオロギー〜
> 「何か新しいものを初めて観察することではなく、古いもの、古くから知られているもの、あるいは誰の目にも触れていたが、見逃されていたものを、新しいもののように観察することが、真の独創的な頭脳の証拠である。」
フリードリヒ・ニーチェ
# 3.1 プログラミングセオリー
- プログラミングの最大の関心事は「最高のコード」を作ること
- 最高のコードとは「拡張方法が多く存在し、余分な要素が存在せず、読みやすく、理解しやすいコード」
###### 最高のコードを実現するためのセオリーを支える3つの価値
1. コミュニケーション（3.2）
2. シンプル（3.3）
3. 柔軟性（3.4）
###### 価値とプログラミングの架け橋となる6つの原則
1. 結果の居所化（3.5）
2. 繰り返し最小化（3.6）
3. ロジックとデータの一体化（3.7）
4. 対称性（3.8）
5. 宣言型の表現（3.9）
6. 変更頻度（3.10）
###### 関連
- ある技術を適用する時に、考慮すべき観点のことを「フォース」という
# 3.2 コミュニケーション
- 「他の人はこのコードを見てどう感じるだろうか？」と考える
# 3.3 シンプル
- 玉石（本質的な部分と余分な要素）を明確にし、余分な部分が紛れ込まないようにする
- シンプルにするとコミュニケーションが良好になる
# 3.4 柔軟性
- 柔軟性とはコードの変更の容易さのこと
- 　複雑性を持たず、柔軟性を持つために、即効果のあるコード以外は書かない
# 3.5 結果の居所化（＝変化の影響）
- 変化の影響が、局所に留まるようにコードを構成する
- 複雑性を持たず、柔軟性を持つために、即効果のあるコード以外は書かない
- 関係性の高いコード（お互いに頻繁に呼び出しあっているモジュールなど）を集約してモジュール化する
# 3.6 繰り返しの最小化（=重複を極力排除する）
- コードをたくさんの小さな部分に分割し、別のコードとの共通項を導きやすくする
- コード内で「完全に同じ所」「とりあえず似ている所」「まったく異なる所」を明確に色分けすることで、コードが読みやすく修正コストも抑えられる
# 3.7 ロジックとデータの一体化
- 「ロジック」と「ロジックが操作するデータ」を互いに近く（同じ関数や同じモジュール）に置く
# 3.8 対称性
- コードに一貫性を持たせ、「同じ考えなら、コードのどの場所で現れても、同じように表現される」ようにする
###### 同じことは同じ表現にする
- 「追加」メソッドがあれば、対になる「削除」メソッドを作成する
- あるグループにある関数は、同じ引数を取るようにする
- あるモジュール内のデータは、すべて生存期間が同じであるようにする
- ある関数内で、呼び出す関数の抽象度は同じレベルとする
# 3.9 宣言型の表現
- コードの意図を伝えようとする時、できるだけ「命令型」より「宣言型」で表現する
- 命令型：問題の解法（データ構造とアルゴリズム）を記述
- 宣言型：問題の定義（解くべき問題の性質や、その際に満たすべき制約）を記述
# 3.10 変更頻度
- 同じタイミングで変更される（「変更理由」が同じ）要素は同じ場所に置き、異なるタイミングで変更される要素は別の場所に分けておく
- 「変更理由」を複数持つコードは脆い
- 「変更理由」が1つのコードは高い凝集性を満たしているため堅牢
###### 関連
- 「単一責任の原則」モジュールを変更する理由は、1つより多く存在してはならないという原則
記事を楽に書く努力をする

# はじめに

Qiitaで記事を書くことが楽しくなってきたのですが、Mark Downで書くことがいまいち慣れないな…と思い、自分なりに楽にできるような方法を模索してみました。
同じ悩みを持っている方に届けば幸いです。
逆に、もっとこうしたらよくなる！という方法をご存じの方はぜひコメントください。

# ユーザー辞書を使う

ユーザー辞書によく使うMark Downを登録しました。
何を当たり前な…となるかと思いますが、これで以前に比べて格段に書くスピード、手間が減ったように思います。

## ユーザー辞書の登録方法（Win11）

Windowsタスクバー、（あとかある部分）を右クリック、
「単語の追加」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/b648d3ae-2f1f-d359-00e9-0a6430fdcad1.png)

単語の登録画面が表示されます。ここでは例として、
「い」と入力した場合、「今から帰ります。」と候補に出るようにします。

・単語（登録したい内容）
・よみ
・ユーザーコメント（任意）

を入力し、「登録」ボタンを押して登録完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/71547f6f-202f-9530-ee70-49f3a1149d21.png)

登録後、「い」と入力した場合、「今から帰ります。」が候補に表示されるようになりました。これで登録成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/8545b85c-e851-fcb8-8cb4-aaa5dfc81103.png)

この要領でMark Down記法をいくつか登録したのですが、
以前に比べて記事を投稿するのが楽になりました。

他にもよい方法があれば都度投稿していきたいと思います。

# おわりに

まだまだ改善できる余地はあると思います。
もっともっとアウトプットに対するハードルを下げて、より自分の中の知識を手軽に発信で着るようにしていきたいと思います。
multipassのdockerに、VSCODEでSSH接続した件

Macで使っているVirtualBoxで動いているUbuntu１８.０４で、multipassが使えることを知り、この数日色々取り組んでいます。
その中で、dockerが使えることを知り、下記の記事を書きました。

https://qiita.com/masaru21/items/0b26d8c4559a07cefe9f



![スライド3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/f0be7c79-f275-b93e-dc42-8cb0f7460027.jpeg)
私の環境を図にしてみました。

multipassのチュートリアルでdockerをインスタンスする中で、Portainerを知りました。
![VirtualBox_Ubuntu0319_26_03_2022_13_53_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/2b2476d8-6e40-53d6-103f-85d39ef00f20.png)
このテンプレートの中で、WordPressを見つけました。

早速、WordPressのイメージのデブロイを試みました。

そして、公式のWordPressのdockerのページで、docker-compose.ymlの設定を学びました。

https://hub.docker.com/_/wordpress

仮想マシンでのホストOSのUbuntu１８.０４の中に、docker-compose.ymlを保存して、実行しました。
ところが、エラーになりました。

私は、この時Multipassで作られたドッカーは、ドッカーなのでUbuntu１８.０４の上で動いていると持っていました。でも、実際は、dockerという名前のインスタントの上で、ドッカーが動いていました。

パスは、multipassのチュートリアルを読み、下記のコマンドでパスを通しました。
```bash
multipass alias docker:docker
```

このdockerのインスタンスの中に、docker-compose.ymlをセットする必要があると思いました。
それで、VSCODEでファイルの修正ができるように、dockerのインスタンスにSSH接続できるように試みました。

## 秘密鍵
下記の記事を参考に、秘密鍵のペアを作りました。

https://qiita.com/kazokmr/items/754169cfa996b24fcbf5

https://www.attachmate.com/ja-jp/documentation/reflection-desktop-v16/rdesktop-guide/data/ssh-keygen_command_rf.htm

https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-20-04-ja



```bash
ssh-keygen
```


## ポート２２を開けました。
一応念の為ポート２２を開けました。
```bash
sudo ufw allow ssh
```

## dockerのインスタンスに、公開鍵をセット
今回作った公開鍵をdockerの中に、セットします。

今回作った公開鍵は、ここにあります。

```bash
/home/アカウント名/.ssh/id_rsa.pub
```
viで開いておくと良いと思います。

Ubuntu18.04で作った公開鍵を、下記のdockerのインスタンスのファイルの位置にある”authorized_keys”に保存します。

テキストエディタでコピーする形で、大丈夫です。


```bash
.ssh/authorized_keys
```

:::note alert
今回、すでに"authorized_keys"が、ありました。
既に存在する場合は、上書きせず追記してください。

既にあるキーの下に、改行して追記してください。

```bash
vi .ssh/authorized_keys
```
という感じで、authorized_keysを開くと良いと思います。
:::


https://qiita.com/nnahito/items/dbe6fbfe347cd66ae7e6


公開鍵の追記のことは、こちらの記事も参考になります。

https://yukituna.com/3286/

## SSHで接続を試みます。

ssh ubuntu@XXX.XXX.XXXX.XXX

IPアドレスは、Portainerにアクセスした時のIPアドレスと同じです。

シェルを開いた時と同じインスタンスの表示が出たら、無事に接続できています。

## VSCODEの接続設定
VSCODEの拡張機能で、Remote-SSHをインストールします。

こちらの記事が、参考になります。

https://zenn.dev/s_ryuuki/articles/66e2391c2d5f98

接続の指定は、ubuntu@XXX.XXX.XXXX.XXXです。

この後”秘密鍵の交換・・・・パスワードを入力してくださいとダイアログが、表示されます。
この時は、先に秘密鍵を作った時に設定した **パスフレーズ** を入力してください。

:::note warn
Ubuntuにログインするときのパスワードと、間違えないでください。

:::

この後少し時間がかかるかもしれませんが、色々と設定されるみたいです。
![スライド2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/1be40675-b388-0718-595c-7a56f280894e.jpeg)

これで接続できました。

## 仮想マシンを作り直した時
IPアドレスが同じ仮想マシンを作り直したときに遭遇した出来事を、こちらのサイトで書きました。

https://zenn.dev/masaru21/articles/db4576e3163694

公開鍵の編集の方法も、説明しています。
[JavaScript] プロパティを限定してオブジェクトのシャローコピーを行う

次のようにオブジェクトの指定プロパティのみをコピーしたいときがあります。

```js
const input = {
  a: "A",
  b: "B",
  c: "C",
  d: "D"
};

let output;
output = {
  a: "A",
  b: "B"
};
console.log(output); // {a: "A", b: "B"}
```

※let を使っているのは1ファイルで動作確認したからなので、普通はconst 使ってください。


## シャローコピーしてプロパティを削除する方法

```js
output = {...input};
delete output.c;
delete output.d;
console.log(output); // {a: "A", b: "B"}
```

悪くはなさそうですが、オブジェクト作ってから削除するのもどうかなと思います。

## 普通のオブジェクト生成

```js
output = {
  a: input.a,
  b: input.b
};
console.log(output); // {a: "A", b: "B"}
```

これがごくごく普通で一般的な方法と思います。
が input や a とか b を何度も書くのもちょっと冗長に感じます。

## 分割代入とオブジェクト省略記法を使った書き方

```js
let { a, b } = input;
output = { a, b };
console.log(output); // {a: "A", b: "B"}
```

a b を重複して書かなければいけないという問題もあるし、それ以上に a b という一時変数が生成されてしまうという問題があります。

次のように書きたいところだけど、そうすると想定した結果にならずに、output = input と同じになってしまいます。

```js
output = {a,b} = input;
console.log(output); // {a: "A", b: "B", c: "C", d: "D"}
```

## 関数を使って分割代入とオブジェクト省略記法を使う

そこでこちらの方法。
a b を重複して書かなければいけないという問題は残ったままだけど、一時変数は外部に影響を与えない。
それなりにきれいな書き方だと思う。

```js
output = (({ a, b }) => ({ a, b }))(input);
console.log(output); // {a: "A", b: "B"}
```

## reduceを使う。

何やっているかわからなくなって可読性が悪そうだけど、このような書き方でも同じ出力を行うことができます。

```js
output = 'a,b'.split(',').reduce((r, k)=>{
  r[k] = input[k];
  return r;
}, {})
console.log(output); // {a: "A", b: "B"}
```

こういう場合は、関数化してしまうとよいでしょう。関数化してしまえば内部実装などどうでもよいです。

```js
const copyProp1 = (obj, propNames) => {
  return propNames.split(',').reduce((r, k)=>{
    r[k] = input[k];
    return r;
  }, {})
};

output = copyProp1(input, 'a,b');
console.log(output); // {a: "A", b: "B"}
```

## Object.assign と map を使う

オブジェクトをそれぞれ作ってマージするというやり方でも行えます。オブジェクト生成数とマージ処理があるのでなんか遅くて無駄な気もしますが。

```js
output = Object.assign({}, ...'a,b'.split(',').map(k=>({[k]: input[k]})))
console.log(output); // {a: "A", b: "B"}
```

これも、関数化してしまうと内部が読めなくても問題がないです。

```js
const copyProp2 = (obj, propNames) => (
  Object.assign({}, ...propNames.split(',').map(k=>({[k]: obj[k]})))
);

output = copyProp2(input, 'a,b');
console.log(output); // {a: "A", b: "B"}
```

## いろいろ対応したいなら、関数に閉じてしまえばよい。

自作の Parts.js で実装してます。

```js
output = copyProperty(input, 'a,b');
// あるいは
output = copyProperty(input, ['a', 'b']);
```

主な処理のソースコードはここにあります。単に配列か文字列かで場合分けしている程度なことですが。

partsjs/_copyProperty.js at master · standard-software/partsjs
https://github.com/standard-software/partsjs/blob/master/source/object/_copyProperty.js

いろいろな引数に対応したければ、関数で書いてしまえばいいでしょう。

## 最後に

即時で書くときに
「関数を使って分割代入とオブジェクト省略記法を使う」のやり方もよいかもだけど
誰にでも読みやすいということを考えると
「普通のオブジェクト生成」のやり方が一番いいかもしれません。

何かの参考になったら、LGTMください。

もっとこんな風なやり方あるよ、とかあったら教えていただけると助かります。
Discord.jsで多機能Botを作る ～開発環境の構築～【#1】

今回からDiscord.jsで多機能Botを作っていきます
# 開発環境
- Windows10
- npm 8.3.0 (今からインストールします)
- node 17.1.0 (今からインストールします)

# Node.jsのインストール
[Node.jsの公式サイト](https://nodejs.org/en/download/)に行って、Nodeをインストールします。

Currentをクリックして、
![Qiita-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049721/e2f59fcf-2d7b-8281-50c6-d2ddc8ab7eb7.png)

Windows Installerをダウンロードしましょう。
![Qiita-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049721/0e57c1e0-2a3a-6a48-c17e-53e0ebc7f19d.png)
ダウンロードが終わったら、インストーラーを開いて、指示に従ってインストールしましょう。
npmは、Nodeをインストールすると一緒についてくるらしいです。
下記のコマンドを実行して、返事が来たら成功です

```powershell
npm -v
8.3.0

node -v
v17.1.0
```

# Visual Studio Code(VScode)のインストール
[VScodeの公式サイト](https://code.visualstudio.com/Download)に行きます。

Windowsをクリックして、インストーラーをダウンロードしてください。
![Qiita-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049721/a9417adc-5379-05b5-4b87-fc7171beb729.png)
インストーラーを起動し、指示に従ってインストールしましょう。

# DiscordのBotを作る準備
WindowsPowerShellをインストールし、下記のコマンドを実行しましょう

```powershell
cd "作業フォルダを置くディレクトリ"
mkdir discordbot
cd discordbot
npm init -y
npm i discord.js js ms canvs aurora-mongo
code .
```

すると多分VScodeが起動すると思います。
これで、開発環境の構築は終了です。

# 次回 ～DiscordのBotの起動とコマンドハンドラーの作成～
# リンク
- [Node.js](https://nodejs.org/en/download/)
- [VScode](https://code.visualstudio.com/Download)
PowerShellでアプリケーションの差分を出す

↓の記事で取得したbaseファイルと、別端末で同じスクリプトを実行したtarget_XXファイルを比較して差分を出しています！
[PowerShellでアプリ情報を取得する](https://qiita.com/sakekasunuts/items/106f9c0f828a07e81592)

```:フォルダ構成
親フォルダ
　├─result　←ここに差分のアプリ(csvファイル)が出力される。
　├─csv
　｜　├─base.csv　←事前にベースとしたいファイル名を「base.csv」に変更して下さい。
　｜　├─target_1.csv
　｜　└─target_2.csv
　└─compare.ps1
```

```PowerShell:compare.ps1
New-Item result -ItemType Directory -Force
$content = Get-ChildItem .\csv
$base = Import-Csv -Encoding OEM .\csv\base.csv | %{$_.DisplayName}

#繰り返し処理
foreach ($i in $content){
    $target = Import-Csv -Encoding OEM .\csv\$i | %{$_.DisplayName}
    $sabun = $base | Where-Object { $target -notcontains $_ }
    Write-Host "$i の処理が完了しました"
    $sabun > .\result\$i
}
```

```:実行結果（target_1.csv）
7-Zip 20.02 alpha (x64)
Android Studio
N Air 1.0.20190912-1
XMind 11.1.0
HP Documentation
```
```:実行結果（target_2.csv）
7-Zip 20.02 alpha (x64)
Android Studio
N Air 1.0.20190912-1
XMind 11.1.0
HP Documentation
Helltaker
Vampire Survivors
7 Days to Die
Enter the Gungeon
Hacknet
```

## 意外とハマったところ
リストはexport-csvできない
[PowerShellのcsv出力が上手くいきません。](https://teratail.com/questions/125185?link=qa_related_pc#:~:text=%E3%81%99%E3%81%A7%E3%81%AB%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA%E6%B8%88%E3%81%BF%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%E3%81%AA%E3%81%AE%E3%81%A7%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA%E3%81%99%E3%82%8B%20Export%2DCsv%20%E3%81%AF%E4%BD%BF%E3%81%88%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82)
アプリケーションの雛形を作成する。

駆け出しエンジニアのTakaです。
本日はアプリケーションの雛型の作成の仕方を学んだのでシェアさせて頂きます。

まず、大切になってくるのは、
1,今から自分の作成するアプリケーションの内容を考えることです。どんなアプリを作りたいのかしっかりと考えます。

2,次にアプリケーションの名前を考えます。

3,その後に、アプリケーションの雛型を作ります。
その際に使うのがrails new コマンドです。

rails newコマンドでアプリケーションに必要になってくる基本的なデータやファイルは一式揃います:relaxed:

```
rails new 作成するアプリケーションの名前
```

4,次にデータベースを作成します。
※データベースとは決まった形で整理したデータの集まりのこと。
例えば、氏名、電話番号、社員番号などがバラバラに整理されていたら分かりにくいように、整理してまとめたもののことをデータベースという。
アプリケーションが生み出すデータを保存するところです。
```
rails db:create
```

5,データベースを作成した後にサーバーを起動します。
```
rails s
```

これでlocalhost:3000にアクセスしたらhappyな画像が映し出されているはずです。

この一連の流れはアプリを作成するときに必ず必要になってくるので覚えておきましょう。
AWS Schema Conversion Tool とは

## 勉強前イメージ

DBに関係ある系でconversionやからスキーマを変換するやつ？

## 調査

### AWS Schema Conversion Tool とは

AWS Schema Conversion Tool 略して SCT ということもあります。
こちらはスタンドアローンアプリケーションになっており、Windows Serverにインストールしたりします。

SCTを使用すると、データベースエンジン間で既存のSQLスキーマーを変換できます。
どういうことかというと、データベースの移行を行う際移行にあたりどれくらいの難易度なのか、またDMSと連携すると実際データのコピーも可能です。
特に机上での検討を行う際の資料として評価レポートを作ることができます。
以下のような難易度で評価されます。

- 自動変換
- 簡単なアクションが必要(1h程度)
- 複雑なアクションが必要(4h程度)
- 大規模なアクションが必要(4h以上)

また、それぞれ全体のどれくらいか自動変換できるのか や 自動変換ができない場合は詳細での原因などが提示されます。

変換等はできますが、パフォーマンステストはできないので
移行後のパフォーマンステストはクライアント側で行う必要があります。

## 勉強後イメージ

移行の時にSQLを(一部)自動で変換してくれたりする機能なんだね。
どれくらいめんどくさいかってのも見えるのはPJ始まった最初の段階では欲しい情報だね。

## 参考

- [AWS のサービスを使ったオンプレミスからのデータベース移⾏](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-18_AWS_Summit_Online_2020_DAT01.pdf)
- [複雑なデータベース移行の負担と時間を削減するAWS DMSとAWS SCT](https://swri.jp/article/1008)
[javascript] env使いたい時にでたエラー

javascriptで環境変数を使いたい。
node_moduleの[dotenv](https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import)を入れたのだけどうまく動かなかった時の忘備録

環境
es6
typescript
webpack

手順
1. npm install dotenv --save
2. .envをproject直下に作成
```.env
SECRET_KEY="HOGE"
```
3. 呼び出し

```index.ts
import 'dotenv/config'
const PRIVATE_KEY = process.env.PRIVATE_KEY;
```

# エラー1
確かにあるのになぜかモジュール読み込めていない。
```
ERROR in ./node_modules/dotenv/config.js
Module not found: Error: Can't resolve './lib/cli-options' in '[...]/node_modules/dotenv'
 @ ./node_modules/dotenv/config.js 6:6-34
 @ ./src/index.ts

ERROR in ./node_modules/dotenv/config.js
Module not found: Error: Can't resolve './lib/env-options' in '[...]/node_modules/dotenv'
 @ ./node_modules/dotenv/config.js 5:6-34
 @ ./src/index.ts

ERROR in ./node_modules/dotenv/config.js
Module not found: Error: Can't resolve './lib/main' in '[...]/node_modules/dotenv'
 @ ./node_modules/dotenv/config.js 2:2-23
 @ ./src/index.ts
```

# 解決法
拡張子の'.js'が抜けてた。
tsの拡張子を省略できる一方でjsを書き忘れると拡張子の解決ができなくなるみたい！

```webpack.config.js
module.exports = {
    // ...
    resolve: {
        extensions: ['.ts', '.js'],
    },
}
```

# エラー2

```
ERROR in ./node_modules/dotenv/lib/main.js
Module not found: Error: Can't resolve 'fs' in '[...]/node_modules/dotenv/lib'
 @ ./node_modules/dotenv/lib/main.js 1:11-24
 @ ./node_modules/dotenv/config.js
 @ ./src/index.ts
```

# 解決法
割とみんな出会っているみたい。
fsはnodeのポリフィルのために使っているみたいで、フロントでは必要ないので以下の設定を追加すれば良いらしい
参考:[Can't resolve 'fs'](https://megu-tech.hatenablog.com/entry/2019/10/09/170631)
```webpack.config.js
module.exports = {
    // ...
    node: { fs: 'empty' }
}
```
Prisma備忘録

## 基本的なワークフロー

![Prisma workflow](https://res.cloudinary.com/prismaio/image/upload/v1628764839/docs/aRJmVFY_osasel.png)

上は`prisma generate`を使った場合のワークフローだが、`prisma migrate`でもほとんど同じ：

1. `prisma`と`@prisma/client`をインストール
    - `prisma`はコマンドラインツール（以前は`@prisma/cli`だった）。`--save-dev`で構わない
    - `@prisma/client`はJavaScript/TypeScriptから操作するためのインターフェースライブラリ。
1. `prisma init`で初期化。
    - この段階で、設定ファイル類（`prisma/schema.prisma`, `.env`など）が自動的に生成される。
    - 「次のステップ」がコンソール上に表示されるので、そこまで迷わないはず
1. スキーマを設定ファイル`prisma/schema.prisma`で編集
    - 編集するごとに`prisma migrate`でマイグレーションをすると、データベースのアップデート以外にJavaScript/TypeScriptのファイルが自動生成される。
    - `@prisma/client`から、データベース操作用クラスをインポートして使える。

## インストール

```bash
npm i prisma --save-dev
npm i @prisma/client
```

## 設定ファイルの生成・初期化

```bash
npx prisma init
```

- `--datasource-privider` オプションをつけることで、データベースのタイプを指定できる（デフォルトだと`postgresql`だったはず）
- `prisma/schema.prisma`上で、データベースのタイプを指定。
- `.env`上で、データベースのURLを指定
    - ふつうのデータベースなら`<provider-type>://<host>:<port>`でよい
    - SQLiteなら`file:./<database-name>.db`のような相対パスとして指定

## スキーマの編集

例：
```"schema.prisma"
// ...

model Post {
  id         Int        @id @default(autoincrement())
  title      String     @db.VarChar(200)
  published  Boolean    @default(true)
  content    String
  authorId   Int
  author     User       @relation(fields: [authorId], references: [id])
  categories Category[]
}

// ...

```

関連付けの方法：

- ＊-to-oneの関係の場合： `@relation`を使う（上の`author User`）。`fields`で指定、関連づけるエンティティのID（上では`authorId`）を保持しておいて、「このフィールドを使って別のエンティティを関連づける」ことを指示できる。
- one-to-manyの関係の場合：配列型の属性を定義（上の`categories Category[]`）。逆側のエンティティで`@relation`の指定をしている場合、`references`で指定したフィールドを用いた関連付けが行われる（上の`author User`の例なら、`User`はそのフィールド`Posts[]`の関連付けに、`Post`の`id`を使用する）。

## マイグレーション

```bash
npx prisma migrate dev ...
```

- `--create-only`を入れると、マイグレーション用のSQL文は生成するがデータベースには適用しない。生成された文を自分でカスタマイズすることも可能。
- `--preview-feature`を入れると、（おそらく）どういうことをするかをコンソール上に表示してくれる（のだと思う）。
- `--name <stage name>`を入れると、マイグレーション名を指定できる。自分なりのマイグレーション内容の説明を入れたりするのに使う。

いちおう`prisma db push`というコマンドも存在している。これはマイグレーションを「オフィシャル」なものにする前にプロトタイピングをして動作を確認したい場合に使うようだけれど、詳細は今のところ知らない。

## 参考

### 一般

- https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch
- https://www.freecodecamp.org/news/build-nodejs-database-using-prisma-orm/
- https://dev.to/aryanjnyc/introduction-to-prisma-with-next-js-1l0

### マイグレーション

- https://www.prisma.io/docs/guides/database/developing-with-prisma-migrate
- https://www.prisma.io/blog/prisma-migrate-preview-b5eno5g08d0b
- https://www.prisma.io/docs/guides/database/prototyping-schema-db-push

### クライアント

- https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/generating-prisma-client
HerokuにGitHub経由でDjangoアプリをデプロイする。DBにはPostgreを使う。（2022.3.26）

最近、djangoアプリを使える様に練習中です。簡単な事から始めて徐々に自分が実装したい物を作りたいと思っています。

<h1>背景</h1>
前回、デプロイするアプリにCSSを反映する事が出来ました。データベースにはSQLite3を使いましたが、webアプリとして使いたい時はPostgreを使った方が便利な様です。実際SQLite3では、いろんなデバイスから入力した際、きちんと保存できていない事がありました。

前回の投稿
[デプロイするDjangoアプリ（メモアプリ）にCSSを反映させる（2022.3.19）](https://qiita.com/tan0ry0shiny/items/7dce5df9da62599bcd3d)
<h1>目的</h1>
今回はPostgreを使ってデプロイしたいです。

<h1>方法</h1>
今回は既に作っていたアプリのDBをSQLite3からPostgreに変更します。基本的には

[こちら（DjangoにPostgreSQLデータベースを導入する方法）](https://zenn.dev/hathle/articles/django-postgresql)を参考にしました。
<h2>Postgreを使う設定</h2>

1. settings.pyの修正をします。DBにPostgreを使える様に書き換えるのですが、今回は.envファイルを使って環境設定を書きたいと思います。
1. .envの追加をします。こちらにPostgreの設定を記述します。
<h3>.envファイルの作成</h3>
アプリのルートディレクトリに「.env」ファイルを作成して、下の様に記述します。詳しくは

[参考2](https://zenn.dev/hathle/articles/django-postgresql)をご覧下さい。


```django:appディレクトリ/.env
DATABASE_URL=postgres://test_user:test_password@localhost:/test_db
```
<h2>Postgreのインストール</h2>
ローカルにPostgreSQL データベースを構築します。やってて思いましたが、実際に使うのはサーバーのDBなのでこれはいらないかもしれません。とは言っても動作確認はしたいのでローカルに入れておくのは良いと思います。こちらも詳しくは

[参考2](https://zenn.dev/hathle/articles/django-postgresql)をご覧下さい。

```ubuntu:ubuntu
$ sudo apt install postgresql
$ sudo service postgresql start
$ systemctl enable postgresql
$ sudo -u postgres psql
```
<h2>本番環境でのmigrate</h2>

[GitHubとHerokuを連携してDjangoアプリをデプロイする（2022.3.15）](https://qiita.com/tan0ry0shiny/items/149179d3d6a3f6c5aa73)では、SQLite3を使っており、デプロイする時にmigrateをされていたのかもしれません。この時は問題なかったのですが、今回はデプロイ後にアプリを開いて見るとエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/343dcc1e-1c1b-5890-b45f-cfc029c28b15.png)


仕方がないので、ローカルからHerokuコマンドでmigrateしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/cbde70fd-700c-e764-13e0-57c65f5fd47b.png)

<h1>結果</h1>
これで問題なく動くようになったので、しばらくはこれで運用したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/b8242b17-5d44-cfb0-dedc-137f4aa9b6f0.png)

DBが何を使っているのかは確認の仕方が分からなくて出来ていませんが、状況的にPostgreを使ってる事が考え易いので、今回の目的は達成出来ていると考えています。
<h1>考察</h1>

環境設定ファイルを「.env」にまとめていますが、肝心の隠匿化が出来ていません。恐らく、「.gitignore」に入れてgithubに上げれば良いんだと思いますが、それもそのうち調べて実装したいと思います。

<h1>課題</h1>
ディープラーニング使った簡単なアプリをデプロイしたいです。まずは文字認識くらいですかね。

<h1>参考</h1>

1. [デプロイするDjangoアプリ（メモアプリ）にCSSを反映させる（2022.3.19）](https://qiita.com/tan0ry0shiny/items/7dce5df9da62599bcd3d)
1. [DjangoにPostgreSQLデータベースを導入する方法](https://zenn.dev/hathle/articles/django-postgresql)
android:layout_width="0dp"て何？

# この記事は
Androidで画面を構成していく時、`height`や`width`などを指定することは頻繁にあることと思います。

このような時に、多くの場合は、`wrap_content`や`match_parent`を使いますが、たまに`android:layout_width="0dp"`のような表現を見ることがあります。
ではこれらの違いを見ていきましょう

# wrap_content：子に合わせる
これはその中に入るビューの大きさに任せるよ、という意味です。
つまり、例えば`layout_height="wrap_content"`で指定されたButtonの中に`layout_height="100dp"`のTextViewを入れたとします。その場合、Buttonの高さはTextViewに合わせて100dpになります。


# match_parent：親に合わせる
これは、親(1つ上のビュー)の大きさに合わせるよ、という意味です。
例えば、`layout_height="100dp"`としているButtonの中に`layout_height="match_paretnt"`で高さを指定したTextViewを入れるとします。その場合、TextViewの高さは親であるButtonと同じ高さである100dpに設定されます。


# 0dp：match_constraint
:cat: これは`ConstraintLayout`を使う上での話です！
ここでタイトルに戻ります。`android:layout_width="0dp"`とは何なのでしょうか。
この`0dp`とは実は`match_constraint`のことを言っています。
つまり、親が`ConstraintLayout`の場合、相対的に変化する親の`ConstraintLayout`の高さに応じて中身も高さを変えるよ、ということになります。
background-colorをbackgroundで一括指定してはいけない

``background-color``の省略記法に知見がありましたので共有します。

海外の動画ですが、こちらを引用させていただいております。

https://www.youtube.com/watch?v=iGkK-5il6Mk

``background-color``は以下のように一括指定記法を用いて``background``で省略することができます。

```CSS:style.css
div {
	background: #fff;
}
```

しかし、このような場合はどうでしょうか。

```html:index.html
<div class="hero inverted">This is hero area</div>
```

```CSS:style.css
.hero {
	background-image: url(./images/hero.jpg);
	background-size: cover;
	height: 500px;
	font-size: 5rem;
	text-align: center;
	line-height: 500px;
}

.inverted {
	color: #fff;
	background: #333;
}
```

同一の``div``内に複数のクラスを設定しており、``.inverted``で一括指定記法を使って背景に``#333``を指定しています。

これはこのように表示されます。

![2022-03-26_18h15_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/c87d27d1-862a-2bb4-d407-3d48b935ea2d.png)

``.hero``で指定しているはずの背景画像が表示されません。

原因を開発ツールで確認してみましょう。

![2022-03-26_18h16_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/0af217fe-0915-dfca-9d39-d3544b09f8a5.png)

``background-image``が``initial``で上書きされ、``.hero``で指定した背景画像が無効化されています。

これはなぜかというと、``.inverted``で一括指定記法で記述した``background-color``以外は指定なしと見做され、``initial``が指定されているというわけです。``initial``は初期値という意味です。

参考に``background``で関連のプロパティー一覧です。

| プロパティ | 初期値 | 意味 |
|:-----------|:------------|:------------|
| background-image | none | 背景画像を設定する |
| background-position | 0% 0% | 背景画像の初期位置を設定する |
| background-size | auto auto | 要素の背景画像の寸法を設定する |
| background-repeat | repeat | 背景画像をどのように繰り返すかを設定する |
| background-attachment | scroll | 背景画像の固定・移動を指定する |
| background-origin | padding-box | 背景の基準位置を指定する |
| background-clip | border-box | 背景の適用範囲を指定する |
| background-color | transparent | 背景の色を指定する |

画像を表示させるには、きちんと``background-color``と省略せずに記述すればOKです。

```CSS:style.css
.inverted {
	color: #fff;
	background-color: #333;
}
```

![2022-03-26_18h29_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/c062fc68-e44d-b87d-2901-fc34a9b193fb.png)

意図したところにのみCSSが当たります。

![2022-03-26_18h31_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/77852d10-b3d1-5f77-e062-6cd4d8eb3a42.png)

この例からもわかる通り、そもそも``background``は``background-``に続く複数のプロパティを一括で指定するためのものであり、ただ省略したいがために使うべきではありません。

私は元々きちんと``background-color``を使う派だったのですが、``background``で省略している記事が非常に多いことから真似をして省略するようになってしまいました。

**意図して省略しているならいいですが、そうでなければ省略はすべきではない**ですね。
TomcatでJAX-WSを使う

業務でアプリケーションサーバ（glassfish)で動いているSOAP(JAX-WS）のアプリケーションを新しいサーバへマイグレーションしなくてはいけなくなった。新しいサーバにマイグレーションすると共にアプリケーションサーバをglassfishからtomcatへ変更するために色々調べたのでそのためのリンク集をまとめた。

## JAX-WSの実装系

+ metro
https://javaee.github.io/metro-jax-ws/
https://eclipse-ee4j.github.io/metro-jax-ws/

+ Apache Axis2
https://axis.apache.org/axis2/java/core/

+ apache cxf
https://cxf.apache.org/docs/jax-ws.html

### metro
glassfishはJAX-WSのリファレンス実装(metro)を使っている。互換性重視のためmetroの古いバージョンで動かせるようにした。

+ sun-jaxws.xml作成
glassfishはjax-wsの参照実装のためsun-jaxws.xmlが不要でjax-wsが動作する。他のアプリケーションサーバーはsun-jaxws.xmlにクラスを登録する必要がある。

+ web.xmlの修正
sun-jaxws.xml同様に他のアプリケーションサーバーではContextListenerとServletを登録する必要がある。以下の公式ドキュメントに詳細は書いてあるので参照してほしい。
https://javaee.github.io/metro-jax-ws/doc/user-guide/ch03.html#the-sun-jaxws-xml-file

:::note info
DataSource
DBのデータソースの名前の命名規則が異なり、環境によってデータソース名の変更が必要な場合がある。スプリングのフレームワークでは以下のような変更が必要だった
glassfishの場合 "jdbc/sampledb"
tomcatの場合 "java:comp/env/jdbc/sampledb"
:::


## 今後
マイグレーション作業は、動けば終わりでなく、機能的にデグレがないか、ピークパフォーマンスに問題がないか、ロングランテストで問題がないかを確認する必要がある。

## その後
+ 開発環境、本番環境でそれぞれ約2週間以上のデグレ試験をして問題がないこと確認。
+ ピークパフォーマンスに問題ない事を確認。
+ ロングランテスト（１時間）で問題ない事を確認。
上記３つを確認して実際に本番にリリースしてみるとQPSが低い場合にレスポンスタイムのAVEと90%tile,95%tile問題がある事が確認されロールバックする事になった。コネクションプール数、最大接続数などが最適値になっていないため、レスポンスタイムの結果が以前より悪くなった。レスポンスタイムはAVE,MAXの他に90%tile,95%tileの測定するべきで、ユーザーにも予め共有しておく事が好ましい。またロールバック基準をあらかじめ定めてユーザー側に提示しておく必要も重要であると今回の経験より学んだ。
[AWS SAM] 1つのtemplate.ymlから複数環境へのデプロイ

# 方針

- 参考にさせて頂いた記事によると、1ソース(1つのtemplate.ymlなど)から複数環境にdeployしたい場合次の通りとしたほうが良いと判断
    - 環境ごとのAPI Gateway
    - 環境ごとのLambda Application & Function
- (初めは1つのAPI Gatewayで複数ステージを作れば良いと思ってたがSAMがそのやり方に対応していないらしい)

## 参考

[AWS SAMにおける環境管理のベストプラクティス | 株式会社CyberOwl](https://www.cyberowl.co.jp/blog/technology/1634#7mw8fyo9)

# 作業後のイメージ

- devとprodの2つの環境でdeployする想定

## API Gateway

- dev-XXXとprod-XXXの2つが作成される

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490917/f414e1cd-2b06-8fc7-a0fd-2c91b952f9df.png)


### ステージ

- devの場合、ステージ名を”dev”とする
- prodの場合も同様にステージ名は”prod”となる

![stage-name.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490917/a9e4ffbd-7c16-c6fe-f97d-9d1816e8773d.png)


## Lambda

- dev-XXXとprod-XXXの2つが作成される

![Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490917/fb512363-1188-e8df-969e-e399f080f360.png)


# やったこと

## 環境を定義するパラメータを作成

- 今回は `ENV` というパラメータに設定された値によって環境ごとのdeployを実現する

### 受け取り側

- deploy時に `-config-env` をつけない場合はデフォルトで”dev”を入れている
    - production環境にdeployするには明示的に環境を指定するオペレーションとするため

```yaml
Parameters:
  ENV:
    Type: String
    Default: dev
```

### 定義側

- deploy時に `-config-env prod` とすることで ENVパラメータに”prod”が設定される

```yaml
[prod.deploy.parameters]
parameter_overrides = "ENV=\"prod\""
```

## API Gatewayを(明示的に)定義

- 環境によって明示的に「API Gatewayの名前」を変更するため
    - ついでにステージ名も変えておく
- 元々AWS::Serverless::Apiが未定義だったため、API Gatewayは自動作成されていた

```yaml
    Resources:
++    RestApi:
++      Type: AWS::Serverless::Api
++      Properties:
++        Name: !Sub ${ENV}-sample-api-gateway
++        StageName: !Ref ENV
```

## 各LambdaFunctionを定義したAPI Gatewayに紐付け

```yaml
    ExampleFunction:
        Type: AWS::Serverless::Function
        Properties:
          Events:
            Api:
              Properties:
++            RestApiId: !Ref RestApi
```

- (不要なプロパティは省略して記載している

## (おまけ)API Gateway IDの出力用の表現を変更

- ${ServerlessRestApi} ⇒ ${RestApi}
    - `ServerlessRestApi` はAPI Gatewayが自動で作成される場合のリソース名なので上記で定義した `RestApi`(任意に設定可) に変更している
- endpoint末尾の “Prod” ⇒ ${ENV}
    - endpoint末尾はステージ名が適用されるため

```yaml
Outputs:
  WebEndpoint:
    Description: "API Gateway endpoint URL for Prod stage"
    Value: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/${ENV}/"
  # Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
```

# 動作確認

- エンドポイントの一部は修正している
- devとprodそれぞれのエンドポイントが叩けていて、想定通りの値が返ってくることを確認できればOK！

```yaml
$ curl https://xxxxxxxxx.execute-api.region-name.amazonaws.com/dev/     
{"message":"Hello world!"}%                                                                                                                                                        

$ curl https://yyyyyyyyy.execute-api.region-name-1.amazonaws.com/prod/    
{"message":"Hello world!"}%
```
チェックボックスの作り方

チェックボックスの作り方を調べていると、いくつかの方法があることがわかった。

①``check_box`` モデルに関連するチェックボックス　　
　※パラメーターとして値を保存したい場合
②``check_box_tag`` モデルに関連しないチェックボックス
③``collection_check_boxes`` 複数選択のチェックボックス

今回実装したい内容は①に当てはまるので、それをまとめる。


### check_box

まずはマイグレーションファイルに以下を入力。
```ruby:
class Createxxxxxx < ActiveRecord::Migration[6.0]
  def change
    create_table :xxxxxx do |t|
      t.boolean :カラム名　　# 追記
     
      t.timestamps
    end
  end
end
```
次にビューファイル。
```html:
<%= f.check_box 'カラム名', {:checked => true}, checked_value = “true”,unchecked_value = “false” %>
```
これでDBには(false：チェックなし) or (true：チェックあり)が登録される。


ちなみに上記のコードを分解すると、以下の内容となる。
``f.check_box(カラム名, {オプション},checked_value = “true”,unchecked_value = “false” )``


### オプションについて
オプションには以下の種類がある。

1. **:checked**   
  チェックボックスのチェックの有無
2. **:include_hidden**	 
  隠しフィールドは生成されない
3. **:size**	        
  フォームの幅
4. **:maxlength**     	
  入力フィールドに入力可能な最大文字数
5. **:accept**
  フォームで受付可能なMIMEタイプ
6. **:readonly**	
  フォームの内容変更禁止
7. **:disabled**	
  無効化
8. **:tabindex**	
  Tabキーによる入力欄の移動順
9. **:accesskey**
  フォームに移動するショートカットキー
10. **:id**	
  要素固有の識別子
11. **:class**
	要素を分類するクラス名
12. **:title**
	要素の補足情報
13. **:style**
	要素の補足情報
14. **:dir**
	表記方向
15. **:lang**
	基本言語

### checked_value」と「unchecked_value」
「checked_value」と「unchecked_value」は、チェックされた場合と外された場合に取得できる値の設定。
チェックが着いていればtrue、外れていればfalseとなる。
ちなみにtrue、falseの代わりに``checked_value = “1”, unchecked_value = “0”``とすることもできる。

以上。
データラーニングギルド Advent Calendar 2021

データに関する記事を書こう！

https://qiita.com/official-events/30be12dd14c0aad2c1c2

テーマ2『データに関する記事を書こう！』参加記事です。

データラーニングギルド Advent Calendar 2021

https://qiita.com/advent-calendar/2021/data-learning-guild

データラーニングギルド Advent Calendar 2020

https://qiita.com/advent-calendar/2020/data-learning-guild2020


データラーニングギルド Advent Calendar 2019

https://qiita.com/advent-calendar/2019/data-learning-guild


データラーニングギルド というものがあることを知った。

https://data-learning.com/guild

参加者 171人

https://data-learning.com/application

980円/月

会員収入だけだと

167,850 円

広告収入、業務取り付き収入に頼らざるを得ないのか。

# データラーニングギルド Advent Calendar 2021

Qiitaの記事だけ拝見する。

データラーニングギルドAdventCalendar2021始まります！

https://qiita.com/tomoyuki-murakami/items/dbac2fd275cf151844bf

>執筆時点での参加メンバーは約250名ほどで、

80人ほど減っているのか。何があったし。

英語学習ゲーム「英語物語」に関するデータラーニングギルドでの分析企画についての振返

https://qiita.com/kanekoteruaki/items/86340b73bace5dbdb247

"データ"を扱う職種に転職してみて

https://qiita.com/Ippei_3535/items/65d6f325cdf84f17fb8a

情報システム部とデータ分析

https://qiita.com/brume_anna/items/f318a94ccb9d26182476

リモートワーク化で学んだ、DX推進に必要なドキュメンテーション能力の話

https://qiita.com/masanobu-tsuda/items/f626c1700566227b7003

データサイエンティストになって1年 思ったことまとめる

https://qiita.com/TSK14762625/items/f3727317aadcf5a2c3aa

データサイエンティストとしてDXに1年取り組んだ経験を振り返る

https://qiita.com/hasegawa16777216/items/95cb32135de4a6361cf1

本業Webアプリエンジニアのデータサイエンティスト副業事情

https://qiita.com/tamanobi/items/d391e258d11873a9b362

製造業R&Dからデータサイエンティストへの転職について

https://qiita.com/Spica09/items/38ca50672f10c09ee171

データ分析案件1年目でパイプラインを作った話

https://qiita.com/pinana/items/141283d2afe2576a6bb7

英語学習アプリ「英語物語」分析レポート

https://qiita.com/akatuki50/items/cd022ba21069c723a12e

工場系データサイエンティストがスマホアプリのデータ分析をやってみた話

https://qiita.com/Ottey/items/ecd2a4f5a7227d28caed

データエンジニアにキャリアチェンジした1年を振り返る

https://qiita.com/mouritakuto/items/dcfe498dd6411e0dc1f5

ポスドクから企業のデータ分析職に転職した後の一年間を振り返りました

https://qiita.com/tk-ml/items/d514e25ff8cf9553c0ca

30過ぎて機械学習エンジニアになって3年経ったので理想と現実について書いてみる

https://qiita.com/tomone_hata/items/f65848a42ee73541e048

【人生100年時代】続々・50代からのデータサイエンス

https://qiita.com/brainbrown/items/1b7b43b4b0dc48a70fe1

# まとめの前に

３年分拝見してからまとめを書く予定。

１年分のうち、Qiitaの記事だけ拝見した範囲では、内容に違和感はなかった。

ちょっと残念だと思ったのは、いいねがついていない記事があったこと。

ギルドだといいながら、お互いに尊重していない組織をいくつか見たことがある。

何人かが専門家だと思い込んでいて、自分より水準の低いものにはいいねをつけないような姿勢だったり、お金の支払いのある場所では協力するが、それ以外の場所では知らんぷりするような感じ。

猫に学ぶデータサイエンス

https://qiita.com/kaizen_nagoya/items/832af8dc7c6c06e5bbca

知らんぷりも、大事な技だと最近知った。
Windows タスクスケジューラでバッチ/PowerShellを非表示で実行する

# Windows タスク スケジューラでバッチを非表示で実行する

定期実行するため、バッチファイルやPowerShellファイルをタスク スケジューラに登録します。
が、コンソールウィンドウが表示されてしまいます。
バックグラウンドで実行してほしいです。

タスク スケジューラにはVBScriptを登録し、VBScriptからバッチ、PowerShellを実行することで、非表示で実行できます。

1. VBScriptファイルを作成する

    バッチファイルを実行する場合

    ```VBScript
    Set ws = CreateObject("Wscript.Shell")
    ws.run "cmd /c " & Wscript.Arguments(0), vbhide
    ```

    PowerShellを実行する場合

    ```VBScript
    Set ws = CreateObject("Wscript.Shell")
    ws.run "pwsh /c " & Wscript.Arguments(0), vbhide
    ```

2. タスク スケジューラに登録する

![スクリーンショット 2022-03-26 175832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399204/7f4f9632-20b6-09e4-b105-96c9e1202a0e.png)
全国の水族館の情報をスクレイピングしてみた

## はじめに
私は水族館が好きで、色々とあって全国の水族館の情報をスクレイピングしてみました。今回は、その方法をまとめました。

## 全国の水族館の情報をスクレイピングしてみた
### スクレイピングするページ
今回利用したページは以下です。一部載っていない水族館もありますが、そこは気にせず取得していきます。

http://www.web-aquarium.net/

上記のページに記載されている情報は転載を禁止されています。

### スクレイピングの流れ
今回のゴールは、前述したページより水族館の名前、ホームページのURL、住所を取得することを試みます。前述したページには各水族館の説明があるページのリンクが記載されているだけなので、元のページから各水族館のURLを取得し、水族館の説明のページをスクレイピングしていきたいと思います。

今回はPythonを使ってスクレイピングを行います。

### 実際のコード
```python
# 必要なライブラリ
import requests
from lxml import html
from bs4 import BeautifulSoup

# 水族館一覧のページのURL
url = 'http://www.web-aquarium.net/' 

# ページのHTMLを取得する
res = requests.get(url)
res.encoding = res.apparent_encoding
raw_html = res.text
soup = BeautifulSoup(raw_html, "html.parser")

# 水族館のURLリストを作成する
# aタグのみを取得して、URLを作成していく
import re
raw_aquarium_list = soup.find_all("a", href=re.compile("aquarium/aq_"))
aquarium_list_url = ['http://www.web-aquarium.net/' + data.attrs['href'] for data in raw_aquarium_list]

# 水族館の情報リストを作成する
# 元ページのHTMLを取得した時と同じ方法でHTMLを取得していく
import time
aquarium_list = []

for url in aquarium_list_url:
  res = requests.get(url)
  res.encoding = res.apparent_encoding
  raw_html = res.text
  soup = BeautifulSoup(raw_html, "html.parser")
  data = soup.find_all(id="data")
  name = soup.find(id="aqua_name").text
  if data == []:
    continue
  aquarium_list.append([name, data[1].text.replace('\n', '').replace('\t', ''), data[2].text])
  time.sleep(1)

```

## さいごに
スクレイピングしてみると日本には水族館がたくさんあるなと思いました。今回は水族館一覧の情報をスクレイピングしてみましたが、スクレイピングするときは色々と注意することもあります。そこには注意して行いましょう。

https://qiita.com/nezuq/items/c5e827e1827e7cb29011
IAMロールで社外の人へのアクセス権付与

# はじめに
自社のAWS環境のリソースを協力会社などの方に一部委ねて触ってもらう際に利用できる、IAMロールによる権限付与の方法です。
# 概要
社外からアクセスする人それぞれに自社のIAMユーザーを付与する方法もありますが、協力会社のAWSにIAMロールで自社AWSへのアクセス権を提供する方法がお勧めです。IAMユーザーを利用するのに比べて下記のようなメリットがあります。
* IAMユーザーのパスワードやアクセスキーの管理を相手に委ねることができて、ID管理の手間が減る。
* 招かれる側も複数のIDとパスワードを使い分ける必要が無いので手間が減る。

# 設定
下記のような前提でawsが2アカウントがあると仮定します。
| アカウント | ID | 内容 |
|:-:|:-:|:-:|
| aws-a  | 111111111111 |　自社のアカウント。外部から招く側。 |
| aws-b  | 222222222222 |　他社のアカウント。招かれる側。 |

:::note info
awsのアカウントIDは12桁の数字です。
:::

## aws-aの設定
外部アクセス用のロールを作成して、そこに委ねたい権限のポリシーをアタッチします。
### 社外からアクセスされるためのロールを作成する
コンソールから下記のタイプのロールを選択し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/a93ad2c9-d02e-34d0-f552-1e8d388d0906.png)
別のAWSアカウントを選択してaws-bのアカウントIDを指定します。下記のオプションを設定することができます。
<dl>
  <dt>外部 ID を要求する</dt>
  <dd>cli等のプログラムアクセス時に、接続先を明確にするためにキーワードを指定します。外部IDなしでは接続できませんが、パスワードではありません。</dd>
  <dt>MFA が必要</dt>
  <dd>aws-bのコンソールにMFAでログインしたユーザーだけを受け付けます。これを設定しておくと、結果的に協力会社内でのパスワード漏洩の対策にもなりますし、IAMユーザーの使いまわしもほぼ防ぐことができます。</dd>
</dl>

MFAアクセスだけを設定すると下記のようになります。ロールの名前は会社名やプロジェクト名にするとよいと思います。
```json:[role] ex-for-aws-b
{​​​
    "Version": "2012-10-17",
    "Statement": [
        {​​​​​​​​​​
            "Effect": "Allow",
            "Principal": {​​​​​​​​​​​​​​​​​
                "AWS": "arn:aws:iam::222222222222:root"
            }​​​​​​​​​​​​​​​​​,
            "Action": "sts:AssumeRole",
            "Condition": {​​​​​​​​​​​​​​​​​​​​​​​​
                "Bool": {​​​​​​​​​​​​​​​​​​​​​​​​
                    "aws:MultiFactorAuthPresent": "true"
                }​​​​​​​​​​​​​​​​​​​​​​​​
            }​​​​​​​​​​​​​​​​​​​​​​​​
        }​​​​​​​​​​​​​​​​​​​​​​​​
    ]
}
```
このロールにaws-bから必要な操作を許可するポリシーを```ex-for-aws-b```にアタッチします。必要最低限のポリシーに絞って提供するようにしましょう。

## aws-bの設定
ポリシーを作って対象のIAMユーザーにアタッチします。
### 社外からアクセスするためのポリシーを作成する
aws-aで作ったロールを引き受けるためのポリシーを作成します。
```json:[policy]get-access-aws-a
{​​​​​​​​​​​​​​​​​​​​​​​
    "Version": "2012-10-17",
    "Statement": [
        {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111111111111:role/ex-for-aws-b"
        }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    ]
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
```
aws-aにアクセスさせたいIAMユーザーにポリシーをアタッチします。

## アクセス
1. aws-bでポリシーがアタッチされたIAMユーザーでログインします。
1. ロールの切替を行います。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/2806c50b-d732-f87f-d296-24f2cfb7685d.png)
1. aws-aが利用できるようになります。
:::note info
この設定ではaws-bのログイン時にMFAが設定されていない場合、スイッチロールができません。
:::

## アクセスログの確認
CloudTrailでイベント履歴をユーザー名で検索すると、だれが何を行っているか分かるので、チェックできるようにしておきましょう。

# おわりに
設定は簡単なので、社内で複数のAWSアカウントを利用する場合にも有用だと思います。

# 参考文献
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html


https://dev.classmethod.jp/articles/sugano-042-iam-best-practices/

https://dev.classmethod.jp/articles/iam-role-externalid/
[Laravel Eloquent] with関数で複数テーブルからcolumnを指定して取得（Eager Loading）

## サンプルコード

例えば、以下のような3つの親子関係テーブルがあった場合。

・grand_fathers（id, name, age, created_at, updated_at）
・fathers（id, grand_father_id, name, age, created_at, updated_at）
・children（id, father_id, name, age, created_at, updated_at）

```get-family-data.php

$family = GrandFather::with(['fathers' => function ($fathers_query) {
    $fathers_query->with(['children' => function ($children_query) {
        $children_query->select(['id', 'father_id', 'name', 'age']); //「father_id」は必ず必要！
    }])->select(['id', 'grand_father_id', 'name', 'age']); //「grand_father_id」は必ず必要！
}])
    ->where('id', '1')
    ->get(['id', 'name', 'age']);

```

これで、各テーブルからcolumnを指定して取得することができます。

調べていろいろ試しましたが、納得のいくものがなかなか見つからず、
たぶんこれが一番キレイじゃないかなー、、？

もっといいやり方があればコメントいただきたいです。

## リレーション設定は忘れずに！

もちろんですが、withを使用する前にはModelのリレーション設定が必要なのでお忘れなく！

https://cloudsmith.co.jp/blog/backend/laravel/2020/07/1506704.html
Cloud9上のSAM CLIをアップグレードする


# 概要

過去に作成したCloud9環境のSAM CLIのバージョンが古くなっており新しいバージョンに更新したい場合があります。当記事ではその手順について記載しています。
(といっても、手順自体は下記の公式情報に書いてある内容そのままです)

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html#serverless-sam-cli-install-linux-upgrading

# SAM CLIのアップグレード手順

任意のディレクトリ上にSAM CLIのzipファイルをダウンロードして"sam-installation"ディレクトリに解凍
```shell
wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
```

アップデートコマンドの実行
```shell
sudo ./sam-installation/install --update
```

バージョン確認
```shell
sam --version
```
(バージョン確認の実行例)
![cloud9_img.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531623/eca964ec-5b77-fa4c-fe6b-7a7dde7fa5fd.png)

2022-03-22現在では1.41.0にアップグレードされました。

# （Appendix-１）なぜこの記事を書こうと思ったか

以前作成したCloud9環境にて、下記のようなコマンドでnodejs14.xのランタイムのSAMテンプレートを作成しようとしたところ、nodejs14.xはサポートされていないというエラーになったのでアップデートしたいと思いました。

```shell
sam init --runtime nodejs14.x --name sample-nodejs
```

"pip install --upgrade aws-sam-cli"などと実行すればサクっと更新されてくれるだろと思いきや、期待通りに更新されてくれませんでした（エラーにはならないけど"sam --version"コマンドの結果が変わらなかった）。
"cloud9 sam cli upgrade"などでGoogle検索しても意外と前述のシンプルなアップデート手順に辿り着きづらかったので、久しぶりのQiita投稿ですし練習を兼ねて書いてみました。

# （Appendix-２）そもそもCloud9とは

[AWS Cloud9](https://aws.amazon.com/jp/cloud9/)はブラウザ上で利用できる統合開発環境(IDE)のサービスで、AWSのサーバーレスアプリケーション開発などをすぐに開始できる環境を提供してくれます。

AWS CLI、SAM CLIやDockerなどが最初からインストールされており、ブレークポイントを設定したコードデバックも可能です。
ローカルに開発環境を用意する必要がないのでpythonやnodejsを利用してAWS Lambdaなどのスクリプトコードをちょっと書いてみたりしたい場合などに私は重宝しています。

Cloud9自体の利用料金は無料で、実行基盤とするEC2にかかる料金（インスタンス、EBSストレージなど）のみで利用できるので、環境作成時にt2.microのEC2インスタンスタイプを選択すれば、無料枠内で利用することも可能です。
私の個人的な感想では、pythonやnodejsを使ったLambdaの開発においてt2.microインスタンスタイプで不都合を感じたことはないです。

Cloud9環境上での各AWSリソースへのアクセス権限は["AWS Managed Temporary Credentials"](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/security-iam.html#auth-and-access-control-temporary-managed-credentials)という一時的な認証の仕組みで、Cloud9環境を作成した環境オーナーのIAMユーザーとほぼ同等の権限（IAM関連などの一部のオペレーションは制限されている）がデフォルトで利用できるようになっています。
通常、EC2インスンタンスに他サービスへのアクセス権限を設定する場合はIAMロールをインスタンスにアタッチしますが、Cloud9の環境として利用されるEC2インスタンスには、この仕組みによりロールをアタッチする必要がありません。

"AWS Managed Temporary Credentials"の利用は"Preferences > AWS Settings > Crecentials"の設定よりON/OFFを切り替えることができ、OFFにして自分でEC2インスタンスにアタッチしたIAMロールの権限で利用することも可能です。

![cloud9_img2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531623/ee902a24-29c4-b90e-bdec-2d7c67bda518.png)

Cloud9には一つの環境を複数ユーザーでShareして共同作業を行うことを可能にする機能があります。
しかし"AWS Managed Temporary Credentials"は前述の通り環境オーナーのIAMユーザーとほぼ同等の権限を行使できるので、たとえば管理者相当の権限を持つユーザーが作成した環境を、権限を限定された他のIAMユーザーにShareしてしまうと、共有された側が本来持っていない強力なアクセス権限をCloud9環境上では与えてしまいます。
環境をShareするのであれば相手は同じ権限を持ったIAMグループのメンバ間に限定する運用がよいかと思います。

※ 上記のような理由から、他メンバーにShareするときには下記のように警告メッセージを表示してくれます。
![cloud9_share_alart2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531623/cb36b008-5780-afcb-2107-c96413fa342a.png)

(メインテーマよりAppendixの方が情報量が多くなってしまいました。。。)