OmniAICreator/Qiita-1.07M huggingface dataset:
アセットパイプラインについて

アセットパイプラインの意味がよくわからなかったため、調べたことを残しておきます。

### そもそもの話
そもそもwebブラウザは```HTML,CSS,JavaScpirt,WebAssembly```を読み込むことで画面を表示している。(WebAssemblyとは大幅にパフォーマンスが向上する新しいタイプのコード)
その、```HTML,CSS,JavaScpirt,WebAssembly```をブラウザが読み込めるようにする仕組みをアセットパープラインという。

###アセットパイプラインとは

> アセットパイプラインとは、JavaScriptやCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するためのフレームワークです。


自分なりのまとめ
人間が見てわかりやすように配置されているCSSやJavascriptなどの静的ファイルを１つにまとめる機能のこと。
なぜまとめるのか→ファイルへのリクエスト回数を減らして処理を少なくするため。


### アセットパイプラインの流れ
1. 高級言語のプリコンパイル→人間がわかりやすいように書いた言語を機械がわかるように翻訳する
2. 連結→複数のファイルを１つにまとめる
3. 圧縮→余分な改行や余白を削除して読み込みスピードをあげる
4. publicに配置されたファイルを読み取ってブラウザに表示をする

### 実施方法
- 開発環境ではアセットパイプラインを通る仕組みが自動化されているため特に行うことはない
- 本番環境では手動で行う必要がある。<br>
  1. (``rails assets:precompile RAILS_ENV=production``コマンドを実行)
  2. ``config/environments/production.rb``の``config.assets.compile = false``
のfalseをtrueに変える

## 現在の疑問点
なぜ```config.assets.compile = false```をtrueにするのか？
そもそも```config.assets.compile```ってなに？

どうやらconfig.assets.compileは
>ファイルがないときにファイルを探して自動コンパイル

をしくてれるらしい。（Rails ドキュメント引用）
> 説明
「true」の場合は、public/assetsのなかに必要なファイルを見つからなかった時に、app/assetsなどからファイルを探しコンパイル

便利そうには感じるがtrueにしておくとサーバーに負荷がかかるらしい...。
処理速度を早くするためにアセットパイプラインの仕組みを使うのにtrueにして負担かけてもいいものなのか...。
考え出したら止まりません！

以上、アセットパイプラインについて現状わかったことについて記述しました。
まだ細かい部分は理解できていないため勉強していきます！


###　参考記事
https://railsdoc.com/page/config_assets_compile
https://developer.mozilla.org/ja/docs/WebAssembly/Concepts
https://www.transnet.ne.jp/2016/02/28/rails%E5%88%9D%E5%AD%A6%E8%80%85%E3%81%8C%E3%81%A4%E3%81%BE%E3%81%9A%E3%81%8Dcolnr%E3%80%8C%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3/
【AWS - RDS】MySQLに特定のDBのみのアクセスユーザー作成

1つのDBサーバーを使用して、複数のDBを管理している場合、
**特定のDBへのみ**アクセス出来るユーザーを作成したい。

## RDSにアクセス
アクセス権のあるEC2から下記を実行。
※ RDSへアクセス権があることを確認。セキュリティグループ等

```shell
$ mysql -h RDS_ENDPOINT -u root -p
Enter password: パスワードを入力
```

## ユーザーの作成
`ALL` で、全ての権限を付与。
`DATABASE_NAME.*` で、データベース名を指定し、全てのテーブルを対象とする。
`USERNAME@%` で、全てのホストを対象とする。

```sql
GRANT ALL ON DATABASE_NAME.* TO 'USERNAME'@'%' IDENTIFIED BY 'YOUR_PASSWORD';
```

※ `USERNAME` が存在しない場合は、新規でユーザーを作成

### 閲覧専用ユーザー（Read Only）
### 全てのデータベース
```sql
GRANT SELECT ON *.* TO 'USERNAME'@'%' IDENTIFIED BY 'YOUR_PASSWORD';
```

### 特定のデータベース
`DATABASE_NAME` に特定のデータベース名を指定

```sql
GRANT SELECT ON DATABASE_NAME.* TO 'USERNAME'@'%' IDENTIFIED BY 'YOUR_PASSWORD';
```
Mayaバージョンごとの DPI Awareness と 4K モニターの挙動まとめ

いろいろややこしくて困ったので、Maya 2012～2020 の "DPI Awareness" と、4K をメインモニターにした場合、および、2K モニターを混在させた場合の挙動をまとめます。

## (参考) DPI Awareness
https://forest.watch.impress.co.jp/docs/news/1148530.html

Windows10 のプロセスの "DPI Awareness" 値には以下があるそうです。

* 非対応
  高DPI環境に対応していない。システム側で自動的に拡大処理が行われるため操作は可能だが、ボヤけた表示になる

* システム
  高DPI環境に対応するが、スケーリング設定の異なるモニターが混在した環境には対応していない。セカンダリーモニターでは表示がボケることがある

* モニターごと（Per-Monitor）
  スケーリング設定の異なるモニターが混在した環境にも対応する

* モニターごと（v2）
  「Windows 10 Creators Update」で導入。DPIの変更がトップレベルウィンドウだけでなく子ウィンドウ（コントロール）にも通知される


## バージョンごとの違い
maya.exe の DPI Awareness は何なのか。

そして、4Kをメインモニターにしたとき、4Kモニターと2Kモニターの表示がどうなるか。

さらに、maya.exe のプロパティの互換性タブの「高DPIスケール設定の上書き」を変更したときに、それらがどう変わるのか（プロセスの DPI Awareness が変わるとともに、4K や 2K モニターの表示が変わります）を調べました。

ちなみに、maya.exe のプロパティを変更するのではなく、Maya Preferenes のスケーリング設定を OFF にするという設定もあるのですが、それをすると、ところどころ UI が崩れたりして使い勝手が悪くなるので、デフォルトのままが良いようです。


### Maya 2012～2015
* DPI Awareness: システム
* Maya Preferences: Scaling(DPI)設定非搭載
* デフォルト:
  - 4K: ボケないが小さすぎる
  - 2K: ボケる上に小さすぎる（4Kと見た目同じサイズになる）
* maya.exeのスケーリング設定「アプリケーション」:
  - DPI Awareness: モニターごと
  - 4K: ボケないが小さすぎる
  - 2K: ボケずに適正サイズだが、ウィンドウタイトルバーが大きい
* maya.exeのスケーリング設定「システム」か「システム（拡張）」:
  - DPI Awareness: 非対応
  - 4K: ボケるが適正サイズ
  - 2K: ボケずに適正サイズ


### Maya 2016:
* DPI Aware: システム
* Maya Preferences: Scaling(DPI)設定搭載
* デフォルト:
  - 4K: Scaling有効なら、適正サイズでフォントもきれい
  - 2K: 4Kと見た目同じサイズになる（小さすぎる上にボケる）
* maya.exeのスケール設定「アプリケーション」:
  - DPI Aware: モニターごと
  - 4K: Scaling有効なら、適正サイズでフォントもきれい
  - 2K: 4Kのスケーリングのままになる（ボケないが大きすぎる）
* maya.exeのスケール設定「システム」か「システム（拡張）」:
  - DPI Aware: 非対応
  - 4K: 適正サイズでボケる
  - 2K: 適正サイズでボケない


### Maya 2016.5～2020:
* DPI Aware: モニターごと
* Maya Preferences: Scaling(DPI)設定搭載
* デフォルト:
  - 4K: 適正サイズでフォントもきれい
  - 2K: 4Kのスケーリングのままになる（ボケないが大きすぎる）
* maya.exeのスケール設定「アプリケーション」:  
  デフォルトと変わらず。
* maya.exeのスケール設定「システム」か「システム（拡張）」:
  - DPI Aware: 非対応
  - 4K: 適正サイズでボケる
  - 2K: 適正サイズでボケない


## まとめ
* 4K できれいに表示されるのは、Scaling機能を搭載した 2016 以降（それ以前も「DPI Aware=システム」となっているが？）

* 2020.3 現在でも、4K/2K混在での使用は厳しい（「DPI Aware=モニターごと」とはとてもいえないような？）

* 4K メインで使う場合

  - Maya 2015以前（スケーリング非対応）で、文字などが小さすぎるなら、maya.exeのスケール設定を「システム」にすると、ボケるが適正サイズになる。
  - Maya 2016以降（スケーリング対応）なら、デフォルトのまま使うのが快適。

* 4K メインで 2K モニターに Maya ウィンドウを置く場合

  - どのバージョンでも、maya.exeのスケール設定を「システム」にする。ボケずに適正サイズになる。
    4Kの方にウィンドウを移動させるとボケるが適正サイズとなる。

  - Preference で Scaling を off にすることでも適正サイズとなるが、ところどころ UI が崩れてしまう（ファイルダイアログがスカスカになるなど）。
熊本県の Go To EATの加盟店一覧のPDFをCSVに変換

[GoToEatキャンペーンくまもと](https://gotoeat-kumamoto.jp/)の加盟店一覧のPDFをCSVに変換

# コマンド
```shell
wget https://gotoeat-kumamoto.jp/pdf/shoplist.pdf -O data.pdf

apt install python3-tk ghostscript
pip install camelot-py[cv]

camelot -p all -o data.csv -f csv -split lattice -scale 40 data.pdf
```

# Python
```python
import camelot
import pandas as pd

tables = camelot.read_pdf("data.pdf", pages="all", split_text=True, strip_text=" \n", line_scale=40)

dfs = [table.df for table in tables]

df_tmp = pd.concat(dfs)

df = df_tmp.iloc[1:].set_axis(df_tmp.iloc[0].to_list(), axis=1).reset_index(drop=True)
df.sort_values(by=["郵便番号", "町域、番地"], inplace=True)

df.to_csv("kumamoto.csv", encoding="utf_8_sig")
```
Express で簡単な WebAPI を作成 (TypeScript)

次のプログラムを TypeScript に変換しました。
[Express で簡単な WebAPI を作成](https://qiita.com/ekzemplaro/items/1aa57e199b4fed4eb729)

ライブラリーのインストール

```bash
sudo npm install -g express
sudo npm install -D @types/express
```

## サーバープログラム

フォルダー構造

```text
$ tree
.
├── app.ts
└── routes
    └── index.ts
```

```ts:app.ts
//-------------------------------------------------------------------------
//	app.ts
//
//						May/30/2023
//-------------------------------------------------------------------------
var express = require('express')
var routes = require('./routes')
var cfenv = require('cfenv')

var app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.use(express.static(__dirname + '/public'))

const appEnv = cfenv.getAppEnv()

app.post('/post_test',routes.post_test)

app.listen(appEnv.port, '0.0.0.0', function() {
		console.log("server starting on " + appEnv.url)
})

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

```ts:routes/index.ts
// -----------------------------------------------------------------------
/*
	routes/index.ts

						Oct/15/2020
*/
// -----------------------------------------------------------------------
import express from 'express'

exports.post_test = function(req:express.Request, res:express.Response)
{
	var aa:number = 0
	var bb:number = 0

	if (req.body.aa) {
		aa = parseInt(req.body.aa,10)
		}

	if (req.body.bb) {
		bb = parseInt(req.body.bb,10)
		}

	var dict_aa = {aa:0, bb:0, sum:0, diff:0}
	dict_aa["aa"] = aa
	dict_aa["bb"] = bb
	dict_aa["sum"] = aa + bb
	dict_aa["diff"] = aa - bb

	const str_out:string = JSON.stringify(dict_aa)

	res.send(str_out)
}

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

## サーバーの起動

```text
$ export NODE_PATH=/usr/local/lib/node_modules
$ ts-node app.ts
server starting on http://localhost:3000
```

## クライアントで確認

```text
$ http  http://localhost:3000/post_test  aa=12 bb=45
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 37
Content-Type: text/html; charset=utf-8
Date: Mon, 29 May 2023 23:50:22 GMT
ETag: W/"25-an7RCUHgJyWNGztPX4iFA1sXPJ8"
Keep-Alive: timeout=5
X-Powered-By: Express

{
    "aa": 12,
    "bb": 45,
    "diff": -33,
    "sum": 57
}

```

## 確認したバージョン

```text
$ node -v
v20.2.0

$ npm -v
9.6.6

$ tsc -v
Version 4.8.4

$ ts-node -v
v10.9.1
```
Zabbix4.0のダッシュボードでZabbixサーバの起動の値が「いいえ」になっている

# 事象内容
Zabbix4.0をインストール、GUIの初期設定後にAdminユーザでログインをしたら、システム情報画面の「Zabbixサーバーの起動」の項目が「いいえ」になっていた。しばらくすると「Zabbixサーバーが動作していません（画面のリフレッシュを行ってステータスを再確認してください）」とメッセージが出力された。
![WS_2020_1015_000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518227/515aa5d1-ae6d-59d3-079b-02da7ac2ab50.jpeg)

# 原因
/etc/zabbix/web/zabbix.conf.phpにある
$ZBX_SERVER
$ZBX_SERVER_PORT
の設定が適切でなかった、上記の設定に誤りがあると情報を取得ができず、今回の事象が発生してしまう。


```java:
[root@zabbix-master ~]# cat /etc/zabbix/web/zabbix.conf.php
～中略～

$ZBX_SERVER      = 'zabbix';
$ZBX_SERVER_PORT = '10051';
$ZBX_SERVER_NAME = '';
```
ZBX_SERVER='zabbix';と記載している部分が今回の原因だった


# 対応方法
$ZBX_SERVERをlocalhostに変更し、systemctlからzabbix-serverを再起動することで問題を解消した。

```java:
[root@zabbix-master ~]# vi /etc/zabbix/web/zabbix.conf.php
[root@zabbix-master ~]# cat -n /etc/zabbix/web/zabbix.conf.php
～中略～
    11
    12  // Schema name. Used for IBM DB2 and PostgreSQL.
    13  $DB['SCHEMA'] = '';
    14
    15  $ZBX_SERVER      = 'localhost'; #ここを修正した
    16  $ZBX_SERVER_PORT = '10051';
    17  $ZBX_SERVER_NAME = '';
    18
    19  $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;

[root@zabbix-master ~]# systemctl restart zabbix-server

```
ダッシュボードを再読み込みすると「Zabbixサーバーの起動」の項目が「はい」になっている

![WS_2020_1015_001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518227/7b1b31bd-4b7b-718c-d2a3-15f164a1403d.jpeg)

# 備考
1.  /etc/zabbix/web/zabbix.conf.phpはどのタイミングで作成されるのか
2.  $ZBX_SERVERの初期設定はどこで行っていたのか

#/etc/zabbix/web/zabbix.conf.phpはどのタイミングで作成されるのか
Zabbix導入前のスナップショットを復元してyum install後から/etc/zabbix/web/zabbix.conf.phpをlsコマンドで探したところ
**Webインタフェースのインストール(※)の完了後**に作成されていた。
※http\://zabbixサーバのIPアドレス/zabbixに初めてアクセスを行うと表示される設定画面のこと


# $ZBX_SERVERの初期設定はどこで行っていたのか
Webインタフェースのインストールの「Zabbix server details」で設定していた。


![WS_2020_1015_003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518227/0fbd5b4c-8087-ec6f-4e23-d13d38401bf6.jpeg)

↑赤枠をzabbixとしていたので今回の事象が発生した
![WS_2020_1015_004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518227/c28dda2c-34a3-4ad0-d24f-bb599110d800.jpeg)
↑Hostを「localhost」,Nameを「zabbix-master(zabbixを導入したサーバ名)」にして設定を行ったら初回から「Zabbixサーバーの起動」の項目が「はい」になっていた
GitHubのREADMEにデモ動画と画像を埋め込む方法

# はじめに
プログラミング学習をしていく中で、なにかアプリケーションを開発することはよくあると思います。
READMEに開発背景や、使用技術、実装機能など記載するだけでなく実際にそのアプリケーションを動かしている***デモ動画***があるとどんなアプリケーションかイメージがつくのでいいですよね。

自分は今まで、Wantedlyでしかデモ動画を載せておらずGitHubのREADME上には載せていませんでした。そこで今回は、READMEにてデモ動画と画像を埋め込む方法について共有させて頂きます。

# 動画の表示方法
調べてみると、GitHubのWikiを用いてやる方法がありましたのでそちらでやってみました。

流れとしては、
1. wiki作成
2. 作成したwikiリポジトリをローカル上にcloneする
3. 動画や画像を入れるためのフォルダを作成し、必要な動画・画像を入れる
4. リモート上にプッシュ
5. `https://raw.github.com/wiki/[githubユーザー名]/[リポジトリ名]/[動画ファイルへのパス]`でアクセスできるので、こちらをREADMEに記載する！

意外と簡単でした！
載せる動画は下記リンクより、mp4からgifに変換しました。
[acconvert.com](https://www.aconvert.com/jp/video/mp4-to-gif/)

参考記事
[GithubのREADMEにGif画像を埋め込む](https://qiita.com/yamataku29/items/fb14fb99f5024e01b4b8)

# 画像の表示方法
issueを作成して、そこに画像をアップすることでできるらしい！簡単！

流れとしては、
1. 新規issueを作成
2. issueのコメント欄で、表示させたい画像をドロップする
3. アップロードが終わると画像リンクが生成されるため、それをREADMEにそのままコピペ

参考記事
[【GitHub】README.md に画像を表示させる簡単な方法](https://qiita.com/ROY_M/items/2c4feb5de05535441bc8)

# やってみた
雑ですが、こんな感じでできました！（リンクは伏せさせていただきます）

![qiita投稿用.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/17f2e606-a5fa-0df6-db53-5a42bdaff326.png)
（ちなみにこちらは、自分が開発している社内向けの質問アプリケーションで質問が投稿された際にSlackで通知がとぶという機能の画像です笑）


※追記　デモ動画もgif形式にして、画像アップの方法で出来そうでした！
しかし、ファイルサイズは10MBより小さい必要はありました。

# まとめ
今回は、GitHub上に動画と画像を表示させる方法について紹介させて頂きました。
とはいってもすでに多くの方が紹介しているため、自分用にまとめた形になります。

以上！
データベースの文字化けを直す

フォームなどを作っているとアルファベットはいいのですが、日本語投稿が？になってしまいます。その改善方法をまとめました。

#データベースの文字コードをチェック
```
show variables like ‘character%’;
```
を実行してみてください。するとutf8に混じってlatin1が出てこないでしょうか。

#データベースの文字コードを修正
```
set character_set_database=utf8;
```
こんな感じでlatin1のものをutf8に変更していきます。

#テーブルの文字コードを修正
```
alter table table_name convert to character set utf8;
```
以上を試した上で、もう一度日本語の投稿をしてみてください。
Failed to load window layoutが出てUnityが起動しない現象の解決

# 初歩的に見える根深いトラブル

プロジェクトを作成してUnityを開くと，突然このダイアログが出てくるようになりました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/10322f84-aa73-cf43-78d4-8bf6762ff29e.png)

グレゴール・ザムザも早起きするレベルの頻度で発生していて，立ち上がるUnityの数が多いほどこのトラブルと向き合うのだなと残念な思いをしています．

# 課題の解決方法

Unityのプロジェクトを新規作成した，ロードした，というタイミングでこのダイアログが出てきたら以下の方法で救出を試みてください．

## 落ち着く，焦らない
「設定を戻そう」「デフォルトのレイアウトにしよう」と焦るとかえってどこまで操作したのかわからなくなります．**冷静になりましょう**．

## プロジェクトを保存したフォルダを開く

まずは，当該エラーの出てしまったプロジェクトを保存したフォルダを開いてください．プロジェクトの中にLibraryフォルダがあります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/616378de-40a0-c59d-8e97-3341219b16f3.png)

Libraryフォルダの中に実は件のダイアログが表示される原因が存在しています．Libraryフォルダから，`CurrentLayout-default.dwlt`を探してください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/c125e91d-0bda-9304-eb34-25319baf6d6e.png)

本当にぶっ壊れているかどうかに興味ある人は，ファイルサイズを憶えておきましょう．

## Load Default Layoutをクリックする

例のダイアログに戻って，`Load Default Layout`をクリックしてください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/74a768d9-3a9b-cbe0-ab41-db2b5d2b9162.png)

**1回だけクリックするだけでいいです**．何度もこのダイアログは表示されます．だからと言って何度もクリックして良い方向になるとは限りません．

このボタンをクリックすると，`CurrentLayout-default.dwlt`が一時的に修復されます．

## CurrentLayout-default.dwltをバックアップする

ここで必要な操作は`CurrentLayout-default.dwlt`のバックアップです．バックアップする方法はいろいろありますが，**一番簡単な方法はデスクトップにコピーすることです**．ドラッグ＆ドロップでデスクトップに放り込みましょう．

## Unityをダイアログから終了させる

またダイアログに戻って`Quit`ボタンをクリックしてください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/ffb96775-d4ce-2be0-a451-b71cf8c747f4.png)

するとUnityは正常に終了します．もう一度，Layoutフォルダを見てみましょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/7bbdf352-ae63-e018-7b6a-d95daefd4cec.png)

釈然としませんね．`CurrentLayout-default.dwlt`のファイルサイズが1KBに減っています．正常終了した結果，たったの1KBになるわけで釈然としませんが．

## バックアップファイルを壊れたファイルへ上書きする

**先ほどバックアップした**`CurrentLayout-default.dwlt`を，**Libraryフォルダの**`CurrentLayout-default.dwlt`に上書きしてください．

上書きの許可についてダイアログが出てきます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/7fd34053-c0dd-0e18-c03e-993e1fce2add.png)

上書き対象を間違えていないかチェックしてください．上部赤枠の部分で**デスクトップからLibrary**になっているかチェックしてください．古今東西ありがちなのですが，**本番をバックアップで上書きする**なんてよくあることです．逆になってないか確認しましょう．

## Unityを起動する

これでUnity Hub等々でプロジェクトを再度開くと，Unityがちゃんと起動します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32219/560c0ebf-ebb3-1892-c002-209daf5303ea.png)

# なんでCurrentLayoutが壊れるのか？

理由はわかりません．`CurrentLayout-default.dwlt`を開くと，ただのYAMLファイルであることがわかります．差分を取っていないし，様々なところで同様の現象が発生しているそうなので，きっと次のバージョンで直るんだと期待しています．

## 参考文献
https://www.xlsoft.com/jp/blog/blog/2020/09/30/post-13872/

https://issuetracker.unity3d.com/issues/failed-to-load-window-layout-error-window-is-shown-when-trying-to-open-projects-and-specific-regional-format-is-chosen

UnityのIssueを見ると，結構いろいろなバージョンで発生していることがわかります．根深い……．
AWS IAMで学習用のIAMユーザーを作成してみる

## 参考
[AWSではじめるデータレイク: クラウドによる統合型データリポジトリ構築入門](https://www.amazon.co.jp/dp/491031301X/ref=cm_sw_r_tw_dp_x_KDPHFb5D8933E)
## AWS IAMとは
AWSリソースをセキュアに操作するための認証・認可の仕組みを提供するマネージドサービス。
IAM自体の利用は無料となる。

## 機能
- 各AWSリソースに対して別々のアクセス権限をユーザーごとに付与
- 他要素認証によるセキュリティ強化
- 一時的な認証トークンを用いた権限の委任
- 他のIDプロバイダーで認証されたユーザーにAWSリソースの一時的なアクセス
- 世界中のリージョンで同じアイデンティティと権限の利用

## ４つの概念
1. IAMユーザー：AWSを操作する人やサービス
2. IAMグループ：IAMユーザーの集合体
3. IAMポリシー：AWSへのアクセス許可の定義
4. IAMロール：IAMユーザーやサービスに対して権限の譲渡
(IAMロールにアタッチされたIAMポリシーを他のIAMユーザーに委譲できる)

管理者のIAMユーザーは全操作許可のIAMポリシーをアタッチされることで管理者として全操作を行うことができる。
アカウントを作成したユーザーはルートユーザーであるが、日常的なタスクはルートユーザーを使用しないのがベストプラクティス。

## とりあえず管理者権限を付与したユーザーを作成してみる
1. IAMのコンソールから[ユーザー]→[ユーザーを追加]でキャプチャ画像通りに選択し、ユーザー名とパスワードを入力後次のステップへ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434012/1e65d019-f2a1-e48f-8ca5-41e87c4d14c1.png)

2. [既存のポリシーを直接アタッチ]→[AdministratorAccess]にチェックを入れて次のステップへ
3. 次の画面では何もせずさらに次のステップへ
4. 確認画面が表示されるので、[ユーザーの作成]で作成

作成したユーザーでログインするための12桁のアカウントIDを含むURLが表示されるので保存しておき以後の操作（AWS勉強用）は作成したユーザーで進める！
RealSense L515で参考にしたサイト

以下のページだけでpyrealsense2を入れて、サンプルコードを動かすことができました。
途中のシンボリックの部分に関しては、環境ごとに場所が違うので対象ファイルを探してlnしましょう。
また、サンプルコードですが、L515の対応している解像度が違うので書き換える必要があります。

####参考
pyrealsense2
https://qiita.com/comachi/items/14b358568365bc5ee474
l515が対応している解像度
https://github.com/IntelRealSense/librealsense/issues/6684
[rails5]routes.rbでprefix・URI・controller#actionの値を任意にカスタマイズできる

# 環境
- rails 5.2.3

# 各オプションの作用部分早見表

| | Prefix | URI Pattern | Controller#Action |
|-----------|------------|------------|------------|
| namespace  | ○ | ○  | ○ |
| scope      | X | ○  | X |
| module     | X | X  | ○ |
| as         | ○ | X  | X |

　表のPrefix、URI Pattern、Controller#Actionはrake routesでroutingを表示した時の各部分を指しています。

# 例
## やりたい組み合わせ
| Prefix| URI Pattern | Controller#Action |
|-----------|------------|------------|
| new_hoge_team       | huga/team/new        | hoge/team#new         |
 URI Patternのみにhugaをつけたい。

## routes.rb
```
scope :huga, module: "hoge", as: :hoge do
 resorces :team
end
```

# 参考
Railsガイド
https://railsguides.jp/routing.html
Railsのroutingにおけるscope / namespace / module の違い
https://qiita.com/ryosuketter/items/9240d8c2561b5989f049
コマンドラインからINCI名を日本化粧品工業連合会のWEBで検索して成分表示名称などを取得する。

#コマンドラインからINCI名を日本化粧品工業連合会のWEBで検索して成分表示名称などを取得する。
##概要
化粧品の輸入をする場合INCI名で書かれた成分リストを日本語のものに変換する作業が絶対に必要になる。日本化粧品工業連合会のWEBで検索してポチポチとやっていたのだが、めんどくさくなったので、将来の「表ごと変換」も視野に入れてまずはコマンドラインから検索できるようにする。
##前提条件
- mac
- zsh

## 使い方

function(*後述）をコピペで貼り付けてエンター
その後

```sh
% search_from_jcia_by_inci [INCI_NAME]
```

## 例

```sh
% search_from_jcia_by_inci PG
```
### 結果
````sh
<?xml version="1.0" encoding="utf8"?>
<return_data>
  <rows>
    <row id="550009">
      <cell>
                550009  
            </cell>
      <cell>
                ＰＧ
            </cell>
      <cell>
                Propylene Glycol
            </cell>
      <cell>
                本品は、次の化学式で表される二価アルコールである。
            </cell>
      <cell>
                1
            </cell>
      <cell>
                2621
            </cell>
      <cell>
            </cell>
      <cell>
                1
            </cell>
    </row>
  </rows>
  <message>
</message>
  <debug>
</debug>
  <status>1</status>
  <page>0</page>
  <max>1</max>
  <limit>10</limit>
</return_data>

```

## 貼り付けるもの
```sh

function search_from_jcia_by_inci(){

  if test -z $1 ; then
    echo "usage  : search_from_jcia_by_inci [INCI_NAME]"
    echo "ex) search_from_jcia_by_inci BG"
  fi
  (
  PHPSESSID=$(curl 'https://www.jcia.org/user/business/ingredients/search' \
    -H 'Connection: keep-alive' \
    -H 'Accept: */*' \
    -H 'X-Requested-With: XMLHttpRequest' \
    -H 'sec-ch-ua-mobile: ?0' \
    -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
    -H 'Origin: https://www.jcia.org' \
    -H 'Sec-Fetch-Site: same-origin' \
    -H 'Sec-Fetch-Mode: cors' \
    -H 'Sec-Fetch-Dest: empty' \
    -H 'Referer: https://www.jcia.org/user/business/ingredients/namelist' \
    -H 'Accept-Language: ja,en-US;q=0.9,en;q=0.8' \
    --data-raw 'search%5Bfreeword%5D=@'$1 \
    --compressed -i | grep 'Set-Cookie: PHPSESSID=' | cut -d '='  -f2 | cut -d ';' -f1)
    
   curl 'https://www.jcia.org/user/business/ingredients/list/page/0' \
        -H 'Connection: keep-alive' \
        -H 'Accept: text/plain, */*; q=0.01' \
        -H 'sec-ch-ua-mobile: ?0' \
        -H 'X-Requested-With: XMLHttpRequest' \
        -H 'Sec-Fetch-Site: same-origin' \
        -H 'Sec-Fetch-Mode: cors' \
        -H 'Sec-Fetch-Dest: empty' \
        -H 'Referer: https://www.jcia.org/user/business/ingredients/namelist' \
        -H 'Accept-Language: ja,en-US;q=0.9,en;q=0.8' \
        -H 'Cookie: PHPSESSID='$PHPSESSID';' \
        --compressed | xmllint --encode utf8 --format -
    )
  }
```
client-goを利用してGolangからKubernetesのPod一覧を取得するサンプル


# kubectlを利用する場合

```bash

aws eks update-kubeconfig --name vamdemic-development-eks-cluster
```

kube-systemのnamespaceでは、12のPodが起動中

```
yuta:~/go-kubernentes (master *+=) $ kubectl get pod -n kube-system 
NAME                                      READY   STATUS    RESTARTS   AGE
alb-ingress-controller-5b4b5fd775-8vxt7   1/1     Running   1          16d
aws-node-829mc                            1/1     Running   0          16d
aws-node-q4d67                            1/1     Running   0          16d
coredns-79769ff86-h2tck                   1/1     Running   0          16d
coredns-79769ff86-wclkd                   1/1     Running   0          16d
ebs-csi-controller-587cb4db9b-6j8xz       4/4     Running   3          16d
ebs-csi-controller-587cb4db9b-w5s5s       4/4     Running   2          16d
ebs-csi-node-gbpx4                        3/3     Running   0          16d
ebs-csi-node-l8rx5                        3/3     Running   0          16d
efs-csi-node-v6m4m                        3/3     Running   0          16d
efs-csi-node-vtf5r                        3/3     Running   0          16d
kube-proxy-7gbmn                          1/1     Running   0          16d
kube-proxy-8h4tk                          1/1     Running   0          16d
```

# GoでPod一覧を取得する場合


```main.go
package main

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
	"os"
	"path/filepath"
)

func main() {
	// Kubeconfigのファイルパスを指定
	kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config")
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		log.Fatal(err)
	}

	// Kubeconfigを読み込む
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}

	// Pod一覧を呼び出す
	namespace := "kube-system"
	pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Fatalln("failed to get pods:", err)
	}

	// print pods
	// pods.Items: []v1.Pod
	for i, pod := range pods.Items {
		fmt.Printf("[%d] %s\n", i, pod.GetName())
	}
}
```

出力結果

```
yuta:~/go-kubernentes (master *+=) $ go run main.go 
[0] alb-ingress-controller-5b4b5fd775-8vxt7
[1] aws-node-829mc
[2] aws-node-q4d67
[3] coredns-79769ff86-h2tck
[4] coredns-79769ff86-wclkd
[5] ebs-csi-controller-587cb4db9b-6j8xz
[6] ebs-csi-controller-587cb4db9b-w5s5s
[7] ebs-csi-node-gbpx4
[8] ebs-csi-node-l8rx5
[9] efs-csi-node-v6m4m
[10] efs-csi-node-vtf5r
[11] kube-proxy-7gbmn
[12] kube-proxy-8h4tk
```

# 参考
https://pizi.netlify.app/posts/kubernetes-client-go-example/#node%E3%81%AE%E5%8F%96%E5%BE%97
https://github.com/kubernetes/client-go
IBMCloud CertificateManager小ネタ

##小ネタ
* Certificate Managerでは、Let'sEncryptを用いてサーバ証明書を発行します。
クライアント証明書に利用したい話も聞きますが、**Let'sEncrypt(CertificateManager)はクライアント証明書の発行はしない。**
参考:[Let's Encrypt について](https://letsencrypt.org/ja/about/)

* 正確には、証明書のサブジェクトは ドメイン名でなければならず、他の種類のエンティティにできない。
つまり、認証するコンピュータがDNSドメイン名で特定されている場合には、クライアント認証を行うために使用できる。

* 証明書の署名アルゴリズムとしては、**「sha256WithRSAEncryption」**による署名のみサポートする。
nextjsで新たなbuildをデプロイした際、既に古いページをキャッシュしていたクライアントへ強制的にページ更新させる方法

# 問題

nextjsはSPAなのでページ間移動でHTTPのロードが発生しない。
これによって古いページをキャッシュしていたクライアントは、新たなバージョンがサーバーにデプロイされている状態でも、明示的にページリロードをしてもらわない限りは古いページに居残ってしまう。


# 解決方法

1. [generateBuildId][1]を使う（[gitのcommit IDを自動で付与するplugin][2]が便利）
2. 下のようにHTMLソースからbuildIdを読み出す
3. buildId配下のパスが存在すれば新たなbuildはデプロイされていない
4. buildId配下のパスが存在しなければ新たなbuildと考えられる
5. ページを移動した後にこのチェックを行い、リロードが必要な場合は`document.location.reload()`でcacheを無視して読み込む
6. こうすることによってクライアント側は意識することなく、ページを移動した際に新たなバージョンであれば自動的にページ更新をして最新の状態に保てる。

## 事前設定

```js:next.config.js
// https://github.com/nexdrew/next-build-id
const nextBuildId = require("next-build-id")

module.exports = {
  generateBuildId: () => nextBuildId({ dir: __dirname })
}
```

## HTMLソース
![view-source_ubuntu_local_6850.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/9b1b23be-f339-e403-d468-34590546d088.png)


## 変更点

[basePath][3]が設定されていることを考慮して

- `yarn add proper-url-join`

```ts:src/utils/useBuildId.ts
import { useRouter } from "next/router"
import urlJoin from "proper-url-join"
import React from "react"

const useBuildId = () => {
  const { basePath } = useRouter()

  const shouldReload = React.useCallback((): boolean => {
    if (process.env.NODE_ENV != "production") {
      return false
    }

    const buildId = JSON.parse(
      document.querySelector("#__NEXT_DATA__").textContent
    ).buildId

    const request = new XMLHttpRequest()
    request.open(
      "HEAD",
      urlJoin(basePath, `/_next/static/${buildId}/_buildManifest.js`),
      false
    )
    request.setRequestHeader("Pragma", "no-cache")
    request.setRequestHeader("Cache-Control", "no-cache")
    request.setRequestHeader(
      "If-Modified-Since",
      "Thu, 01 Jun 1970 00:00:00 GMT"
    )
    request.send(null)

    return request.status === 404
  }, [])

  return {
    shouldReload,
  }
}

export default useBuildId
```

```tsx:pages/_app.tsx
import type { AppProps } from "next/app"
import { useRouter } from "next/router"
import React from "react"
import { useBuildId } from "src/utils"

function MyApp({ Component, pageProps }: AppProps) {
  const { shouldReload } = useBuildId()
  const router = useRouter()

  React.useEffect(() => {
    const handleRouteChange = (url: string) => {
      if (shouldReload()) {
        document.location.reload()
      }
    }

    router.events.on("routeChangeComplete", handleRouteChange)

    return () => {
      router.events.off("routeChangeComplete", handleRouteChange)
    }
  }, [shouldReload])

  return <Component {...pageProps} />
}

export default MyApp
```


[1]: https://nextjs.org/docs/api-reference/next.config.js/configuring-the-build-id
[2]: https://github.com/nexdrew/next-build-id
[3]: https://nextjs.org/docs/api-reference/next.config.js/basepath
Rails Active_storage -画像の保存を簡易化する-

<h1>Active storageとは</h1>
Active Storageは、ファイルアップロードを行うための機能です。これを使えば、フォームで画像の投稿機能などが簡単に作れます。クラウドストレージサービス(Amazon S3, Google Cloud Storage, Microsoft Azure Storageなど)に対するファイルのアップロードを簡単に行うことができます。

<h2>導入方法</h2>

<ul>
<li>
Active_storageに沿ったテーブルを作る
</li>
</ul>

````
% rails active_storage:install
````
Active_storageをインストールし、関連ファイル(マイグレーションなど)を生成

````
%rails db:migrate
````

Seaquel Proを確認すると以下のようなテーブルが生成されていたらここまでは成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629333/096b1966-6146-3ff1-8acd-b506776d1914.png)
これで画像を保存するための「入れ物」は完成しました。

<h2>モデルの記述：  画像１枚を添付する</h2>
「メッセージに画像を添付する」、「商品情報に画像を添付する」など画像情報は他モデルと関わることが多くあります。ここでよくあるのが、「imagesテーブルがあるからimageモデルを作ってアソシエーションを組む」という考え方です。実はactive_storageで作成したテーブルに関しては別途モデルを作る必要はなありません。関わらせたいモデルに「has_one_attached :ファイル名」を追記すればアソシエーションは完成します。
今回はメッセージとアソシエーションを組むことを想定していきます。
models/message.rb

````ruby
class Message < ApplicationRecord
　　~他 associationなどの記述は省略~

  has_one_attached :image
 
end

````
アソシエーションというよりも、「擬似的な画像カラムを作った」と言った方がイメージしやすいかもしれません。



<h2>コントローラの記述：  ストロングパラメータ</h2>

seaquel_proのmessageテーブルを見てみると、imageカラムは存在していません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629333/c7225415-9189-b9dd-e1ba-f3d5ecb24756.png)

しかしながらモデルで記述したhas_one_attachedによって、messagesテーブルには「擬似的なimageカラム」が存在していることになっています。
※画像情報はrails active_storage:installで生成したテーブル内に保存されます。

このことからmessages_controller.rb内のparamsで画像の情報が飛ばせるようになりました。


controllers/messages_controller.rb

````ruby
class MessagesController < ApplicationController

  def new
    @message = Message.new
  end

  def create
   @mesage = Message.create(message_params)
  end

  private

  def message_params
      params.require(:message).permit(:content, :image).merge(user_id: current_user.id)
  end
end

````

<h2>ビューの記述： 画像の送信</h2>
ここに関してはいつも通りform要素のfile_fieldを使います。

````erb
<%= form_with model: @message, local: true  do |form| %>
  <%= form.text_area :content %><br>
  <%= form.file_field :image %><br>
  <%= form.submit %>
<% end %>

````

<h2>ビューの記述： 画像の表示</h2>
imgタグでも可能ですが、railsのヘルパーメソッドであるimage_tagを使って記述を簡略化します。

````erb
<% if @message.image.attached? %>
  <%= image_tag @message.image %>
<% end %>
````



以上です！！
【iOS】シミュレーターでソフトウェアキーボードを使う

#ソフトウェアキーボード が表示されない場合の対処方法#

メニュー から ソフトウェアキーボード と ハードウェアキーボード を切り替えることができます。
**i/O > Keyboard > Connect Hardware Keyboard**
![switch_keyboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/bd999d5d-1d52-269d-4e50-8c4513e66705.png)
ショートカットは **Shift + ⌘ + K** です。
M5StickCPlusでZoomのミュート&ビデオのON/OFFボタンを作る

Zoomでミーティングしてますか？
デゥアルデスプレイで作業するときミ―ティングしながら仕事をしていると***音声入れたり切ったり***、***ビデオを入れたり切ったり***、ショートカットキーを覚えてれば、キーボードへの入力で済みますが、画面からアイコンを探してクリックするのは煩わしいと思いませんか？

[Zoomのホットキーとキーボードショートカット](https://support.zoom.us/hc/ja/articles/205683899-%E3%83%9B%E3%83%83%E3%83%88%E3%82%AD%E3%83%BC%E3%81%A8%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88)


##開発環境
Windows10
Arduino 1.8.13
M5StickC Plus

##追加したライブラリ
Keyboard　1.0.2

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/2af41b97-aab1-376d-b2ef-5b3ff6bbe822.png" width=70%>


##コード
```.js 
//#include <M5Stack.h>
//#include <M5StickC.h>
#include <M5StickCPlus.h>
#include <BleKeyboard.h>

BleKeyboard bleKeyboard(""M5Zoomcontroller"");
bool blestate = false;

//Alt+V: ビデオのON / OFF
//Alt+A: ミュートのON / OFF
//int btnA = M5.BtnA.isPressed(); // ホームボタン
//int btnB = M5.BtnB.isPressed(); // 右ボタン

void showstate(char *txt) {
  M5.Lcd.setCursor(0, 120);
  M5.Lcd.fillRect(0, 120, 320, 20, BLACK);
  M5.Lcd.printf(txt);
}

void setup() {
  M5.begin();

  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();

  //    M5.Lcd.clear(BLACK);
  M5.Lcd.setTextSize(2);
  M5.Lcd.println("zoom");
  M5.Lcd.println("A:meet");
  M5.Lcd.println("B:video");
   showstate("Disconnected");
}

void loop() {
  M5.update();

  if (bleKeyboard.isConnected()) {
    if (!blestate) {
      blestate = true;
      showstate("Connected");
    }
    delay(100);
    if (M5.BtnA.isPressed()) {
      Serial.println("Sending Enter key...");
      bleKeyboard.press(KEY_LEFT_ALT);
      bleKeyboard.write('a');
        delay(100);
        bleKeyboard.release(KEY_LEFT_CTRL);
      //            bleKeyboard.press(KEY_LEFT_CTRL);
      //            bleKeyboard.press('c');
      //            bleKeyboard.press(KEY_HOME);
      //            bleKeyboard.release(KEY_HOME);
    } else if (M5.BtnB.isPressed()) {
      //          bleKeyboard.press('a');
      //          bleKeyboard.press(KEY_PAGE_UP);
      //          bleKeyboard.release(KEY_PAGE_UP);
      bleKeyboard.press(KEY_LEFT_ALT);
      bleKeyboard.write('v');
        delay(100);
        bleKeyboard.release(KEY_LEFT_CTRL);
    }
  } else {
    if (blestate) {
      blestate = false;
      showstate("Disconnected");
    }
  }
}
```

##PCと接続

PCのbluetoothをONにしてください。以下の一行で書いたた`M5Zoom remote controller` が選択肢で出ていると思います。




```
BleKeyboard bleKeyboard(""M5Zoomcontroller"");
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/13358d99-d411-2166-9abd-c74b7284b60c.png" width=50%>

##参考記事
大変参考になりました、ありがとうございました。
>[キーボードを遠隔操作するデバイスは簡単に作れるらしい](https://qiita.com/aki_suga/items/799ed507f58766887fbc)

##使い勝手
いい感じです。M5StickCを手元に持っていれば少し離れていても消音できてビデオも消せます。急に名前を呼ばれても慌てることなくボタンを押せば音声をONできるので使えそう。
Google Cloud ShellでTerraformerを使う

# 使うもの

## Google Cloud Shell

GCP上に用意してくれる、作業用シェル環境。
Terraformも既に入っているので便利。
https://cloud.google.com/shell/docs/using-cloud-shell?hl=ja

## Terraformer

既存のGCPインフラ構成からTerraformのtfファイルやtfstateファイルを生成してくれるツール。
GUIで先に作ってみて、後からtfファイルが欲しい（インフラ構成をコード化したい）時に便利。
GCP以外にも色々対応してるらしい。
https://github.com/GoogleCloudPlatform/terraformer

# 使い方

ドキュメントに従ってTerraformerをインストール。
https://github.com/GoogleCloudPlatform/terraformer#installation

```sh:CloudShell
export PROVIDER=google
curl -LO https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest | grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64
chmod +x terraformer-${PROVIDER}-linux-amd64
sudo mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer
```

作業ディレクトリを作って、google providerのバージョンを指定。

```sh:CloudShell

mkdir work
cd work
vi main.tf
```

```main.tf
provider "google" {
  version = "3.11.0" # 使っているバージョンに合わせる
}
```

Terraformerを実行。

```sh:CloudShell
#対象のリソースとプロジェクトは適宜指定する
terraformer import google --resources=monitoring --projects=sandbox-xxxxxxxx

#この辺に生成される
cat generated/google/sandbox-xxxxxxxx/monitoring/global/monitoring_notification_channel.tf 
```
AWS から PaizaCloud へのお引越し

### 初めに・・・
AWS に開発環境を作っていましたが、1年ったったので料金体制が微妙に分からなかった事もあり、定額性のPaizaCloudへ移行しました。
AWSで作ったアプリもあったのでPaizaへ移動したのですが、
WASでの環境はRuby 2.6.3 Ruby on Rails 5.2.4.3
Paizaの環境はRuby 2.7.0 Ruby on Rails 6.0.3.2, 6.0.2.1, 5.0.7.2, 5.0.6
なので、動いてくれるわけがなく・・・
試行錯誤の結果、何とか動かすことが出来たので、似たような事で苦労する人が一人でも減るように、そして自分で忘れないために作業手順を残しておきます。

###サーバの作成
これと言って複雑な事はしてません。
Web開発はRuby on Rails
データベースはMySQLとphpMyAdmin
を選択しました。

### rbenvを入れる
ターミナルを開き下記コマンドを順に入力し、rbenvを入れます。

```
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ type rbenv
rbenv is a function
rbenv ()
{
...(省略)...
}
```
$ type rbenv は動作確認らしく
コマンドを実行し、上記のrbenv is a function 以降が表示されれば大丈夫みたいです。

### ruby-buildのインストール
ruby-buildとはrbenvのプラグインらしく、それを入れるために下記のコマンドを入力します。

```
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv install --version
```
インストール出来ていることの確認もこめて
$ rbenv install --versionを行いバージョンが表示されればちゃんとインストールされています。

### インストール可能なRubyのバージョン確認
```
各Ruby実装の最新の安定リリースのみが表示される
$ rbenv install --list

すべてのローカルバージョンを表示する
$ rbenv install --list-all
```
安定板ではRuby 2.6.3が無かったので、今回は $ rbenv install --list-all を実行し2.6.3が有るのを確認し、インストール！

```
$ rbenv install [インストールしたいバージョン]
```
今回は2.6.3を入れたかったので $ rbenv install 2.6.3 としました。

インストールできたか確認する為に下記を実行し、インストールしたバージョンが出てくればOKです。

```
$ rbenv versions
* system
  2.6.3
↑こんな感じで表示されます。
*ついている方が今のバージョンです。
```

### バージョン変更
バージョンの変更方法は下記の2つあるようです。

```
# システム全体のバージョン変更
rbenv global [変更したいバージョン]
# 一部のみバージョンを変更
rbenv local [変更したいバージョン]
```
今回は全体を変えたいので rbenv global 2.6.3 としています。
変更したらもう一度

```
$ rbenv versions
  system
* 2.6.3
↑こんな感じで * が移動していればバージョンの変更が出来てます。
```

ここまで出来たら一旦コマンドメニューを閉じて、再度立ち上げてください。
自分がやった時はこのまま下のrailsのインストールに進むとエラーが出て進めませんでした。

### Ruby on Rails のインストール
Ruby on Railsもバージョンが違うので欲しいバージョンを入れます。
下記コマンドを入力

```
gem i -v [インストールしたいRailsのバージョン] rails
```
今回は5.2.4.3を入れたいので　gem i -v 5.2.4.3 rails
とコマンド入力

入力が終わったら　rails -v をやってバージョンが変わっているのを確かめてください。


以上で自分の場合は以前使っていた環境に変えることができました。
しかし、分かってない所も多いです。

###参考にしたところです
https://qiita.com/toshiro3/items/6f2ee61f552fc4885317
https://qiita.com/tanakayo/items/7b85261924eca1a5a3d6
【python】エラー原因と対処法：slice indices must be integers or None or have an __index__ method

pythonで下記エラーが発生したので、発生原因と対処法メモ。

```
TypeError: slice indices must be integers or None or have an __index__ method
```

##エラー詳細

スライスで変数を指定した際に発生。

```python:
arr = [1,2,3,4,5,6]
mid = len(arr)/2   #エラーの原因

print(arr[0:mid])  #エラー発生処理

#TypeError: slice indices must be integers or None or have an __index__ method
```

エラーの内容は、スライスでは整数か、値未記入か`__index__`メソッドのどれかしか指定できないとのこと。


[`__index__`メソッド]((https://docs.python.org/2.5/whatsnew/pep-357.html))とは、typeでintを返す処理のこと。



<br>
##エラーの原因と対処法

エラーの原因は、len(arr)/2がint（整数）でなかったことによる。
割り算のスラッシュは、対象が偶数の場合でも小数点0を含むfloatになる。

```python:
arr = [1,2,3,4]
type(len(arr)/2)

#float
```

###対処法
スラッシュ２つを使う。「/」→「//」
スラッシュ２つは割り算の整数部のみ（小数点以下切り捨て）

```python:typeの確認
arr = [1,2,3,4]
type(len(arr)//2)

#int
```

<br>

```python:再計算
arr = [1,2,3,4,5,6]
mid = len(arr)//2

print(arr[0:mid])

#[1, 2, 3]
```
【JavaScript】オブジェクトが存在しているように見えるのにその中身を参照しようとするとundefinedになる 

```Javascript
{ apple: 'りんご', lemon: 'レモン' }
```
testObjectという名前の上記のようなオブジェクトを参照したいとします。

「りんご」という文字を取り出したいので、

```Javascript
console.log(testObject.apple);
console.log(testObject['apple']);
```
などとしてもコンソールには

```Javascript
undefined
```
の表示。


オブジェクト自体はあるのになぜ中身は参照できないの！？！？と困惑するかと思います。
それは、実はオブジェクトではなくて**json型**のデータではないでしょうか。

試しに、元のデータを見るため

```Javascript
console.log(testObject);
```
としてみてください。

```Javascript
{ apple: 'りんご', lemon: 'レモン' }
```
ではなく

```Javascript
{ "apple": "りんご", "lemon": "レモン" }
```
のように出てくるかと思います。(※キーも値もダブルクォーテション)

こうなった場合、これはオブジェクトではなくjson型のファイルということです。

#結論
```Javascript
testObject = JSON.parse(testObject);
```
をしましょう。

これをすることで**json型**が**Object型**に変換されます。

その後

```Javascript
console.log(testObject.apple);
```
をすると

```Javascript
りんご
```

表示できました！

逆に、Object型からjson型に変換したい場合には

```Javascript
testObject = JSON.stringify(testObject);
```
を使ってくださいね！
macOS セキュリティアップデート2020-002が入らない(High Sierra)

#シャットダウンができない！

万が一のこともありますので、予め必要なバックアップは取っておいたほうが良いと思います。

ダウンロードされたファイルは`/Library/Updates/`にいます。

```
$ softwareupdate -i -a
```

を行った後

```
$ sudo shutdown -r now
```

で再起動してください。
画面フリーズの状態などでどうにもならなくなった場合はハードウエェアリセットの上電源を再投入します。

アップデートに成功した際のバージョンは`10.13.6(17G12034)`になるはずです。
HPEのiLO5の設定

HPE社のサーバマシンにはiLOと呼ばれるサービスプロセッサ的機能が備わっています。
これを上手に使うとサーバ管理、特にリモート管理が楽になります。

初期設定のままで使える場面もありますが、遠隔で無人な場合もあります。後からあーすれば良かった、こうすれば良かった。というのは困るのでちょっと設定してみました。

- iLO5が対象です。
- iLOへのログインなどは出来る前提での説明です。
- ML30などのNICが2個付いていてどちからがiLO5のインタフェースになる。という前提です。

# Portの固定
LAN1とLAN2があるこのどっちかを限定するための設定。

    </>hpiLO-> cd /map1/enetport1/lanendpt1
    </map1/enetport1/lanendpt1>hpiLO-> dir
    
    status=0
    status_tag=COMMAND COMPLETED
    Tue Oct 13 16:17:56 2020
    
    
    
    /map1/enetport1/lanendpt1
      Targets
        ipendpt1
      Properties
        EnabledState=shared LOM
        MACAddress=b4:7a:f1:XX:XX:XX
        LOMAndFlexibleLOMPortNumber=1
      Verbs
        cd version exit show set
    
    
    </map1/enetport1/lanendpt1>hpiLO-> set LOMAndFlexibleLOMPortNumber=2
    
    status=0
    status_tag=COMMAND COMPLETED
    Tue Oct 13 16:25:27 2020
    
    Network settings change applied.
    
    
    Settings change applied, iLO 5 will now be reset.
    Logged Out: It may take several minutes before you can log back in.

    CLI session stopped
    Received disconnect from XXX.XXX.XXX.73 port 22:11:  Client Disconnect
    Disconnected from XXX.XXX.XXX.XXX port 22

しばらく待つと、iLOの再起動が終わって再びログインできるようになります。

# IPアドレスの固定
通常はDHCPでアドレスが決定されるようですが、それでは不安なので、IPアドレスを固定します。

まず、DHCPでアドレスを決定する機能を止めます。

    </>hpiLO-> cd /map1/dhcpendpt1
    </map1/dhcpendpt1>hpiLO-> set EnabledState=no

再起動します。
再びログインします。
IPアドレスを設定します。

    </>hpiLO-> cd /map1/enetport1/lanendpt1/ipendpt1
    </map1/enetport1/lanendpt1/ipendpt1> set IPv4Address=192.168.4.4

192.168.4.4は架空のアドレスです。ここでサブネットマスクを入力する前に再起動に入ってしまいます。
再びログインします。

    </>hpiLO-> cd /map1/enetport1/lanendpt1/ipendpt1
    </map1/enetport1/lanendpt1/ipendpt1> set SubnetMask=255.255.255.0

# VLANIDの設定

Tag付きのVLANも使えるみたい。

    </>hpiLO-> cd /map1/vlan1
    </map1/vlan1> set VLANID=4

ここでも再起動に入ります。

ここまで出来たら、概ね希望通りの動作が可能になると思いますが、確認のために一度電源をOFFしてコンセントからも抜いて電源を入れ直して動作確認を行ってください。

また、ネットワーク周辺の設定ではIPアドレスとネットマスクなどの矛盾が生じることも考えられます。そこらへんは辻褄をよく考えて設定を実行してください。
【Rails】deviseで現在ログインしているユーザー情報の取得方法

#はじめに

deviseでは「現在ログインしているユーザーの情報を取得」する事ができます。
例えば、「名前」「生年月日」「住所」「電話番号」など、対象のユーザーが既に登録した情報を表示する方法を紹介します。

###目次

1.current_userメソッド
2.遷移先のview



#開発環境
ruby 2.6.5
rails 6.0.0
devise 4.7.3

##前提
devise導入済み
model生成済み
ユーザー登録済みでデータを既に持ってる
view作成済み


#実装

それでは実装して行きます。

####1.current_userメソッド

deviseを導入しているため使用できるメソッドで、current_user(現在ログインしているユーザー)の情報が取得できます。

```index.html.erb
<%= link_to current_user.nickname, edit_user_registration_path(current_user), class: "user-name" %>
    　　　　  #↑ここ#　　　　　　　　　　　　　　　　　　　　　　　　　　　#↑ここ#
```

例えば、マイページでユーザー情報を編集したい時を想定します。link_toメソッドでcurrent_user.nameと記述すると、今ログインしてるユーザーのnameカラムに保存されてる名前が表示れます。
また、url指定したpathの後ろにcurrent_userをつける事で、遷移先にもそのユーザー情報を表示させる事ができます。

※注意：urlはreils routesでコントローラー#アクションを探しください。


####2.遷移先のview
遷移先のviewページでは、既に登録されてるユーザーの情報を表示させます。


```edit.html.erb
<%= form_with model: @user, url: edit_addresses_path,  class: 'registration-main', local: true, method: :get do |f| %>

<%= f.text_area :name, class:"input-default", id:"name", placeholder:"例) 太郎", maxlength:"40" %>

<% end %>
```

今回ユーザー情報を編集するページを作りたいのでapp> views> devise >registrationsにあるedit.html.erbのファイルを編集します。
form_withメソッドを使います。
devise内部で@userが定義されていて、既にデータが代入されてるので「model: @user」とします。
「do |f|」とする事で「end」までの「f.text_area :カラム名（今回はname）」に現在のユーザー情報が表示されます。


※注意：deviseのviewをよび出してる場合は既に生成さてるファイルを使うと便利です。
参考記事
https://qiita.com/AKI3/items/bf0d5b57029abfc8154c



#まとめ
以上、現在ログインしているユーザー情報の取得方法でした。
current_userメソッドを使う事がポイントです。

###最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜
世の中ではMFAのリセット処理をどうやっているのか

# MFA の導入と 認証情報のリセットについて
* 2要素認証をサービスに導入を検討
* 認証情報のリセット方法をどうするのが良いのか悩んだ
* 世の中のサービスがどうしているのかを参考にしてみる

# CoinCheck の場合
## 特徴
### 認証の要素
* パスワード（必須）
* メールアドレス(必須)
* SMS（必須）
* MFA デバイス（任意）

## パスワードのリセット
### ログイン画面
* パスワードをお忘れですか？リンクをクリック
![スクリーンショット 2020-10-15 13.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/db3b19c2-857a-470b-f7bd-9a29af4487a5.png)

### メールアドレスの入力
![スクリーンショット 2020-10-15 11.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/019e930c-f886-d036-263a-f80032e0e709.png)

### SMSに認証コードが送られる
![スクリーンショット 2020-10-15 11.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/def3d5f2-ca9d-1a1a-8de6-40e09bde9523.png)
#### SMSの内容
![20201015_141256.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/4913afac-d5be-523d-00f7-0b78a80ba693.jpeg)


### メールアドレスにパスワード再設定用URLが送られる
![スクリーンショット 2020-10-15 11.28.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/f7c06d7e-1fad-aec6-8f97-03f16e8a2862.png)

#### メールの内容
![スクリーンショット 2020-10-15 11.29.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/4617f688-0e18-8954-46d1-60f44a61d7d5.png)

### パスワードの再設定画面
![スクリーンショット 2020-10-15 11.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/8515f2da-662f-5d35-7913-c5a59c18fab0.png)

## MFAデバイスのリセット
### ログイン画面
![スクリーンショット 2020-10-15 13.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/db3b19c2-857a-470b-f7bd-9a29af4487a5.png)

### 2要素目による2段階認証画面
* `認証アプリが使えない方`リンクをクリック
![スクリーンショット 2020-10-15 11.33.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/2d598db8-9fed-bdd4-8db2-54c797cb8879.png)

### 2段階認証の解除アナウンス画面
* 電話番号・メールアドレスが変わっていない場合は、本人で解除手続きができる
* MFAデバイスと、電話番号orメールアドレスどちらかが不明な場合は、問い合わせによる対応
![スクリーンショット 2020-10-15 11.33.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/9c0acac9-b3d8-9e86-4a20-79645e55afc0.png)

### 電話番号・メールアドレスが変わっていない場合の解除手続き
![スクリーンショット 2020-10-15 11.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/63e9bd45-755e-1151-0b17-9899792073da.png)

#### メールの内容
![スクリーンショット 2020-10-15 11.37.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/dfc68c5d-941b-8730-46e5-1056dbf624e2.png)

### 解除画面でSMSに送信された認証コードを入力
![スクリーンショット 2020-10-15 11.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/7a05cac7-8f0a-895b-5ff6-26f42f939f24.png)

### MFAデバイスの解除完了
![スクリーンショット 2020-10-15 11.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521224/7f9e3860-d9d6-8ca5-3bf4-939986ed8130.png)
CloudFormation EFSテンプレートサンプル

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EFSName:
    Type: String
    Default: hoge
  SecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
  Subnets:
    Type: List<AWS::EC2::Subnet::Id>
Resources:
  FileSystem:
    Type: AWS::EFS::FileSystem
    Properties:
      FileSystemTags:
        - Key: Name
          Value: !Ref EFSName
      Encrypted: true
  MountTarget1:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref FileSystem
      SecurityGroups: !Ref SecurityGroups
      SubnetId: !Select
        - '0'
        - !Ref Subnets
  MountTarget2:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref FileSystem
      SecurityGroups: !Ref SecurityGroups
      SubnetId: !Select
        - '1'
        - !Ref Subnets
  MountTarget3:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref FileSystem
      SecurityGroups: !Ref SecurityGroups
      SubnetId: !Select
        - '2'
        - !Ref Subnets



```
【Ruby on Rails】Skipprを使用した画像スライドショー

# 目標
![スライドショー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/de4bbca0-5238-565b-ad41-7d06610e7d17.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
※　▶◯◯　を選択すると、説明等が出てきますので、
　　よくわからない場合の参考にしていただければと思います。

- [deviseでログイン環境構築](https://qiita.com/japwork/items/275110b810965fbdf72f)
- [ログインユーザーのみができる投稿機能](https://qiita.com/japwork/items/8dfb52121036791ac4fb)
- [投稿の編集機能（更新、削除）](https://qiita.com/japwork/items/e258ccbbe4f48ea5a3b5)
<details><summary>補足</summary>
rails g devise:install は deviseの初期設定を行います。</details>

# 流れ
1　gemの導入
2　Skipprサイトからファイルをダウンロード
3　実際のコード



# gemの導入
Railsでjqueryを使えるようにします。

```rb:Gemfile
gem 'jquery-rails'
```
```:ターミナル
$ bundle insatll
```
```erb:app/assets/javascripts/application.js
//= require jquery　←追加
//= require jquery_ujs　←追加
//= require activestorage
//= require turbolinks
//= require_tree .
```

# Skipprサイトからファイルをダウンロード
公式サイト
http://austenpayan.github.io/skippr/

こちらのGithubをクリックし、ZIPファイルをダウンロードしてください。
![スクリーンショット 2020-10-15 13.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/32bc02dd-44e7-aa1f-c40e-7a4e8f05b151.png)
![スクリーンショット 2020-10-15 13.22.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/3a5bbbb2-837e-06c5-5a83-b02d4d2e7626.png)

解凍後、下記の通りに保存してください。

- skippr.min.jsファイルは、app/assets/javascriptsフォルダに
- skippr.cssファイルは、app/assets/stylesheetsフォルダに
![スクリーンショット 2020-10-15 13.25.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/fb6c447f-8c84-7a13-bda2-64a137152d3b.png)



# 実際のコード
app/assets/imagesにimage1.jpg〜image4.jpgを保存してください。

```erb:app/views/application.html.erb
<div id="box">
  <div id="images">
    <div class="image1"></div>
    <div class="image2"></div>
    <div class="image3"></div>
    <div class="image4"></div>
  </div>
</div>
```
```css:app/assets/stylesheets/application.css
/* 高さを指定することにより画像が表示される */
#box{
  height: 600px;
}
.image1 {
  background-image: url(image1.jpg);
}
.image2 {
  background-image: url(image2.jpg);
}
.image3 {
  background-image: url(image3.jpg);
}
.image4 {
  background-image: url(image4.jpg);
}
```

```js:app/assets/javascripts/application.js
$(document).ready(function () {
  $("#images").skippr({
    // スライドショーの変化 ("fade" or "slide")
    transition : 'slide',
    // 変化に係る時間(ミリ秒)
    speed : 1000,
    // easingの種類
    easing : 'easeOutQuart',
    // ナビゲーションの形("block" or "bubble")
    navType : 'block',
    // 子要素の種類("div" or "img")
    childrenElementType : 'div',
    // ナビゲーション矢印の表示(trueで表示)
    arrows : true,
    // スライドショーの自動再生(falseで自動再生なし)
    autoPlay : true,
    // 自動再生時のスライド切替間隔(ミリ秒)
    autoPlayDuration : 3000,
    // キーボードの矢印キーによるスライド送りの設定(trueで有効)
    keyboardOnAlways : true,
    // 一枚目のスライド表示時に戻る矢印を表示するかどうか(falseで非表示)
    hidePrevious : false
  });
});
```

# まとめ
比較的簡単に導入できるものの、
bootstrapと組み合わせるとうまくいかないこともあるので、
その場合はこちらを参考にしてください。
[【Ruby on Rails】bootstrap4のcarouselをeachメソッドを使いスライドショーを実装](https://qiita.com/japwork/items/8cd9cd96f6716433a505)

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork