OmniAICreator/Qiita-1.07M huggingface dataset:
GASでPageSpeed Insights APIを叩いて結果をSpreadsheetに出力する

## PageSpeedInsightsとは

https://pagespeed.web.dev/

Googleのツールのひとつ。
webページの読み込みスピード等の、パフォーマンスのスコアを計測することが出来ます。
対象ページのurlを入力することで計測が可能です。

Googleの検索順位の指標、CoreWebVitalsの対策にもなる改善項目を取得できるため、SEO対策に有効です。

## PageSpeedInsights API とは

https://developers.google.com/speed/docs/insights/v5/get-started?hl=ja

https://developers.google.com/speed/docs/insights/v5/reference/pagespeedapi/runpagespeed

Google純正のAPI。
PageSpeedInsightsの結果をjson形式で取得できます。

今回はこちらを使用して、取得結果をGoogleSpreadSheetに書き込みたいと思います。

## イメージとソースコード

### イメージ1：url入力欄と実行ボタン
![スクリーンショット 2022-07-24 8.51.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831027/ca76c61f-21aa-ee0f-6b89-f8afaab7e63e.png)

### イメージ2：結果の出力
![スクリーンショット 2022-07-25 0.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831027/4d8cf8a3-7a7e-3a0b-3017-99359ec2a98c.png)

※分かりやすいようにヘッダーに色をつけています。

### ソースコード

使用言語：GoogleAppScript

```js
function myFunction() {
  // 対象のスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  // 読み込むシート
  var read_sheet = ss.getSheetByName("実行")
  // 書き込むシート
  var write_pc_sheet = ss.getSheetByName("結果-PC")
  var write_sp_sheet = ss.getSheetByName("結果-SP")

  // 対象のurlを取得
  var range = read_sheet.getRange("B3");
  var url = range.getValue();

  var arrPc = getResult(url, "desktop"); // PCの結果を取得
  var arrSp = getResult(url, "mobile");  // SPの結果を取得

  writeResult(write_pc_sheet, arrPc); // PCの結果を書き込む
  writeResult(write_sp_sheet, arrSp); // SPの結果を書き込む
}

function getResult(url, strategy){
  // PageSpeed Insights APIを実行
  var result = UrlFetchApp.fetch(
    'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' 
    + url // 計測対象のurl
    + "&locale=ja" // ローカライズ
    + "&strategy=" + strategy // 端末の指定
  );
  // JSONの結果を配列にする
  return JSON.parse(result);
}

function writeResult(sheet, arr){
  // パフォーマンス
  var performance = arr["lighthouseResult"]["categories"]["performance"];
  // ヘッダ
  sheet.appendRow([
    "id", 
    "title", 
    "score"
  ]);
  // 値
  sheet.appendRow([
    performance["id"],
    performance["title"],
    performance["score"]
  ]);


  // 改善項目・内容を書き込む
  // シートの最終列を取得
  var lastRow = sheet.getLastRow();
  // 最終列から2行空けて書き込み
  sheet.getRange(lastRow+2, 1, 1, 3).setValues([[
    "id",
    "title",
    "description"
  ]]);

  // 改善項目（オブジェクト）
  var audits = arr["lighthouseResult"]["audits"];
  // 一行ずつ書き込む
  Object.keys(audits).forEach(function (key) {
    var audit = audits[key];
    if (audit["id"] === false || audit["title"] === false || audit["description"] === false) {
      return;
    }
    sheet.appendRow([
      audit["id"],
      audit["title"],
      audit["description"]
    ]);
  });
}
```




#### 注意
* GASのデフォルト仕様では、1分間のクエリ実行回数に制限が掛かっています。こちらのソースコードをそのまま使用しても、制限に引っ掛かり失敗する可能性があります。
    * Googleに申請することで上限を増やすことが出来るようです。
オンライン会議いつも遅れる人をTeachable Machineで素早くつかまえてみた！

# 「出欠確認作業」これを楽に、しかも早くしたい！
**私はこの確認作業で、いつも時間に追われながら、一覧表を上に下にスクロールしています。**
人事部ではないけど、労務管理しています。オンライン会議が普通になってはや数年。みなさんは、出欠確認はどのようにしていますでしょうか？きっと私と同じように、入室していない人をあの**小さな画面で一人ずつ確認して、来ていない人に電話**をしているのではないでしょうか？電話をかけるにも、まずは確認作業が必要ですよね。デジタル化になっても**出欠確認はいつまでもアナログ。。。**　時間がかかって困っています。これって、どうにかならないの？と思い**画像判別**に挑戦しました！

今回は、いつも遅れる**しんのすけさん**を、いち早くつかまえてみることにしました。
おや？上司の方は名前を見つけれず、しんのすけさんに電話をかけたようです。
![画像学習③.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/4bbf6078-450f-07ef-1bb2-25640d26e8f9.jpeg)
いつもよく遅れるしんのすけさん💦
今日は一番のりで間に合ったみたいですが、すぐに名前を見つけてもらえなかったみたいですね・・・。しんのすけさんの名誉のためにも、早く来た日は素早く確認できるようにしてみましょう！

:::note
今回の登場人物は、フィクションですので、温かい目で見てください（笑）
:::
# 今回使用したもの
[Teachable Machine](https://teachablemachine.withgoogle.com/)　
[Node-RED](https://nodered.org/)
[Make](https://www.make.com/en)
[LINE](https://developers.line.biz/ja/)
# 学習と検証
まずは**Teachable Machineでしんのすけさんの学習**です。
比較対象として、今回はオレンジを学習しました。
![画像学習.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/e02f38e3-486d-adab-ea78-572fb6e12a54.jpeg)
検証すると、顔のアップや一部でも認識OKです！

次に、**Node-REDとTeachable Machineを連携させて検証**します。
![画像学習④.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/5b83544a-2e2a-79de-fb67-d1e768ee375b.jpeg)
検証では、しんのすけさんの認識OKです！
しんのすけさん！あと少しです！待っててくださいね～✨(*'▽')✨

:::note
ここまでは、比較的順調に進めます。
:::

次に、**Makeと連携させ、LINEに結果を送ることができるかを検証**します。
**Makeでの設定**です。LINEには、**発見！「検証結果」！！**　というメッセージが送られてくるようにしました。
![画像学習⑤.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/66d85f0a-771b-a6c5-ab72-2fc580ab1635.jpeg)
**Node-REDでの設定**です。
比較対象のオレンジで検証をしました。
![画像学習⑦.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/5e4c967a-6d1f-255f-5cfd-bd72beae38df.jpeg)　

::: note warn 
LINEとの連携はすぐにできましたが、メッセージが届く時に　**「検証結果の名前」**　が来ず、<font color="red">**発見！「　」！！**</font>　となって名前が出ず、ここがかなり苦労しました。
:::
# 実装してみます！
それでは、**LINEにメッセージが届くか**を検証します。

https://twitter.com/natsupariri/status/1551194188733362177

はい！しっかりと結果が届き、**しんのすけさんを素早くつかまえることに成功**！✨( *´艸｀)✨
これで素早く見つけることができるようになりましたが、今後は早く入室してくださいね～✨

# まとめ
今回は、いつも遅れる一人を素早くつかまえるために、ターゲットを絞りましたが、将来的には、**参加者全員をあらかじめ学習しておき、スプレッドシートに作成した名簿に入力して集計する**、というところまでできたらいいなと考えています。夢は膨らむばかりです！
画面をスクロールしながらの出欠確認は時間との闘いです。次の会議はこれを使い、まずしんのすけさんを真っ先につかまえます！

最後までお読みいただき、ありがとうございました！
html_safeの意味

# 背景
controller.rbにhtmlを埋め込んでもhtmlの下のようにソースコードが表示されてしまう

**失敗例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177825/1b451b2c-80a3-f73d-9015-d792c62a6c8b.png)


# 結論
`render html: msg.html_safe`
このように、html_safeを入れること
**成功例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177825/8781e6f0-a3b5-779c-afb6-acff8548bea1.png)

# 全体ソースコード
```ruby:改善後sample
class HelloController < ApplicationController
    def index
        #render plain:"Hello, This is Rails sample page!"

        msg = '
        <html>
        <body>
            <h1>Sample Page</h1>
            <p>this is sample page!</p>
        </body>
        </html>
        '
        render html: msg.html_safe
    end
end
```

# 原因
Railsのrenderは基本的に、htmlのタグをすべてエスケープするみたい。
その理由としては、クロスサイトスクリプト攻撃のような外部から悪意のあるコードを受け取っても実行しないようにするためと思われる。
husky の pre-push が stdin is not a tty で失敗する

## 概要
件名のとおりですが、husky の pre-push が stdin is not a tty で git push に失敗します。使用しているのは Git Bash です。
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70638/ad688a84-d2d8-4ed3-824d-6c1350ce2ff3.png)

## 環境
- Windows 10 Pro
- git version 2.37.1.windows.1
- yarn v1.22.15
- husky v8.0.1

## 再現環境
最小構成として以下で再現します。ちなみに `yarn run foo` ではなく `npm run foo` だと問題なく動きますので、どうも Yarn について回っている問題のようです。

```json:package.json
{
  "devDependencies": {
    "husky": "^8.0.0"
  },
  "scripts": {
    "foo": "echo foo"
  }
}
```

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

yarn run foo
```

## 対処
Yarn の問題らしいです。
husky公式リポジトリのIssueにhuskyを作ったtypicodeさんより対処方法がコメントされていました。
https://github.com/typicode/husky/issues/850#issuecomment-774231951

これを丸パクリして解決しました。圧倒的感謝っ・・・！

```sh:.husky/common.sh
command_exists () {
  command -v "$1" >/dev/null 2>&1
}

# Windows 10, Git Bash and Yarn workaround
if command_exists winpty && test -t 1; then
  exec < /dev/tty
fi
```

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

yarn run foo
```

## 余談
これ、検索しても最近の例はあまりないのでなんか僕の環境の問題だったりするんですかね、もしかして。少しもやっとしますが、とりあえず直ったのでよしとします。
【MySQL】コマンド備忘録

# MySQLの起動、停止
起動
```
mysql.server start
```
停止
```
mysql.server stop
```
再起動
```
mysql.server restart
```

# MySQLへログイン、ログアウト
ログイン
```
mysql --user=root --password
mysql -u root -p;
```
ログアウト
```
exit;
```
# 作成したデータベース、テーブル一覧の確認
データベース
```sql
SHOW databases;
```
テーブル
```sql
SHOW tables;;
```
# データベースの作成
```sql
CREATE DATABASE dbname;
```
# 操作するデータベースを指定
```sql
USE dbname;
```
# テーブルの作成
```sql
CREATE TABLE tbname (id INT AUTO_INCREMENT, name TEXT, PRIMARY KEY (id));
--           テーブル名（カラム名 型 オプション, カラム...
```
# テーブル構造の表示
```sql
DESCRIBE tbname;
```
基礎情報技術者理論(1)

1. 離散数学

基数，基数の変換，数値の表現，算術演算と精度など，コンピュータで扱う数値表現を理解し，担当する事項に適用する。
集合，論理演算の基本法則，手法を理解し，担当する事項に適用する。

(1) 基数

基数（radix）とは、位取り記数法で数値を書き記す際に各桁の重み付けの基本となる数で、位が上がる毎に何倍になるかを表す。我々が普段使っているのは隣の桁が 10 倍あるいは 10 分の 1 となる 10 進数（10 進法）であり、基数は 10 である。

2 進数，8 進数，10 進数，16 進数の対応を次表に示す。

10 進数整数をr進数へ変換
10 進数の整数値xをr進数に変換する手順は次のとおり。

1. xをrで割ったときの商pと余りqを求める。
2. pの値が 0 ならば終了。それ以外ならばpを 
xと読み替えて 1. へ戻る。

計算の終了後，これまでに求まったqの値のうち,最後に求まったqの値を最上位桁として順に下位方向に並べたときの数列が変換されたr進数の値である。

(2) 数値の表現

コンピュータの中では，整数だけでなく負数や小数点数なども，すべて 0 と 1 の 2 進数で表される。

浮動小数点数

浮動小数点（floating point number）とは，コンピュータにおける数値の表現形式の一つで、数値を桁の並びを表す仮数部と小数点の位置を表す指数部に分割して表現する方式。小数点以下の値を含む数値の表現法として最も広く利用されている。

（浮動小数点数の例）6.02 × 1023，-0.73 × 10-2
浮動小数点数は，小数点の位置を固定せずに小数点数を表現する方法である。数値を指数形式（± f × re）で表した時の，「符号（正を 0，負を 1）」，「仮数 f」，「指数 e」を下図の順に並べて表現する。これを浮動小数点形式という。ここで，r は基数を意味し，通常，基数は 2 である。また，仮数 f は「0.1xxx」となるように，指数 e と桁合わせをする。
macターミナルでの処理が完了したらLINEに通知する

## macターミナルでの処理が完了したらLINEに通知する
### 本記事の目的
そろそろ処理終わってるかな？と、ターミナルを覗きに行く時間をなくすことです。
この時間がなくなると、他の作業に結構集中できます。
ソフトウェアエンジニアや機械学習エンジニアで、時間のかかる処理（コンテナのビルド・デプロイや、パラメータのチューニングなど）をターミナルで行っている方にぜひお試しして頂きたいです。

### 手順
1. LINENotifyのトークンを発行する
1. pythonファイルを作成(pythonを書けない方でも大丈夫です)
1. ターミナルでの処理実行文を作成

### LINENotifyのトークンを発行する
[こちら](https://qiita.com/chivi_dump/items/a62a7b8c32e6ea894a09)の記事がとても参考になります。

### pythonファイルを作成(pythonを書けない方でも大丈夫です)
以下のファイルを作成します。
```notify.py
import requests

def main():
    send_line_notify('解析作業終わったってばよ')

def send_line_notify(notification_message):
    """
    LINEに通知する
    """
    line_notify_token = 'ここに発行したトークンをコピペ'
    line_notify_api = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': f'Bearer {line_notify_token}'}
    data = {'message': f'message: {notification_message}'}
    requests.post(line_notify_api, headers=headers, data=data)

if __name__ == "__main__":
    main()
```

### ターミナルでの処理処理文を作成
以下の文をコピーしてターミナルにてペーストし、実行
```ターミナルにコピペ.text
#メイン処理がtest.pyの実行である場合
python3 test.py ; python3 $HOME/line_notify/notify.py
```
上記を実行すると、以下の様な通知が来ます。
![IMG_3489.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659845/bb3d9015-78f1-648e-7c88-a56346fa806b.jpeg)
IMG_3489.jpg

以上です。

### 余談
余談ですが、私は実行する文が複数ある場合、以下の様なtextファイルを作成し、ターミナルにそのままコピペをしています。すると処理が次々に実行されます。
```
#awsにログイン
aws ecr get-login-password --region ap-northeast-1 --profile default | docker login --username AWS --password-stdin https://hogehoge.dkr.ecr.ap-northeast-1.amazonaws.com

#コンテナのビルドなど
docker-compose up -d app db
docker-compose up -d
docker-compose exec worker python test.py ; python $HOME/line_notify/notify.py
pwd

#ディレクトリを移動
cp bayesian_optimization.pickle ../bayesian-optimization
cd ..
cd bayesian-optimization

poetry run python3 test.py
python $HOME/line_notify/notify2.py

#最後の文は実行されないので、実行したい処理の後に以下を追加
ls
```
実際にコピペするときは、コメントアウトは覗きます。

お読み頂きありがとうございました。
「リーダブルコード」の要約 ~1章を1つの画像にして全章分作ってみた~

## はじめに

書籍「リーダブルコード」はエンジニアなら全章覚えてきおきたい内容ですが、読み返すにも全部読むにはなかなか時間がかかります。

全章の概要を載せて、手軽に知識の定着・覚えているかの確認ができるといいなと思いました。

そこで、少し詳しめの索引として機能させれば、時短で全章を確認できるかな？

と思って１枚画像としてまとめてみました。

（10章などは実際のコードが例としてたくさん出てくるので、要約しずらく、本を読んだほうが良い章もあります）

## 引用文献

https://www.oreilly.co.jp/books/9784873115658/

## 1章 理解しやすいコード

![スクリーンショット 2022-07-25 0.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/4fe22710-e8f0-6c3a-c1c5-015ddd37909a.png)

## 2章 名前に情報を詰め込む

![スクリーンショット 2022-07-25 0.07.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/8d89541b-fd84-f369-7140-a3103f402dae.png)

## 3章 誤解されない名前

![スクリーンショット 2022-07-25 0.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/62150066-eb60-bc6a-7a5c-8808a495f922.png)

## 4章 美しさ

![スクリーンショット 2022-07-25 0.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/5dd082cf-151f-4fcb-aba5-07ba02d9273f.png)

## 5章 コメントすべきことを知る

![スクリーンショット 2022-07-25 0.03.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/e9c74114-4d8d-304e-bb3c-bd8775f49e54.png)

## 6章 コメントは正確で簡潔に

![スクリーンショット 2022-07-25 0.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/422bd185-df5d-e500-7adb-18c9f40ee2d0.png)

## 7章 制御フローを読みやすくする

![スクリーンショット 2022-07-25 0.01.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/debefc9d-917c-8382-fac8-fb00e7d21eee.png)

## 8章 巨大な式を分割する

![スクリーンショット 2022-07-25 0.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/53e05541-87de-7f7c-3a41-5508e3294c39.png)

## 9章 変数と読みやすさ

![スクリーンショット 2022-07-24 23.59.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/460ce4bf-c319-5c05-af57-bc9989d98c3b.png)

## 10章 無関係の下位問題を抽出する

![スクリーンショット 2022-07-24 23.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/18263fa8-e0c5-a616-c44a-0bebfc93e3b4.png)

## 11章 一度に1つのことを

![スクリーンショット 2022-07-24 23.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/0bb4f38e-4db4-463a-17e4-821e012e8348.png)

## 12章 コードに思いを込める

![スクリーンショット 2022-07-24 23.53.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/ddd9fe93-7fa6-413f-fbdf-452e8531c8e3.png)

## 13章 短いコードを書く

![スクリーンショット 2022-07-24 23.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/b36cce7a-4ad9-cfc4-07dd-bc5d99a18474.png)

## 14章 優れたテストコード

![スクリーンショット 2022-07-24 23.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/8498c512-dae1-1681-b781-d73815f6534e.png)
QRコードエンコーダーについて


## 制作経緯
Githubの講習会などを行なった時に、出席確認のためにQRコードを作成する機会が多く、QRコードを作成するのが大変だったので、プログラムを起動してコピペをしてもらえれば簡単に表示できるQRコードエンコーダーを作成した。

## 使用方法

今回ライブラリを用いて開発しているため、makeファイルを作成しました。ですのでmakeファイルを用いたコンパイルをよろしくお願いします。

〜コンパイル方法〜
```
rm -f myqrencode && make myqrencode && ./myqrencode
```

〜実行画面〜
```
> QRコード化したい文字を入力してください
aaa

// URLでも文字列でも対応しています

> 6文字(全角のみ)まで中に表示することができます。
こんにちは

// QRコードの中心に文字が表示されます。
// 顔文字やQRコードの説明を書いてみてください。
// 全角にしか対応していないのでご注意ください。
```

## 使用ライブラリについて
今回ProjectNAYUKI様のQRコードエンコードライブラリを用いて開発をおこないました

URL: https://www.nayuki.io/page/qr-code-generator-library#c

## リリースについて
brewを用いて各PCにインストールができるようになっています。
気になった方はインストールをしてみてください。

〜インストール手順〜
```
//インストールするリソースを追加
> brew tap harutiro/myqrencode
//インストール
> brew install myqrencode
//実行
> myqrencode
```

## 作成した資料一覧について
HomeBrewのリリース方法をまとめた記事

https://zenn.dev/harutiro/articles/bf66acd8fabf63

QRエンコーダーのつい買い方をまとめた記事

https://qiita.com/harutiro/items/025353cec772a3c47388
フロントエンドでよく使う便利なプラグインとツールライブラリのご紹介

### 序文

開発では、再利用しやすくするために、一般的に使用されるコードブロックと関数ブロックをカプセル化することがよくあります。 次に、それを抽出して独立して機能を完了し、APIまたは構成アイテムを介して他のパーツと対話し、プラグインを形成します。

以下は、私が仕事で蓄積したいくつかの一般的なフロントエンドオープンソースプラグインであり、ここにのみリストされています。詳細な使用法は、各プラグインまたはGayhubの公式Webサイトで紹介されています。 注：ソリューションには複数のプラグインが存在することが多く、読者は実際のビジネスニーズに応じて選択する必要があります。交換と補足のためにメッセージを残してください。 ^ _ ^

### 関数ライブラリ
Lodash（推奨）：https://github.com/lodash/lodash
Underscore：https://underscorejs.org/
Ramda：https://github.com/ramda/ramda
outils：https://github.com/proYang/outils
30-seconds-of-code：https://github.com/30-seconds/30-seconds-of-code

### アニメーションライブラリ
Animate.css

CSS3アニメーションライブラリは、現在最も一般的なアニメーションライブラリでもあります。
https://daneden.github.io/animate.css/

Anime.js：
アニメーション用の強力で軽量なJavaScriptライブラリ
http://animejs.com/

Hover.css：
CSSホバーホバー効果は、リンク、ボタン、画像などに適用できます。
https://github.com/IanLunn/Hover

wow.js：
スクロールアニメーション
WOW.jsはanimate.cssに依存しているため、animate.cssで60種類以上のアニメーション効果をサポートしています。
https://github.com/matthieua/WOW

scrollReveal.js：
wow.jsに似ています
https://github.com/jlmakes/scrollreveal

Magic.css：
css3アニメーションアニメーションライブラリ
https://github.com/miniMAC/magic

Waves：
クリック波及効果
github.com/fians/Waves

move.js：
JSを介した一連のCSSアニメーションの順次実行を制御する小さなJavaScriptライブラリであり、CSS3アニメーションを非常にシンプルでエレガントなものにします。
https://github.com/visionmedia/move.js

Velocity.js：
フェード、スクロール、スクロール、停止、終了、反転などのアニメーション効果を含むフル機能のJavaScriptアニメーションスイート。
https://github.com/julianshapiro/velocity
gnuplotで上に二つ目のx軸を書く

図の上に二つ目のx軸を書くのが目標。
ここでは、gnuplotでのやり方で書く。pythonでの作図も勉強し次第追記したいと思っている。

#### 結論
要は、plotコマンドを使う際にaxis x1y1, axis x2y1みたいにして書けばいい。

例）y軸を共通でもつ場合、
```
plot "data.txt" using 1:3 axis x1y1, "data.txt" using 2:3 axis x2y1
```
これで、data.txtの3列目を共通のy軸としながら二つのx軸を持つグラフを書ける。

目盛や範囲は、xとしていたところをx2とすればOK.
例）　set x2range [10:100]
phpmyadminへの接続方法【Mac用】

※自分用の忘備録

あまり使用することがないため、
いざ使う時のためにphpmyadminへの接続方法を記載。

MAMPを起動後、ブラウザにて以下のURLへアクセスする。
<pre>127.0.0.1/phpmyadmin/</pre>
もしくは、以下のURL。
<pre>localhost/phpmyadmin/</pre>

phpMyAdminの画面が表示されればOK！
（自分用）Pythonによるデータサイエンスで覚えるほどではないがよく使うコード集

完全に自分用です。
適宜アップデートしていきます。
複数環境での検証などはしておりません、また、解決方法の網羅性なども全く担保しておりませんので、万が一参考にされる場合はその点ご了承ください。


## pandas編
### csvファイルをエクセルで読み込める文字コードで出力
```python
# エンコードとして、'utf-8-sig'を付与
df.to_csv('./df.csv', encoding='utf_8_sig')
```

### jupyter notebook上で表示出来る最大列数を変更
```python
# 第二引数で表示列数を指定
pd.set_option('display.max_columns', 50)
```

## matplotlib編
### 日本語の表示
```python
import matplotlib.pyplot as plt
# 使用できるフォントは環境（主にOS）によって違うと思います
plt.rcParams['font.family'] = "MS Gothic"
```

## 参考元
- [Jupyter notebookで列をすべて表示したい](https://qiita.com/daifuku_mochi2/items/30258e58750ff8e85d37)
- [[Python] Excelで文字化けしないCSVファイルを書き出す](https://qiita.com/y4m3/items/674423b596284bbc7cf7)
- [Matplotlib 日本語の表示方法 厳選３選｜最適な方法選んで！](https://www.yutaka-note.com/entry/matplotlib_japanese#rcParams%E3%82%92%E8%A8%AD%E5%AE%9A)
Linux で、とあるコマンドが含まれるパッケージ名を特定する方法

# はじめに
Linux を勉強してて沼るパターンとして、自身の環境と参考サイトの環境で、OS のディストリビューションやバージョンが異なることで、必要なコマンドをインストールする際のパッケージ名がわからない、といった事例があるあるかと思います。

そんな時に便利な読み替え方法を共有します。

# インストールしたいコマンドがどのパッケージに含まれるかを確認する
## yum provides
```
# uname -rs
Linux 3.10.0-1160.62.1.el7.x86_64

# more /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

# yum provides which
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
which-2.20-7.el7.x86_64 : Displays where a particular program in your path is located
Repo        : base



which-2.20-7.el7.x86_64 : Displays where a particular program in your path is located
Repo        : @anaconda



# 
```

## apt-file search
```
# uname -rs
Linux 5.10.102.1-microsoft-standard-WSL2

# more /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
# 

# apt-file search -x "^.*/which$"
bash-doc: /usr/share/doc/bash/examples/functions/which
debianutils: /bin/which
epic4-help: /usr/share/epic4/help/4_Misc/which
epic4-help: /usr/share/epic4/help/6_Functions/which
ircii: /usr/share/ircII/help/which
scrollz: /usr/share/scrollz/help/which
yash: /usr/share/yash/completion/which
zsh-common: /usr/share/zsh/help/which
# 
```

# おわりに
Linux は色々な種類があり、微妙にコマンドの仕様が異なるのでそれぞれ覚えるのが大変かと思います。
ですがどれも考え方は大体一緒なので、まずはどれか一つのパッケージマネージャで出来ることをある程度理解するのがおすすめです。

yum と apt ではコマンド対応表などもネット上にあるので、こんな便利なことが出来る、という概念とキーワードさえ押さえておけば、上手くググることで別のパッケージマネージャでも同等のコマンドを見つけれたりします。
ICML2022の枝刈り論文 (3)

# 概要

この記事では、[ICML2022](https://icml.cc/)の枝刈り論文を紹介します。[^1]

[その1](https://qiita.com/kyad/items/b32f38ae16ea47e5d517) [その2](https://qiita.com/kyad/items/938c808c20a90ce0d1ad)

[^1]: 画像や数式は論文から引用しています。


# Coarsening the Granularity: Towards Structurally Sparse Lottery Tickets

https://arxiv.org/abs/2202.04736

(ICML2022 Spotlight)
概要：Structuredな当たりくじを見つける方法。
新規性：IMP (Iterative Magnitude Pruning) をstructuredにすると精度が落ちるし当たりくじに当たらなくなる課題を初めて解決する方法を提案した。
キモ：UnstructuredのIMPの後に後処理を入れる。2種類提案した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/2363c2ba-ac96-67ae-a131-6edc22f6a96e.png)
1. Refill. 刈った後に重要なチャンネル(重みのL1ノルムなどで測る)を戻す。
2. Regroup. 似た特徴を見つけて潰す。似た特徴を見つけるにはhMETISを使う。
評価：画像認識タスクで実験した。Wide-ResNetで2%、MobileNetで1%落ち
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/84fb0381-7d9c-5c2b-6a8a-9d806c8d9bf0.png)

# DepthShrinker: A New Compression Paradigm Towards Boosting Real-Hardware Efficiency of Compact Neural Networks

https://arxiv.org/abs/2206.00843

概要：DepthShrinker. Inverted residual blockなどの高速化方法。
研究機関：Meta
新規性：MobileNetV2やEfficientNet-Lite0を3~4倍高速化した。
キモ：Inverted residual blockのうち、寄与していないActivationを除いてFine-tuningして1つのdenseなConvにマージする。
Activationに学習可能なマスク$m$をつけて学習する。($m$が大きいほど重要)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/0e4937ac-c2b0-e274-c98d-373f569971cd.png)
評価：MobileNetV2やEfficientNet-Lite0で適用前後で比較した。ResNetでも実験した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/84e83c69-bbf1-ef8d-5e6c-6e60f873748a.png)
【Android】たまに出てくるFirebaseってなんなの？

# はじめに
Android開発をやっていてたまに目にする **「Firebase」** という言葉が気になったので、調べたものを記事に残します
Firebaseの公式サイトを見て、どういったものなのかをまとめたものです

# Firebaseとは
Firebase公式サイトでは
>Firebase は、優れたアプリを開発し、ユーザーベースを拡大し、収益を高めるためのツールです。インフラ構築に手間取ることなくビジネスを収益化し、ユーザーにとっての利便性に集中できます。

とあります。

アプリで使われる、クラウドから提供するサービスの一つ　ということですね
Javaコードを書くだけで簡単にサーバーとのやり取りができるのが魅力的ですね



# Android プロジェクトに Firebase を追加する
Firebaseをアプリに追加するには、Firebaseコンソールから　Firebase構成ファイルをダウンロードし、Androidプロジェクトに移動させるなどの、タスクを行います

方法１
1.Firebaseプロジェクトを作成し、androidアプリに接続します
2.Firebaseコンソールで、プロジェクトの概要ページの中央のAndroidアイコン、または「アプリを追加」をクリックし　設定ワークフローで「Android パッケージ名」を入力　「アプリを登録」をクリック
3.google-services.jsonをダウンロードし、Firebase Android構成ファイルを取得します
4.Gradleファイルにgoogle-servicesプラグインを追加し、アプリにFirebaseプロトコル有効にします
5.Firebase SDKを追加
6.アプリを同期して全ての依存関係に必要なバージョンがあることを確認します

方法２
1.Android Studioでプロジェクトを開き、「Tools」→「Firebase」の順にクリックしFirebase Assistantを開き　「Assistant」ペインで追加するFirebaseプロダクトを選択します
2.セクションでチュートリアルのりくをクリックし　アプリを同期して、全ての依存関係に必要なバージョンがあることを確認します

# おわりに
今回はFirebaseがどういうものか、また、Firebaseの実装方法を記事にしました
経験として　この工程をやってみるのもいいと思うので、その時には実装にあたって気をつけた点や躓いた点も一緒に記事にできたらいいなと思います
WSL2のUbuntu 22.04起動時に「リモートデスクトップ接続(mstsc.exe)」が起動して困った方へ

WSL2のUbuntuを22.04にした後「リモートデスクトップ接続」(プロセス=mstsc.exe)が自動的に起動してしまい、困ってる方へ。
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22754/4cfde7d0-4af5-55a7-f9fc-646c8da9440b.gif)
以下に、回避方法があります。

https://github.com/microsoft/wslg/issues/655#issuecomment-1013824017

具体的には `.wslconfig` に以下の記述をすればOKです。(ファイルが無ければ新規作成)

```ini:.wslconfig
[wsl2]
guiapplications=false
```

このファイルは `%UserProfile%` ディレクトリに保存します。一般的には `C:\Users\<ユーザー名>\` ディレクトリです。

#### 参考

[WSL での詳細設定の構成](https://docs.microsoft.com/ja-jp/windows/wsl/wsl-config)

EoT
[Safari]Webページの表示したくない要素を消す

### 目的

- safari上で表示される一部要素を非表示にしたい
- safariの機能拡張を使わずCSSで非表示にする

### 環境

* macOS: 12.4
* safari:15.5

### 独自のスタイルシートを適用する

https://support.apple.com/ja-jp/guide/safari/ibrw1075/mac
> Webページのスタイルシートではなく独自のCSSを使用します。ポップアップメニューをクリックし、「その他」を選択します。

独自のCSSを適用できる機能が標準であるのでそれを利用する。

環境設定(command + ,) > 詳細 > スタイルシート
から適用できる。

![スクリーンショット 2022-07-23 22.57.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168023/b96426d0-3a67-2e71-372a-54fde8c37330.png)

### 例)ニコニコ動画のプレミアム入会のポップアップを非表示にする

赤枠が消したい要素。

![スクリーンショット 2022-07-23 23.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168023/b1abacef-4087-4905-6493-1dbd599a2213.png)

プレミアム会員入会の圧がすごい。
以下の手順で非表示にする。

##### 1. デベロッパツールを開く (開発 > Webインスペクタを表示)

##### 2. 非表示にしたい要素のidもしくはclassを探す

##### 3. ピックアップしたid,classを非表示にするようにcssに記述する

##### 4. cssをsafariに適用して再起動する

以下のようなCSSファイルを適用した。

```css
.common-header-m5ds7e {
    display: none !important;
}
.SeekBarStoryboardPremiumLink {
    display: none !important;
}
.PreVideoStartPremiumLinkOnEconomyTimeContainer {
    display: none !important;
}
.PlayerOverlayBottomMessage {
    display: none !important;
}
```
Linuxについて５（自分用メモ


ユーザーにはユーザーID（UID)という固有ID番号が割り当てられる。
Linux上ではユーザーの識別はUIDで行われる。

UIDの確認
id ［ユーザー名］

ユーザー名とUIDの対応はユーザー情報が格納されたファイル/etc/passwordに記述される。

●ユーザーの種類
・root　ID「０」
システム全体を制御する権限をもつ。
・システムユーザー　ID「1~99」
システムプログラムやサーバソフトウェアを実行する特別なユーザー
・一般ユーザー　ID「100以上」
システムを利用するユーザー

・一時的にrootユーザーに切り替えるコマンド
su ［-］　［ユーザー名］

※［-】を省略してもrootユーザーになれるが、以下の点が異なる。
１、rootユーザー用コマンドの多くが使えない
２、カレントディレクトリが元のまま

・元のユーザーに戻るコマンド
exit

・rootユーザーの権限が必要なコマンドを実行（予め設定が必要）
sudo コマンド

●ユーザーは何らかのグループに所属しなければならない

所属グループの確認コマンド
groups　［ユーザー名］

※idコマンドでもグループ情報を確認できる

●ユーザーの作成
useradd ユーザー名

※ユーザーを作成できるのはrootだけなので、su - コマンドでrootに切り替える

●パスワード設定
passwd ［ユーザー名］

※passwdコマンドは一般ユーザーでも使えるが、その場合は自分のパスワードのみ変更できる

●ユーザーの削除　rootユーザーのみ
userdel ［-r］　ユーザー名

●ホームディレクトリごとユーザーを削除する
userdel -r ユーザー名

●グループ作成　rootのみ
groupadd グループ名

●ユーザーの情報を変更（グループに作成済みユーザーを参加させる）　rootのみ
usermod -G　グループ名　ユーザー名

●グループの削除　rootのみ
groupdel グループ名

※ユーザーが削除するグループにプライマリグループとして存在する場合はグループ削除できない。

グループの情報は/etc/groupファイルに格納される
elasticsearch，kibana，td-agentでログデータの可視化において型がstringになってしまう問題について

# 問題
td-agentでログを取得してkibanaで可視化しようとするときに、ちゃんと設定できていないと取得したログすべてがstring型になってしまいvisualizeなどで可視化できない可能性がある。

# 解決方法
そんなときの解決方法を解説する。
大まかに方法は以下の2つがある。
* elasticsearch（es）のmapping設定
* td-agentのtype設定

## esのmapping設定
自分的には、こちらを推奨している。（なんとなく型情報の管理がしやすそう）
まずesの前提知識として、以下を覚えておいてほしい。
* 既存indexのmappingは削除、変更はできない。（追加は可能）
* mapping情報のないfieldをもつドキュメントがindexに登録されたときは、esのdynamic mappingによってよしなにfieldの型を判断してくれる。（つまり勝手に型情報が定義されちゃう）
* index templateを設定しておけば新しく作られるindexには自動的にmapping情報を登録してくれる。
* 既存のindex patternも削除、変更はできない。（追加は可能）あと、indexを再作成したらindex patternも再作成する必要がある。

具体的にindexにmappingを登録する方法は、いくつか存在するが今回は、kibana上のdev-toolsのコンソールから操作を行うことを想定する。（esのapi叩くときの文法とそんなに変わらないと思う。）
```
PUT index/_mapping
{
"properties": {
  "field name":{
    "integer"
  ],
  "field name":{
    "float"
  ],
}
}
```
※index：indexの名称
※field name：任意のtd-agentから送信されてくるデータのfield名称

実際は、この作業だけじゃうまく行かない事がある。ていうかほぼうまく行かないと思うので、上の方に記載した、esの前提知識をよく見てほしいこれが結構重要になってくる。それでもできなかったらtd-agent側で設定を変更する。

ちなみにコンソールに以下を打ち込むとindexのmapping情報を取得もできる
```
GET index/_mapping
```

## td-agentのtype設定
これは、td-agent側で送信するログfield情報をあらかじめ定義してesに突っ込み、esのdynamic mappingでよしなに型を定義してもらおう的な感じです。（パスは確か/etc/td-agent/td-agent.conf）

設定変更する場所は、td-agentの設定ファイルの<source>の部分に以下のtypesというパラメータを追加する。
```
<source>
  type tail
  path /var/log/nginx/access.log
  pos_file /var/log/buffer/nginx/access.pos
  tag nginx.access
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)"(?:\s+(?<http_x_forwarded_for>[^ ]+))?)?$/
  time_format %d/%b/%Y:%H:%M:%S %z
  types code:integer,size:integer    #これを追加する
</source>
```

ちなみに上のformatの部分を変更することで、様々なログファイルの切り分けが可能になる。ここの正規表現は、普通の正規表現と違って複雑なので、後日記事にするかもしれない。

# まとめ
esは結構な厄介者です。検証環境作ってあげて色々といじってあげるのが、一番勉強になる気がします。時間があればes,kibanaの検証環境の作成方法なども記事にします。
Adobe XD のスタータープランを使う方法

公式サイトからいつの間にか消えていたAdobe XD無料スタータープラン。
7日間お試し！ではなく意地でも無料で使いたい私がたどり着いた入手方法です。
<font color=#DDDDDD>Adobeさん怒らないで...</font>
*****
### 最初試したこと
調べてみると、公式のスタータープランDLリンクページは生きているらしいので↓からDLしてみました。
https://d-cubed-lab.com/adobexd-starterplan

の、ですが、、、
ダウンロードが終わるとAdobe Creative Cloudアプリが開かれ、XDの入手選択肢が「体験版」or「購入する」になってしまいました。
![スクリーンショット 2022-07-24 21.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745096/98f260d2-12ed-e390-d343-1496fc77c303.png)
*****
### 次に試したこと（うまくいった！）
諦めきれない私は↓の記事に辿り着きました。
https://nisimura.org/adobe_xd_starter_plan/

**そんな方法があったとは！！！**

要は一度期間限定無料プランを申し込んでから解約することでスタータープランとして使用継続できる仕組みになっているようです。

上記参考ブログ主さん、Adobeさんありがとうございます。
【#38 エンジニア転職学習】Go WebApp　フロントエンド部分作成

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

使用しているGoのUdemy教材後半部分である、
Webアプリ作成演習を学習していきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はCandleStickのデータフレーム作成、APIHandler、jQueryを使用したフロントエンド部分作成を学習しました。

* データフレーム
* APIHandler
* **フロントエンドchart作成　←Topics!!**

# フロントエンド chart作成
以下今回のフロントエンド部分作成時の個人的ポイントです。
* chart作成のHTMLは基本的なものは`developers.google.com/chart/`からテンプレート取得
* jQueryは「Google Hosted Libraries」よりリンク取得で簡単導入可能
* その他のグラフ導入等もdevelopers.googleのexampleベースで作成していく

本日やった章以降はビットコインの売買や分析に関する機能になり、
その理論的なところも含めての講座内容になっているようです。
現時点では、追加機能よりwebアプリのベース部分を作成する流れを体験したかったので、
この教材は本日で終了にしたいと思います。

##### 使用している教材はこちら↓


https://www.udemy.com/course/go-fintech/


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
なぜSAPなのか？

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# SAPとは
SAP(エスエーピー)とは、 __数あるERPの内の1つで、SAPという企業が製造しているもの__ です。
いくつもの企業がERPを製造していますが、その企業群の中で、ERPのシェア世界一がSAP社が提供するSAPです。

※ERPについてわからない方は、私が以前書いたこちらの記事を参照してください。
[ERPでビジネスはどう変わる？](https://qiita.com/7_inai_/items/6d73bc2b614ed19d017a)

# なぜSAPなのか？
ERPのなかで世界シェア1位を誇るのがSAPだと前述しましたが、なぜSAPが選ばれるのでしょうか？
その理由を見ていきましょう。

- 世界のスタンダードであるから
逆説的ではありますが、SAPは世界のスタンダードとして広く認知されていることから、選ばれているということも挙げられます。また、世界のスタンダードなので、多言語・他通貨に対応し、世界各国の法律にも対応しています。
- ベストプラクティス
SAPはその長い歴史から、多くの優良企業の業務フローに対するノウハウを蓄積しています。その業務フローをSAPを導入することで真似することができるのです。SAPでは、このような既に実績のある最も効率のよい技法、手法、プロセス、活動などのことを __ベストプラクティス__ と呼んでいます。

# 終わりに
SAPはドイツの企業です。ドイツと日本は共に __モノづくりの国__ と言われ、よく比較対象となります。モノづくりでは現場の力が強く、現場の要求に振り回されるため __汎用性が必要なERPの開発には向いていない__ はずですが、SAPは世界1位のシェアを誇っています。ではなぜドイツ発の企業にも関わらずここまで成長することができたのでしょうか？その答えはドイツの職業訓練制度にあります。ドイツ企業は職業訓練制度が発展していて、同じ資格の職ならどんな企業でも仕事の内容はほとんど同じです。つまり、職業≒業務という考え方が職業訓練により一般化されています。SAPはその一般化された業務プロセスをERPに取り入れることで、ドイツNo.1のERPへと発展しました。そしてアメリカでSAPのシェアが広まった理由としては、アメリカでは、独自の業務のやり方に固執せず、ERPの標準の業務を採用するメリットを肯定的に捉える企業が多かったため、アメリカでの発展にも繋がりました。
日本でもSAPのような世界に誇れるソフトウェア企業が生まれることを期待しています。

最後までお付き合いくださりありがとうございました。
【自己学習】Go言語を学ぶ(6)

公式チュートリアルから基本を学ぶ
https://go-tour-jp.appspot.com/list

## For(繰り返し)

* 基本的に、 for ループはセミコロン ; で3つの部分に分かれています:

  * 初期化ステートメント: 最初のイテレーション(繰り返し)の前に初期化が実行されます
  * 条件式: イテレーション毎に評価されます
  * 後処理ステートメント: イテレーション毎の最後に実行されます
  * 初期化ステートメントは、短い変数宣言によく利用します。その変数は for ステートメントのスコープ内でのみ有効です。

ループは、条件式の評価が false となった場合にイテレーションを停止します。

サンプルコード:
1~9まで足していき合計値を出力
```go
package main

import "fmt"

func main() {
  sum := 0
  for i := 0; i < 10; i++ {
    sum += i
  }
  fmt.Println(sum)
}
```
結果: 45

## For continued

* 初期化と後処理ステートメントの記述は任意で可能。

サンプルコード
```go
package main

import "fmt"

func main() {
  sum := 1
  for ; sum < 5; {
    sum += sum
  }
  fmt.Println(sum)
}
```

結果: 8

## For is Go's "while"

* for文はセミコロン(;)を省略することもできます。つまり、C言語などにある while は、Goでは for だけを使います。

サンプルコード
```go
package main

import "fmt"

func main() {
  sum := 1
  for sum < 5 {
    sum += sum
  }
  fmt.Println(sum)
}
```

結果: 8

## Forever(無限ループ)

ループ条件を省略すれば、無限ループ( infinite loop )になりますので、無限ループをコンパクトに表現できます。

サンプルコード
```go
package main

func main() {
  for {
  }
}

```

結果: 無限ループする
初心者　MySQL8に挑戦する 12

# -138億2000万と2022を共存させる方法は
　
　今日はnumbers→CSV→SequelAce→MySQLで入力してみる。

　テーブルも新しくしてみよう。

- create table tabula_rasa(****);

　25項目もあるので、もちろん一回ではできない。カンマが足らないとか、なんとか、かんとか、言われながら一つ一つ直す。「ここが変」と言ってもらえるって、つくづくありがたい。

## Idをauto_incrementにするならprimary keyに指定すべし
　が一番重要な修正だったかな。あとはただの書き間違い、という感じ。

　さあ、テーブルができたので、次はnumbersから表を読み込むよ。
　私はこれで年表をつくろうとしているんだが、一番昔が138億年前のbig bang。で、現在は2022年。

- yearというcolumnに-13.82x10^9と書いたら、それはintegerじゃない、といわれた。

　だめ？　じゃあ、

- year -13820000000　と書いたら、大きすぎ、といわれた。

　えー、どうしろと。まあいいや。練習なんだし、1382でいこう。太陽系の形成、地球の誕生を456とか454とかで済ませて、無事OKが出る。

　次、引っかかったのは緯度、経度。ここもInt指定だけど、big bangに緯度も経度もないから「blank」て書いてあったのが、整数じゃない、と怒られる。はい、ごもっとも。とりあえず０でごまかす。

　さあ、もう一回、import・・・・よっしゃ〜できた〜！！　久々の快感。

　アプリに繋がってないのが玉に瑕だけれども、この際、先にテスト用データベースをしっかり作ろう。numbersから入れられるなら、楽勝じゃないの。

## 明日は、追加や、修正や、削除もやってみよっと。

https://qiita.com/dongri727/items/ca17cab051ca0e2a1cce

https://qiita.com/dongri727/items/066c90d7cbf2457f1951
ピアノ・将棋・囲碁業界に学ぶ　IT業界の初心者対応

新人は初心者ではない。新人のうち、経験のない人が初心者で、プログラミングの経験のある人は１流のプロの場合がしばしばある。

新人(学生)を指導するよりも新人(学生)に指導してもらった方が効率的。仮説（139）

https://qiita.com/kaizen_nagoya/items/db993b1536055029f7c8

大学で潰されたり、大学院で潰されたり、企業の新人教育で潰されたり、企業の配属先で潰された若者からも、いろいろな勉強会で指導していただいてきた。


# ピアノ・将棋・囲碁

ピアノ、将棋・囲碁の世界では、小学生で専門家（プロ）になることができる。

|学歴|専門家｜
|:--|:--|
|小卒|　天才|
|中卒|　秀才|
|高卒|　勉強家|　　
|大卒|普通の専門家|

大卒で初心者って言ってていいのは、IT関係の専門を習得していない人だけかもしれない。

IT業界でやめるとよいかもしれない３つの習慣（年齢・学歴（大学名）・理系文系）
https://qiita.com/kaizen_nagoya/items/f0d252d1e70ccea18efc#comment-da0f2fb4493caa2cb00e

学歴がなければ、資格試験を受ければよい。

10代、20代にお勧めの資格 
https://qiita.com/kaizen_nagoya/items/4e0eb6e5d30c0237469d

一緒に実験プロジェクトをやってくださった高校新卒の方は、基本情報は受かっていた。
勉強家だと思う。JAVAのSilverもすぐに受かった。

Fラン「文系」によるFラン「文系」のためのFラン「文系」プログラマ /Fラン「文系」でも就職(プログラマ)できる５つの道。仮説（178）
https://qiita.com/kaizen_nagoya/items/c72fa39e3191ea0290df

「@spaces 平成のうちにやめたかった『ITの7つの無意味な習慣』」に付け加えたかったこと。仮説（169）
https://qiita.com/kaizen_nagoya/items/e6f9c2e0afbf8ab4181c

#参考資料

DoCAP（ドゥーキャップ）って何ですか？ 
https://qiita.com/kaizen_nagoya/items/47e0e6509ab792c43327

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
【ちょいネタ】Raspberry Pi PicoのBOOTSELボタンでリセットする方法とクロップアップダウン時の消費電流

Raspberry Pi Picoのプログラミング環境として、オススメなのはArduino IDEです。
昨年、その扱い方を解説する本をKindle書籍として出版しましたが、その中で紹介しているボード定義よりも使いやすい[arduino-pico](https://github.com/earlephilhower/arduino-pico)というものがあるため、新たに書き直したものを出版しました。
<a href="https://www.amazon.co.jp/2022%E5%B9%B4%E7%89%88%E3%83%9E%E3%82%A4%E3%82%B3%E3%83%B3%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%E4%B8%80%E6%AD%A9%EF%BC%81-Arduino-IDE%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8BRaspberry-Pi-Pico-ebook/dp/B0B6T396NC?_encoding=UTF8&qid=&sr=&linkCode=li3&tag=jksoft-22&linkId=3453413adca9a07c6fba607716325e01&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B0B6T396NC&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=jksoft-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=jksoft-22&language=ja_JP&l=li3&o=9&a=B0B6T396NC" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />  
[2022年版マイコンはじめの一歩！ Arduino IDEではじめるRaspberry Pi Pico: 1st](https://amzn.to/3v921iY)

紹介しているボード定義は、すでに[Raspberry Pi Pico W](https://www.switch-science.com/catalog/8171/)にも対応していて、Wi-Fiも手軽に扱えるようになっています。
この記事では、書籍には書かなかった小ネタを紹介します。

## Raspberry Pi PicoのBOOTSELボタンでリセットする方法
Raspberry Pi Picoにはリセットボタンがありません。Arduino IDEで書き込む際は、自動的にリセットかけてくれるので、特に問題はありませんが、それでもスケッチを頭から動かしたいときにリセットしたくなるタイミングがあります。その際には、以下のように書くとBOOTSELボタンでリセットできるようになります。

```c++
void setup()
{

{

void loop()
{
  if(BOOTSEL){
    delay(10);
    while(BOOTSEL);
    delay(10);
    rp2040.reboot();
  }
}
```
[arduino-pico](https://github.com/earlephilhower/arduino-pico)では、`BOOTSEL`にBOOTSELボタンの状態が入ります。それを読み込んで、BOOTSELボタンを押して、離した際にリセットがかかるようにしたスケッチです。
BOOTSELボタンを押したときにリセットをかけるとBOOTモードが切り替わってしまうため、離したときにリセットがかかるようにしています。delayはチャタリングを防止するためのものです。
(2023/04/09 編集 いつの間にか、リセット用の関数が用意されていたため、それを使用するように上記スケッチを書き換えました。arduino-pico 3.1.0では確認済み)

## クロップアップダウン時の消費電流
[arduino-pico](https://github.com/earlephilhower/arduino-pico)では、Raspberry Pi Picoのクロックを簡単に切り替えられるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/60020b59-61ba-3bdf-9e44-fdf4f18377b7.png)

高速な処理が必要な場合は、オーバークロックすることも可能ですが、Raspberry Pi Picoとしてはクロックダウンして消費電流を押さえられる方が魅力だと思います。
通常の133MHzではRaspberry Pi Pico単体の消費電流は`20mA`程度ですが、クロックが50MHz、250MHzのときに次のようになりました。

* 50MHz
`11mA`程度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/e3c7dabe-3ef9-c8a9-230a-bd1acb90ede5.png)

* 250MHz
`37mA`程度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/fbe99a6f-61b7-24b2-9d15-43a943d0d048.png)

Raspberry Pi Picoの電源回路は、アップダウンコンバータを積んでいるので単３電池2本でも動くようになっています。バッテリー駆動の場合は、50MHzにダウンすれば電池寿命は倍程度になる様です。
MySQLdが動かないので修正

以下のmysqlのログ見るに、/var/lib/mysql
~~~~~
$ sudo vim /var/log/mysql/error.log
2022-07-24T10:46:07.641883Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.29-0ubuntu0.22.04.2) initializing of server in progress as process 1069697
2022-07-24T10:46:07.646856Z 0 [ERROR] [MY-010457] [Server] --initialize specified but the data directory has files in it. Aborting.
2022-07-24T10:46:07.646994Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
2022-07-24T10:46:07.647182Z 0 [ERROR] [MY-010119] [Server] Aborting
~~~~~
なので、 /var/lib/mysql の中身全部消して作り直した。
~~~~~
$ sudo rm -rf /var/lib/mysql
$ sudo mkdir /var/lib/mysql
$ sudo chown mysql:mysql /var/lib/mysql/
$ sudo chmod 777 /var/lib/mysql
$ sudo mysqld --initialize

~~~~~
EC2+Flask+AWS Rekognitionで画像処理を行う

# 画像に映っている人物の年齢と人数を取得する
## AWS Rekognitionとは
- AIを活用した画像認識サービス
- APIのように簡単に利用可能
- 画像から様々な解析が可能
## 本記事では以下の方法については省略します
- ec2インスタンスの起動
- nginx+uwsgi+flaskでのWEBサーバの構築
## IAMロールを作成する
- IAMのダッシュボードから「ロール」を選択
- 「ロールを作成」を選択
- 以下の項目を選択して「次へ」を選択
    - 信頼されたエンティティタイプ「AWSのサービス」
    - 一般的なユースケース「EC2」
- 許可ポリシーで「AmazonRekognitionFullAccess」と検索しチェックを付けて「次へ」を選択
- 任意のロール名を付けて「ロールを作成」を選択
## EC2インスタンスにロールをアタッチする
- EC2ダッシュボードから「インスタンス」を選択
- AWS Rekognitionを使いたいインスタンスにチェックを付ける
- アクションのセキュリティから「IAMロールを変更」を選択
- 作成したIAMロールを選択する
## flaskからAWSRekognitionに問い合わせる
- EC2上でboto3をインストールする
```
pip3 install boto3
```
- 年齢と人数情報を取得するプログラム
```
import os
import boto3
import json
from flask import Flask, request, Response, render_template

app = Flask(__name__)
client = boto3.client('rekognition', 'ap-northeast-1')

@app.route("/analysis")
def analysis():
    age = 0
    people = 0
    # 年齢取得
    img = open("./images/img1.jpg", 'rb')   #解析したい画像のパスを指定
    response = client.detect_faces(
        Image={
            'Bytes': img.read()
        },
        Attributes=[
            'ALL'
        ]
    )
    if 'FaceDetails' in response:
        FaceDetails = response['FaceDetails']
        if not FaceDetails:
            pass
        else:
            age = int(FaceDetails[0]['AgeRange']['Low']) 
            age2 = age + int(FaceDetails[0]['AgeRange']['High'])
            age = age2 // 2 #解析結果の平均を取得

    # 人数取得
    img = open("./images/img1.jpg", 'rb')
    response = client.detect_labels(
        Image={
            'Bytes': img.read()
            }
        )
    for label in response['Labels']:
        if label['Name'] == 'Person':
            people = str(len(label['Instances']))
            return '人数：' + people + ' 平均年齢：' + str(age)

if __name__ == "__main__":
    app.run()
```
# 引用
https://tsukasa-blog.com/programming/amazon-rekognition-method/
https://tekuzo.org/awsai-countperson/
https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/rekognition-dg.pdf
AndroidStudioアップデート方法(Mac)

AndroidStudioは常にアップデートをしている為、最新でアプリ開発ができる様にしておくことが理想ではあります。

AndroidStudioのアップデート方法を記載しておきます。

# AndroidStudioアップデート方法(Mac)
![スクリーンショット 2022-07-23 18.09.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/909772e1-afe3-3bd6-1f04-fc9f2e2d002a.png)

左上に画像のリンゴマークがあると思います、その隣のAndroidStudioをクリックします。

![スクリーンショット 2022-07-23 18.10.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/76a04022-403c-3ba1-b3a4-dfa5a7f1cc2e.png)
上から2番目のChace for Updates...をクリックします。


新しいバージョンがある場合は下記の画像の様なものが右下に出るはずです。
![スクリーンショット 2022-07-23 18.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/bc3429ae-8c33-cd3f-72a9-a904a42e5ccd.png)

Updateをクリックするとアップデートが始まります。

以上です。
暗記しておくものでは無いので、アップデートする際はこのページを見てもらえればと思います。
Androidエミュレーターの位置情報を好きな位置に設定する方法

今回はAndroidエミュレーターの位置情報を好きな位置に設定する方法を書いていこうと思います。

# Androidエミュレーターの位置情報を設定方法

![スクリーンショット 2022-07-23 15.42.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/dc04963e-1a46-c79b-00d6-f5ea36bc7bc4.png)

まずはエミュレーターを起動し、一番右の三点リーダーをクリックします。

そうするとこの様な画面が立ち上がります。

![スクリーンショット 2022-07-23 15.57.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/8eb81fe5-14f5-70eb-66fe-e6efc638d1f9.png)

位置情報を設定したい箇所にクリックします。
その後右下のSetLocationをクリックすると位置情報が変更されます。

簡単に位置情報を変更できるので便利ですね！
以上です。
SwiftUIでViewを傾ける方法

今回は色々何ができるのか試していて、使用頻度は低そうなので、忘れてしまいそうなので、記録に残しておこうと思います。

使用バージョン
Xcode13

# Viewを傾け方法

``` ContentView.swift
Text("Hello")
    .clipped()
    .rotationEffect(.degrees(90), anchor: .center)
```

rotationEffectで傾けられます。
第一引数の.degrees()の数字は傾けたい角度を入れてください。
第二引数 anchor:は基準位置を指定します。今回は真ん中を基準にして回転します。


rotationEffectの後にclippedをするとはみ出た部分が見えなくなります。

以上です。
使う機会があれば参考にしてください！
Sinatraのロギングを設定する

## これはなに

Sinatraのロギングについて調べたのでまとめる。

Sinatraのバージョンは`2.2.2`

## ロギングを有効にする

Sinatraのロギング設定はクラシックアプリケーションでは有効でモジューラアプリケーション（`Sinatra::Base`クラス）では**無効**となっている。

そのため、モジューラアプリケーションの場合は以下のように設定する必要がある。

```app.rb
require 'sinatra'

class App < Sinatra::Base
  configure :development, :production do
    enable :logging
  end
end
```

↑のように設定することで`Rack::CommonLogger`のログがWebサーバー側のログに出力されるようになる。
ただ、`STDERR`にログが出力されるため注意が必要。

別のファイルに書き込むようにしたい場合は、自分で`Rack::CommonLogger`ミドルウェアを設定する必要がある様。（↓のブログを参照）

https://hawksnowlog.blogspot.com/2019/04/how-to-output-log-on-sinatra.html

また、任意のログを出力したい場合は、以下のように`logger`を設定することでログを出力できる。
以下は`STDOUT`に出力する例。

```app.rb
require 'sinatra'
require 'sinatra/custom_logger'
require 'logger'

class App < Sinatra::Base
  helpers Sinatra::CustomLogger
  configure :development, :production do
    logger = Logger.new($stdout)
    set :logger, logger
  end

  get '/' do
    logger.info('Logging!')
    'hello world'
  end
end
```

## Refs

- [Sinatra: Configuring Settings](http://sinatrarb.com/configuration.html)
- [Sinatra::CustomLogger (part of Sinatra::Contrib)](http://sinatrarb.com/contrib/custom_logger)
- [hawksnowlog: Sinatra のロギングを考える](https://hawksnowlog.blogspot.com/2019/04/how-to-output-log-on-sinatra.html)
- [Sinatraのロギング機構について調べてみた - SHOYAN BLOG](https://48n.jp/blog/2016/05/27/sinatra-logger/)
開発のチーム力が弱いと感じたのでGithub Actionを書いてみた。

この記事は、自社開発企業のエンジニア職として勤める私が、
開発陣のチーム力が非常に弱い事を感じ、
チーム力を引き上げるためにとあるコードを書きました。という内容になっています。

# 背景
私の所属する開発チームの体制は、CTOを含め5~10名（うち、フリーランス1名）となっています。
基本的には、CTOから降りてきた開発要件が各エンジニアにアサインされて開発を行い、
残るエンジニア・CTOがGithub上のプルリクエストをレビューする形になっています。

# チーム力における課題
　普段から開発に携わっていて、チーム力が非常に弱いと感じていました。
その要因の1つとして、 **機能開発が属人化している** のではないかと感じていました。

具体的に言うと、
+ 開発経験の薄いエンジニアの割合が高い
+ 新規機能・基盤の開発が比較的経験者だけで解決してしまっている

そしてさらに、
+ コードレビューのレビュアーが、 **上級者にしか振られない**
と言う問題がありました。

# コードレビューが原因となる属人化
　実装を一段落終えた後にプルリクエストを作成するのですが、
ここでレビュアーを手動でアサインする際に、どうしても経験のあるエンジニアにレビュー依頼が集中してしまっていました。

このこと自体、特に問題にはされていなかったのですが
```
+ コア機能の仕様を一部のエンジニアしか知らない
+ コードレビューに特定の人しか関わらないため、仕様が共有されない
+ バグが起こったり仕様説明が必要となった際に、特定の人しか解決できない
+ そもそも、みんなの開発スキルが上がらない
+ フリーランスにレビュー依頼が集中し、開発が進まない
```

などといった問題を日々感じるようになり、
皆にコードレビューに関わってもらえるようにするため
1つのGithub Action Workflowを書きました。

# Github Actionで、レビュアーを自動でアサインした
実際に書いたコードがこちら。
```yml
name: assign_review_request

on:
  pull_request:
    types: [opened, reopened]
    branches-ignore:
      - 'staging'

jobs:
  assign:
    runs-on: ubuntu-20.04
    steps:
      - name: Set reviewers
        run: |
          reviewer_count=$(cat ${{ github.event_path }} | jq '.pull_request.requested_reviewers | length')
          if [[ 0 == $reviewer_count ]]; then
            reviewers=()
　　　　　　　　　　　　　　　　　　　　　　　　# レビュアー対象者を羅列し、シャッフルする
            accounts=$(shuf -e user_1 user_2 user_3 user_4 user_5 ...)
            for i in $accounts
            do
              if [ $i == ${{ github.actor }} ]; then
                continue
              fi
              reviewers+=($i)
              if [ ${#reviewers[@]} ]; then
                break
              fi
            done
            curl -X POST \
                -H "Accept: application/vnd.github.v3+json" \
                -H "Content-Type: application/json" \
                -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
                -d "{ \"reviewers\": $(printf '%s\n' "${reviewers[@]}" | jq -R . | jq -s .) }" \
                https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers
          fi
```

ちなみに、Github Actionとはどのような仕組みなのか触れておくと、
リモートレポジトリへのPushやPublishなどのイベントが発生した際に
特定のジョブを自動で実行する仕組みです。

今回は、プルリクエストが開かれた事をトリガーにしました。

（ちなみにbranches-ignoreの所ですが、
ステージング環境用のブランチに向けたプルリクエストでは、
特にコードレビューを必要としていないためジョブをスキップしています）

ジョブの中でやっている事はごく単純で、
レビュアー候補をランダムに選択して、[レビューリクエストのAPI](https://docs.github.com/ja/rest/pulls/review-requests#request-reviewers-for-a-pull-request)を実行しています。


shufコマンドには入力された内容をシャッフルして出力する機能がありますが、
-eオプションで並び替えられた内容を配列に変換する事ができます。

$accountsには、レビュアー対象者がランダムの順番で入っています。
それぞれの要素をfor文で回して、それがプルリク作成者でなければレビュアーに追加、
レビュアーの候補者数が一定になればループ処理を抜けてAPIをcurlで実行しています。


# レビュアーアサインを自動化した事の成果
成果として実感しているのは、次のような感じです
```
+ これまで関わってなかった人も、（渋々ではあるが）レビューに加わってくれるようになりつつある
+ プルリクに関わる事で、機能に対する意識を持つようになっている（と、嬉しい）
```

ただ、中には
自分が振られても他者がレビューし終えるまで何もしなかったりする人もいて、
仕組みを作っても、プロダクト改善に関わってくれるかどうかは結局それぞれの意識の問題なのか、と思ったりもしていますが、こればかりは仕方ないですね。。

今回は、プルリクのレビューの仕組みを触ってチーム力改善にコミットしてみました。
久々に、シェルスクリプトを書けて楽しかったです。
ファイルの合成、合体、連結

目的は、複数のファイルの中身を合成・合体すること。
ここでは、A.txt（列数はA列）、B.txt（列数はB列）、C.txt（列数はC列）を合体させて、新しいnew.txtを作るとする。
※あくまでも単純な合体のみを考え、ファイル合成時に計算をしたりは考えない。

合成・合体の方向性として、大きく二つある。：
1. **縦方向に合体**
A.txtのファイルの最後にB.txtを加えて繋げる感じ。そのため、合体後のファイルの列数は、はじめA列だが途中でB列に変わり、C列に変わる。
  イメージは、
A.txt
B.txt
C.txt
という感じ。


1. **横方向に合体**
横並びでの合体。そのため、合体後のファイルの列数は(A+B+C)列になる。
  イメージは、
A.txt B.txt C.txt
という感じ。


#### 縦方向の合体
```
cat A.txt B.txt C.txt > new.txt 
```
と順番に並べるだけ。もともと"cat"は"concatenate（連結する）"からきているのでむしろこちらが本来の(?)使い方かも。

#### 横方向の合体
```
paste A.txt B.txt C.txt　> new.txt
```
と順番に並べるだけ。あとでawkなどで好きな列順に変えるのもあり？
【discord.js】modal windowを使ってみる

初書 ： 2022/07/24
node : 17.9.0
discord.js: v13.6.0

# 前書き

最近のdiscordに追加されているスラッシュコマンドやボタンなどの一つに、modalがある。
これが入力フォームの役割をしてくれるので、これを使ってみる。
なお、discord.jsの13.0.0の時は存在していなかったので、途中から追加された機能になる。

# 前提

・botは一通り動作すること

# 参考サイト

[Modals | discord.js Guide](https://discordjs.guide/interactions/modals.html#building-and-responding-with-modals)

# とりあえず書いてみる

上記参考サイトにコードの一例があったのでそのまま書いてみる。
ちなみにスラッシュコマンドで実行できるように書いている。

```ts: index.ts
import {
  Client,
  MessageActionRow,
  Modal,
  ModalActionRowComponent,
  TextInputComponent,
} from 'discord.js';

const client = new Client({ intents: [] });

client.once('ready', async () => {
  const command = await client.application?.commands.set([
    {
      name: 'ping',
      description: 'ping',
    },
  ], SERVER_ID); // サーバーにコマンドを登録する
});

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isCommand()) return;
  if (interaction.commandName === 'ping') {
    const modal = new Modal().setCustomId('myModal').setTitle('My Modal'); // 1
    const favoriteColorInput = new TextInputComponent()
      .setCustomId('favoriteColorInput')
      .setLabel("What's your favorite color?")
      .setStyle('SHORT'); // 2
    const firstActionRow = new MessageActionRow<ModalActionRowComponent>().addComponents(
      favoriteColorInput,
    ); // 3
    modal.addComponents(firstActionRow); // 4
    await interaction.showModal(modal); // 5
  }
});

client.login(envObj.DISCORD_TOKEN);
```

コード説明
1.のところでmodalを表示させるための基盤となるクラスを生成。
setCustomIdはmodalを識別するためにつける任意のid、setTitleはmodal windowの上部に表示されるタイトル。

2.のところでmodalに載せるコンポーネントを生成する。今回はtextフィールドを表示させている。
setCustomIdはtextフィールドを識別するためにつける任意のid、setLabelはtextフィールドの上に表示するメッセージ、setStyleは1行か複数行かを選択できる。

3.のところで2で生成したコンポーネントを入れたMessageActionRowを生成している。

4.のところでmodalに3のコンポーネントを入れている。

5.のところでmodalを表示する。

これで実行し、スラッシュコマンドで`/ping`と打つと、modal windowが表示される。

# modalの結果を受け取る

以下のコードを追加する

```ts: index.ts
client.on('interactionCreate', async (interaction) => {
  if (!interaction.isModalSubmit()) return;
  const value = interaction.fields.getTextInputValue('favoriteColorInput');
  await interaction.reply(`Your favorite color is ${value}`);
});
```

modalの送信は、isModalSubmitで受け取れる。
今回はmodalの中に`favoriteColorInput`を設定したので、`getTextInputValue`から取得している。
また、replyは他のスラッシュコマンドやボタンなどと同じ感じで返信することができる。

# 注意点

Modal windowを表示させる場合、先に`deferReply`を使っていると表示できない(エラーが出る)。

# 終わりに

今のところ`TextInputComponent`しかなさそう？
[discord-modals](https://www.npmjs.com/package/discord-modals)にはSelectMenuを表示させることが出来そうな項目があるが、discordjs単体ではそれらしきクラスを見つけることが出来なかった。
【Xcode】"XXXXXX"をインストールできませんでした

# はじめに
![スクリーンショット 2022-07-24 18.58.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/359e04e6-07d6-a0c8-dfe4-fe0808aeb6aa.png)
```
あとでやり直してください。
```
```
Watch-only apps cannot be contained in companion apps installed on the companion.
```

SwiftUIレイアウト一本勝負をやっていたところ上のような状態になってしまってシュミレーターでビルドできなくなってしまいました。
発生条件と解決方法を記事にしておきます。

# 発生条件
① シュミレーターでApple Watchをビルド
② 起動しているApple Watchを停止する
③ iPhoneでビルド ← ここで発生

# 解決方法
「Product」を選択し、「Clean Build Folder」を押します。
![スクリーンショット 2022-07-24 19.06.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8978528a-34b7-1858-3254-593dbcbc2b10.png)

# おわり
みた事ないエラーだったのでドキッとしました