OmniAICreator/Qiita-1.07M huggingface dataset:
OCI フレキシブルロードバランサー(FLB)でルールに基づいて振り分け先バックエンドセットを選択

## はじめに
　OCIのフレキシブルロードバランサー(FLB)では、「ルーティング･ポリシー」と呼ばれるルーティングルールを使用することで、ルールに応じて特定のバックエンドセットにアクセスを振り分けることが可能です。この機能の動作確認を行ったため、備忘録として記載します。
　
　なお、動作確認に必要なCompute,VCN,Subnet等の作成作業についての記載は本記事では省略します。

## フレキシブルロードバランサー(FLB)のルーティング･ポリシー
　ルーティング･ポリシーとは、ロードバランサーのリスナーに適用されるルーティングルールの名前付きのリストで、ルールは順序指定が可能です。

　ルールで定義した特定の条件に一致するかどうかに基づいて、受信トラフィックをルーティングすることができます。ルーティング･ポリシーでは、「パス」、「リクエストCookie」、「リクエスト･ヘッダー」、「URL問い合わせ」、「ネストした一致」を条件に使用することが可能です。これらのルールとバックエンドセットを紐づけることで、振り分け先の選択が可能となります。

　今回は、「リクエスト･ヘッダー」を条件に使用した振り分けの動作確認を行いました。

## バックエンドセット作成
　はじめにバックエンドセットを用意します。条件に応じて振り分け先のバックエンドセットが変化しているかを確認するために、今回はバックエンドセットを以下のように2つ作成しました。

　各バックエンドセットには1インスタンスずつComputeを登録しています。アクセス先が変わっているかを判別するために、各インスタンスにあるindex.htmlの内容を修正しています。
![バックエンドセット作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/744a6719-605e-9f4b-e463-1bf382b0f611.png)

## ルーティング･ポリシー作成
　続いてルーティングポリシーを作成します。今回は、ルールを二つ用意しています。リクエストヘッダーに含まれる「Test」の値を条件に、振り分け先のバックエンドセットをそれぞれ指定しています。
![ルーティングポリシー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/4594c660-8cbc-0b4e-275f-98a17360dbb9.png)
　今回の例では、「Test」の値が"A"である場合はバックエンドセット「bs_1」、「Test」の値が"B"である場合はバックエンドセット「bs_2」にトラフィックが流れます。

## リスナーへのルーティング･ポリシー登録
　上記で作成したルーティング･ポリシーをFLBのリスナーに紐づけます。リスナーの編集画面を開き、「ルーティング･ポリシー」の項目から今回作成したルーティング･ポリシーを選択します。
![ルーティングポリシー登録.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/349f7cc4-1119-3df5-d57c-8fc8aa4472c2.png)

## 動作確認
　実際にFLBに対してcurlでhttpリクエストを実行してみます。リクエストする際には、判定に使用する「Test」をヘッダーに付与して実行します。XXXには、FLBのIPアドレスを指定します。
```
curl -H Test:A http://XXX.XXX.XXX.XXX:80
curl -H Test:B http://XXX.XXX.XXX.XXX:80
```
実行した結果、以下の通り「Test」の値に応じて異なるバックエンドセットにアクセスしていることが確認できました。
![実行結果.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/b8c77537-e1ef-e65e-52d1-8350597c3cd8.png)
　本当はリクエスト送信元のIPアドレスで振り分けを行いたかったのですが、リクエストヘッダーにはIPアドレスを判別可能な情報が入っていなかったため断念しました。
　ただ、アプリケーションからhttpリクエストを行う際にヘッダに追加することは可能なので、その際の振り分けには利用可能な機能だと思われます。

## 追記(2023/9/4)
　以前はcurlコマンドで確認を行いましたが、Google ChromeにはModHeaderという拡張機能があります。この拡張機能を利用すると、リクエストヘッダーを追加することが可能です。

　chromeウェブストアにアクセスしてModHeaderを入手します。
　ChromeにModHeaderを追加するとアドレスバーの横にアドオンのアイコンが表示されるため、その中からModHeaderを選択します。
　![addon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/b2c85f12-d96e-c014-daee-349c7c01f169.png)
　ModHeaderをクリックして「+MOD」>「MODS」>「Request header」を選択すると、ヘッダーに追加するフィールド名と値を入力画面が表示されます。
![modheader.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/b3ac39bd-a0ad-1ebc-9ee9-63cd0468c636.png)
　リクエストを送りたいページに遷移した状態でフィールド名と値を設定し、ブラウザでページのリロードを行うと、入力した内容が追加された状態でリクエストが送られます。
　curlコマンドで動作確認した時と同じルーティングポリシーで、動作確認をした結果です。(curlコマンドを使用した時と同様な結果になっていることが分かります)
![modheder_test_A.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/f413db85-ba70-8da0-561b-7ba816998c56.png)
![modheder_test_B.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599194/4ee9a2cc-8f2a-1d5b-2525-0900b1609c6e.png)
Typescript の型エイリアスを override する方法

# 環境

* typescript - v5.2.2

# 基本的な型エイリアスの拡張方法

```typescript:交差型

// 基本とするオプション
type BaseOptions = {
  mode: string;
  ratio: number;
}

// モードパラメタの列挙
type CameraModeEnum = "" | "user" | "environment";

// 拡張したオプション（交差型）
type CameraOptions = BaseOptions & {
  mode: CameraModeEnum;
}; //=> {mode: string | CameraModeEnum, ratio: number }

function getCamera(options:CameraOptions){
  // options は BaseOptions と CameraOptions の両方の特性をもつので string と "" | "user" | "environment" の両方が受け入れ可能
  ...
}
```

型エイリアス( type ) を拡張させるは、交差させるしか方法がない。
上書き(override)したい。

# 結論

## override みたいな事をする

```typescript: Omit
// 基本とするオプション
type BaseOptions = {
  mode: string;
  ratio: number;
}

// モードパラメタの列挙
type CameraModeEnum = "" | "user" | "environment";

// 拡張したオプション（交差型）
type CameraOptions = Omit<BaseOptions, "mode"> & {
  mode: CameraModeEnum;
}; //=> {mode: CameraModeEnum, ratio: number }

function getCamera(options:CameraOptions){
  // options は BaseOptions と CameraOptions の両方の特性をもつのが
  // mode プロパティは Omit<> により BaseOptions から消されるので
  //CameraOptions の mode:"" | "user" | "environment" のみが受け入れ可能になる
  ...
}
```

# 参考

https://stackoverflow.com/questions/48215950/exclude-property-from-type
FWのスループットの計測(構想編)

ネットワークののパフォーマンスを調べるツールでiperf3というコマンドがあります。

サーバ・クライアントのツールで、スループットが計れます。

インターネット上に公開されているサーバもいくつかありますが、負荷になるので現実的に利用可能なサーバはほとんどありません。

ちょっと考えて下記のような方法を思いつきました。

インターネット側のifにプライベートなIPを降り、その先に同じネットワークでiperf3のサーバを上げ、そこへ接続して、計測する方法です。

![FW-iperf3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/da085577-d465-8167-dcc0-80b84e762df9.png)

クラウドにサーバー借りて、そこを使うという方法もありますが、この方法であれば費用はかかりません。
XSSによる影響と対策を簡単にまとめた

# 目次

1. XSSとは？
1. 攻撃による影響は？
1. XSS対策として必要なこと

# XSSとは？

![スクリーンショット 2022-10-26 0.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/ae9d6946-8072-b325-4e0a-9589fdc26dfd.png)

* Cross Site Scripting の略
* 攻撃対象のアプリケーションに対してスクリプトを埋め込まれ、利用者のブラウザ上で実行されることで被害をもたらす攻撃

# 攻撃による影響

サイト利用者に対しての攻撃

* 本物サイト上に偽のページが表示される
    * フィッシング
        * 企業やサービスのWebサイトに悪意のあるURLを記載することで、ユーザを偽サイトに誘導し、個人情報及び機密データを入力させられる
    * 偽情報流出
* ブラウザに保存されているCookie上の情報を盗まれる
    * セッションハイジャック・・・格納されたセッションIDが盗まれることが原因で、利用者へのなりすましに遭う
        * サーバ内への侵入
        * 機密情報の搾取(さくしゅ)
        * 不正出金
        * クレジットカードの不正利用
    * 個人情報等が格納
        * その情報が漏えいする
* 任意のCookieをブラウザに保存させられる
    * セッションIDが送り込まれ、セッションID固定化攻撃を受ける

# XSS対策として必要なこと

>1)　HTMLテキストの入力を許可しない場合の対策
2)　HTMLテキストの入力を許可する場合の対策
3)　全てのウェブアプリケーションに共通の対策

https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_5.html

それぞれの根本的解決を抽出して下に記載します

## 1)　HTMLテキストの入力を許可しない場合の対策

### 根本的解決

* 出力する要素に対してエスケープ処理を入れる
    * ウェブページの表示に影響する特別な記号文字（「<」、「>」、「&」等）を、HTMLエンティティ（「`&lt;`」、「`&gt;`」、「`&amp;`」等）に置換する
    * エスケープ処理が必須となる場面
        * 外部からウェブアプリケーションに渡される「入力値」の文字列
        * データベースやファイルから読み込んだ文字列
        * 何らかの文字列を演算によって生成した文字列
        * JavaScriptのdocument.writeメソッドやinnerHTMLプロパティ等を使用して動的にウェブページの内容を変更する場合

    [sanitize-html](https://www.npmjs.com/package/sanitize-html)のようなライブラリを使用してサニタイズしたりします

* URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可
    * urlには、「javascript:」の形式で始まるものもある
        * 出力するリンク先や画像のURLが、外部からの入力に依存して動的に生成される場合、そのURLにスクリプトが含まれていると、XSSへの脆弱性が生まれる

* `<script>...</script>`で 要素の内容を動的に生成しない
    * 外部からの入力に依存する形で動的に生成される場合、任意のスクリプトが埋め込まれてしまう可能性がある
    * 例）innerHTML

* スタイルシートを任意のサイトから取り込めるようにしない
    * スタイルシートには、スクリプトを記述することができる
        * 任意のサイトに置かれたスタイルシートを取り込めるような設計をすると、生成するウェブページにスクリプトが埋め込まれてしまう可能性がある

## 2)　HTMLテキストの入力を許可する場合の対策

### 根本的対策

* 入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する
    * ただし、これには複雑なコーディングが要求され、処理に負荷がかかるといった影響もあるため、実装には十分な検討が必要

構文解析・・・プログラミング言語 → 機械語への変換の際に行われる処理の一つ

## 3)　全てのウェブアプリケーションに共通の対策

### 根本的対策

* HTTPレスポンスヘッダのContent-Typeフィールドに文字コード（charset）を指定する
    * 「Content-Type: text/html; charset=UTF-8」のように、文字コード(charset)を指定
        → 省略した場合、ブラウザは、文字コードを独自の方法で推定して、推定した文字コードにしたがって画面表示を処理

    webサーバーにApacheを使用している場合、以下のように文字コードの指定を行う

```httpd.conf ファイル、または、.htaccess ファイル
AddType "text/html; charset=UTF-8" html
```

返ってきたレスポンスヘッダが以下

`charset=UTF-8`を文字コードとして指したことで、`Content-Type`として返却されています

```HTTPレスポンスヘッダ.
HTTP/1.1 200 OK
Date: Sat, 29 Oct 2022 11:03:45 GMT
Server: Apache
Last-Modified: Sat, 29 Oct 2022 12:03:45 GMT
Connection: close
Content-Type: text/html; charset=UTF-8
```

* 文字コード指定をしない場合に生まれる脆弱性
特定の文字コードをブラウザに選択させられる。
文字列を埋め込んだ上、その文字コードで解釈した場合にスクリプトのタグとなるような文字列を埋め込まれる可能性がある
その場合、仮にエスケープ処理を入れている場合でも想定していた文字コードとは異なる文字コードを指定された場合はエスケープ処理が走ることはない

# 参考

https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_5.html
【Python】イテレータが何となく分かる様になる

# イテレータ

イテレータとは？

* データの流れを表現するオブジェクト
* 要素を1つずつ取り出せるオブジェクト
    * `__iter__()`メソッドから取り出されたオブジェクトが**イテレータオブジェクト**
    * データがなくなると、StopIteration 例外を送出する

https://docs.python.org/ja/3.10/glossary.html#term-iterator

## イテレータオブジェクトを作ってみる

```python
fruits = ["apple", "orange", "grape"]

iterator = iter(fruits)
print(iterator)  # <list_iterator object at 0x10fd7bf70>
```

```python
for i in iterator:
    print(i)

# apple
# orange
# grape
```

リストと同じようにfor文でループすることが可能です

ではリストとの違いは？

## 次の要素を調べる

組み込み関数`next`を使用することで次の要素を調べることができる
この機能はリストには無いが、**イテレータオブジェクトだからこそ使用できます**

### イテレータの場合

```python
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
```

```
apple
orange
grape
Traceback (most recent call last):
  File "/Users/ShoyaBaba/application/practice/python-practice/sample2.py", line 9, in <module>
    print(next(iterator))
StopIteration
```

一つ一つ要素の出力をしています
`grape` の次の要素は存在しないので`StopIteration`例外が送出されます

### リストの場合

```python
print(next(fruits))
```

```
Traceback (most recent call last):
  File "/Users/ShoyaBaba/application/practice/python-practice/sample2.py", line 6, in <module>
    print(next(fruits))
TypeError: 'list' object is not an iterator
```

リストでは、イテレーターでは無いためTypeErrorがはかれます。

## イテレータオブジェクトは使用済みの同じものを返す

> (list のような) コンテナオブジェクトは、自身を iter() 関数にオブジェクトに渡したり for ループ内で使うたびに、新たな未使用のイテレータを生成します。これをイテレータで行おうとすると、前回のイテレーションで使用済みの同じイテレータオブジェクトを単純に返すため、空のコンテナのようになってしまします。
https://docs.python.org/ja/3.10/glossary.html#term-iterator

これだけでは意味が分かりませんでした。
実際にコードにしてみます

### [リストの場合] 2箇所でforループをする

> コンテナオブジェクトは、自身を iter() 関数にオブジェクトに渡したり for ループ内で使うたびに、新たな未使用のイテレータを生成します。

```python
fruits = ["apple", "orange", "grape"]

for f in fruits:
    print(f)

for f in fruits:
    print(f)
```

```
apple
orange
grape
apple
orange
grape
```

for文で2度同じオブジェクトのループが実行されて、出力もされます

### [イテレータの場合] 2箇所でforループをする

> これをイテレータで行おうとすると、前回のイテレーションで使用済みの同じイテレータオブジェクトを単純に返すため、空のコンテナのようになってしまします。

```python
fruits = ["apple", "orange", "grape"]

iterator = iter(fruits)

# 1
for i in iterator:
    print(i)

# 2
for i in iterator:
    print(i)
```

```
apple
orange
grape
```

`1`のfor文の出力のみがされます。
iteratorオブジェクトは使用済みのため、`2`では空のコンテナが返されます

## どこで使う？

どんなものかはなんとなく分かったが、そもそもの用途が分からない

イテレータの機能として、**操作のステップごとに、順に要素を取り出せる**事が挙げられます。

これを利用できる例としては、、、

* テキストファイルを開いて、１行ごとに読み取り、表示
    * 1行目には、hogehogeの処理をして、表示
    * 2行目には、hugahugaの処理をして、表示

# 最後に

for文があるのでイテレータは滅多に使わないみたいですが。。
こんなものがあるのかと知っておくだけでも良いかもしれないですね
【2023年8月版】vSphere Client で 「この接続ではプライバシーが保護されません」 を回避する

# はじめに

ESXi7/8 でハイパーバイザー構築したけど、vSphere Clientにブラウザでアクセスするたびに、

`この接続ではプライバシーが保護されません`、`NET::ERR_CERT_AUTHORITY_INVALID` って表示される。。。

# ゴール

ブラウザでアクセスする際に、'この接続ではプライバシーが保護されません' が表示されないようにする

# 環境

ESXi7/ESXi8
macOS12.6 + GoogleChrome

# 作業

## vSphere Clientでの作業

domain と search domainを設定し、メンテナンスモードにした後、再起動する

### domain　と search domain を設定

- Default TCP/IP satck の設定を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/a9ae9d98-5493-345b-e1b3-30465c1783b9.png)

- domain と search domain を適当に設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/baed88fb-efbb-d4d6-d042-b53c428d4356.png)

## rui.crt と rui.key をバックアップ

必要であれば、scpなどで以下のファイルをバックアップ
- /etc/vmware/ssl/rui.crt
- /etc/vmware/ssl/rui.key

## generate-certificates　の実行

SSH接続して `/sbin/generate-certificates` を実行し、再起動する

## 証明書のインポート

scpなどで、 `/etc/vmware/ssl/castore.pem` を取得する。
ローカルで、`castore.pem` を `castore.pem.crt` にリネームする。
キーチェーンアクセスで システムキーチェーン -> システム -> 証明書にドラッグしてインポートする。
または、castore.pem.crtをFinderでダブルクリックしてインポートする。
VMWare Installerという証明書がキーチェーンアクセスに証明書として追加されるので、右クリックして情報を見る。
信頼タブ（縦のタブ）を開いて、この証明書を使用するとき：を `常に信頼` に変更する。
VMWare Installerの証明書が、`この証明書はすべてのユーザにとって信頼されているものとして指定されています` と表示される。

## vSphere Clientの動作確認

vSphere Clientへ、ブラウザでアクセスすると、`この接続ではプライバシーが保護されません` が表示されなくなる。
メンテナンスモードを解除する。

# さいごに

かんたんでしたね
3Dプリンタの1層目定着設定

3Dプリンタを使用していて失敗するそのほとんどが定着不足だと思う。
印刷物が倒れる、ずれるなどして積層が継続できなくなり、鳥の巣が生まれる。
定着がしっかりできれば、このようなトラブルからさようならできる。

スライサーソフトで1層目の設定（『初期』設定とも呼ばれる）を変えることで、圧倒的に定着力を増すことができる。
Ender-3 S1 Pro、 Creality Slicer、 PLAを使用した設定を紹介する。

『初期』設定
・ノズル220℃
・プレート70℃
・移動速度10mm/sec
・高さ0.3mm
・ライン150%
・フロー150%
・ファン0%

目的としては
①PLAを良く溶かす、なかなか固まらせない。このために温度設定を高く、ファンを止めて冷却もしない。
②定着しないうちにノズルが引き回すのを予防するため移動速度を遅くする。
③素材をたっぷりと出すために、高さとフロー（フィラメントの押出量）とライン幅を増やす。実際にはノズルの押し付けと素材の変形があるため横方向に広がり指定よりも太い描画になるが、外壁ライン同士がよく繋がり、隙間なく形成される。
クラウドの種類(IaaS / PaaS / SaaS)

早速はじめていきましょう！

先ず、クラウドコンピューティングでは利用形態による種類分けとして、IaaS(アイアースまたはイアース)PaaS(パース)SaaS(サース)がありますよね。
詳細は次の図のようになります。
利用形態により、自由に活用ができる反面、管理も必要となります。

<クラウドサービスモデル>
-
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2233790/cec43c65-810b-27eb-8517-6cf19ca0a2bf.png)
■SaaS(Software as a Service）
クラウドにあるソフトウェアを、インターネットを経由してユーザーが利用できるサービスとなり、特徴としては、どこでも利用できて運用・保守が不要であるという点です。
上記サービス以外にも、Gmail,Drop-box,MicrosoftTeams,Salesforceがあります。

普段何気なく利用しているWebアプリケーションがクラウドの一種となっていますよね。
最初から完成されたものを利用すると考えて頂ければ分かりやすいです。

■PaaS(Platform as a Service)
オペレーティングシステムやミドルウェアまでを管理しており、AWSではマネージドサービスと呼ばれ、ある特定の機能だけを利用者に提供するものになります。

■IaaS(Infrastructure as a Service)
サーバーだけ、ネットワークだけといった特定の機能を提供します。
利用者側で詳細な設定ができる反面、管理する範囲も広くなります｡

これまで、オンプレミスでは、サーバーやネットワーク機器の故障対応は利用者自身で全て行う必要がありましたが、これらはAWSのIaaSやPaaS/SaaSを利用することでAWSの責任で復旧が行われることになり、利用者がサーバーのハードウェア故障時にデータセンターへの入館や復旧作業を行う必要がなくなります。

■まとめ（AWSと絡めて考えていきます）
AWSと利用者の間で負うべき責任の境界範囲を「責任共有モデル」として定めています。
・利用者はクラウドの「内」のセキュリティ責任(利用者が設定できる範囲)を担当します。

・AWSはクラウド「の」セキュリティ責任(サービス自体の提供やメンテナンスなど)を担当します。

・クラウドでは利用形態による種類分けとして、「IaaS」「PaaS」「SaaS」の3つに分けられます。

■カジュアル面談受付中
下記からスケジュール設定可能となります。
https://t.co/91lhm0x2JE
～・～・～・～・～・～・～・～・～・～・～
LinkedIn
https://www.linkedin.com/in/akkodis-okada/
Twitter(X)
https://twitter.com/edamamecook
Nextjsで.envが読み込まれない (undefinedになる)

# はじめに

Nextjsを使っていて調べてもなかなか解決までいかないことがあったので記事にしていきます

# 問題

Nextjsで`.env`から環境変数を読み込もうとしてルートディレクトリに`.env`ファイルを作り以下の内容を書きました

```.env
API_PROXY=https://www.hoge.jp
```

そして環境変数`API_PROXY`を読み込み表示します

```index.tsx
cosole.log(process.env.API_PROXY)
```

しかしなぜか`undefined`になり読み込みができませんでした

# 解決方法

ランタイムを`node`にしていたので環境変数の先頭に`NEXT_PUBLIC_`をつける必要がありました

```.env
NEXT_PUBLIC_API_PROXY=https://www.hoge.jp
```

```ts
console.log(process.env.NEXT_PUBLIC_API_PROXY)
```

これはクライアントでフロントを使うときには必要なので`use client`していたので読み込めなかったような気がしています

# おわりに

知らなかった。。
この情報があまりネットにはなかったのですが、デフォルトでnextjsを作成して使っているのでハマる人多いのではないかとおもいました

# 参考
https://fwywd.com/tech/next-env
[Rails]　真偽判定メソッド

# 目的
Railsでは多くの真偽判定メソッドがあるので、まとめる

# 前提
- 変数データが何もない状態のnullは、rubyではnilという.。
- rubyのif文などでメソッドを使わず、変数単体で真偽判定する場合、
　変数が「false」と「nil」のときだけがfalseで、他はtrue。
　他の言語ではfalseが多い「0」などもtrue。
　混乱するので記述。

# 真偽判定メソッド
#### nil?
```
変数.nil?
```
Ruby標準メソッド。nilの場合にtrueを返して、それ以外はfalse。

####  empty?
```
変数.empty?
```
Rubyの標準メソッド。空の文字列、空の配列の場合にtrueを返す。
nilだとNoMethodError発生

#### blank?
```
変数.blank?
```
Railsで拡張されたメソッドなので、Railsでしか使えない。
nil?+empty?のメソッド。nilまたは空のオブジェクトの時にtrueを返す。

#### present?
```
変数.present?
```
Railsで拡張されたメソッドなので、Railsでしか使えない。
blank?の逆のメソッドで、nilまたは空のオブジェクトでない時にtrueを返す。

## 少し番外
#### exists?
```
オブジェクト.exists?(条件)

# 例
User.exsists?(name: '田中')
```
Railsで拡張されたメソッドなので、Railsでしか使えない。
指定した条件のレコードがデータベースに存在するかを真偽地で返すメソッド。

# 参考にさせていただいた記事
- [Ruby 当たり前のtrue/false](https://qiita.com/shizuma/items/e6310d78d9c64ea5365c)
- [【Rails】nil?, empty?, blank?, present?, exists?の違いと使いどころ](https://nishinatoshiharu.com/rails-boolean-methods/)
- [nil? empty? blank? present? の使い分け](https://qiita.com/somewhatgood@github/items/b74107480ee3821784e6)
- [【Rails】 exists?メソッドの使い方~present?との違い](https://pikawaka.com/rails/exists)
CodeIgniter4でのデータベース管理の基本

## はじめに

原則としては内部向けですが、自分もはまった経験がある部分なので、もしかしたら役に立つかもしれないので公開します。（CodeIgniter3以下でも基本は同じですが、関数名の変更があるので注意してください：例えばCI3までは `add_field` → CI4 では `addField` ）

[おそらく一番参考になるサイト（英語）](https://makitweb.com/update-table-structure-using-migration-in-codeigniter-4)

## データベース管理の流れ

CodeIgniter4のデータベース管理の流れを整理してまとめておきます。

1. `php spark migrate:create <管理ファイル名>`
1. 管理ファイルを編集して `up` にアップデート内容を記述
1. 管理ファイルを編集して `down` にアップデートを戻す内容を記述
1. `php spark migrate` で完了！
1. `php spark db:table` などで変更内容を確認

`migrate:create` で管理ファイル名の連番オプションを変更することも可能なので、プロジェクトで統一して管理してください。（例えば `--suffix` で `<日付-管理ファイル名>` の形でマイグレーションファイルが生成されます）ちなみに `migrate:create` を使わなくてもマイグレーションファイルを作れますが、管理面からこれを使っておいたほうが良いです。

#### 使う関数

- `$this->forge->addField([...])` → フィールドの追加
- `$this->forge->dropField([...])` → フィールドの追加
-  `$this->forge->addKey('<カラム名>')` → インデックスの追加
-  `$this->forge->createTable('<テーブル名>')` → テーブルの作成
-  `$this->forge->dropTable('<テーブル名>')` → テーブルの削除
-  `$this->forge->addColumn('<テーブル名>', [...])` → カラムの追加
-  `$this->forge->dropColumn('<テーブル名>', [...]);` → カラムの削除
-  `$this->forge->modifyColumn('<テーブル名>', [...])` → カラムの定義変更

`[...]` にカラム定義を配列の形で入れて、基本的には以下の関数を使ってデータベースを管理しますが、既に作成されたテーブルに対して `addField` を適用しようとするとエラーになります。既に存在するテーブルに対してカラムの追加を行う場合は `addColumn` を適用してください。

#### 変数定義

上記 `[...]` に代入する配列内のカラム定義の例は以下のようになります。配列は変数として与えることもできます。

```
'<カラム１>'  => [
    'type'          => '<変数型>',
    'constraint'    => '文字数',
    ... <続く> ...
],
'<カラム２>'  => [
    'type'          => '<変数型>',
    'constraint'    => '文字数',
    ... <続く> ...
],
... <続く> ...
```

#### 補足

SQLAlchemyなど、DERaCで主に使っているPythonフレームワークのデータベース管理ではデータベースモデルのファイルを編集してマイグレーションコマンドを打ち込むとマイグレーションファイルが自動的に作成される形になります。CIの場合、モデルの定義はマイグレーションファイルで直接管理して、モデル定義ではデータベース操作を定義する構造になります。
メール送信するRailsアプリの開発環境構成

Railsの開発環境でメールのテストを行う場合、多くの方がMailcatcherをお使いなのではと思います。

私がMailcatcherを使う場合によく行う設定を共有したいと思います。
好みとがあるので正解っていうわけじゃないです。念のため。

まずはRailsアプリ側です。
ポートをいろいろと設定しても良いのですが、せっかくなので使いまわしできそうな delivery_method を定義してしまいます。

config/initializer/mailcatcher.rb を下記内容で追加します。
```ruby
ActionMailer::Base.add_delivery_method :mailcatcher, Mail::SMTP,
                                       server: 'localhost', port: 1025
```

あとは、config/environments/development.rb に下記を追記することで、mailcatcherが利用できます。

```ruby
config.action_mailer.delivery_method = :mailcatcher
```

なんか、ファイルが増えたり記述量が増えたりしているようにも見えますが、メリットとしては、何をやっているか？が直感的に記載されていることがメリットだと思います。

普段、Linux 上で開発しているという方は、Mailchatcher をsystemdで起動してしまったほうが何かと便利かもしれません。

私はこんな感じの設定で動かしています。
```systemd
[Unit]
Description=MailCatcher
After=network.target
[Service]
Type=simple
User=<<user>>
WorkingDirectory=/home/<<user>>
ExecStart=/home/<<user>>/.rbenv/versions/3.1.2/bin/mailcatcher --foreground
TimeoutSec=300
Restart=always
[Install]
WantedBy=multi-user.target
```
ご参考まで。
改行を含むログをgrepフレンドリーにするPerlスクリプト

1つのログメッセージ自体に改行が含まれているログファイルをgrepすると、ログメッセージの一部しか表示されません。各ログエントリーの先頭にフォーマット化されたテキストがあり、そのテキストでgrepしたときにはログメッセージ全体を見たいものです。それをなんとかするPerlスクリプトです。（なぜPerlなんか使うのかという疑問に対しては、この記事の最後に言い訳を書いておきました）

ちょっと意味が伝わりづらいと思うので、例を示します。

こんなようなログファイルがあったとします。

```plain
2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.421 [INFO][Thread-2]: log message message bbb
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT
    id,
    name,
    ...
```

これを Thread-1 でgrepすると、こうなってしまいます。

```plain
2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT
```

SQLが1行目しか見れません。

ログメッセージごとにタイムスタンプやそのほかのメタ情報が先頭に付与され、そのあとにログメッセージ本体が続くフォーマットですが、ログメッセージ自体に改行が含まれると、このようにとても残念なことになります。

ログファイルを以下のように変換できれば、grepしても情報が失われずに済みます。grepする前にメタ情報を各行に追加してしまうのです。

```plain
2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.421 [INFO][Thread-2]: log message message bbb
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   id,
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   name,
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   ...
```

このログファイル変換をパイプで処理するPerlスクリプトを書きました。


# Perlスクリプト

`forgrep.pl` などのファイル名で以下のスクリプトを作ります。

```perl
use strict;
use warnings;
use utf8;

my $currHead = "";

sub modifyLine {
    my ($line) = @_;
    chomp($line);
    if ($line =~ /^([-:\.0-9]{10}T[-:\.0-9]{12}\s+)(.*)$/) {
        $currHead = $1;
        $line = $2;
        while () {
            if ($line =~ /^(\[.+?\])(.*)$/) {
                $currHead .= $1;
                $line = $2;
            } else {
                last;
            }
        }
        if ($line =~ /^(:\s+)(.*)$/) {
            $line = $2;
        }
        return $currHead . ": " . $line;

    } else {
        return $currHead . "| " . $line;
    }
}
while(<STDIN>) {
    print modifyLine($_) . "\n";
}
```


# 使い方

```plain
$ cat log.txt | perl ./forgrep.pl | grep 'Thread-1' | less -S
```

`less`コマンドの`-S`オプションは、長い行があったときにターミナル上で折り返さずに、右にスクロールできるようにするものです。


# なぜPerl？

Perlは多くの環境で使えるスクリプトです。明示的にインストールしなくても使えることが多いです。しかし、プロジェクトでメインの言語となっているケースは少ないです。プロジェクトでPerl自体のバージョン管理やパッケージ管理がされていることがないため、勝手に使ってもチームで管理しているコードと衝突することがほぼありません。なので、私はちょっとしたテキスト処理に使うスクリプトにPerlを使うことが多いです。今月私が一番書いたプログラミング言語はPerlです。
レポートの検索条件を取得する

以下のような質問があったので、答えたのですが回答が気に入らなかったのか、質問ごと消されましたね。（久々に日本人で質問ごと消してなかったことにする人に会いました。次からはこんな被害にあわないで済むように、質問に解答しない人のリストに追加しました。）


この質問は過去にも何度か見たことがあるので、ちょっと記録しておきます。
	 	

レポートの検索条件で使用されている項目の調査
カスタムオブジェクトの項目の精査を行いたいと思っております。

ただ、ユーザがレポートの検索条件で使用している可能性もあるため、レポートの検索条件で使用されている項目を一覧などで取得する方法があれば非常に助かります。

https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007FTGZg

私の今の見解では

レポートの設定はSOQLでは検索できないと思います。内容はメタデータに格納されているので、メタデータを取得してテキストを検索するようなツール（簡単なのはUnix系のコマンドgrepなど）を使えば検索できると思います。

メタデータですが、１件ずつならSalesforce Reports and Dashboards REST APIでも可能ですが、これでは大変なので force CLIなどのメタデータを一括で取得できるツールを利用したほうがいいと思います。


Get Report Metadata
https://developer.salesforce.com/docs/atlas.en-us.246.0.api_analytics.meta/api_analytics/sforce_analytics_rest_api_get_reportmetadata.htm
Create a Partner Site with Experience Cloud


+ [Create a Partner Site with Experience Cloud](https://trailhead.salesforce.com/content/learn/projects/create-a-partner-community)

+ [Not able to complete the challenge because of a missing profile - Set Up an Experience Cloud Site for Salesforce Customer Identity](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007GGc1N)

"Partners" profile がないらしい。

プロファイルを作ってなかったみたいですね。

:::note
Are you using a playground running the following modules?

https://trailhead.salesforce.com/content/learn/projects/create-a-partner-community/setup-the-community
:::


+ [
Partner Site Permission Set option not found](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Ot5UYSAZ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3afc003d-49db-b35b-e753-802e93f50c62.png)


:::note
Can you confirm that you have done the below correctly:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/77720dbe-5caf-e378-afe1-fd9b4cdbad79.png)

:::
PowerAutomateForDesktopの技術検証⓶（①）の補足

　前回の記事にて、Web操作がハードウェアイベントのみなのではという検証結果を出しましたが。そうではなさそうというのが判明したので記事にしてみたいと思います。
↓前回の記事はこちら
「PowerAutomateForDesktopの技術検証⓵」
https://qiita.com/horiivalue/items/31fa95435342d64375bc

# やったこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533364/ff03974e-1ba3-e1da-35f9-03de41d2a100.png)

⓵ここの「詳細」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533364/52a1ba5f-812b-04c6-8bac-2c810c062f34.png)

⓶この「物理クリックを送信」のところを上図の通りに「オフ」にします。

# 検証

以下の内容で検証

⓵ウィンドウが「標準」、動作の途中は何も操作はしない。
⓶ウィンドウが「最大化」、動作の途中は何も操作はしない。
⓷ウィンドウが「最大化」の時に動作の途中でマウスを動かす。

# 検証結果

⓵ウィンドウが「標準」、動作の途中は何も操作はしない。
試行３回、成功３回、失敗０回
⓶ウィンドウが「最大化」、動作の途中は何も操作はしない。
試行３回、成功３回、失敗０回
⓷ウィンドウが「最大化」の時に動作の途中でマウスを動かす。
試行３回、成功３回、失敗０回

となりました。どうやら、以下の動作みたいになることが判明いたしました。
⓵「物理クリックがオン」→ハードウェアイベント
⓶「物理クリックがオン」→ウィンドウメッセージorシミュレート

従って、Web上の動作の安定時には「物理クリックをオフ」にしておいたほうがよさそうです。
SpringBootでのリクエストパラメータの受け取り方

リクエストパラメータを受け取る際の備忘録。
SpringBootでリクエストパラメータを受け取るには、以下の３つのアノテーションを使い分ける。
- パスパラメータ
- クエリパラメータ
- リクエストボディ
それぞれの使い方を以下にまとめる。

パスパラメータ
[@PathVariable](https://qiita.com/naoki-shichida/private/8b17b76c0dcaddd49aca#pathvariable)

クエリパラメータ
[@RequestParam](https://qiita.com/naoki-shichida/private/8b17b76c0dcaddd49aca#requestparam)

リクエストボディ
[@RequestBody](https://qiita.com/naoki-shichida/private/8b17b76c0dcaddd49aca#requestbody)

# Spring Boot Version
3.1.1

# 用途、具体例
### @&#xFFF0;PathVariable
URLの一部をメソッドの引数として受け取るために使用する。
```java
https://example.com/products/{productId}
```
```java
@GetMapping("/products/{productId}")
public Product getProductDetails(@PathVariable Long productId) {
    // productIdを使用して製品詳細を取得する処理...
}
```

### @&#xFFF0;RequestParam
クエリパラメータやフォームデータをコントローラメソッドの引数として受け取るために使用される。

```java
@GetMapping("/products")
public Product getProducts(@RequestParam String param1, @RequestParam String param2) {
    // クエリパラメータの値を使用して処理...
}
```
```java
@PostMapping("/products")
public String createProduct(@RequestParam String name, @RequestParam String authorName) {
    // フォームデータを使用して処理...
}
```
https\://example.com/products?param1=value1&param2=value2のようなURLで、param1やparam2のクエリパラメータの値を取得する際に使用する。

### @&#xFFF0;RequestBody
HTTPリクエストのボディ部分からデータを受け取るために使用される。JSON形式で受け取るのが一般的である。

```java
@PostMapping("/products")
public String createProduct(@RequestBody ProductForm productFormData) {
    // productFormDataを使用して処理...
}
```
```java
@Data
public class ProductForm {

    /**
     * 製品名
     */
    private String name;

    /**
     * 製品著者
     */
    private String authorName;

}
```
@&#xFFF0;RequestBodyを使うと以下の利点などがある。
- JSONなどの形式で送信されるデータを受け取り、Javaオブジェクトに変換してコントローラーメソッドに渡すことができる
- formクラスにパラメータを定義するのでリクエスト項目が増えてもコントローラーがスッキリする
新しいRustベースのゲームエンジンの紹介

こんにちは、私はゲーム開発者として活動していますが、日本語は母国語ではありません。そのため、翻訳に誤りが含まれている可能性がありますので、ご了承ください。今回、新しいゲームエンジンを紹介したいと思います。このエンジンは、日本語にも対応しています。

**Rust ゲームエンジンの概要 - goku**

**主要な機能:**

- **Rustベース**: Rustだけで完全に構築されており、効率的なパフォーマンスとメモリの安全性を保証します。
- **sdl2 の統合**: sdl2 とのシームレスな統合により、プラットフォームと機能のサポートが広がります。
- **プラットフォームの対応**: WindowsとWASMの両方のために最初から設計されており、互換性を確保します。

**キーフィーチャー:**

1. **SpriteSheet によるレンダリング**: 効率的なイメージのパッキングを可能にし、複数のオブジェクトのレンダリングパフォーマンスが向上します。
2. **AnimatedTexture 構造**: スプライトオブジェクトのタイムアニメーションを容易にします。
3. **TextureManager**: テクスチャのローディングとエラーハンドリングのプロセスを合理化します。
4. **タイルシステム**: 開発者が詳細なゲームの風景やシーンを作成するのを可能にします。
5. **カメラの機能**: プレイヤーや特定のGameObjectを経験の中心に保つ動的なビューを提供します。
6. **パーティクルシステム**: ゲームのリアル感を高めるための自然現象のシミュレーション。
7. **オーディオシステム**: `sdl2::mixer` と統合され、多様なゲームサウンドスケープのプラットフォームを提供します。
8. **AIのためのビヘイビアツリー**: ゲーム内のエンティティが様々な振る舞いを示すことを可能にし、ゲームのリアル感を向上させます。
9. **パララックス背景**: 2Dゲームの風景に深さをもたらします。
10. **フレームレート管理**: 異なるハードウェアセットアップ間でのゲームプレイの一貫性を確保します。

**追加のユーティリティ:**

- **GUIの統合**: ボタンやチェックボックスなどのUI要素の追加を容易にします。
- **InputHandler**: デバイス全体でのユーザーのインタラクションの確実なキャプチャを提供します。

**開発者のための利点:**

- **効率的なパフォーマンス**: Rustの力を利用してゲームのレンダリングを最適化します。
- **クロスプラットフォームのデプロイメント**: WindowsとWASMの両方に一度開発します。
- **包括的なドキュメンテーション**: エンジンの各機能をナビゲートするのを助ける詳細なガイド。

**エンゲージメント:**

このエンジンの成長には、エンジンを活用したり、貢献したりすることに興味がある開発者の専門知識とフィードバックが不可欠です。

---

このゲームエンジンは、Rustベースのゲーム開発において精度と力を約束します。

[GitHub](https://github.com/ladroid/goku) | [ドキュメンテーション](https://lados-organization.gitbook.io/goku/v/goku-game-engine_jp/)
Next.jsでホワイトリスト形式のIP制限をかける

## 概要
Next.js（v13.4.12）の環境でMiddlewareを利用してIP制限をかける方法を共有します。

## サンプルコード
```TypeScript:/src/middleware.ts
import { NextRequest, NextResponse } from 'next/server'

// IPホワイトリスト
const IP_WHITELIST = ['xxx.xxx.xxx.xxx', 'yyy.yyy.yyy.yyy']; // IPアドレスをマスクしています。

export async function middleware(request: NextRequest) {
  const res = NextResponse.next();

  // IPアドレスを取得
  let ip: string = request.ip ?? request.headers.get('x-real-ip') ?? '';

  // プロキシ経由の場合、x-forwarded-forヘッダーからIPアドレスを取得
  if(!ip && forwardedFor){
    const forwardedFor = request.headers.get('x-forwarded-for');
    ip = forwardedFor.split(',').at(0) ?? 'Unknown';
  }

  // 取得したIPアドレスがホワイトリストに含まれているかチェックし、含まれていない場合はアクセス拒否
  if(!IP_WHITELIST.includes(ip)){
      return NextResponse.redirect('https://example.com/access-denied'); // アクセス拒否のページにリダイレクト
  }

  return res;
}
```

## 実装の背景
実装するアプリは想定している使用者が限定的でサービスとして利用者を伸ばすものではなかったため、簡単にセキュリティを堅牢にするためにホワイトリスト形式でIP制限をかけることになりました。

実際に実装を進めると、IPの取得にてこずりました。

## サンプルリポジトリ・サンプルアプリケーション
https://github.com/ryosuke-horie/middleware-ip-limit

Vercelへデプロイしました。
https://middleware-ip-limit-one.vercel.app/

ホワイトリストに指定したIPからアクセスするとNextjsのWelcomeページが表示できますが、それ以外のIPから遷移すれば、「Access Denied」と表示されるようになります。
Pod がコントローラでサポートされていないため、スケールダウンがブロックされています

リージョンクラスタの実験をしていて、以下のような表示がコンソールに出ています。

```
Pod がコントローラでサポートされていないため、スケールダウンがブロックされています
Pod に Deployment や Replicaset などのコントローラがないため、使用率の低いノードのスケールダウンがブロックされています。詳細については、ログをご覧ください。  
```

```
推奨される対応
Pod にアノテーション "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" を設定するか、Pod に Deployment や Replicaset などのコントローラを定義します  
```

```
resource.type="k8s_cluster"
resource.labels.location="asia-northeast1"
resource.labels.cluster_name="cluster-1"
logName="projects/<PROJECT-ID>/logs/container.googleapis.com%2Fcluster-autoscaler-visibility"
(jsonPayload.noDecisionStatus.noScaleDown.reason.messageId="no.scale.down.node.pod.not.backed.by.controller" OR jsonPayload.noDecisionStatus.noScaleDown.nodes.reason.messageId="no.scale.down.node.pod.not.backed.by.controller")
```

```
CA によるノードの削除を防ぐ Pod の種類はありますか？
https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node
```

Cloud Logging で確認すると、nginx11 というのが、asia-northeast1-a にあるノードにいて、そいつのことを言っているらしい。
kind: Pod で作成した nginx11 という pod を削除したら、ログが消えた。ただ、このお知らせは、しばらく出ているみたいだ。
せんせー、レーザー誘起ブレイクダウン分光法ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、レーザー誘起ブレイクダウン分光法ってなに？

# レーザー誘起ブレイクダウン分光法とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## レーザー誘起ブレイクダウン分光法って何？

みんな、レーザーって知ってますか。あの強い光のことです。
そして、物を調べるために色んな光を使うことがあるんです。
レーザー誘起ブレイクダウン分光法は、レーザーを使って物の中身を調べる特別な方法のことを言います。

## どういうこと？

この方法では、レーザーを物に当てると、物がちょっとだけ壊れて、きらきらと光ることがあるんです。
そのきらきらと光る色や形を見ることで、物が何からできているのかを知ることができるんです。

## どうしてそれがすごいの？

この方法を使うと、サンプル（調べたい物）を壊さずに、すぐにその場で中身を調べることができるんです。
だから、例えば、危険な物質が入っていないかを調べたり、古いものの成分を知ったりするのに役立ちます。

## だから、レーザー誘起ブレイクダウン分光法ってなに？

レーザー誘起ブレイクダウン分光法は、レーザーの光を使って、物の中身を調べるための特別な方法なんです。

# まとめ

このように、レーザー誘起ブレイクダウン分光法は、物の中身をすぐに調べるためのとても便利な技術なんです。
せんせー、クリスタル成長技術ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、クリスタル成長技術ってなに？

# クリスタル成長技術とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## クリスタル成長技術って何？

みんな、キラキラと輝く宝石や、塩や砂糖のようなかたちをした物を見たことありますか。
これらは「クリスタル」と呼ばれるもので、とてもきれいですよね。
クリスタル成長技術とは、これらのクリスタルをわざと大きく成長させる方法のことを言います。

## どういうこと？

クリスタルは、とてもきれいな形をしていて、それぞれの物質によって違う特別な形をしているんです。
クリスタル成長技術を使うと、私たちが欲しい大きさや形のクリスタルを作ることができます。

## どうしてそれがすごいの？

クリスタルは、ただきれいなだけじゃなくて、電気の道具や医薬品、宝石など、たくさんの用途で使われているんです。だから、上手にクリスタルを作る技術は、たくさんのものを作るのにとても大切なんです。

## だから、クリスタル成長技術ってなに？

クリスタル成長技術は、キラキラとしたきれいなクリスタルを、私たちが使いたいような形や大きさに成長させる技術のことなんです。

# まとめ

このように、クリスタル成長技術は、たくさんの物を作るために必要な、クリスタルを上手に作るための特別な技術なんです。
sedコマンドでの置換対象文字列にやたらと特殊文字が含まれている場合にめちゃめちゃハマったのでメモを残す

sedコマンドでの置換対象文字列にやたらと特殊文字が含まれている場合にめちゃめちゃハマったのでメモを残す。
注目すべきは以下３点。
1. sedコマンドの引数は特殊文字3種($`\\)以外をエスケープするダブルクォートを使用すること
2. 特殊文字3種($`\\)のエスケープにはバックスラッシュを使用すること
3. ダブルクォートで囲まれた文字列の内部でダブルクォートを使用する場合にはバックスラッシュでエスケープすること

```
#!/bin/bash

# note <RTF.list>
# s3://mybucket-01/cloudwatch/env01/RTF/`date -d '${target_date}' +"%Y%m"`/,_aws_RTF_errorlog_`date -d '${target_date}' +"%Y%m%d"`

listfile=/opt/usrshell/conf/RTF.list

while read line
do
    echo ${line}
    target_line=$(echo ${line} | sed "s/\`date -d '\${target_date}' +\"%Y%m\"\`/hogehoge/")
    echo ${target_line}
done < ${listfile}
```
せんせー、マイクロバイオーム解析ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、マイクロバイオーム解析ってなに？

# マイクロバイオーム解析とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## マイクロバイオーム解析って何？

みんな、私たちの体にはたくさんの小さな生き物たちが住んでいることを知ってますか。
これらの小さな生き物たちのことを「マイクロバイオーム」と言います。
そして、それらの生き物たちが私たちの体で何をしているのかを調べることを「マイクロバイオーム解析」と言います。

## どういうこと？

私たちのお腹の中や肌の上には、たくさんのバクテリア（細菌）やその他の微生物が住んでいるんです。
これらの生き物たちがどんなものなのか、どれくらいいるのか、どんな役割を持っているのかを調べるのが、マイクロバイオーム解析の仕事なんです。

## どうしてそれがすごいの？

これらの小さな生き物たちは、私たちの健康や体調にとても影響を与えているんです。
だから、これらの生き物たちをよく知ることで、もっと健康になったり、病気の原因を見つけたりする手助けになります。

## だから、マイクロバイオーム解析ってなに？

マイクロバイオーム解析は、私たちの体に住む小さな生き物たちを調べることで、私たちの健康をよくするための手がかりを見つける研究なんです。

# まとめ

このように、マイクロバイオーム解析は、私たちの体の中にいる小さな生き物たちの秘密を解明して、健康を守るための大切な研究なんです。
せんせー、スマートタトゥーってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、スマートタトゥーってなに？

# スマートタトゥーとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## スマートタトゥーって何？

みんな、タトゥーを知ってますか。
それは、体に絵や模様を描くことです。
でも、「スマートタトゥー」は、ただの絵じゃなくて、特別な技術が入っている絵なんです。

## どういうこと？

スマートタトゥーは、体に貼るだけで、体の状態や情報を教えてくれる特別なタトゥーです。
たとえば、体の温度や汗の量などを測って、それをスマートフォンに送ってくれることもあります。

## どうしてそれがすごいの？

このタトゥーを使うと、自分の体調がどうなっているのか簡単にわかるようになるんです。
そして、もし体調が悪くなってきたら、早く気づくことができるから、健康を守るのに役立つんです。

## だから、スマートタトゥーってなに？

スマートタトゥーは、体に貼る絵で、私たちの体の情報を測って教えてくれる特別なものなんです。

# まとめ

このように、スマートタトゥーは、ただの絵じゃなくて、私たちの健康を守るためのとても便利な技術が詰まったものなんです。
せんせー、シリコンカルバイドデバイスってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、シリコンカルバイドデバイスってなに？

# シリコンカルバイドデバイスとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## シリコンカルバイドデバイスって何？

みんな、電気を知ってますよね。
電気をうまく使うための道具や機械がたくさんあります。
シリコンカルバイドデバイスは、電気を使う道具の中で、特に熱に強いとか、電気を上手く流すことができる特別なものなんです。

## どういうこと？

シリコンカルバイドというのは、特別な材料の名前で、とても丈夫だし、熱にも強いんです。
普通の電気の道具と違って、この材料で作られたデバイスは、もっとたくさんの電気や高い温度でも壊れにくいんです。

## どうしてそれがすごいの？

たくさんの電気を流す必要がある場所や、とても暑い場所で電気の道具を使いたいとき、シリコンカルバイドデバイスはとても役立つんです。だから、色んな場所でこのデバイスが使われているんです。

## だから、シリコンカルバイドデバイスってなに？

シリコンカルバイドデバイスは、特別な材料でできた、電気をうまく扱える丈夫な道具のことなんです。

# まとめ

このように、シリコンカルバイドデバイスは、たくさんの電気や高い温度の中でも頼りになる、特別な電気の道具なんです。
【Karabiner】MacのOutlookでEmacsキーバインディング

:::note info
対象読者
- **Emacser**
    - (Vimのキーバインディングも同様の手続きでできるはず。ｼﾗﾝｹﾄﾞ)
- MacでOutlookを使っている人
- Karabinerを使っているけどOutlookに反映されなくて(´·ω·`)ｼｮﾎﾞｰﾝな人
:::
::: note alert
免責
- Web版/PWA版は本記事の対象外です
:::

# Emacs Key bindingsのインポート

::: note warn
注意
- 既にインポートしている人は必要なし
- 以下の手順で`Emacs Key bindings(rev xx)`のxxは最新版(現時点で13)を選択しておけば問題ないはず
:::

<details><summary>手順(クリックして表示)</summary>

`Karabiner-Elements Settings`
↓
`Complex Modifications`
↓
`Add rule`
↓
`Import more rules from the Internet (Open a web browser)`
↓
`Emacs key bindings(rev xx)`
↓
`Enable All`
</details>

# JSONファイルに追記

1\.
インポートした`Emacs key bindings`に対応する以下のJSONファイルを開く

`~/.config/karabiner/assets/complex_modifications/xxxxxxxxxx.json`
- `complex_modifications`ディレクトリにはインポートしたルールごとに複数のJSONファイルが存在する。その内、`Emacs key bindings`に対応するファイルを開く
- 個々のJSONファイルは`xxxxxxxxxx(10桁の数字).json`という名前で保存されているため、ファイル名だけで特定するのは難しいはず
- JSONファイルの冒頭部分に`"title": "Emacs key bindings(rev xx)",`という記述があるかどうかで判断できる

2\.
`bundle_identifiers`キーのペアであるリストの要素に以下を追記

`"^com\\.microsoft\\.Outlook$"`
- リストなので直前の要素の後ろに`,`を付けるのを忘れずに

```diff_json
"conditions": [
                {
                    "type": "frontmost_application_if",
                    "bundle_identifiers": [
                        "^com\\.microsoft\\.Excel$",
                        "^com\\.microsoft\\.Powerpoint$",
-                       "^com\\.microsoft\\.Word$"
+                       "^com\\.microsoft\\.Word$",
+                       "^com\\.microsoft\\.Outlook$"
                      ]
                  }
              ]
```

`bundle_identifiers`キーはこのJSONファイル内で設定されているキーバインドごとに存在するため、Outlookで有効にしたい任意のキーバインドに対して同様の操作を行う(基本的に`bundle_identifiers`キーが出てくるファイル内の全ての箇所に対して行えばよい)。



3\. 
ファイルを閉じる
↓
Karabinerを再起動

# チェック

Outlookを開く
↓
以下を試す
^ + a (行頭移動)
^ + e (行末移動)
^ + k (kill-line)
etc.
↓
🍺
せんせー、ビオミメティクスってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、プロトセルってなに？

# プロトセルとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ビオミメティクスって何？

みんな、自然や動物たちのすごい技を見たことあるかな？たとえば、くもの巣が雨にも風にも強いことや、鳥がどうやって空を飛んでいるのか、こんな自然の秘密を学び、それを人間の技術や商品に生かそうとする学問を「ビオミメティクス」と言うんです。

## どういうこと？

ビオミメティクスは、自然の中にあるアイディアや解決方法を学び、それを私たちの生活や技術に応用することです。
たとえば、飛行機のデザインは、鳥の飛び方からヒントを得ていることもあるんです。

## どうしてそれがすごいの？

自然は長い時間をかけて、最も効率的で素晴らしい方法を見つけてきたんです。
ビオミメティクスを使うことで、人間も自然の知恵を借りて、もっと良い製品や方法を作り出すことができるんです。

## だから、ビオミメティクスってなに？

ビオミメティクスは、自然のすごい技や知恵を学び取り、それを私たちの技術や商品に生かす学問なんです。

# まとめ

このように、ビオミメティクスは、自然の知恵を活用して、私たちの生活をより良くするためのとても興味深い学問なんです。
せんせー、ネットワークコンテナ技術ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、ネットワークコンテナ技術ってなに？

# ネットワークコンテナ技術 とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ネットワークコンテナ技術って何？

みんな、おもちゃの箱を知ってますか。
おもちゃを整理して、それぞれの箱に入れることができますよね。
ネットワークコンテナ技術も似たようなものです。
コンピュータの中で、プログラムやアプリをそれぞれの「箱」に入れて、きちんと動かす技術のことを指します。

## どういうこと？

コンピュータにはたくさんのプログラムやアプリがあり、それらを上手く動かすためには「場所」が必要です。
ネットワークコンテナは、それぞれのプログラムやアプリに独自の場所を与えて、他のものと干渉しないようにする役目があります。

## どうしてそれがすごいの？

これを使うと、たくさんのプログラムやアプリを安全に、そして同時に効率よく動かすことができます。
それは、おもちゃがそれぞれの箱に入っているのと同じで、取り出しやすく、整理されているからです。

## だから、ネットワークコンテナ技術ってなに？

ネットワークコンテナ技術は、コンピュータの中でプログラムやアプリを整理して、上手く動かすための特別な「箱」のことなんです。

# まとめ

このように、ネットワークコンテナ技術は、コンピュータの中でたくさんのプログラムやアプリを効率よく動かすための便利な技術なんです。
せんせー、タングステンジセレニド超伝導体ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、タングステンジセレニド超伝導体ってなに？

# タングステンジセレニド超伝導体とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## タングステンジセレニド超伝導体って何？

みんな、電気を知ってるよね？電気は、いろんなものを動かす力を持っています。
でも、普通の電線の中を電気が流れると、ちょっと熱くなることがあります。
でも、「超伝導体」という特別な物質は、電気を完全に無抵抗で流すことができるんです。
タングステンジセレニドは、その超伝導体の一つとして知られています。

## どういうこと？

タングステンジセレニドとは、特定の元素でできた物質で、電気をすごく効率よく流すことができる性質を持っているんです。これを使うと、電気がとてもスムーズに動くのを感じることができます。

## どうしてそれがすごいの？

電気がスムーズに動くと、機械や装置がもっと効率的に動くことができるんです。
そして、エネルギーの無駄が少なくなるから、環境にも優しいんです。

## だから、タングステンジセレニド超伝導体ってなに？

タングステンジセレニド超伝導体は、電気をすごくスムーズに流すことができる特別な物質のことなんです。

# まとめ

このように、タングステンジセレニド超伝導体は、電気を効率よく流すためのとてもすごい物質なんです。
HTML入門 ~head要素とメタデータ~

# head要素
head要素は文書のメタデータを表すものです。
子要素には様々なメタデータを記述します。

## content model
メタデータ（title要素は必須。他にlink要素、meta要素、script要素、style要素がある）

# 次回に続く。。
テスト
プログラミング初心者の医学生が残り少ない夏休みでGithubcopilotとchatGPTの力を借りてアプリ開発してみた Day10

# これまでの経過
* [Day1(2023/08/20)](https://qiita.com/Shigemaxxx/items/606e7e58fe83f98bb780)
* [Day2(2023/08/21)](https://qiita.com/Shigemaxxx/items/ab1f0aecc291bb77534d)
* [Day3(2023/08/22)](https://qiita.com/Shigemaxxx/items/39ab4b0876cb6849fcf3)
* [Day4(2023/08/23)](https://qiita.com/Shigemaxxx/items/2657a3efc2ca29c0389a)
* [Day5(2023/08/24)](https://qiita.com/Shigemaxxx/items/f3ee98a1fb5868131820)
* [Day6(2023/08/25)](https://qiita.com/Shigemaxxx/items/6373c01527989fabde61)
* [Day7(2023/08/26)](https://qiita.com/Shigemaxxx/items/b76801eefe64b89a08ac)
* [Day8(2023/08/28)](https://qiita.com/Shigemaxxx/items/1da5fde3d49fccff7c1e)
* [Day9(2023/08/29)](https://qiita.com/Shigemaxxx/items/da5b7fc3417f7bb2a425)

# Day10(2023/08/30)


新たにUdemyを購入しました↓． 
>[もう絶対に忘れないGit・GitHub【Git 100本ノック+300枚の図解+丁寧な解説で長期記憶に焼き付けろ！】](https://www.udemy.com/course/git100test/)

現在必要かどうかはわかりませんが，後々必要になってくると思うのでセールのうちに購入しました．
firebaseは以前購入していた↓に少し解説があるようなので今回は購入を見送りました．
>[Flutter & Dart - The Complete Guide [2023 Edition]](https://www.udemy.com/share/1013o43@gHGgQz4oYqCCcbsyAYt8qQGc-c3eDVyN3NMWxfZL7E1LG8fXM-cSGNFTy3rESA2i/)

今日はプログラミングに当てる時間がありませんでした.
おそらく,夏休み中に終わりません...
すみません.
【LINE Messaging API】"The property, '', in the request body is invalid"エラーの解決法

# 背景
PythonでLINE Messaging APIをたたくときにそこそこ詰まってしまいました。
エラー内容でググっても記事がヒットしなかったので、同じエラーで詰まっている人の役に立てればうれしいです


# エラーが起きたコード

``` python
import requests

url = " https://api.line.me/v2/bot/message/push"
header = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {チャネルアクセストークン}"
}
body = {
    "to": "Ub66965b7294ff3a70a2804b4560.....",
    "messages": [
        {
            "type":"text",
            "text":"Hello"
        }
    ]
}

res = requests.post(url=url, headers=header, data=body)
print(res.text)
```

# 実行結果

```
{"message":"The property, '', in the request body is invalid (line: 1, column: 1)"}
```

# 解決策
変数`body`を`dict`型から`str`型キャストするとメッセージを送信することができました！
`dict`から`str`への変換は`json.dumps()`を使います

```python
import requests
import json # jsonモジュールをインストール

url = " https://api.line.me/v2/bot/message/push"
header = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {チャネルアクセストークン}"
}
body = {
    "to": "Ub66965b7294ff3a70a2804b4560.....",
    "messages": [
        {
            "type":"text",
            "text":"Hello"
        }
    ]
}

#これ！
body = json.dumps(body) 

res = requests.post(url=url, headers=header, data=body)
print(res.text)
```

`header`は`dict`型のまま行けたことが罠でした、、
Cloudflare Workers x HonoでJWT認証を設定する


# はじめに :jack_o_lantern:

皆さん Hono はご存知でしょうか？:fire:

Cloudflare Workers 上で動作する軽量な Web フレームワークです。
Web Standard の API に準拠しているため、コードを読むだけでも学習になり、おすすめです。

今回は Hono を利用して CloudFlare Workers 上に OpenAI API のプロキシを作成しました。
JWT 認証を設定する際に、正しい方法が分からず、苦労したのでメモしておきます。

> 大変参考になった記事
> **[Hono と Cloudflare Workers で Azure OpenAI Service の proxy を作った話](https://zenn.dev/calldoctor_blog/articles/deb21728bbe99a)**

成果物はこちら => **[openai-proxy](https://github.com/TellMin/openai-proxy)**

## どう実現したか :zap:

### 1. 環境変数の取得

Hono のテンプレートからプロジェクトを作成した場合、デバッグ時に wrangler を利用していることが分かります。

```json
"dev": "wrangler dev src/index.ts"
```

環境変数を設定する場合、`wrangler.toml`に記載することも可能ですが、今回は`.dev.vars`に設定しました。

設定された環境変数は、次のように Bindings の型を定義することで、`Hono`の context 内で利用できるようになります。

> [Cloudflare Docs - Environmental variables](https://developers.cloudflare.com/workers/wrangler/configuration/#environmental-variables) > [Hono - Bindings](https://hono.dev/getting-started/cloudflare-workers#bindings)

```typescript
type Bindings = {
  OPENAI_API_KEY: string;
  SECRET: string;
};

const app = new Hono<{ Bindings: Bindings }>();
```

### 2. JWT 認証の設定 :old_key:

Hono では、`app.use`を利用した特定のルートにマッチするリクエストに対して、ミドルウェアを設定することができます。

```typescript
// https://hono.dev/middleware/builtin/jwt#usage より引用

const app = new Hono();

app.use(
  "/auth/*",
  jwt({
    secret: "it-is-very-secret",
  })
);

app.get("/auth/page", (c) => {
  return c.text("You are authorized");
});
```

このままでは secret を環境変数から取得することができないため、次のように実装する必要がありました。

```typescript
app.use(
  "*",
  async (
    c: Context<{
      Bindings: Bindings;
    }>,
    next: Next
  ) => jwt({ secret: c.env.SECRET })(c, next)
);
```

> [Hono - Using Variables in Middleware](https://hono.dev/getting-started/cloudflare-workers#using-variables-in-middleware)

typescript で実装したため、型定義を行う必要があります。
要領としてはカスタムミドルウェアを作成する場合と同様らしいです。

### プリフライトリクエストの許可 :small_airplane:

CORS を設定する場合、プリフライトリクエストを許可する必要があります。JWT 認証を行うためには Authorization ヘッダーが必要ですが、クライアントからリクエストを送信する場合、単純リクエストに該当しないため、プリフライトリクエストが送信されます。

> [CORS の理解を深める - Simple Requests(単純リクエスト)とは](<https://zenn.dev/riko/articles/cors_deepen_understanding#simple-requests(%E5%8D%98%E7%B4%94%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88)%E3%81%A8%E3%81%AF>)

そのため、Options メソッドが正しく処理されるように設定するとよいでしょう。

```typescript
app.options("*", (c) => {
  return new Response(null, {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "POST, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type, Authorization",
    },
  });
});
```

プリフライトリクエストはブラウザが自動的に送信する機能のため、サーバーサイドからのみ呼び出される場合は、この設定は不要です。
認識が誤っていたらご指摘よろしくお願いいたします。

## まとめ :sun_with_face:

JWT 認証の処理について、Hono/JWT の実装を読み込んだのですが、非常に参考になりました。

> [hono/src/middleware/jwt/index.ts](https://github.com/honojs/hono/blob/main/src/middleware/jwt/index.ts)

同様に、他のミドルウェアやコードについても Web Standard に準拠しているため、理解を深められるかと思います。

折角プロキシを作成したので、次は利用するクライアントアプリケーションについて記事を書きたいと思います。

Open AI API 周りの実装については触れませんでしたが、詳しくは Vercel の記事をご覧ください。

> [Docs - OpenAI](https://sdk.vercel.ai/docs/guides/providers/openai)

イカ、よろしくーーー！:octopus:
plotlyでローディング動作しない

スタイルが影響してる。
```python
external_stylesheets = [
    "https://cdn.jsdelivr.net/npm/modern-css-reset/dist/reset.min.css",
    "https://codepen.io/chriddyp/pen/bWLwgP.css",
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
```
はずす
```diff_python
-app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
+app = dash.Dash(__name__)
```
【Rails】Deviseでパスワードのバリデーションを追加する方法

Userモデルに以下の記述を追加することでバリデーションを追加できます。

```rb:user.rb
# ...

VALID_PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i
validates :password, format: { with: VALID_PASSWORD_REGEX, message: 'は半角英数を両方含む必要があります’}

# ...
```
Obsidian スペルチェック無効化 赤線を消す

Obsidianというメモアプリ?を使っていて、赤線が鬱陶しかったので消す方法

1: cmd + p でコマンドパレットを開きます
2: ```toggle spellcheck```とを検索、選択してEnter
3: 完了!!

コマンドパレット
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333049/872fabde-08df-3367-3632-7fe9ce24bb15.png" width=50%>

cmp + p じゃなくても、画面左にあるボタンからひらけます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333049/745f2114-018a-0295-a7cc-0d6a8c100b75.png">
URLからIPアドレスを調べる

# URLからIPアドレスを調べたい！
クラウドを使って開発をしていると、ちょくちょくこう思うことがあったので備忘録として残しておきます。

# nslookupコマンドを使うとできる
nslookupコマンドで調べたいFQDNを指定します
例として、下記のコマンドを実行すると[google.com](https://www.google.com/)のIPアドレスが返ってきます
```
> nslookup google.com

サーバー:  dns-a.bbtec.net
Address:  218.176.253.65

権限のない回答:
名前:    google.com
Address:  172.217.174.110
```

名前（ドメイン名）が`google.com`であり、IPアドレスが`172.217.174.110`であることがわかります。
実際にブラウザで`172.217.174.110`にアクセスするとGoogleのトップページが表示されます。

ちなみに上に書いてある`218.176.253.65`はDNSサーバーのIPアドレスの様です。


# 参考
- [コマンドプロンプト【nslookup】の使い方,見方,オプション～権限のない回答,unknown,逆引き,DNSサーバ指定方法,キャッシュについて～](https://milestone-of-se.nesuke.com/sv-basic/windows-basic/nslookup/)
Slim【入門の書】

### 【概要】
---
erb形式でコードを買いていた人は、slimについてなかなかとっつきにくいのではないしょうか？
今回は、Slimでコードを書くためのポイントを押さえて、Slimな生活を送りましょう〜！

### 【Slimとは】
---
・「Slim」は、HTMLを簡潔に書くためのテンプレートエンジンの一種であり、主にRubyプログラミング言語と組み合わせて使用ます。
・HTML文書をより短く、読みやすく、メンテナンスしやすい形式で表現で記述できます。

例を見て見ましょう。
```ruby
<div class="container">
  <h1>Hello, World!</h1>
  <p>This is a paragraph.</p>
</div>
```

```slim
.container
  h1 Hello, World!
  p This is a paragraph.
```

このように、通常の`erb`形式と比較して、効率的に記述できるのが、`slim`になります。

### 【Slimの導入1】
---
gemfileにこのように記述しましょう。
```ruby
gem 'slim-rails'
```

この状態で、`bundle install`でインストールできます。ここで、注目するのは、作成する形式です。
`もし今後作成するviewファイルがerb`形式から`slim`形式に置き換える場合は、下記のように`config`を設定してください。

```ruby
module App
  class Application < Rails::Application
    config.generators.template_engine = :slim #slimに変更
end
```

### 【Slimの導入2】
---
上記では、今後作成するviewをslimにする方法を紹介しました。
今度は、既存の`erb`を`slim`に変更してみましょう。

```ruby
gem 'html2slim' # erb->slimに変更するためのgem

erb2slim 変換するフォルダまたはファイル #erb残して変換
erb2slim 変換するフォルダまたはファイル -d #erb削除して変換
```
これで、形式を変更する準備はできました。また、一括で変更した場合などは、下記の記事を参考にしてください。

https://qiita.com/mocchicc/items/abab4cdfac7b542742a6

### 【Slimの記述の仕方】
---
ここから本題の説明になります。まずは、記述の特徴を抑えましょう。
|erbの書き方|slimの書き方|説明|
|:-:|:-:|:-:|
|`<p>要素1</p>`|p 要素1|p要素の書き方|
|`<div>要素2</div>`|div 要素2|div要素の書き方|
|<% if %>|- if|if文の書き方|
|<%= content %>|= content|値等の表示|
|id="qiita"|#qiita|idの書き方|
|class="notion"|.notion|classの書き方|
|`<div class=”slim楽しい”>`|div.slim楽しい|divとclassの書き方|
|`<div id="qiita" class="notion">コンテンツ</div>`|div#qiita.notion コンテンツ|mixパターン|

おおよそこの表をみてもらえればわかると思います。

これを参考にformのパターンを例に考えてみましょう。

### 【slimのサンプル】
---
erbのパターン
```ruby
<form action="/submit" method="post">
  <label for="username">ユーザ名:</label>
  <input type="text" id="username" name="username">
  <label for="password">パスワード:</label>
  <input type="password" id="password" name="password">
  <button type="submit">送信</button>
</form>
```
slimのパターン1
```slim
form action="/submit" method="post"
  label for="username" ユーザ名:
  input type="text" id="username" name="username"
  label for="password" パスワード:
  input type="password" id="password" name="password"
  button type="submit" 送信
```
slimのパターン2
```slim
form(action="/submit" method="post")
  label(for="username") ユーザ名:
  input(type="text" id="username" name="username")
  label(for="password") パスワード:
  input(type="password" id="password" name="password")
  button(type="submit") 送信
```

### 【引用元】
---
Slim入門をして書き方を練習をしました
https://qiita.com/pugiemonn/items/b64171952d958dc4d6be
[Rails4,Rails5] erbファイルをSlimに一括変換するGemとRubyワンライナー
https://qiita.com/mocchicc/items/abab4cdfac7b542742a6