OmniAICreator/Qiita-1.07M huggingface dataset:
Fiberとは（golang）

# Fiberとは

golangのフレームワークの一種です。
[公式ページ](https://github.com/gofiber/fiber) によると、

> Fiber is an Express inspired web framework built on top of Fasthttp, the fastest HTTP engine for Go.

FiberはFasthttp（Go言語で最速のHTTPエンジン）上に構築された、 ExpressにインスパイアされたWebフレームワークです。
（イメージとしては、golangの速さ＋ [Express](https://expressjs.com/) の使い易さを合わせたフレームワークといった感じでしょうか）

## Fiberを実際に使ってみる

実際にコードを見ていきます。

初めにインストールするためには、go getコマンドを実行します。

```
$ go get -u github.com/gofiber/fiber/v2
```

main.goに以下のように記述します。

```main.go
package main

import "github.com/gofiber/fiber/v2"

func main() {
  app := fiber.New()
  app.Get("/", func(c *fiber.Ctx) error {
    return c.SendString("Hello, World！)")
  })
  app.Listen(":3000")
}
```

以下のコマンドを実行して、ブラウザで http://localhost:3000 にアクセスすると、「Hello, World！」を返すようにしました。

```
$ go run main.go
```

## Expressとの比較

Expressを使用したことがある人は「おっ！」となったかもしれません。
「Express inspired web framework」と言っていたようにかなり類似していることがわかると思います。
続いて、同じ処理をExpressで記述すると、どのようになるのか見てみます。
（※Expressのインストール方法などは割愛しております。）

```app.js
const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(3000, () => {
  console.log('Example app listening at http://localhost:3000')
})
```

かなり似ていますね！！

## 速度に関して（[引用](https://docs.gofiber.io/extra/benchmarks)）

ベンチマークが実施されていたので、一部引用しました。

|フレームワーク|Fiber|Express|
|:---|:---|:---|
|レスポンス（データ更新） [回/秒]|11846|2066|
|平均待ち時間（データ更新） [ms]|42.8|390.44|
|レスポンス（単一クエリ） [回/秒]|368647|57880|
|平均待ち時間（単一クエリ） [ms]|0.7|4.4|
|レスポンス（複数クエリ） [回/秒]|19664|4302|
|平均待ち時間（複数クエリ） [ms]|25.7|117.2|

どの結果もFiberが優れていますね。

## Fiberの他の記述に関して

基本的には他の処理もExpress Likeで記述することができます。

```main.go
package main

import "github.com/gofiber/fiber/v2"

func main() {
  app := fiber.New()

  // 基本的なルーティング
  app.Get("/", func(c *fiber.Ctx) error {
    return c.SendString("Hello, World！)")
  })
  
  // 静的ファイルのルーティング
  app.Static("/static_file", "./public/index.html")

  // ミドルウェアとNextを使用する場合
  app.Use(func(c *fiber.Ctx) error {
    fmt.Println("middreware and next")
    return c.Next()
  })

  app.Listen(":3000")
}
```

## 最後に

今回この記事では、以下の2つをまとめました。

* Fiberとはどういったものなのか
* Expressとの比較

ざっと概要だけ触れる形になってしまったので、次回の記事では、Fiberの使用に関して掘り下げていければと思います。

## 参考

* https://docs.gofiber.io/extra/benchmarks
* https://github.com/gofiber/fiber
* https://expressjs.com/
* https://docs.gofiber.io/#basic-routing
【備忘録】Mission Planner をWindowsにインストールする

## はじめに
Ardupilotで機体の運用及び制御パラメータを調整するには「Ground Control Sation（GCS）」が必要となります。
GCSにはいくつか種類がありますが、ここではMission Planner のインストール方法を紹介します。

## 環境

|項目|詳細|
|-|-|
|PC（OS）|windows11|
|GCS|Misson Planner（1.3.77）|

※ MissionPlanner は Windowsであればインストール可能です

## 1.インストーラをダウンロードする
Mission Planner のインストーラファイルをダウロードする
⇒　[インストーラの場所](https://firmware.ardupilot.org/Tools/MissionPlanner/MissionPlanner-latest.msi)

## 2.インストールする

### 2-1.インストーラの起動
ダウンロードしたmsiファイルをクリックする
　⇒　NEXTをクリックして進める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/1478eb85-6108-6bb6-ca8e-049923d8cdc4.png)

### 2-2. ライセンスの同意
「I accept the・・・」にチェックを入れNEKTをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/66b1e600-cafe-1b66-8bf6-1e666234c1b5.png)

### 2-3.インストール先の指定
指定が無ければNEXTをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/639346b8-4b43-001f-2610-77125bcc9fd7.png)

### 2-4.インストールの開始
INATALLをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/c39cdf2f-1a78-fa3d-d872-e5673d671216.png)

このような警告が出た場合は「はい」を選択して進める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/30a430a9-723b-0d4a-c7be-326e993820ff.png)

### 2-5.USBデバイスのインストール
画面が表示されるので次へをクリックして進める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/3216d99c-f4ca-2529-9552-a8e71e6d3833.png)

### 2-6.インストール完了
完了画面が表示されたらFinishをクリックする
※すぐに使いたい場合は「Launch Mission Planner」にチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/ef423978-9eac-085f-984c-4b11531ec681.png)

## 参考
https://ardupilot.org/planner/docs/mission-planner-installation.html#install-mission-planner

https://ailerocket.com/mission-planner/

https://qiita.com/srs/items/c278c3d9f56b213ba202
paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript 部分数列

部分数列 (paizaランク C 相当)

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__before_after_step4

# 解答例(for,if)
forとifで解きます。答えはansとします。iが一つも存在しなかったら-1なので、初期値-1とします。
aの部分数列がbになっているか、aの先頭から順に調べます。
一番小さいiが見つかったら、そこで線形探索を終わります。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, m] = lines[0].split(" ").map(Number);
const a = lines[1].split(" ").map(Number);
const b = lines[2].split(" ").map(Number);

//bがaの部分数列か調べる
let ans = -1;// i がひとつも存在しない場合は -1

for (let i = 0; i <= n - m; i++) {
  let flag = true;//条件を満たすbが存在したらtrue
  for (let j = 0; j < m; j++) {
    if (a[i + j] !== b[j]) { //条件を満たさなかったら次へ
      flag = false;//満たさない
      break;//次へ
    }
  }
  //条件を満たしたらbreak、一番小さいiを求めるので
  if (flag) {
    ans = i + 1;//一番小さいi
    break;//一番小さいiが求まったので終わり 
  }
}
console.log(ans);
```
高速でファイルやディレクトリをコピーするにはPython? Linuxコマンド?

# 高速に大量のファイルをコピーしたい

shutilのコピー時間にストレスを感じたことありませんか？
機械学習の何万枚ものデータセットをコピーするのとか、Colabの継続可能時間に収まりません。

# Linuxコマンドが速い

結論から言うと、PythonよりLinuxコマンドでコピーしたほうがずっと速いです。

# 比較
jpg画像が５００枚入ったディレクトリをGoogleドライブからColabにコピーする速度を比較します。

### Python

```python
shutil.copytree('source','dest')
```

15秒

### Linuxコマンド

```shell
cp -R sorce dest
```

1.2秒

**１０倍以上速いです**

# ちなみにGoogleDriveとColabで数万枚のデータを扱うには
ColabからGoogleDriveをマウントして数万枚のファイルを一気に扱うと、いつまで経っても処理が終わりません。
これは、ドライブの仕様のようです。タイムアウトが発生します。
５０００枚程度にディレクトリに分割して処理すると、速いです。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
[Python] 16進数→10進数変換(intを使用)のエンディアン調査

## 目的
intを使用した16進数→10進数変換のエンディアン(バイトオーダを調査する)

## 確認方法
0x0110をinputに結果を確認する。

ビッグエンディアンの場合 → 0110 →　272
リアルエンディアンの場合 → 1001 →  4097

## プログラム
```Python
print(int('0110', 16))
```

## 結果
```
272
```

## 結論
ビッグエンディアン

## 補足
下記でlittleエンディアンで読み込めることを確認。
```python
print(int.from_bytes(b'\x01\x10', 'little'))
```

## 参考URL
https://wa3.i-3-i.info/diff112endiannes.html
GitHub上のCSSを<link>タグで召喚したい

GitHubのリポジトリ上にCSSファイルがあります。ローカルに落とせば良いのですが，横着してHTMLの<link>タグの呼び出し先をそのファイルにしたいです。その方がメンテに自動対応できるので（更新が止まっていそうなら落とすべきです）。

どうしましょう？
## CDNを使う
[GitCDN.link](https://gitcdn.link/)にアクセスします。

当該CSSファイルのrawリンクをGitCDNにぶん投げます。rawリンクの具体例は
```
https://raw.githubusercontent.com/USERNAME/REPOSITORY/main/DIRECTORIES/CSS_FILE.css
```
です。raw.githubusercontent.comがポイントです。

得られたURLをHTMLの<link>タグに入れます。

終わり。
## 小声
GitCDNがサ終したら詰みますね……。

あとQiita初投稿でした。備忘録なので短くても許してください。
paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript 連続する k 要素 2

連続する k 要素 2 (paizaランク C 相当)

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__before_after_step3

#　解答例
最も大きいiを答えるので、最大値が等しくても、ansを更新する。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, k] = lines[0].split(" ").map(Number);
const a = lines[1].split(" ").map(Number);

let ans = 0;
let max = -Infinity;
for (let i = 0; i <= n - k; i++) {
  let sum = 0;
  for (let j = i; j < i + k; j++) {
    sum += a[j];
  }
  if (sum >= max) { //最も大きいiなので >=
    max = sum;
    ans = i + 1;
  }
}
console.log(ans);
```
paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript 連続する k 要素 1

連続する k 要素 1 (paizaランク C 相当)

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__before_after_step2

# 解答例
k個の和なので、和の先頭は、aのn-kまで調べます。和については、iからi+k-1までを求めます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, k] = lines[0].split(" ").map(Number);
const a = lines[1].split(" ").map(Number);

let ans = 0;
let max = -Infinity;
for (let i = 0; i <= n - k; i++) { //n-kまで
  let sum = 0;
  for (let j = i; j < i + k; j++) { //和はiからi+k-1まで
    sum += a[j];
  }
  if (sum > max) {
    max = sum;
    ans = i + 1;
  }
}
console.log(ans);
```
paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript 連続する 3 要素

連続する 3 要素 (paizaランク C 相当)

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__before_after_step1

# 解答例(for,if)
forとifを使って解きます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const n = Number(lines[0]);
const a = lines[1].split(" ").map(Number);

let ans = 0;//最も小さいi
let max = -Infinity;//最大値
for (let i = 0; i <= n - 3; i++) {
  const sum = a[i] + a[i + 1] + a[i + 2];
  if (sum > max) { //もっとも小さい i を答えるので > 
    max = sum;
    ans = i + 1;
  }
}
console.log(ans);
```
【インフラ関連】WireSharkのはじめ方

# Wiresharkとは

ネットワークパケットをキャプチャして、分析するツール。無料で利用でき、色々なOSで利用可能。
- Linuxの場合、tcpdumpコマンドを用いてオプションで調整する必要があるが、Wiresharkはプロトコルやポート、インターフェース等の条件を組み合わせて利用可能。
- tcpdumpコマンドと比較して、GUIで操作でき、みやすい。

![スクリーンショット 2022-10-30 15.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/2cfbf819-f020-52be-8ff6-c73d4e83f5d8.png)

# ダウンロード方法

以下リンク先の、ダウンロードサイトから、自分のOSに合ったバイナリを選ぶ。ここでは、
自分は`windows installer(64-bit)`を選択している。
https://www.wireshark.org/download.html
![スクリーンショット 2022-10-30 15.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/37fb4243-56dd-ab62-8b78-cba93b20139c.png)

指示に従い、Nextを押していく。（画像はインストールしたものとは別のバージョンのもの。）
![スクリーンショット 2022-10-30 15.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/e95f1234-bef2-9fc7-1f3f-505def4bd47d.png)

全ての質問に答えた後は、再起動が要求される。
その後、アプリケーションにWiresharkが追加されているはずである。

# 使用方法

wiresharkを起動した後、今使っているネットワークをダブルクリックで選択する。
Lanケーブルを使ってネットに接続しているならイーサネット、Wifiを使用しているならWi-Fiになる。ダブルクリックすると、キャプチャが開始される。
![スクリーンショット 2022-10-30 15.26.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/12e8d5ca-0223-5e71-7538-770dfa0a219f.png)

フィルターの部分でDNSを検索してみる。
![スクリーンショット 2022-10-30 15.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/0043065c-847f-895a-e08d-d76bccf9ac07.png)

コマンドプロンプトを起動して、`nslookup yahoo.co.jp`を入力してみよう。
![スクリーンショット 2022-10-30 15.38.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/5f41f966-16a7-fc3e-33bd-299312845d0c.png)



そして、Wiresharkの画面をスクロールしてみると、yahoo.co.jpの文字を含むパケットを確認できる。つまり、DNSのパケットを取得できている。
![スクリーンショット 2022-10-30 15.36.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/7c0908dd-0534-23d9-ae75-f205aa2ec381.png)

また、HTTP通信の中身を解析したりする事もできる。ラムダ技術部さんの動画がコンパクトでわかりやすかったので、参考までに。

https://www.youtube.com/watch?v=FnhD7ljtPhY


# 参考サイト
https://www.wireshark.org/
https://knowledge.sakura.ad.jp/6286/
paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript 前後関係の基本

前後関係の基本 (paizaランク C 相当)

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__before_after_step0

# 解答例(for,if)
forとifを使って普通に解きます。`a[n-2]=a[n-1]`まで調べます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const n = Number(lines[0]);
const a = lines[1].split(" ").map(Number);

let ans = 0;
for (let i = 0; i < n - 1; i++) {
  if (a[i] === a[i + 1]) {
    ans += 1;
  }
}
console.log(ans);
```
# 解答例(ワンライナー)
reduceを使って一行で解いてみました。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

console.log(lines[1].split(" ").map(Number).reduce((acc, cur, index, arr) => 
cur === arr[index + 1] ? acc += 1 : acc, 0));
```
OCI の ネットワーク・ソース で コンソール に ログイン可能 な IP を制限する(Oracle Cloud Infrastructure)

表題の通り OCI の ネットワーク・ソース で コンソール に ログイン可能 な IP を制限してみますやで。
彡(ﾟ)(ﾟ)

# 1. 参考マニュアル

以下のOCIマニュアルを参考にしています。

https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingnetworksources.htm

https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingpasswordrules.htm#Managing_Authentication_Settings

# 2. ネットワーク・ソース の 作成

画面左上ハンバーガーメニュー → Identity & Security → Network Sources を選択します。

![NetworkSource001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/5cb202ce-d2d4-3c90-8cc9-84d452e4513e.png)

Create Network Sourceボタンをクリックして接続を許可する CIDR(or IP) を入力します。

![NetworkSource002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/a652e162-1111-a6bf-4b85-ee0e5a85cb12.png)

Createボタンをクリックしてネットワーク・ソースを作成します。

# 3. 認証設定の管理 の 変更

画面左上ハンバーガーメニュー → Identity & Security → Authentication Settings を選択します。
![NetworkSource003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/4c198fd9-dd4e-651a-3f81-71759f657737.png)

Edit Authentication Settingsボタンをクリックして認証設定を編集します。

![NetworkSource004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/4d24927d-ab28-8f37-ff4b-37b74a60cbc0.png)

2. で作成した ネットワーク・ソース を選択して Save Changesボタンをクリックします。

# 4. ログインの試行(許可されていないネットワークより)

許可されていないネットワークからのOCIログインを試してみます。
下記のようなエラーが発生してログインできません。

![NetworkSource005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/9d13c3c6-cbaf-dc5e-d039-f3c69dba7549.png)

# 5. ログインの試行(許可されたネットワークより)

許可されたネットワークからOCIにログインしてみます。

![NetworkSource006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/7ce3e161-e5af-bf53-b2e3-e8dd2ed34562.png)

正常にログインできます。

# 6. まとめ

すでに同様の記事は幾つもあるのですが、復習のためにワイ自身でもやってみました。
マニュアルにも記載があるのですが設定をしくじるとログイン不可になって何もできなくなります。

https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingpasswordrules.htm#Managing_Authentication_Settings

```text
 注意

ネットワーク・ソース制限を設定する前に、許可されたネットワークが使用できない場合に
テナンシへのアクセスを可能にするAPIキーが設定されていることを確認してください。
APIキーを設定せず、許可されたネットワークを使用できない場合は、Oracleサポートに
連絡するまですべてのユーザーがテナンシからロックアウトされます。
API署名キーの設定の詳細は、必要なキーとOCIDを参照してください。
```

管理ユーザーのAPIキー発行やサポートサイト(MOS)へのログイン確認など、
あらかじめ対策をしておいて下さいね彡(^)(^)
【試行錯誤】OpenAI Whisperを活用した日本語歌詞のforced-alignment リンクまとめ

# 概要
自分で書いた「【試行錯誤】OpenAI Whisperを活用した日本語歌詞のforced-alignment」記事のリンク一覧です。

[その１：下調べとワンパス](https://qiita.com/shimajiroxyz/items/c019cfd60ba2953eb463)

[その２：音源分離](https://qiita.com/shimajiroxyz/items/6d253a0a6c53ca65027e)

[その３：別ライブラリによる音声区間検出](https://qiita.com/shimajiroxyz/items/de213cd333e7bf846781)

[その４：stable-tsを試す](https://qiita.com/shimajiroxyz/items/fdbeeb563be5b08837b0)

[その５：正解データづくり](https://qiita.com/shimajiroxyz/items/e1a1ba595c77688606d7)

[その６：音声認識結果と正解歌詞の対応付け](https://qiita.com/shimajiroxyz/items/6b0ac09fa225e0b062d5)

[その７：最初から最後まで処理をつなげる](https://qiita.com/shimajiroxyz/items/9779a04a3acc2c809163)

## 番外編

- [torchaudioのforced_align用ハイレベルAPIを試す](https://qiita.com/shimajiroxyz/items/ccbef2f851b15252cfa6)
- [日本語版wav2vec2でforced-alignment](https://qiita.com/shimajiroxyz/items/90280465572bcd5e0a63)
OneDrive for BusinessでmdファイルをWikiっぽく使いたい

SharePointOnlineやOneDrive for BusinessではMarkdown記法で書いた拡張子mdのファイルをアップロードしブラウザで開くとHTMLで整形されたものが表示されます。
このmdファイルに書く他のmdファイルへのリンクをいかに簡潔に書くか、というのが今回の目的です。

結論としては、OneDrive for Businessであれば`?parent=.&id=`を固定部とし、その後にファイルパスを書く書き方になります。
SharePointOnlineではidにフルパスを指定しないと表示されませんでした。
```
* [index](?parent=.&id=Markdown/index.md)
* [page1](?parent=.&id=Markdown/folder1/page1.md)
* [page2](?parent=.&id=Markdown/folder1/page2.md)
* [page3](?parent=.&id=Markdown/folder1/folder2/page3.md)
```

以下のルールで書きます。
* クエリ文字列だけを書きます。
* parentは省略不可ですが値は何でもよいので「.」あたりを指定します。ファイルのパスがわかりやすいよう前側に書いたほうがよいです。parentを省略するとフォルダとみなされたような表示になります。
* カレントは常にドキュメントのトップなので、どの階層のmdファイルからでもidはトップからのパスで書きます。

上記の例は以下のフォルダ構成の場合の例です。
```
Markdown
│  index.md
│
└─folder1
    │  page1.md
    │  page2.md
    │
    └─folder2
            page3.md
```

## mdファイル内のリンクをクリックしても開かいない問題
mdファイル内のリンクは、どうやらmdを表示しているiframeでブロッキングしているようでクリックしても開きません。
なので、CtrlキーかShiftキーを押しながらクリックして、別タブ/別ウィンドウで開くようにします。

## 思い至った経緯
Markdownで書けるので、あとはリンクさえ簡潔に書ければと思い至ったわけです。
ただ、SharePointOnlineやOneDrive for Businessの各ファイルのリンクは絶対パスでとても長く、またmdファイル内で相互リンクすることを想定した実装になっていません。

いろいろ試行錯誤した結果、以下をクエリ文字列として書くのが最小セットと思われます。（2022年10月時点）
* 「id=＜ドキュメントのトップからのパス＞」でmdファイルを指定
* 「parent=<任意>」は必須
* その他のパラメタは不要
繰り返してみるfor.while（学んだこと）

for文while文で繰り返してみる
===
~~~java repeat.java
public class repeat{
    public static void main(String[]args){
        for(int i=1; i<=5; i++){
            System.out.println(i+"回繰り返している(for)");
        }
        int j=1;
        while(j<=5){
            System.out.println(j+"回繰り返している(while)");
               j++;
        }
    }
}
~~~
結果
===
1回繰り返している(for)
2回繰り返している(for)
3回繰り返している(for)
4回繰り返している(for)
5回繰り返している(for)
1回繰り返している(while)
2回繰り返している(while)
3回繰り返している(while)
4回繰り返している(while)
5回繰り返している(while)
固定幅の中に全幅の要素を入れて画面幅一杯に表示するCSS

# 最初に結論
内側の要素に下記のようなスタイルをかけると実現できます。
```css
  .inner {
    width: 100vw;
    margin-left: calc(calc(100% - 100vw) * 0.5);
  }
```

サンプルのCodePen。
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="eYKpoRg" data-user="kaitou1192" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kaitou1192/pen/eYKpoRg">
  Untitled</a> by Kaitou (<a href="https://codepen.io/kaitou1192">@kaitou1192</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# なんでこんな話をするのか？
HTML&CSSの最初の段階で、大枠のページ幅や画面幅を制御するためにwrapper要素を設定することがありますが、後々の改修で打ち出し画像エリアや、ナビゲーションの幅は、そのwrapper要素の幅より大きくしたいということを稀に良く依頼されます。

仮にそのはみ出る要素がwrapper要素の上や下であれば、wrapper要素の外に出してしまうという手もありますが、真ん中あたりに出てきてしまうと、wrapper要素を分割するわけにもいかず…… 途方に暮れることも。

JSで頑張ってやるという手もあるのですが、その場合はwindow resizeと組み合わせることになるため、もっさりした挙動になってしまいがちです。

そんなときに、CSSだけでさっとやる方法があると便利なわけです。

# ポイント
固定幅要素はpx、全幅の要素はvwのため、固定幅のものを下回った場合に挙動が怪しくなりがちのため `@media` で、固定幅の要素を下回らないようにしています。ここは `Math.max()` とかを使っても上手く作れそうな気もしますが、一旦メディアクエリーで対処しています。
【PHP】多次元連想配列

## はじめに
PHPの初学者向けに多次元連想配列の使い方などをまとめました。

## 連想配列
PHPには、基本となるデータ型として`スカラ型`があります。

スカラ型は主に4種類
|型　日本語|型　英語|説明|
|---|---|---|
文字列型| string　|'Hello'や'こんにちわ'などの文字列|
|整数型| integer |1、2、3などの整数|
|浮動小数点型|float|1.4や3.4などの小数|
|論理型|boolean|TrueかFalse|

このスカラ型だけでデータを表現しようとすると表現力が弱いので、そこで使われるのが複数のスカラ型を組み合わせた`複合データ型`です。
連想配列やクラスのオブジェクトなどがそれに該当します。

例として人間というデータを連想配列で表してみます。
```php
$human = [
 'name' => 'みうら',
 'birthday' => '5月12日',
 'height' => 180,
 'weight' => 65
];
```
連想配列は、キーを使って各データに名前をつけ、キーとバリューを対応付けたものを複数束ねたものになります。
　
先ほど作った連想配列からデータを取り出してましょう。

```php
$human = [
 'name' => 'みうら',
 'birthday' => '5月12日',
 'height' => 180,
 'weight' => 65
];

$key = 'name';

echo $human[$key];

//　出力結果
みうら
```

## 多次元連想配列
多次元連想配列は連想配列の中に連想配列を組み合わせたものです。

```php
$tweet = [
 'ユーザー' => [
  'ユーザー名' => 'みうら',
  '誕生日' => '5月12日',
  'フォロー中' => 200,
  'フォロワー' => 10
],
 '投稿日時' => 2022-10-10 23:59,
 'いいね' => 0,
 'リツイート数' => 0
];

echo $tweet['ユーザー']['ユーザー名'];

// 出力結果
みうら
```
多次元連想配列でデータにアクセスする時は、キーを2つ指定します。
echoで角括弧を2つ使うとわかりづらいんですが、間に「の」を入れて読むとコードが読みやすいです。

連想配列がどれだけ深くなったとしても、角括弧を3つ4つと増やすだけで簡単にデータにアクセスする事ができます。
XtraBackup 8.0インストール時にlibevがなかったのでremiからインストールした

# XtraBackup 8.0インストール時にlibevがなかったのでremiからインストールした
環境としてはRHEL 7.8（古い:fearful:）で実施しました。

## remiレポジトリのインストール

```
# sudo yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

## perconaレポジトリのインストールと有効化
https://docs.percona.com/percona-xtrabackup/8.0/installation/yum_repo.html
こちらを参考にしています。

```
# sudo yum install https://repo.percona.com/yum/ percona-release-latest.noarch.rpm
# sudo percona-release enable-only tools release
```

## percona xtrabackup のインストール

```
# sudo yum install percona-xtrabackup-80
```
Torus Walletの概要理解

## はじめに
仮想通貨・NFTを管理するウォレットに、Torus Walletというものがあることを最近知り、触ってみた。
※間違っている部分があるかもしれません。ご指摘いただけると幸いです

## Torus Walletとは
SNSアカウントを元に、「秘密鍵・公開鍵のキーペア」を生成してくれるウォレットである。
Torus WalletではSNSアカウントと「秘密鍵・公開鍵のキーペア」が紐づいているため、ユーザはSNSアカウントのパスワードを記憶しているだけで、「秘密鍵・公開鍵のキーペア」の管理ができる。
また、トークンを送信する際、送信先は「0xaabbcc.....」という形式のアドレスでなく、SNSのアカウント名で指定することができる。


## Torus Walletのすごいところ
Torus Walletは、「__ノンカストディアルウォレット__」かつ「__秘密鍵をユーザが管理しなくてよい__」という部分が、長所だと思う。

#### ノンカストディアルウォレットとは
秘密鍵を自分で管理するタイプのウォレットのことである。
逆に、秘密鍵を第三者が管理するタイプのウォレットを「カストディアルウォレット」という。
MetamaskやTorus Walletはノンカストディアルウォレットである。
仮想通貨交換所のウォレットは、カストディアルウォレットである。

カストディアルウォレットの場合、ユーザは秘密鍵を企業に管理してもらうことになる。
企業がユーザの秘密鍵を管理する場合、「暗号資産交換業」に当たるため、国への申請などが必要となる。

#### 秘密鍵をユーザが管理しなくてよいとは
Torus Walletは、ノンカストディアルウォレットであり、秘密鍵は企業に管理されない。
しかし、ユーザが秘密鍵を管理するわけでもない。

Torus Walleの秘密鍵は、分散鍵生成という仕組みにより生成される。
（分散鍵生成では、誰にも秘密鍵を知られずに鍵生成ができるらしい。）
生成された秘密鍵はSNSアカウントに紐づけられる。
ユーザはSNSアカウントの管理さえしていれば、秘密鍵を管理できるという仕組みである。

## OpenseaでTorus Walletに接続してみた
OpenseaはTorus Walletに対応している。
接続できるウォレットの一覧から「Torus」を選択すると、Torus Walletに接続できる。
![スクリーンショット 2022-10-31 215759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526265/9e8a3f98-2dd3-08c3-fd6f-418dd2dacb5e.png)

「Torus」を選択すると、SNSアカウントでログインするように促される。
![スクリーンショット 2022-10-31 215938.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526265/a48c07e4-efdd-5271-d238-3248ac8a202c.png)


今回はTwitterでログインする。
Twitterのユーザ名とパスワードを入力する。
![スクリーンショット 2022-10-31 220308.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526265/97eff09e-ec2f-374e-ad4e-e47af8b4b3df.png)

SNSアカウントでログインすると、Openseaへの接続が完了する。
Torus Walletのサービス登録する必要もなく、NFT取引に利用できるアカウントを取得することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526265/92160611-4a3a-cfc8-2194-20bfc162877a.png)


## まとめ
今まで、Metamaskしかウォレットを知らなかったので、Torus Walletはとても便利なウォレットと感じた。
会員登録なしで利用できる点、SNSのアカウント名指定でトークン送信できる点が、とても便利に感じました。
カスタムドメインについて

●カスタムドメイン
Azure ADのドメイン名（テナント名）は、ユーザーがAzure ADで認証される際に入力する視覚情報の一部。
Azureポータルにサインインする際には、「ユーザー名＠Azure ADドメイン名」を指定して認証する。
初期ドメイン名は「xxx.onmicrosoft.com」という形式。

必要に応じてカスタムドメイン名を追加できる。「xxx.com」や「xxx.co.jp」など。
カスタムドメイン名を設定しておくと、そのドメイン名でAzureADの認証を行える。つまり、「ユーザー名＠xxx.com」のような短い名前を使用して、ユーザーがAzureポータルにサインインできる。

※無制限にカスタムドメイン名を設定できるわけではない。
カスタムドメイン名を追加するには、組織がそのドメイン名を所持しており、それをインターネット上で確認できる状態でなければならない。（そのドメイン名の正規の持ち主であるか、という所有権が確認される）

●カスタムドメインの設定
AzureポータルのAzure Active Directoryのカスタムドメイン名のメニューから行う。規定のドメインを削除することはできない。
カスタムドメインの追加をクリックすると、入力する画面が出てくるので組織が所有するドメイン名を入力して、ドメインの追加をクリック。

※カスタムドメイン名を追加すると、追加したドメイン名がプライマリドメイン（ユーザー作成時の規定値）として使用される。別のドメイン名をプライマリドメインに設定したい場合は、そのドメイン名をクリックし、プライマリドメインの変更する。
Javaの例外処理

Javaの例外処理についてのアウトプットをします！
## 例外とは
コンパイルが成功しても、実行した際にエラーが発生することがある。実行時に発生したエラーのことを例外と呼ぶ。例外が発生することを、「例外がスローされる」と言う。
例外クラスとchecked例外とuncheked例外の2種類に分類される。
checked例外はDBなどJava実行環境以外が原因で発生し、uncheked例外は実行中のプログラムが原因で発生する。checked例外は例外処理が必須である。

## try-catch-finally
tryブロック、catchブロック、finallyブロックで構成される例外処理。
|try|catch|列3|
|:--|:--:|--:|
|例外が発生しそうな箇所をtryブロックで囲む|例外が発生した場合の処理を記述|例外の発生有無に関係なく実行する処理を記述|

```java
public class Main{
    public static void main(String[] args){
        String[] animal = {"猫","犬","兎"};
        for(int i = 0; i < 4; i++) {
            try{
                System.out.println(animal[i]);
            }catch(ArrayIndexOutOfBoundsException e){
                System.out.println("例外発生");
            }finally{
                System.out.println("必ず実行");
            }
        }
    }
}
```
実行結果
```
猫
必ず実行
犬
必ず実行
兎    
必ず実行
例外発生
必ず実行
```
上記のコードは配列には3つの要素が入っていて、for文で順番に配列の中身にアクセスしている。
しかし4回実行されるようになっているので4回目は「不正なインデックスを使って配列がアクセスされた」と言う例外が発生される。なのでcatchブロックの引数に(ArrayIndexOutOfBoundsException)と書いておけば、4回目の時に「不正なインデックスを使って配列がアクセスされた」という例外をcatchブロックで検知してcatchブロックの中の処理が実行される。finallyブロックは例外があってもなくても必ず実行される。

## throws
try-catch-finally以外にもthrowsキーワードによる例外処理ができる。例外が発生する可能性のあるメソッドを定義する時「**throws 発生する例外クラス名**」と指定しておく。そのメソッド内で指定された例外が発生した場合、例外オブジェクトがメソッドの呼び出し元に転送される。

#### throwsの利点
throwsを利用しない場合の例外処理を見ていく。
```java
class Test{
    void live（....){
        Animal animal = new Animal;
        animal.eat(...);
        animal.sleep(...);
    }
}

class Animal{
    void eat(...){
        try{
            ...
        }catch(ArrayIndexOutOfBoundsException e){
            ...
        }
    }
    void sleep(...){
        try{
            ...
        }catch(ArrayIndexOutOfBoundsException e){
            ...
        }
    }
}
```
この方法でも問題ないがメソッドを定義する度に例外処理を書くことになっている。
もし同じ内容の例外処理であった場合コードが重複してしまうことになる。
throwsを利用した場合
```java
class Test{
    void live（....){
        Animal animal = new Animal;
        try{
            animal.eat(...); //①
            animal.sleep(...);//②
        }catch(ArrayIndexOutOfBoundsException e){
            //例外発生時の処理
        }
    }
}

class Animal{
    void eat(...) throws ArrayIndexOutOfBoundsException{
        //不正なインデックスを使って配列がアクセスされた例外が発生した場合、①(メソッドの呼び出し元)に例外オブジェクトを転送する
    }
    void sleep(...) throws ArrayIndexOutOfBoundsException{
        //不正なインデックスを使って配列がアクセスされた例外が発生した場合、②(メソッドの呼び出し元)に例外をオブジェクト転送する
    }
}
```
メソッド名の後に「**throws ArrayIndexOutOfBoundsException**」て記述しているのでメソッド内でArrayIndexOutOfBoundsExceptionの例外が発生した場合はメソッドの呼び出し元に例外を転送する。そしてメソッドの呼び出し元をtryブロックで囲んでいあるので、その下のcatchブロックでArrayIndexOutOfBoundsExceptionの例外オブジェクトをcatchでき例外発生時の処理が実行できる。

以上、Javaの例外処理についてでした:grinning:
間違っている箇所や、便利な書き方があればご教授お願いいたします！
現場参画 ~立ちはだかるPLSQL~

#### 【この記事のテーマ】
・現場参画　雰囲気
・PLSQL

初投稿になります！
今月の初旬から新しい現場に参画しました。そこの会社は一棟本社ビルを構えワンフロアおしゃれなカフェスペースみたいになっている「ザ・今時のIT会社」という感じです。朝の出勤時間はフレックス制が敷かれている為定時の時刻に来る人はまちまち。私は外部からきているので基本的に定時出社定時退勤です。今まではこんな綺麗なところで働いたところがなかったので毎日とてもウキウキしながら通っています。

本題ですが**PLSQL**！です。みなさんは聞いたことありますか？？今までSQLは沢山扱ってきましたがPLSQLは初めて出会いました。一緒のタイミングで参画した方にも聞きましたがやはり初めて扱うそうでした。ネットを色々と探してみてもSQLに比べて文献が少ないようにみえました。


PLSQLを扱うメリット　SQLに対して何が違うのか
一つこれに限るという結論に至りました。
↓
**・複数のSQL文をまとめて実行できる！**

一文一文実行しなければいけないSQL文がまとめて実行できます。
PROCUDUREと呼ばれる中にINSERTやSELECT、UPDATEなど色々実装する事ができます。
まとめて実行できることにより効率の良い開発と保守性のあるアプリケーションができるということです。

。。。ただ！！それは良いのですがSQLと違う部分が少々出てきて戸惑っています。
例えば変数への代入です。普段であれば ‘**=**’で済む話ですがPLSQLになると ’**:=**’とコロンつけないといけないみたいです。ここが引っかかって数日コンパイルエラーに悩まされました。。
このようにSQLとは少し違う部分がありコンパイルエラーがよく出るのでひたすらソースを見直します。そのせいかSQLの力がここ１ヶ月で相当上がったように感じます。PLSQLと言っても中身はSQLですのでINNER JOIN やGROUP BY、 SUMなどの集約関数も当然のように出てきます。それをひたすら見直しているので自然とかなり力がついたと思っています。

今まで全く触ってこなかったPLSQLこれからも使う場面は少ないかもしれないがSQLの力は相当つく事がわかりモチベーションがかなり高いです。SQLの力がつけば大抵の現場で戦力になると思い今は必死にSQLの勉強をしています。自作のアプリケーションにもバンバンSQLで楽しい機能を実装していきたいと思います!!
大学掲示板アプリの開発

Railsで大学掲示板アプリのポートフォリオを作成しました。

![スクリーンショット 2022-10-31 17.24.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/7e729aee-62d9-79dc-65bd-a274625db5ed.png)

## 目的

背景や目的としては、自分が通っている大学の掲示板サイトがあれば、学生同士で講義や大学について情報共有ができ、便利だと感じたからです。

## 使用言語

・フロントエンド：Ruby on Rails, Ruby
・バックエンド：MySQL
・コンテナ:Docker
・デプロイ：Heroku

## 作った機能
### 記事投稿機能

![スクリーンショット 2022-10-31 17.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/50a59c61-e758-a6de-ce33-a012e949c3d9.png)
CRUD処理ができるようになってます。

### ユーザー登録機能
![スクリーンショット 2022-10-31 17.25.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/93b2e582-6093-90a1-cd02-fc65c1868dd0.png)

Railsの機能を使って、ログイン、登録機能を実装しています。
deviseは使用していないので、今後実装したいです。

### いいね機能
![スクリーンショット 2022-10-31 17.24.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/88152357-3fe0-71a9-1eaa-d8aa729e8b99.png)

投稿のいいねができます。

### プロフィール機能
![スクリーンショット 2022-10-31 17.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/ce2b496c-38c4-6560-f64f-96e7a0603a85.png)

プロフィールの変更などができます。

### 検索機能
![スクリーンショット 2022-10-31 17.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569989/5c542ac7-871d-9490-73e5-3c671f6cd642.png)

単語検索とタグ検索機能があり、検索することができる。

## 苦労した点
### usersテーブルとboardテーブルの関係性
例えば、掲示板の個別ページから表示されている投稿者プロフィールから、その人のプロフィールを飛ばそうとするとなぜかboardのidが入ってしまうという現象が起きて、それを解決するのに時間がかかりました。

## 今後実装したい機能

技術不足で実装できていない機能はかなりあります。

・管理者機能
・下書き機能
・タグの追加機能
【Rails】Twitterクローンを作ってみた〜ツイート機能編〜

## はじめに
[【Rails】Twitterクローンを作ってみた 〜ユーザー詳細ページの作成〜](https://qiita.com/bloom__fu/items/8cb6002c44d7eb998358)の続きです。こちらを前提に進めていきますので、まだご覧になっていない方はそちらからご覧ください！※こちらはdockerでの環境構築を省きます。
## サービス環境
- ruby 3.0.0
- Rails 6.0.4
- docker
- mysql 8.0.2
- Slim, SCSS

## ツイート機能作成
#### 条件
- 「つぶやく」ボタンクリックで新規ツイート作成ページに遷移
- テキストを入力し投稿することでトップページにツイートが表示される。
Tweetモデルの作成をし、UserモデルとTweetモデルを関連付けさせてください。Tweetは最大140文字までとします。また、Tweetモデルのテキスト部分のカラム名はtextとしてください。
#### 実装流れ(簡略)
① Userモデルに紐付けたTweetモデル作成(textカラムを持つ)
② db:migrate
③ userモデル編集(has_many :tweets, dependent: :destroy)
④ tweetモデル編集(バリデーションをかけてtextを最大140文字までとする)
⑤ tweetsコントローラ作成、編集
⑥ routes.rb追記
⑦ tweets/new.html.slim書く。cssも同様に。
⑧ tweets/index.html.slim書く。cssも同様に。
⑨ 上記tweets/index.html.slimをTOPページにしてしまう。(routes.rb編集、homeコントローラ削除等)
#### ツイートページ
![スクリーンショット 2022-10-30 21.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/a1e522a9-371a-4751-ffdb-a9a37419a191.png)


#### TOPページ(ツイート一覧)
![スクリーンショット 2022-10-30 21.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/8f98783e-6f45-c17e-e48f-6f95e56bb3e2.png)

## 解説
#### profiles_controller.rb
```ruby
class TweetsController < ApplicationController
  skip_before_action :authenticate_user!, only: [:index]

  def index
    @tweets = Tweet.all.order(created_at: "DESC")
  end

  def show
  end

  def new
    @tweet = Tweet.new
  end

  def create
    @tweet = current_user.tweets.build(tweet_params)
    if @tweet.save
      redirect_to root_path, notice: "ツイートを作成しました"
    else
      flash.now[:alert] = 'ツイートの投稿に失敗しました'
      render new_tweet_path
    end
  end

  private

  def tweet_params
    params.require(:tweet).permit(:text)
  end
end

```
本物のTwitter同様、ツイート順に表示されるようにしました。crateアクションでは現在ログインしているユーザーしかツイートできないようにcurrent_userメソッドを利用しました。さらにはツイートが成功した時と、失敗させた時を条件分岐させてアラート等が出るように工夫しました。
#### モデルの紐付け
models/user.rb
```ruby
has_many :tweets, dependent: :destroy
```
models/tweet.rb
```ruby
class Tweet < ApplicationRecord
  belongs_to :user

  validates :text, length: { maximum: 140 }, presence: true
end
```
ユーザーがたくさんのツイートを作成できるようなメカニズムです。presence: trueとすることで、ツイート内容が空だとツイートできない仕組みです。



## 実装を通して学んだこと
#### 1. モデルへの紐づけ
前回同様。モデルとのアソシエーションがどういう関係にあるのかということ。modelを作成するときにreferencesを使い、暗黙の了解で、モデルを関連付けした時にはコントローラ内でbuildを使うことを学びました。
#### 2. 重複したTOPページの一括化
重複したTOPページを一括化してルーティングを編集することにより、コードを集約できることを学びました。コードを書く量も減り、効率化できるなと感じました。
#### 3. flash
redirect_toを使う際にはflashは要らず、renderを使う際にはflashが必要だということを学びました。
#### 4. 改行を入れるということ
それぞれファイルの文末には改行を入れるということを学びました。なぜなら、行＋改行で初めて行になるそうです。業界知識としてこのことを学べてよかったです。私の使っているエディタはvscodeですが設定で保存時に文末改行を入れることができます！
## 感想
前回同様モデルの紐付けを行いました！紐付けに慣れきたなと感じました。重複したビューを一つだけにして、ルーティングを編集するというやり方は非常にためになりました。これからも使っていこうと思います。htmlでつまづいた部分は何もtextが入力されていない時にツイートを送信できないようにするということです。こちらは```required: 'required'```で解決できることを学びました。
次回は**コメント機能の作成**についてアウトプットしていこうと思います！読んでいただきありがとうございました。
## 参考記事
- https://railsguides.jp/action_controller_overview.html#flash
- https://bottoms-programming.com/archives/indent-tab-space-and-new-line.html#toc5
- https://magazine.techacademy.jp/magazine/28499
SEOについてまとめてみた

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# SEOとは
SEO(エスイーオー)とは、Search Engine Optimizationの略で、直訳すると __「検索エンジン最適化」__ という意味です。ブラウザアプリで検索した時に、`検索結果の上位や目立つ場所に表示させるための施策`のことを指します。

# SEOの仕組み
検索順位は、__クロール__(検索エンジンの巡回）× __インデックス__（データベースへの保存）× __アルゴリズム__ による評価という3つの組み合わせで決まります。
- クロール
クローラーという検索エンジンのロボットが、リンクを辿って世界中のページを巡回し、ページ情報を取得します。
- インデックス
クロールによって検出したページにアクセスし、各ページの内容を分析した得られた結果をデータベースに保存します。
- 検索アルゴリズム
数百あるアルゴリズムでサイトを評価し、順位を決定、検索結果に表示させます。

例えばGoogleでは、Webページの内容をGooglebotなどのクローラーが読み取り、その読み取った内容をGoogle検索エンジンのインデックスに登録（巨大なデータベースに格納）します。
そのデータベースに格納されてる膨大な情報内容と検索アルゴリズムを照合して評価し、最も関連性の高い有用な回答（Webページ）を検索結果に表示（ランク付け）します。

# SEO対策
### ■E-A-Tを理解する
E-A-Tとは、Googleが良質なWebサイトを見極めるための基準を定めたもので、次の3つの言葉の頭文字です。
- Expertise(専門性)
- Authoritativeness(権威性)
- Trustworthiness(信頼性)

これらに関しては、具体的なスコアやランキングアルゴリズムがあるわけではありませんが、EATを理解し、EATの評価レベルの向上を意識してページを作成することは、SEOにとって非常に重要です。

### ■HTMLの最適化
WebページはHTMLという言語で構築されており、このHTMLを最適化することがSEOにとって非常に有効です。
例えば以下のようなことに注意して、コーディングすると良いでしょう。
- タイトルを設定する
検索ワードとして想定している __ターゲットキーワード__ を決め、タイトルにターゲットキーワードを入れたり、競合上位サイトのタイトルに含まれているようなタイトルを入れます。
- 画像タグのalt属性にもキーワードを入れる
クローラーは人間のように画像を見て、それの内容を判断することができません。そこでalt属性にその画像の説明文を挿入することで、__クローラーがその画像の内容を理解する手助け__ となります。
- 箇条書きを有効的に使う
私も記事を書くときに箇条書きをよく使用しますが、箇条書きは人間が理解し易いというユーザー側のメリットだけでなく、__スペニットにも表示されやすい__ というSEO的なメリットもあります。
※スペニットとは、検索結果ページで断片的に表示される各Webページの説明文です。


# 終わりに
私自身SEOという言葉を知ったのは最近のことで、私の両親が経営している酒屋が通販サイトを立ち上げたことがきっかけでした。何か力になりたいと思い調べたのですが、想像以上に奥が深く素人が簡単に口出しできるようなものではありませんでしたが、何を基準にWebサイトの上位に表示されるページが決まっているのかを知ったことは、非常に意味があったと思っています。


最後までお付き合いくださりありがとうございました。
curlでPOSTする時にクエリストリングをURLエンコードする

# 課題

curlには送信するデータをURLエンコードするための `--data-urlencode` オプションがあるが、これはPOSTリクエストにおいてリクエストボディにデータを追加するためのものである。
そのため、当たり前ではあるが、このオプションを付けてPOSTリクエストを送ってもクエリストリングではなくリクエストボディにURLエンコードしたデータが追加される。

```bash
$ curl localhost:50021 --data-urlencode text=こんにちは -v 
*   Trying 127.0.0.1:50021...
* Connected to localhost (127.0.0.1) port 50021 (#0)
> POST / HTTP/1.1
> Host: localhost:50021
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 50
> Content-Type: application/x-www-form-urlencoded
```

POSTリクエストを送る際にクエリストリングにURLエンコードした文字列を追加したい場合にはどうすれば良いのだろうか？

# 解決策

curlの`--get` オプションを追加することで、POSTリクエストにおいてクエリストリングにURLエンコードした文字列を追加することができる。


```bash
-G, --get
              When used, this option will make all data specified with -d, --data, --data-binary or --data-urlencode to be used in an HTTP GET request
              instead of the POST request that otherwise would be used. The data will be appended to the URL with a '?' separator.
```


```bash
$ curl localhost:50021 --get --data-urlencode text=こんにちは -v
*   Trying 127.0.0.1:50021...
* Connected to localhost (127.0.0.1) port 50021 (#0)
> GET /?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF HTTP/1.1
> Host: localhost:50021
> User-Agent: curl/7.79.1
> Accept: */*
```
【超シンプル版】Rails アプリを Cloud Run で動かしてみよう

## はじめに

Rails アプリを実行するためのサーバー環境はたくさんあると思いますが、今回は手軽に始められる Cloud Run を利用して Rails アプリを動かしてみようと思います。
今回は Cloud Run に触れることを目的に超シンプル版で構築していきます。

## Cloud Run とは

> フルマネージドのサーバーレス プラットフォームでお好きな言語を使用して、スケーラブルなコンテナ型アプリを構築してデプロイできます。

https://cloud.google.com/run

Google Cloud が提供するプロダクトの１つです。
プログラミング言語の縛りはなく、リクエストが来たときにインスタンスが起動してレスポンスを返すサーバーレスタイプのプロダクトです。

利用している時間だけ課金されるタイプです。無料枠もありますので、個人で試したい時には良さそうですね。

## 前提

- Ruby 3.1.2
- Rails 7.0.4
- Google Cloud アカウント作成済み
  - https://cloud.google.com
- gcloud コマンドが使える
  - https://cloud.google.com/sdk/docs/install


## 利用するプロダクト

- Cloud Run
- Cloud Build
- Container Registry

## 構築の流れ

1. Rails アプリ作成
1. Cloud Build でイメージ作成
1. Cloud Run にデプロイ

### Rails アプリ作成

scaffoldでシンプルなCRUDページを作成します。
```shell
# Rails アプリ作成. この後は sample-app 配下で作業します
$ rails new sample-app
$ cd sample-app

# scaffold でページ作成
$ bin/rails g scaffold Post title:string content:text
$ bin/rails db:migrate

# http://localhost:3000/posts で動作確認します。
$ bin/rails s
```

### Cloud Build でイメージ作成

イメージ作成の設定ファイル Dockerfile を作成します。
```shell
$ touch Dockerfile
```

```Dockerfile:Dockerfile
FROM ruby:3.1.2
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
RUN bundle exec rails db:migrate
# Cloud Run はデフォルトポート8080で起動
EXPOSE 8080
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "8080"]
```

Cloud Build の設定ファイル cloudbuild.yaml を作成します。
```shell
$ touch cloudbuild.yaml
```

```yaml:cloudbuild.yaml
steps:
  # Cloud Build でビルド
  - id: "build image"
    name: "gcr.io/cloud-builders/docker"
    entrypoint: 'bash'
    args: ["-c", "docker build -t gcr.io/${PROJECT_ID}/${_SERVICE_NAME} . "]
  # Container Registry にアップロード
  - id: "push image"
    name: "gcr.io/cloud-builders/docker"
    args: ["push", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"]
substitutions:
  _SERVICE_NAME: sample-app-service
images:
  - "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"
```

Cloud Build でビルドして、Container Registry にアップロードします。
Cloud Build API の権限がない場合は、許可するか聞かれることがあります。
```shell
$ gcloud builds submit .
```

### Cloud Run にデプロイ

Cloud Run にデプロイします。
こちらもAPI権限がない場合は、許可するか聞かれることがあります。
```shell
# --image は Container Registry にアップロードしたものを設定
# --allow-unauthenticated で誰でもアクセスできるようにする
$ gcloud run deploy sample-app-service \
   --image gcr.io/cloud-run-build/sample-app-service \
   --region asia-northeast1 \
   --allow-unauthenticated

...

Service URL: https://sample-app-service-[xxx]-an.a.run.app
```

Service URL が表示される為、`/posts/new`にアクセスして登録処理ができれば完了です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322836/e4173ce9-9f48-3f3b-c87e-47eae1a01fd5.png)

## まとめ

今回は超シンプルに Cloud Run でアプリを動かしました。
実際のサービスを運用するにはデータベースに Cloud SQL を使ったり、環境変数を Secret Manager で管理するなど、他のプロダクトの連携が必要になります。
実運用に近い形も検証して、また記事にしていきたいと思います！

## Reference

https://cloud.google.com/build/docs

https://cloud.google.com/run/docs
AtCoderで入緑しました

# ３年かけて目標の緑コーダーになりました。
コンテスト参加回数、97回目で入緑しました。
![スクリーンショット 2022-10-31 19.37.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/14a7a1b6-d542-49b2-75e4-e1998a05e28d.png)

## 精進したAC数
- AtCoder 910AC
- アルゴ式 199AC
- AOJ - オンライン プログラミング チャレンジ 119AC
- 合計1228AC

個人差はありますが、精進をしてAC数を増やす毎にレートも増加していきます。
精進をする事でしかレートは増えないです。

## Difficulty Pies
![スクリーンショット 2022-10-31 19.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/d0276864-04bc-161d-0909-de76756b59f0.png)

自身と同じ色の問題、または１色上の問題を解きましょう。
茶コーダーからは、茶色diff以上の問題を解くとレートが上昇しました。

## これからの精進
緑diffの問題になると解説ACができない問題が多くなりました。
しばらくは数学の勉強に時間を使おうと思います。

## 才能の限界を感じた
AtCoderのレートは数学力と関連していると感じました。
数学力でレートの限界値が決まっています。
レート/数学力, 820/1136という感じです。
精進することでレートを増やせますが、
数学の勉強をしていないとレートの増加が止まるタイミングがきます。

## 買って良かった参考書
- [問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%80%8C%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%C3%97%E6%95%B0%E5%AD%A6%E3%80%8D%E3%81%8C%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F%E6%9C%AC-%E7%B1%B3%E7%94%B0-%E5%84%AA%E5%B3%BB/dp/4297125218/ref=sr_1_1?adgrpid=52139121726&gclid=CjwKCAjw5P2aBhAlEiwAAdY7dDHD6jcvepm0NlQizBh9SVa5xgfiDDVr7k8w2TkO4yxjaBnixIY8GBoC-48QAvD_BwE&hvadid=611399643083&hvdev=c&hvlocphy=1009466&hvnetw=g&hvqmt=e&hvrand=18417354316911051166&hvtargid=kwd-299147546391&hydadcr=16039_13594018&jp-ad-ap=0&keywords=%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0+%E6%95%B0%E5%AD%A6&qid=1667213968&qu=eyJxc2MiOiIxLjU3IiwicXNhIjoiMC45MiIsInFzcCI6IjAuOTYifQ%3D%3D&sr=8-1)
- [競技プログラミングの鉄則](https://www.amazon.co.jp/%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E9%89%84%E5%89%87-%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%8A%9B%E3%81%A8%E6%80%9D%E8%80%83%E5%8A%9B%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B77%E3%81%AE%E6%8A%80%E8%A1%93-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E7%B1%B3%E7%94%B0/dp/483997750X/ref=sr_1_1?crid=2N3R3BSERP2QM&keywords=%E9%89%84%E5%89%87%E6%9C%AC&qid=1667213999&qu=eyJxc2MiOiIwLjgxIiwicXNhIjoiMC45NSIsInFzcCI6IjAuOTQifQ%3D%3D&sprefix=%E9%89%84%E5%89%87%2Caps%2C226&sr=8-1)
- [PAST本](https://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%AE%9F%E6%8A%80%E6%A4%9C%E5%AE%9A-%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%EF%BC%BB%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%BC%EF%BD%9E%E4%B8%AD%E7%B4%9A%E7%B7%A8%EF%BC%BD-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%B2%A9%E4%B8%8B-%E7%9C%9F%E4%B9%9F-ebook/dp/B08QRNJ7M3/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=716SP7EJVOZG&keywords=PAST%E6%9C%AC&qid=1667214110&qu=eyJxc2MiOiIwLjAwIiwicXNhIjoiMC4wMCIsInFzcCI6IjAuMDAifQ%3D%3D&sprefix=past%E6%9C%AC%2Caps%2C195&sr=8-1)
- 高校数学の白チャート(全種類買いました)

本は積み本せずに読みましょう。
本は買うだけだとレートは上がらないです。

## まとめ
AtCoderはオンラインゲームとして最高のゲームです。
また、業務にも役立つのでエンジニアの趣味として素晴らしいです。

目標を達成したのでしばらくは大学の講義、勉強を優先します。
これからのコンテストはunrated参加にします。
【Turbopack】Webpackの正統後継、Turbopackが登場

2022/10/26、VercelはWebpackの正統後継を詠ったバンドルツール、[Turbopackを発表しました](https://twitter.com/vercel/status/1584961746418208774)。

以下はVercelのブログから、[Introducing Turbopack: Rust-based successor to Webpack](https://vercel.com/blog/turbopack)の紹介です。

# Introducing Turbopack: Rust-based successor to Webpack

Vercelの使命は、イノベーターが閃きを形作るのに必要なスピードと信頼性を提供することです。
昨年は、我々は`Next.js`がアプリをバンドルするスピードを向上することに注力しました。

JavaScriptベースからRustベースのツールに移行するたびに、如実に効果が現れました。
Babelからの移行では、トランスパイルの速度が**17倍**になりました。
Terserの移行においては、minifyが**6倍**になり、さらに読み込み時間の短縮と帯域の使用量まで削減できました。

残りの山はひとつ、Webpackです。
Webpackはこれまで30億回以上もダウンロードされており、もはやWeb構築には欠かせないツールとなっています。
しかし、もっと早く、もっとスケール可能なツールが必要なときがやってきました。

本日、我々はWebpackの正統後継、[Turbopack](https://turbo.build/)を発表します。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/d2230565-0d37-7196-74ee-8ab5805746f2.png)

Turbopackは、Webpackの生みの親であるTobias Koppersその人が率いる、次世代のWebバンドルソフトウェアです。
Turbopackはオープンソースであり、そして今後はあらゆるフレームワークに対応していきます。

Next.js 13では、[next dev --turbo](https://turbo.build/pack/docs)コマンドでTurbopackのアルファ版を試すことができます。


## How fast is Turbopack?


最速の開発環境を実現するために、Turbopackは新しいインクリメンタルアーキテクチャで構築されています。

大規模なアプリケーションではViteの10倍、そしてWebpackの700倍の速度で動作します。
さらに大きなアプリケーションでは差がさらに広がり、実にViteの20倍の速度までなることもあります。

Turbopackは、必要最小限のアセットのみをバンドルするため、起動時間が非常に速いこともポイントです。
3000モジュールを含む場合、Viteでは11.4秒かかるアプリがTurbopackではわずか1.8秒で起動します。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/b30fcc3a-7953-92aa-8287-0cd005890b09.png)

さらに詳しく知りたいときは[ドキュメント](https://turbo.build/pack/docs/core-concepts)を参照し、ベンチマークを試してみてください。

## Why is Turbopack so fast?

Turbopackのアーキテクチャは、[Turborepo](https://turborepo.org/)およびGoogle Bazelなどから教訓を得ています。
すなわち、同じことを2回行わない、キャッシュを使う、です。

TurbopackはTurboをベースに作られています。

TurboはオープンソースのRust製インクリメンタルメモ化プログラムです。
Turboでは、プログラム中のあらゆる関数をキャッシュすることができます。
プログラムが再度実行されたとき、入力が変更されないかぎり関数を再実行しません。
このアーキテクチャにより、関数レベルで多くの処理をスキップることが可能になりました。

より詳細は、[Turboのドキュメント](https://turbo.build/pack/docs/core-concepts)をご覧ください。


## The future of Turbo

まず、[Next.js 13](https://beta.nextjs.org/docs)の開発サーバにはTurbopackが適用されます。
超高速のHMRを実現し、またReact Server Components・TypeScript・JSX・CSS等をネイティブにサポートします。

最終的には、ローカルとクラウドの両方でNext.jsのプロダクションビルドをサポートします。
さらに[Vercel Remote Caching](https://vercel.com/docs/concepts/monorepos/remote-caching)を用いて、チーム全体でTurboキャッシュを共有できるようにする予定です。

現在のWebpackユーザには、Rustベースへの段階的な移行パスを提供します。

ユーザがより早く開発サイクルを回し、なにかを閃いた瞬間に実装できる環境をサポートします。
我々は、Turboエコシステムのもたらす未来に、これ以上ないほど期待しています。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/b6b692b9-f89c-30df-1d08-9e21e9cd1c5b.png)


[Turbopackのアルファ版](https://turbo.build/)をぜひ体験してください。


# 感想

700倍ってなんだよ異次元すぎだろ。

そんなわけで`Next.js`は、今後全面的にTurbopackに移行していくようです。
ビルドが高速化することにより、これまでよりも仕事が楽になりますね。

しかしそもそも、毎回ビルドするという手間そのものをどうにかするようなパラダイムシフトは起こらないものだろうか。
[Flutter]TextFormFieldをタップした時に全選択する方法

TextFormFieldの中のOnTapで下記の処理を追加すればOKです。

イメージはこちら。

<img width="400" alt="スクリーンショット 2022-10-31 19.49.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/106ab241-562d-e5c8-9a12-2f1690de9ae8.png">

ソースはこちら。（コピペでOKです）

    TextEditingController textEditingController = TextEditingController();

    TextFormField(

      onTap: () {

        textEditingController.selection = TextSelection(
            baseOffset: 0,
            extentOffset: textEditingController.text.length
        );

      },
      controller: textEditingController,
    ),


全選択するための情報が当時あまりなくて仕方なくタップしたら値をクリアするみたいな感じで進めてたんですが、相談したらパパパッと修正してもらえたので自信の忘備録も兼ねて投稿です。

どなたかの参考になれば幸いです。
Container - Replace Docker with Podman in MacOS

```console

johnnychu@ ~ % brew install podman-desktop
johnnychu@ ~ % podman machine init --cpus=2 --disk-size=60 --memory=4096 -v $HOME:$HOME
johnnychu@ ~ % podman machine stop
johnnychu@ ~ % podman machine set --rootful
johnnychu@ ~ % podman machine start

Starting machine "podman-machine-default"
Waiting for VM ...
Mounting volume... /Users/johnnychu:/Users/johnnychu
API forwarding listening on: /var/run/docker.sock
Docker API clients default to this address. You do not need to set DOCKER_HOST.

Machine "podman-machine-default" started successfully

johnnychu@ ~ % sudo /opt/homebrew/Cellar/podman/4.3.1/bin/podman-mac-helper install

```

# Reference
* https://medium.com/@butkovic/favoring-podman-over-docker-desktop-33368e031ba0
* https://dic.vbird.tw/network_project/zunit12.php
* https://hackmd.io/@katydu/HkxtoWItGj
【React】同じpropsから複数のローカル変数を取り出す時は、分割代入が便利な件

# はじめに

タイトル通りなのですが、同じpropsから複数のローカル変数を取り出す時は、
[分割代入](https://typescript-jp.gitbook.io/deep-dive/future-javascript/destructuring)が非常に便利です。

# 分割代入

このようなコードがあるとします。

```typescript
export const CompanyPanel = memo((props: Props) => {
  const id = props.company.id;
  const name = props.company.name;
  const deleted = props.company.deleted;
```

分割代入を使うと…

```typescript
export const CompanyPanel = memo((props: Props) => {
  const { id, name, deleted } = props.company;
```

このように省略してスッキリと書くことができるので便利です。

# 参考

https://typescript-jp.gitbook.io/deep-dive/future-javascript/destructuring
【CONEXIOBlackBearでこんなことをやってみた】サーバーPUSHを試してみた！

# サーバーPUSHとは？
![Qiita_図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2637100/cde8c7ad-2af7-1a0c-0ae3-4ea5df2f7da4.png)
**IoTの第一ステップは可視化**と言われています。可視化の例として、現場に設置したセンサーのデータをIoTゲートウェイ経由でクラウドに送信し、状態監視をするパターンがありますね。<strong>「状態監視で異常を検出した場合に即座に現場に知らせたい！」</strong>といった時、サーバーPUSHの技術を使うと、そのようなことも簡単にできるようになります。

<strong>サーバーPUSHは、インターネット上のサーバーから端末(ゲートウェイ含む)に通知を送るための技術です。</strong>HTTPを使う方式としては、ポーリング、ロングポーリング、Server-Sent Events (SSE)、WebSocketなどがあります。**今回はWebSocketを使ってみました。**

# システム構成

![Qiita図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2637100/02a35170-1862-6d7e-02a3-1429c3f6d7c9.png)
今回の例は**サーバーから[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)が通知を受けるとパトライトを点灯させる**というシステムです。通知を出すケースとしては、以下の二つを想定しました。

・通知1 : 監視しているデータが**しきい値を超過した場合に通知**
・通知2 : サーバーの監視画面から**ユーザーが手動(Web画面上の操作)で通知**

通知1および通知2を試すために用意したシステムが上図に示したものです。
センサーから取得したCO2濃度を[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)経由でクラウドに通知します。

クラウドでは送られてきたデータをグラフ表示し、しきい値超過を検出したら[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)に通知を出します(通知1)*。またグラフ表示画面には手動で通知を出せるスイッチを用意しました(通知2)。

サーバーから通知を受けた[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)は、**パトライトの点灯指示**を出すようにしています。通知1が赤のパトライト、通知2が橙のパトライトです。 

# 実装
![Qiita_図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2637100/127816fb-af09-d15b-9e9d-d79bdc68b559.png)
[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)上で動かすプログラムは、**Node-RED**で作成しました。
Node-REDについては、本連載の第1回および第2回でも紹介していますが、**各種通信のためのモジュールが用意されている**ので、比較的簡単にプログラムを作成することができます。WebSocketのモジュールもあったので使ってみました。

<strong>サーバー上で動かすプログラムは、WebSocketサーバーとWebサーバーの二つです。</strong>どちらもNode.jsで実装しています。**WebSocketサーバー**は、センサーデータの受信、しきい値判定、通知(サーバーPUSH)を実行します。**Webサーバー**は、Web画面の提供(グラフ表示、手動スイッチ)です。

# 動作確認

![Qiita_図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2637100/88edb3d6-73c8-d939-b487-27014156845f.png)
**【通知1の確認】**
CO2濃度がしきい値を超過すると、サーバーから[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)に通知が送られ、
パトライト赤が点灯することが確認できました(上図)。

![Qiita_図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2637100/6446bb61-f97e-6122-bc98-57c0d4002eed.png)
**【通知2の確認】**
Web画面から「パトライトON」のスイッチを押すと、サーバーから[**CONEXIOBlackBear**](https://conexio-iot.jp/serviceproduct/blackbear.html?utm_source=qiita&utm_medium=blog&utm_campaign=qiita&utm_id=qiita)に通知が送られ、パトライト橙が点灯することが確認できました(上図)。

# まとめ
今回ご紹介したサーバーPUSHの例では、クラウドからIoTゲートウェイ経由でパトライトに通知を送るという単純なものでしたが、<strong>この技術は機器の制御にも応用することができます。</strong>可視化の次の段階として制御を検討している場合には、サーバーPUSHは欠かせない技術になりそうです。
REALFORCE(Windows)をMacBookで使う


Windows専用のキーボードをGetしたので、MacBookユーザーに向けてキーボードのマッピングを紹介します。

Macで快適に使うために、「Karabiner-Elements」で僕が設定している、カスタマイズ設定を紹介します。

# MacBookでRealforceを使うなら「Karabiner-Elements」がオススメ

Windows専用のキーボードは、Macとはキー配列が違うので接続しても使えないキーがあり、何かと不便なのです。

そこで使うのmacOSから使うときにはキーマップ変更ソフト
　**[Karabiner-Elements](https://karabiner-elements.pqrs.org/)** 
がオススメです。

この **Karabiner-Elements** を使いキーボードのマッピングを変更することで、より快適なキーボードになってきます。
これを使わないと **「無変換」「変換」「半角/全角」** のキーで入力の変換が出来ないことになり、とっても不自由なキーボードとなってしまうのです。


## 「Karabiner-Elements」の設定を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86428/0c1c212d-c297-bf31-54d7-9799c2969308.png)

***

## 東プレ「REALFORCE」のキーマップ変更内容
| From key   | To key       |
|:-----------|:------------:|
|caps_lock	|left_control
|PCキーボードのかなキー	|right_command
|PCキーボードの無変換キー	|英数キー
|PCキーボードの変換キー	|かなキー
|left_alt	|left_command
|left_command	|left_option
|left_control	|left_command


### 新しくREALFORCEを購入したときは
現在はMac配列のREALFORCEが販売されているので、最初から「REALFORCE for Mac」を買うのがオススメです(笑)

自分が初めて **REALFORCE** を購入したときは、Mac版は無かったですし、無線タイプのREALFORCEもありませんでした。

改めて、