OmniAICreator/Qiita-1.07M huggingface dataset:
split()　文字列を分割　JavaScript

## 用途
文字列を分割して使いたい時に使用する。

## 使用方法
```js:書き方
var hoge = "文字列";
hoge.split(区切り文字や正規表現, 分割数);
```
文字列を任意の場所で分割することができる。分割数は省略できる。

```js:例
var hoge = "01-02-03-04-05-06";
var array_hoge = hoge.split('-', 4);

console.log(array_hoge);
// ["01","02","03","04"]
```

```js:応用
var hoge1 = "2000-01-02";
var hoge2 = hoge1.split('-')[0]; // 「-」で区切って配列に入れた後の1番目の文字列 
var hoge3 = hoge1.split('-')[1]; // 「-」で区切って配列に入れた後の2番目の文字列 
var hoge4 = hoge1.split('-')[2]; // 「-」で区切って配列に入れた後の3番目の文字列 

console.log(hoge1);
// 2000-01-01
console.log(hoge2);
// 2000
console.log(hoge3);
// 01
console.log(hoge4);
// 02
```
スプレッドシートに貼り付けたCSVを列展開

スプレッドシートに貼り付ける内容をSlackに通知してユーザに貼り付けてもらう運用をしたかった。
しかし、API経由でSlackに通知するとタブがスペースに変換されてしまう。[参考](https://qiita.com/M_Ishikawa/items/8d8db8d0c50039777f00)

ユーザそれぞれにJavaScriptを入れてもらうのは現実的ではなかったので、
通知はカンマ区切りにし、貼り付けた後にGAS実行してもらうこととした。

```
// シートが開かれたときにメニューに追加
function onOpen() {
  SpreadsheetApp.getUi()
  .createMenu('GAS実行') // メニュー項目名
  .addItem('選択範囲のカンマを右に展開', 'commaExpand') // 項目の追加
  .addToUi();
}

// 選択列の内容をカンマ区切りで右列に展開する
function commaExpand(){
  let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  let activeRange = sheet.getActiveRange();
  let paste = activeRange.getValues().map((val) =>{
    target = val
    if(Array.isArray(val)){
      target = val[0].toString()
    }
    return target.split(',')
  })
  let pasteRange = sheet.getRange(activeRange.getRow(), activeRange.getColumn(), paste.length, paste[0].length)
  pasteRange.setValues(paste)
}
```
GitHubにPersonal Access Tokenでアクセスできるようにする。


## なぜ、Personal Access Tokenなのか
GitHubのPrivate Repositoryにアクセスする方法はいくつかあります。

その中でも、今回紹介する方法は、Personal Access Tokenを利用する方法です。

公開鍵暗号方式を使った[sshでの通信はGitHub側からも非推奨](https://docs.github.com/ja/get-started/getting-started-with-git/about-remote-repositories)になり、[HTTPでのパスワードとユーザーネームを使った方法は廃止](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/)になりました。


そんな中で、非常に便利なのが、Personal Access Tokenを使った方法。
従来のHTTPSに、このトークンを載せるだけで認証が済んでしまうのだ。

この方法では、レポジトリごとにset-urlする必要もないし、二段階認証もスムーズに利用できるのでおすすめです。

## 設定方法

以下のページ通りに進め、GitHub上でTokenを入手する。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token

```
$ git config --global url.https://ユーザーネーム:入手したトークン@github.com/.insteadOf https://github.com/
```

これで、全てのHTTPリクエストをトークン経由で行えるようになるので、いちいちレポジトリごとにTokenの設定をする必要はなくなる。
laravel ULIDを発行するライブラリを使ってみた

# 概要

- PHPにてULIDを発行する事のできるライブラリであるrobinvdvleuten/php-ulidを使ってみたのでまとめる。

# ご注意

- 筆者は各検証をlaravelのtinkerを用いて行った。
- 本記事は公式githubのUsageを日本語訳してちょっとメモを付け足しただけです。

# 導入方法

1. 下記コマンドを実行してライブラリをインストールするだけ。

    ```terminal
    $ composer require robinvdvleuten/ulid
    ```

# 使用方法

- まずは下記の様にuseでライブラリのファイルを読み込む。

    ```php
    use Ulid\Ulid;
    ```

- ULIDを発行する時

    ```php
    $ulid = $Ulid::generate();
    // $ulidに発行されたULIDが格納されている
    ```

- ULIDの英文字部分を小文字で発行してほしい時

    ```php
    $ulid = $Ulid::generate(true);
    // $ulidに発行されたULIDが格納されている
    ```

- ULIDのインスタンスからタイムスタンプを抜き出したい時（タイムスタンプはUnix時間で出力される）

    ```php
    $ulid = $Ulid::generate();
    $ulid->toTimestamp();
    ```

- タイムスタンプ（Unix時間）を指定してULIDを発行してほしい時

    ```php
    $ulid = $Ulid::fromTimestamp(タイムスタンプ);
    // $ulidに発行されたULIDが格納されている
    ```

# 参考文献

- [robinvdvleuten/php-ulid](https://github.com/robinvdvleuten/php-ulid)
iPhone の safari で２回目以降の window.open できない → できた！

# したいこと

親画面から子画面のポップアップをしたい。

子画面が無ければ新規で起動し、あればそれをアクティブにする。
（つまり開く子画面は１つのみであり、無限増殖しない。）

# 困った現象

ほとんどのブラウザは以下の方法でＯＫだったはずですが・・・

親画面
```html:old1.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旧 親画面</title>
<script>

function winOpen() {
    window.open( 'old2.html', 'old2' ).focus;
}

</script>
</head>
<body>
  <div>
    旧 親画面
  </div>
  <div>
    <button onclick="winOpen();">子画面起動</button>
  </div>
</body>
</html>
```

子画面
```html:old2.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旧 子画面</title>
<script>
</script>
</head>
<body>
  <div>
    旧 子画面です
  </div>
</body>
</html>
```

でも iPhone の safari の場合、ポップアップ後、子画面をそのままにして、親画面に戻って、再度ポップアップしても、子画面がアクティブになりません。

また他のＰＣやブラウザでも、子画面をそのままにして、親画面に戻って親画面をリロード（あるいは再起動）したら、再度ポップアップしても既存の子画面がアクティブにならず、新規で子画面が起動してしまいます。

# 解決策

トリッキーな方法ですが、以下の方法で解決できると思います。

親画面
```html:new1.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新 親画面</title>
<script>

var winPopup;
window.addEventListener( 'pagehide', winClean );

function winClean() {
    window.open( 'new3.html', 'new2' );
}

function winOpen() {
    if ( winPopup ) {
    if ( ! winPopup.closed ) {
        winPopup.close();
    }
    }
    winPopup = window.open( 'new2.html', 'new2' );
}

</script>
</head>
<body>
  <div>
    新 親画面
  </div>
  <div>
    <button onclick="winOpen();">子画面起動</button>
  </div>
</body>
</html>
```

子画面
```html:new2.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新 子画面</title>
<script>
</script>
</head>
<body>
  <div>
    新 子画面です
  </div>
</body>
</html>
```

ダミー画面
```html:new3.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ダミー画面</title>
<script>

window.addEventListener( 'load', winClean );

function winClean() {
    window.close();
}

</script>
</head>
<body>
  <div>
    ダミー画面
  </div>
</body>
</html>
```

ダミー画面は、お掃除用画面です。
子画面が残らないよう強制的にクローズします。

じつは親子間でドメインが異なると、うまくポップアップできない場合があるのですが、ダミー画面はその問題を解消してくれます。
（親子が同じドメインなら、ダミー画面は要らないはず。）

これで iPhone の safari を含むすべてのブラウザで、
親画面から子画面のポップアップができるはずです。

# 参考

[2回目以降のwindow.openでの各ブラウザでのフォーカスについて](https://yksnyh-lab.cyou/window-open-focus/)
[ページのコンテンツから離れたタイミングのブラウザイベントの選び方](https://benevolent0505.hatenablog.com/entry/2020/12/01/093000)
SIGNATEのコンペを題材にPDCAを回す(2022.4.15～)

# 背景
気分転換にコンペに参加しました。開催中のコンペなので、SIGNATEに迷惑がかかる様な情報は出しません。
# 目的
今まで、コンペを計画的にやって来ませんでした。今回からちょっと真剣に自分なりのPDCAを作ろうと思います。
# 方法
自分が行った事を追記していきたいと思います。

1. ラベルエンコーディング：LightGBMの機能を使うために質的データをラベルエンコーディングしておきます。確か論文に書いてあったと思うのですが、よく覚えていません。(Guolinら(2017)、[LightGBM: A Highly Efficient Gradient Boosting
Decision Tree](https://proceedings.neurips.cc/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf)、NIPS)：前処理
1. LightGBM：モデル
1. kfold：学習方法

# 結果
以前なら、これで結構良い位置に行けたんですが、今回はそうでもなかったです。早く自分の方法を作る必要性を感じます。
# PDCA
1. これをひたすら回しながら、知見や理解を深めていきたいと思います。
1. とりあえず、「Uryu Shinya(2020.4)、[Practical Data Science with R and Python](https://uribo.github.io/practical-ds/01/eda.html)」を参考に進めていきたいと思います。
## 1.データの確認
### 1-1.EDA
「まずは簡単な集計・可視化をします。データを要約、図示することで、個々の値からは見えなかった情報やデータ間の関係を把握するのが目的です。特に欠損値や異常値（外れ値）、データの分布などデータ全体あるいはデータ間の関係性やそのばらつきを見るのに可視化は重要です。」([Practical Data Science with R and Python](https://uribo.github.io/practical-ds/01/eda.html))

「モデリングでは、目的変数の挙動（予測、分類）を明らかにすることがゴールとして設定されます。変数が多いデータであるほど確認する図の数が多くなり、効率的ではなくなります。そのため、まずはモデリングの目的変数となるデータを詳しく見ることを勧めます。また、この段階で作る図は初期モデルを構築する前段階で示唆を提供するものであると望ましいです。そこで目的変数に影響する説明変数、説明変数間の関係を明らかにすることで、次のモデリングプロセスに活かせる知識を得られることが期待できます。」([Practical Data Science with R and Python](https://uribo.github.io/practical-ds/01/eda.html))


## 2.前処理
## 3.学習
### 3-1.モデルの検討
### 3-2.評価関数の検討
## 4.予測
# 課題
1. Optuna：時間がかかるうえにそこまでスコアも良くならないのは経験的に知っているので後回しにします。パラメータ設定を考える際に検討しようと思います。
1. 「[Kaggleで勝つ](https://www.amazon.co.jp/dp/B07YTDBC3Z/ref=cm_sw_r_tw_dp_HSWQFS7F3GE7J24ZCN1M)」のメソッドを全部試したいところです。
# 参考
1. Uryu Shinya(2020.4)、[Practical Data Science with R and Python](https://uribo.github.io/practical-ds/01/eda.html)
RAID構成を実際構築してみた

# まずはじめに

現在、linuxの勉強（LPIC2レベル相当）の学習を進めていく中、
ストレージ領域の範囲があったので、前にvatualboxで構築したLinux環境ですぐ実践できそうだったので、実際に手を動かしやってみました！

今回はその際の手順をメモベースにまとめているので、
詳しく参照したい人は下記URLを確認してみてください。

参考URL
https://www.serotoninpower.club/archives/124/#%E8%A6%81%E4%BB%B6


## 手順その１　仮想ディスクの作成

まず、バーチャルボックス内で仮想ディスを作成していきます。
GUI操作で設定よりストレージを追加。
（IDEとSATAあるが今回SATAを使用）

RAID５構成にするため３本分作成。
→それぞれsdb~sddで認識。
※sdaはすでにOSインストールで使用

## 手順その２　認識を確認

次に作成した仮想ディスクがきちんとOSから認識されているのか確認。

     #ls -l /dev | grep sd  #sdと名がつくデバイス一覧を表示


     #df -T  #dfコマンドでディスク使用量を表示。同時にオプションでファイルシステムも表示

あとはlv,vgdisplayコマンドで現在使用されているボリュームグループをそれぞれ確認。

→ **ここでは現状の論理ボリュームを確認することで新しく作成したsdb~が今作ったものであるものであると確認できる**
※現状使用されているのは/dev/sda1 sda2
・/dev/sda2全体がlvとして認識されている


## 手順その３　パーテションを作成

fdiskコマンドを使用し、パーティションを作成
参考：https://atmarkit.itmedia.co.jp/ait/articles/1803/01/news034.html


※パーテションタイプはfdで作成 （１６進数で254）

## 手順その4 RAID構成を作成

mdadmコマンドを使って、RAIDアレイを作成。
こんな感じ

        #mdadm -C /dev/md0 --level 5 --raid-devices3 /dev/sdb1 /dev/sdc1 /dev/sdd1　

※-Cでクリエイトモード（作成モード）に入り、
今回は、/dev/md0という名前で　RAID５を作成。
その後にRAIDに組み込むデバイスを指定。

##  忘れずに、、

最後は普通のハードディスク同様忘れずに、

**ファイルシステムを作成→マウント**


今回は以上です。
Livewire不要　Laravelページネーション後の自動スクロール

# [<font color="#333">何をしたいか</font>](#-2.はじめに)
ページネーション後にリロードされて一番上に行くのではなく
ページネーション後はある要素まで自動でスクロールしたい時があります。
amazonのレビューみたいな感じで。

LaravelであればLivewireを使用してページネーションを作成すれば良いですが
Laravelのバージョンが古いと使えないのかな？

まぁ、jQueryでサクッと実装できるのでコピペして使ってください。
なので別にLaravelとか関係ないです。


```Scroll.js
$(function(){

  //URLパラメータ取得
  function getParam(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}
//上記記述で例えば　https://hoge.com?page=2　と言うURLならgetParam('page')で「2」が取得できる

//もしページネーション中なら指定したidの要素までスクロール
if(getParam('page')){
  var target = $('#js-review').offset().top;
  $('html,body').animate({scrollTop: target}, 'slow');
//スクロールスピードはご自由に！！
}


});

```
ベリーイージー(^^♪
CentOS django

vi CentOSLAMP.sh

```

#インストール
sudo yum remove php*
sudo yum remove mariadb-libs
sudo rm -rf /var/lib/mysql

#phpをExtraでインストール
sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum install epel-release
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum -y install --enablerepo=remi,remi-php74 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql

#python3をインストール
sudo yum groupinstall -y "Development Tools"
sudo yum install -y kernel-devel kernel-headers bzip2-devel libdb-devel libffi-devel
sudo yum install -y gdbm-devel xz-devel ncurses-devel readline-devel tk-devel uuid-devel　openssl-devel

#Python3に必要なモジュールをインストール（ついでにgitも）
sudo yum install -y gcc gcc-c++ git
sudo yum install -y python3 python3-pip python3-setuptools python3-wheel python3-devel httpd-devel

#Djangoとmod_wsgiのインストール。
sudo pip3 install -y django mod_wsgi

#インストール確認djangoとmod_wsgiが表示されればインストール成功
sudo yum install -y python3 python3-devel
pip3 install mod_wsgi



#javaJDK1.8.0をインストール
sudo yum install -y java-1.8.0-openjdk-devel.x86_64

#MySQL8のインストール
sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

#mysql-develをインストール（mysqlclientに必要）
sudo yum install -y mysql-devel
sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
sudo yum install mysql-community-server -y
sudo pip3 install mysqlclient
sudo systemctl enable --now mysqld
sudo systemctl status mysqld
 
#mysql起動設定
sudo systemctl start mysqld.service
sudo systemctl stop mysqld.service
sudo systemctl restart mysqld.service
sudo systemctl enable mysqld.service

#apacheインストールから設定
sudo yum -y install httpd
sudo systemctl start httpd

#redisインストール
sudo yum install -y redis
sudo systemctl start redis
pip3 install django-redis

#redisとapacheの確認
sudo systemctl stop redis
sudo systemctl restart redis
sudo systemctl restart httpd
sudo systemctl enable httpd
sudo systemctl is-enabled httpd
sudo systemctl enable redis
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload

```
sudo chmod u+x CentOSLAMP.sh
sudo ./CentOSLAMP.sh
HTTP Referrer-Policy ヘッダー概要


## Refererヘッダーとは

* アクセス元情報を渡すためのHTTPヘッダー
* Webブラウザなどにより自動でRequestヘッダーとして送信元のURL情報を付与される



## Referrer-policyヘッダーとは

* Refererヘッダーで送られる情報をリクエストにどれだけ含めるかを制御するHTTPヘッダー

### Refererヘッダーによる重要情報漏洩への対応

* 遷移元アクセス時のURLに重要情報(パスワードなどユーザー認証情報)が含まれていた場合、その情報が遷移先のサイトに送られてしまう。

  * 例

    ```http
    Referer: https://example.com/auth?emailaddress=test@mail.com&password=Passw0rd
    ```

* Refererヘッダーに指定される情報をReferrer-policyヘッダーによって制御することで、重要情報の漏洩を防止する。

## 構文

```http
Referrer-Policy: {ディレクティブ}
```



## ディレクティブ

| ディレクティブ                  | 説明                                                         |
| ------------------------------- | ------------------------------------------------------------ |
| no-referrer                     | リクエストにはリファラー情報を含めない。                     |
| no-referrer-when-downgrade      | プロトコルのセキュリティ水準が同一、もしくは向上する場合 (HTTP→HTTP, HTTP→HTTPS, HTTPS→HTTPS) に、オリジン、パス、クエリ文字列が Refererヘッダーで送信される。 |
| origin                          | オリジンのみが Referer ヘッダーで送信される。<br/>例： https://example.com/page.html の場合 https://example.com/ |
| origin-when-cross-origin        | 同一のプロトコル水準 (HTTP→HTTP, HTTPS→HTTPS) で同一オリジンのリクエストを行う場合、オリジン、パス、クエリ文字列を送信する。<br />オリジン間リクエストや安全性の低下する移動先 (HTTPS→HTTP) ではオリジンのみを送信する。 |
| same-origin                     | 同一オリジンのリクエストではオリジン、パス、クエリ文字列を送信する。<br />オリジン間リクエストでは Referer ヘッダーを送信しない。 |
| strict-origin                   | プロトコルのセキュリティ水準が同じである場合 (HTTPS→HTTPS) にのみオリジンを送信する。<br />安全性の低下する移動先 (HTTPS→HTTP) には Referer ヘッダーを送信しない。 |
| strict-origin-when-cross-origin | 同一オリジンのリクエストを行う際はオリジン、パス、クエリ文字列を送信する。<br />オリジン間リクエストでは、プロトコルのセキュリティ水準が同じである場合 (HTTPS→HTTPS) にのみオリジンを送信する。<br />安全性の低下する遷移先 (HTTPS→HTTP) には Referer ヘッダーを送信しない。 |
| unsafe-url                      | リクエストに依らず、オリジン、パス、クエリ文字列を送信する。 |



## 参考情報

* [Referrer-Policy](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referrer-Policy)
ポートフォワーディングとは

とあるポートにやってきたデータを別のところに転送すること
入り口と出口の設定
ポートには番号が決まっているポート（Webは20、メールは25）と決まっていないポートがある。

## Dockerでの使用例
コンテナに対しブラウザでアクセスするためには外界と接続設定が必要。
そのためにポートを設定する。
たとえばApacheは、サーバの決められたポート（80）でサイトの閲覧者がアクセスしてくるのを待ち構えている。
要求にしたがってWebサイトのページを渡すのだが、コンテナの中のApacheはいくら待機していても直接外とつながっていないため、閲覧者がたどり着けない。
そこで、代わりに母体となる物理的なマシンに閲覧者からの要求を受けてもらって、それをつたえてもらう
母体（ホスト）のポート8080とコンテナのポート80をつなぐ例
`-p 8080:80`


# 参考記事
https://wa3.i-3-i.info/word12664.html

# 参考図書
https://www.amazon.co.jp/dp/B08T961HKP/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
AWSでディープラーニングを実践しようとしたら、CPUの上限に引っかかった話

## AWSでディープラーニングを実践しようとしたら、CPUの上限に引っかかった話
こんにちは、「AWSで始めるクラウド開発入門」という教材を使用しAWSを勉強しています。
現在5章を学習中で、用意されたdocker imageに移動し、さてg4dn.xlargeインスタンスを建てようと思った矢先、エラーがでてしまったので今回はそれについて話していきます。
## g4dn.xlargeインスタンスとは
結論から言うと、<b>GPUを搭載したインスタンスタイプ</b>のことを指します。
webアプリケーションのデプロイなどではt2.microインスタンスなどが用いられます。
これらは、CPUのみのインスタンスとなります。

このg4dn.xlargeインスタンスを使用する際の一例として<b>ディープラーニングなどの解析</b>が挙げられます。
GPUは設計上、行列の計算などの単純かつ規則的な計算を得意とします。この性質はディープラーニングと相性が良く、CPUのみの演算よりも遥かに高い処理速度を発揮します。

## 学習の流れ
4章と同じ流れで
- venvを作成し、依存ライブラリのインストールを行う
- SSH鍵を生成
- デプロイを実行
という流れで進んでいきました。

## デプロイ中にエラーがでた。
デプロイ中に以下のエラーが発生しました。
```
You have requested more vCPU capacity than your current vCPU limit of 0 allows for the instance bucket that the specifi
ed instance type belongs to. Please visit http://aws.amazon.com/contact-us/ec2-request to request an adjustment to this
limit. (Service: AmazonEC2; Status Code: 400; Error Code: VcpuLimitExceeded; Request ID: ここにidが入ります。
; Proxy: null)
```
調べてみると、vCPUの利用上限を超過していることから起きている模様、、
エラーにかかれているURLから利用上限の引き上げの申請を行いました。

今回は".large"のインスタンスを使用したいことからvCPUの申請する数を4としました。
【vmstat】linuxサーバのメモリやCPU等の状況をグラフ化するツールを作った

## 作ったもの
以下リンクです。vmstat visualizerと名付けました。

https://vmstat-visualizer.netlify.app/jp

vmstatコマンドの出力結果をインプットに下記のようにシステム（CPU、メモリ、プロセス、IO、システム、スワップ）の状況をグラフ化します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2289954/19011cf4-095e-5a30-be6f-df9267b2c30c.png)

## 作った背景
オンプレのデータベースサーバを構築したときに、性能テスト時のリソース状況見るためにvmstatコマンドで取得したログをExcelでグラフ化していました。
世の中のエンジニアでそんなことをしている方意外といるのではないかな・・・と思い、作ってみました。

よければ使ってみてください。
OpenAPI(Swagger 3.0) ReDocのResponse Samplesに多次元配列を反映させる方法

## 環境
- OpenAPI(YAML形式) 3.0.2
- ReDoc 2.0.0

## 発生している問題
### 以下のJSONを表現したい
```json
{
  "languages": [
    {
      "id": 1,
      "name": "PHP"
    },
    {
      "id": 2,
      "name": "Javascript"
    }
  ],
  "countries": [
    {
      "id": 1,
      "name": "JP"
    },
    {
      "id": 2,
      "name": "US"
    }
  ]
}
```
### Preview上では適切に表現できているYAML
```yaml
# schema以下から記述
type: object
properties:
  languages:
    type: array
    items:
      oneOf:
        - type: object
          properties:
            id:
              type: integer
              example: 1
            name:
              type: string
              example: "PHP"
        - type: object
          properties:
            id:
              type: integer
              example: 2
            name:
              type: string
              example: "Javascript"
  countries:
    type: array
    items:
      oneOf:
        - type: object
          properties:
            id:
              type: integer
              example: 1
            name:
              type: string
              example: "JP"
        - type: object
          properties:
            id:
              type: integer
              example: 2
            name:
              type: string
              example: "US"

```
## 解決方法
### 表現できているJSON(上記JSONと同じ)
```json
{
  "languages": [
    {
      "id": 1,
      "name": "PHP"
    },
    {
      "id": 2,
      "name": "Javascript"
    }
  ],
  "countries": [
    {
      "id": 1,
      "name": "JP"
    },
    {
      "id": 2,
      "name": "US"
    }
  ]
}
```
### YAML
```yaml
# 省略 
content:
  application/json:
    schema:
      # 上記YAMLのexampleだけを削除したもの
    example:
      {
        "languages": [
          {
            "id": 1,
            "name": "PHP"
          },
          {
            "id": 2,
            "name": "Javascript"
          }
        ],
       "countries": [
         {
           "id": 1,
           "name": "JP"
         },
         {
           "id": 2,
           "name": "US"
         }
       ]
     }
```
:::note
結局JSONで記述するんかい！という感じですが、Swagger Viewerを使っている方なら**このJSONの記述は簡単に行うことができます**。
以下に補遺としてその手順を記載します。
:::
## 補遺:exampleへのJSON記述
1. まずは記述例2のように素直に記述します
1. 次にSwagger Viewerで**ブラウザで**開きます(デフォルトはVSCode内で開く設定になっています。setting->検索窓にswagger->Swagger Viewer: Preview In Browserの項目にチェックを入れましょう)
1. PreviewにはJSON形式で表示されるので、それをコピーします
1. それをexampleに貼りつけ、schemaからexampleの値を削除すれば完了です！
工程にもよりますが、上記の手順で行えば表示を確認・共有しながら作業を進めていくことができるので、私は以上のフローを採用しています。

## 最後に
補足意見や訂正等ございましたらコメントいただけるとありがたいです。
git checkout時にファーストコミット自動化

## ターゲット層
ブランチを切った時間を計測したい人。

## 記事を書く理由
会社の進め方がFour Keysになったからです。Four keysではleadtimeを計測するものがあり、それを計測するためにブランチを切った時間を測る必要がありました。切った時間を取得したかったのですが、切った時間はgitに残らないっぽいです。なので自分でcheckout -bした直後にcommitする必要がありました。それが面倒でかつ、何回か忘れてしまったので自動化しようと思いました。

今進めているFour Keysの詳細はこちら↓

https://cloud.google.com/blog/ja/products/gcp/using-the-four-keys-to-measure-your-devops-performance

## 手順
1. gitconfigにaliasを追加
1. ターミナルを開き直す
1. bcheckoutの実行

## gitconfigにaliasを追加
~/.gitconfigにaliasを追加
```sh:.gitconfig
[alias]
  bcheckout = "!f () { git checkout -b $1 $2; today=`date '+%Y-%m-%d %H:%M:%S'`; comment=\"ファーストコミット:${today}\"; git commit --allow-empty -m \"${comment}\";};f"

# => ファーストコミット:2022-04-14 21:57:09 
```
gitの入力補完を使いたいため、gitconfigで実装しています。

## ターミナルを開き直す
変更したgitconfigを読み込むためにターミナルを開き直します。

## bcheckoutの実行
```
git bcheckout [作成するブランチ名（省略可）] [参照ブランチ名（省略可）]
```
コマンドの実行例
```bash
$ git bcheckout test2
Switched to a new branch 'test2'
[test2 0b6fbe0e] ファーストコミット:2022-04-18 18:59:04
```

## 気づいたこと
- スペースに注意する
```sh
bcheckout = "!f () { git checkout -b $1 $2; today=`date '+%Y-%m-%d %H:%M:%S'`; comment="ファーストコミット:${today}"; git commit --allow-empty -m "${comment}";};f"
```
ダブルクォーテーションにをエスケープしていなかったのでコマンドが正しく解釈されていなかった。

- 最近作ったばっかなので、bcheckoutを打つのを忘れてしまう

git入力補完などの便利設定
https://qiita.com/mikan3rd/items/d41a8ca26523f950ea9d
Dockerのマルチステージビルドとは【個人的なお勉強アウトプット】

## 引用記事
https://qiita.com/polarbear08/items/e6855fc8caea1b03d54f

Dockerイメージの一部を別のイメージで使用する手法のこと。
例えば、ビルドのときは必要だけど実行のときはいらないものを捨てることでイメージのサイズダウンができる。
つまり、マルチステージビルドは実行環境だけあればいいコンテナのイメージをつくる際に威力を発揮する。
CI/CD用のコンテナはビルドの成果物さえあれば良く、むしろビルドの時のみに必要なファイルたちは無駄にコンテナサイズをふくらませる原因となってしまう。
javaScriptからimgタグの情報を取得しようとしたけど[null]だった話

# ことのはじめ

https://qiita.com/hideya670/items/57395a4edde5923c5c9f

以前にゲームの設計をしてそもそも`javaScript`から`html`の`img`をいじれるのかと疑問におもって実験した｡

## 起きたエラー
以下の文で`img`タグをいじろうとした
```javascript:test.js
let img = document.getElementById("humanCard1");
img.src = "./img/c01.png";
```
しかし､帰ってきた答えは
```
null
```
nullなので､`src`プロパティをいじろうとしてもそもそも見つからないからいじれない

## どう解決したか
`test.js`を読み込むタイミングが早かったのが原因
```html:修正前
<head>
  <script src="test.js"></script>
</head>
<body>
  <img src="" alt="" id="humanCard1">
</body>
```
プログラムは上から順に読まれるので
![名称未設定ファイル.drawio (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421721/c11bcb2f-1fba-a59c-09e1-a27b94c8067e.png)

`img`タグを読み込む前に`test.js`を読み込でしまった｡
なので`test.js`は一番最後に読み込むことにした
```html:修正前
<head>
</head>
<body>
  <img src="" alt="" id="humanCard1">
  <script src="test.js"></script>
</body>
```
### 編集後記
とても基礎的な部分でエラーを起こしてしまった｡

##### 参考にしたサイト
[【プログラミング】getElementByIdがnullになるときの対処法【javaScript】]("https://retroid2016.com/2018/06/01/%E3%80%90%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%91getelementbyid%E3%81%8Cnull%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%AF%BE%E5%87%A6%E6%B3%95%E3%80%90ja/")
[【JavaScript】getElementByIdでnullが返ってきたときに確認すること](https://qiita.com/kikuchiTakuya/items/c56c4b25e8b4d005dd8a)
C＃使用してPDFに画像の背景を追加する方法

本日はPDFに関する機能を紹介していだたきたいと思います。PDFは、近年最も人気のあるファイルの1つであり、オフィスでも日常生活でもよく使われています。PDFファイルの背景色は白であることが多く、読みすぎると疲れを感じることも珍しくありません。したがって、その背景を自分の好みに変更して、ファイルの見た目がより美しくするだけでなく、人々も自分の目を健康的に使うことになります。では、次はC＃を使用してPDFファイルに画像の背景を追加する方法について話しましょう。

これは例として使用するファイルのスクリーンショットです。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/d789a978-cea9-739e-997a-4b8b0017731c.png)

## コードを使用する

**ステップ1**　Visual C＃コンソールプロジェクトを作成し、参照を追加して名前空間を使用します。
```
using System.Drawing;
using Spire.Pdf;
```
**ステップ2**　PDFドキュメントオブジェクトを作成し、ソースPDFファイルをロードします。
```
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf");
```
**ステップ3**　PDFファイルの最初のページを取得します。
```
PdfPageBase page = doc.Pages[0];
```
**Zステップ4**　画像を読み込み、ページの背景として設定します。
```
Image backgroundImage = Image.FromFile("C:\\Users\\Administrator\\Desktop\\background.jpg");
page.BackgroundImage = backgroundImage;
```
**ステップ5**　ファイルを保存して再度開きます。
```
doc.SaveToFile("result.pdf");
System.Diagnostics.Process.Start("result.pdf");
```
背景の画像を追加した結果
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/da7989c6-8ef4-6be8-cbf5-d9551ce8b7dd.png)


## 完全なるコード一覧
```
using System.Drawing;
using Spire.Pdf;

namespace Add_image_background_to_PDF
{
    class Program
    {
        static void Main(string[] args)
        {
            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf");
            PdfPageBase page = doc.Pages[0];
            Image backgroundImage = Image.FromFile("C:\\Users\\Administrator\\Desktop\\background.jpg");
            page.BackgroundImage = backgroundImage;
            doc.SaveToFile("result.pdf");
            System.Diagnostics.Process.Start("result.pdf");
        }
    }
}
```
## 結語

PDFはMicrosoftのOfficeソフトウェアではありませんが、多くの利点があるため広く使用されています。 WordやExcelなどのファイルに比べて、PDF自体は編集しにくく、他のコンポーネントを使う必要があります。この例では、E-iceblue社の無料のPDFコンポーネント[Spire.PDF for .NET](https://www.e-iceblue.com/Download/download-pdf-for-net-free.html)を使用しました。日常では色んな要求も満たすことができるし、とても便利です。ではまた！
iconvを使って、文字コードを変換する

## 環境

Ubuntu 20.4

## やったこと

S-JISで作成したtest.txtを、Ubuntuで表示すると、このように文字化けを起こします。
```
$cat test.txt
◆◆◆◆◆
◆◆◆◆◆
◆◆◆◆◆
```

Ubuntuで文字コードを変換するには、**iconv**を使います。iconvで扱える文字コードの一覧を表示してみます。
```
$iconv -l
```

沢山の文字コードが扱えるようになっているが、今回は、S-JISとUTF-8が使えればOKです。
```
$iconv -l | grep -e UTF-8 -e SJIS
```

S-JISのファイルを、UTF-8に変換して表示してみます。オプション**f**で、読み込みファイルの文字コードを指定し、オプション**t**で、出力する文字コードを指定します。
```
$iconv -f sjis -t utf8 test.txt
あああ
いいい
ううう
```

出力する文字コードはデフォルトで、UTF-8になっているため、**-t utf8**は省略して、このように記述してもOKです。
```
$iconv -f sjis test.txt
あああ
いいい
ううう

```

ファイルの文字コードを調べたい場合は、**nkf**コマンドを利用します（この手のコマンドは、恐らく、nkfくらいしかなさそうです）。iconvは文字コードを変換することはできるが、現在のファイルの文字コードを確認することはできないようです。
nkfはUbuntuにはデフォルトで入っていないため、インストールすることになります。なお、nkfは、iconvのように、文字コードを変換する機能も持っています。

nkfをインストールします。
```
$sudo apt-get update
$sudo apt-get install nkf
```

インストールされたことを確認します。（因みに、nkfは富士通が開発しています。）
```
$nkf -v
```

nkfで文字コードを調べる場合は、このようにします。
```
$nkf --guess test.txt
$nkf -g test.txt
Shift-JIS(CRLF)
```

iconvでS-JISをUTF-8に変換して、別ファイルに保存します。
```
$iconv -f sjis -t utf8 test.txt > test_utf8.txt
```

UTF-8に変換されたことが確認できました。
```
$nkf --guess test_utf8.txt
UTF-8(CRLT)
```

文字化けせずに表示されるようになりました。
```
$cat test_utf8.txt
あああ
いいい
ううう
```

UTF-8をS-JISに変換して表示してみると、当然、文字化けを起こします。
```
$iconv -f utf8 -t sjis test_utf8.txt
◆◆◆◆
◆◆◆◆
◆◆◆◆
```

次は、UTF-8からS-JISに戻してみましょう。
```
$iconv -f utf8 -t sjis test_utf8.txt > test_sjis.txt
```

S-JISになりました。
```
$nkf --guess test_sjis.txt
Shift_JIS (CRLF)
```

UTF-8のファイルを、S-JISとして読み込んでみるとどうなるかやってみます。当然、エラーになりました。
```
$iconv -f sjis -t utf8 test_utf8.txt
iconv: illegal input sequence at position 8
```

## 補足

nkfを使って、test.txtの文字コードを調べるには、このような標準的な書き方をする以外に、
```
$nkf --geuss test.txt
```

catでファイルを開いて、パイプを使ってnkfに標準入力を渡すといった使い方もできます。
```
$cat test.txt | nkf --guess
```
ブラックジャックのなんちゃって設計(js) part1 超大まかにプロパティとメソッドをまとめた

# はじめに
プログラミングの練習としてとりあえず作ってみる
**素人が曖昧な知識で作成しています**
jsの練習のためjsで書きます

# カードクラス
### プロパティ
* 値(j,q,kは10点となる)
* 画像

# デッキクラス
トランプのカードをまとめたもの
### プロパティ
* カード一枚一枚
* すべてのカードを入れたリスト
* カウンター 
### メソッド
* デッキを混ぜる(リストの並びをぐちゃぐちゃにする)
* カード取り出す
* カウンターを1増やす

# プレイヤー
### プロパティ
* 自分が持っているカード(リスト)
* 自分のカードの合計値
* 手札の中にAがあったときの合計値
* フラグ
    * ブラックジャック達成
    * 手札の中にAがあるかどうか
    * 手札の中に10点札があるかどうか
    * 自分のカードの合計が22以上かどうか

### メソッド
* カードをもらう
* カードの合計を計算する
* 手札の中にAがあったときの合計値を計算
* 自分のカードの合計が22以上か調べる
* 自分のカードがブラックジャックを達成しているか
* 自分の手札に10点札があるか
* 自分の手札にAがあるか(1点,10点と2つの扱いがあるため)
* 各フラグのゲッター
* 自分のカードのゲッター

# コンピューター (プレイヤーを継承)
### メソッド
* 自分のカードが18以下か調べる
* 手札に[A]がある時の自分のカードが18以下か調べる

# 出力用のクラス
### プロパティ
* 人間の手札画像の場所を記録した変数
    * 手札1
    * 手札2
    * 手札3
    * 手札4
    * 手札5
    * 手札6
    * 手札7
    * 手札8
* 手札の変数をまとめたリスト
* コンピューターの手札画像の場所を記録した変数
    * 手札1
    * 手札2
    * 手札3
    * 手札4
    * 手札5
    * 手札6
    * 手札7
    * 手札8
* 手札の変数をまとめたリスト
* 人間の合計値を表示する場所を保存した変数
* 人間の手札に関する情報を表示する場所を保存した変数
* コンピューターの合計値を表示する場所を保存した変数
* コンピューターの手札に関する情報を表示する場所を保存した変数
* 勝負結果を表示する場所を保存した変数
### メソッド
* 人間の合計値を表示
* 人間の手札を表示
* 人間の手札に関する情報を表示
* コンピューターの合計値を表示
* コンピューターの手札を表示
* コンピューターの手札に関する情報
* 結果を表示


# メイン
### プロパティ
* デッキオブジェクト
* コンピューターオブジェクト
* プレイヤーオブジェクト(人間)
* 出力オブジェクト
* ボタン類
    * カードをもらう
    * 勝負に進む
    * やり直す
### メソッド
* 一番最初にやることをまとめたメソッド
* プレイヤーにカートを渡す
* 人間のターンの時の処理をまとめたメソッド
* コンピューターのターンの時の処理をまとめたメソッド
* 勝敗を決める
* コンピューターの表示類を変える
* 人間の表示類を変える
* ボタンを押したらカードをもらう
* 勝負に進むボタンを押したらコンピューターのターンにうつる
* リセットボタンを押したら再スタート
【備忘録】マウントしました

## やろうとしたこと
・WebAPサーバの資材をNFSサーバに格納（EC2をそれぞれ1台）
・WebAPサーバからマウントして表示させること

## 参考にしたページ
https://hara-chan.com/it/infrastructure/how-to-mount-server/
https://hara-chan.com/it/infrastructure/fstab/
https://linuc.org/study/knowledge/505/

## 手順
前提：/etc/hosts でNFSサーバ、WebAPサーバを登録済み
1. AWSセキュリティグループの確認
1. NFSサーバの/etc/exports 編集
1. WebAPサーバの/etc/fstab 編集

#### AWSセキュリティグループ
インバウンドルールで「タイプ」NFSが入っていることを確認する
※直接追加でなくとも含まれて入ればOK

#### NFSサーバの/etc/exports 編集
NFSサーバ
```bash
# systemctl enable nfs
# systemctl start nfs
# vi /etc/exports
      /public WebAP(rw)	
```
この時点でマウント自体は可能になっているはず
WebAPサーバ
```bash
# mount -t nfs NFS:/public /media
```

#### WebAPサーバの/etc/fstab 編集
今後はサーバ起動時にマウントできるようにする目的
```bash
# vi /etc/fstab
      NFS:/public /media nfs rw 0 0
# mount -a
```


#### ここまでやったらサーバ再起動させた時にマウントできているはず
名古屋市内外のポスティング費用の相場

名古屋市内外のポスティング費用の相場イベントや親規オープンなどで、広告の一つとして挙げられるのが、「ポスティング」です。古くからある広告手法の一つですが、東海配布に任せていただければ、より効率的な集客が可能です。チラシの配布を行う場合、多くはポスティング業者に依頼をすることになると思いますが、相場がいくらなのかがやっぱり一番気になりますよね。まずポスティング価格の算出方法ですが、多くの業者が「１枚いくら」という単価計算をしています。例えば「１枚５円から」といった感じです。ポスティングの単価を決める要因は「配布方法」「地域」「枚数」「配布期間」によって決まります。まず配布方法には「単配」「併配」の二種類があります。単配とは１枚のチラシのみを配ることです。併配とは、他社のチラシと一緒に配布することです。配布方法の性質上、単配の方が併配より単価は高くなります。地域に関しては名古屋市内又は市外の違いになります。単配の場合名古屋：市内３円～７円市外県外：５円～９円併配の場合市内：１円～３円　市外２円～５円になります。名古屋市内では中村区中区など都心部に近ければ近いほど価格は下がります。理由はポストの数が多いので１日で配布できる枚数が多いからです。名古屋市外で一日で配ることの出来る枚数は８００～１０００枚です。１日で単配で配る時間を７時間として１日当たりの価格は６０００円～８０００円になります。チラシを配るペースはどこの業者も変わりません。ポスティングにかかる人件費も考えると、おおよその相場だと思われます。業者によってはこれより安い価格を提示している場合もありますが、極端に安い見積もりを打ち出す業者は雇用体制、配布体制などに問題を抱えている可能性があるので気をつけましょう。

名古屋のポスティングは東海配布
OpenAPI(Swagger3.0) ネストされたSchemaの表現

## 本記事の構成
[表現したいJSON]
[具体的なYAML形式の記述]

## 本記事で扱わないこと
- OpenAPIやSwaggerの歴史
- 基本的な構文やオブジェクトの解説

## 環境
- OpenAPI 3.0.2(YAML形式)
- Visual Studio Code
- Swagger Viewer

## 記述例1 type:object 
### 第2階層まで
#### JSON
```json
{
  "user": {
    "id": 1,
    "name": "hoge"
  },
  "token": "10|j1uEhWklM8IQlWcxFOeqag78gsHTQOAA0v3mK"
}
```
#### YAML
```yaml
type: object
properties:
  user:
    type: object
    properties:
      id:
        type: integer
        example: 1
      name:
        type: string
        example: "hoge"
  token:
    type: string
    example: "10|j1uEhWklM8IQlWcxFOeqag78gsHTQOAA0v3mK"
```
### 第3階層まで
#### JSON
```json
{
  "user": {
    "id": 1,
    "username": "hoge",
    "pets": {
      "dog": "ぽち"
      "cat": "たま"
    }
  },
  "token": "10|j1uEhWklM8IQlWcxFOeqag78gsHTQOAA0v3mK"
}
```
#### YAML
```yaml
type: object
properties:
  user:
    type: object
    properties:
      id:
        type: integer
        example: 1
      username:
        type: string
        example: "hoge"
      pets:
        type: object
        properties:
          dog:
            type: string
            example: "ぽち"
          cat:
            type: string
            example: "たま"
  token:
    type: string
    example: "10|j1uEhWklM8IQlWcxFOeqag78gsHTQOAA0v3mK"
```
さらに階層が深くなっていっても上記例より、`type:object`を重ねていけば良いことがわかりますね
## 記述例2 type:array
### Array of Object
#### JSON
```json
{
  "languages": [
    {
      "id": 1,
      "name": "PHP"
    },
    {
      "id": 2,
      "name": "Javascript"
    }
  ],
  "countries": [
    {
      "id": 1,
      "name": "JP"
    },
    {
      "id": 2,
      "name": "US"
    }
  ]
}
```
#### YAML
```yaml
type: object
properties:
  languages:
    type: array
    items:
      oneOf:
        - type: object
          properties:
            id:
              type: integer
              example: 1
            name:
              type: string
              example: "PHP"
        - type: object
          properties:
            id:
              type: integer
              example: 2
            name:
              type: string
              example: "Javascript"
  countries:
    type: array
    items:
      oneOf:
        - type: object
          properties:
            id:
              type: integer
              example: 1
            name:
              type: string
              example: "JP"
        - type: object
          properties:
            id:
              type: integer
              example: 2
            name:
              type: string
              example: "US"
```
:::note alert
2022/4/15現在この記法では、Swagger Viewerでは正常に表示されますが、**ReDocを用いたHTMLではうまく表示されません**(Response Samplesに配列番号0のものしか表示されません)。
この問題を回避する方法は**schemaと同じ階層にexampleを記述する**ことです。
具体的な記述は[こちらの記事](https://qiita.com/akitika/items/4213398cf5aab8ed6ab5)を参考にしてください。
:::

## 最後に
補足意見や訂正等ございましたらコメントいただけるとありがたいです。
webstormで注意したこと


# npmのバージョンがずれないようにする
![Screenshot 2022-04-15 15.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/594e972e-2829-540d-f25e-19a6118c249b.png)

# .ideaがgithubに送られないようにする

```
## キャッシュを削除

$ git rm --cached -r .idea
```

```
GitHubに反映させる

$ git add --all
$ git commit -m "reflect the setting of .gitignore"
$ git push
```

参考: https://laraweb.net/environment/7362/

# 空白表示
設定/エディター/一般/外観 => 空白を表示をチェック

# eslint prettier

https://pleiades.io/help/webstorm/eslint.html#ws_js_eslint_activate

# npmをタブに表示

ファイルを右クリックして
npmを表示

![Screenshot 2023-06-19 19.07.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/c3aa8b73-a8b3-b9e3-52ca-538e32c618f5.png)

# stylelintrc
![Screenshot 2023-06-19 21.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/89572ed6-68c8-2309-31c1-48d4c3039429.png)
openapi-generator-cliを使ってみた 体験時のメモ

# 概要

- openapi-generator-cliを使ってみた時の体験メモをまとめる。
- 筆者はDockerコンテナを使って試してみた。
- openapi.yamlをもとにphp-laravelのコードを出力してもらう。

# 準備

- 下記のようなyamlファイルを用意した。（/messageにアクセスしたらHello World !を返すだけ。）

    ```openapi.yaml
    openapi: "3.0.3"
    
    info:
      title: "Sample API"
      version: "1.0.0"
    
    paths: 
      "/message":
        get:
          summary: "Sample API get operation"
          description : "Sample API get operation"
          responses:
            "200": 
              description: "Success operation"
              content:
                application/json:
                  schema:
                    type: string
                    example: "Hello World !"
    ```

# 体験方法

1. 任意のディレクトリに移動する。
1. 当該のディレクトリに先に用意したopenapi.ymlファイルをコピーして持ってくる。
1. 下記コマンドを実行してyamlファイルからphp-laravelのコードを出力する。

    ```terminal
    $ docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
        -i /local/openapi.yaml \
        -g php-laravel \
        -o /local/out/php-laravel
    ```

1. 出力が完了すると当該のディレクトリ直下の`/out/php-laravel`にコードが出力される。
Nuxt.jsでTwitterカードが表示できないときのワークアラウンド

# 事象
こちらで紹介されている事象の解決策
https://kakkiii-blog.dev/posts/510/
head内のstyleがmetaタグより上にある。

# 解決策
https://nuxtjs.org/ja/docs/concepts/views/#%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88-apphtml
app.htmlに直接metaタグを書くととりあえず解決できる。

```
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    <meta property="og:title" content="{title}">
    <meta property="og:image" content="{image_url}">
    <meta property="og:description" content="{description}">
    <meta property="og:url" content="{url}">
    <meta property="og:type" content="website">
    <meta property="og:site_name" content="{site_name}">
    <meta name="twitter:site" content="@account">
    <meta name="twitter:creator" content="@account" />
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="{title}">
    <meta name="twitter:image" content="{image_url}">
    <meta name="twitter:description" content="{description}">
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }} class="body-class">
    {{ APP }}
  </body>
</html>
```
Go言語 : 再帰(フィボナッチ数の計算)

## 再帰
ある処理内部で、再びその処理自身を呼び出すような処理。

## フィボナッチ数
2つ前の項と1つ前の項を足し合わせていくことでできる数。
自然界に多く見られる、数学的規則性。

## Code
```Go
	var fibonacci func(n int) <-chan int
	// 何番目を求めるかを定義
	fibTarget := [5]int{10, 15, 20, 25, 30}

	// フィボナッチ数を求めるための無名関数を格納
	fibonacci = func(n int) <-chan int {
		result := make(chan int)

		// 無名関数によるゴルーチン
		go func() {
			// チャネルを閉じるための予約
			defer close(result)
			// 2以下の場合は必然的に1
			if n <= 2 {
				result <- 1
				return
			}
			// 再帰により、n-1番目を求める
			f1 := <-fibonacci(n-1)
			// 再帰により、n-2番目を求める
			f2 := <-fibonacci(n-2)
			// n-1番目とn-2番目を足し、フィボナッチ数を求める
			result <- f1 + f2
		}()

		return result
	}

	// ターゲットのフィボナッチ数を求める
	for _, f := range fibTarget {
		fib := <-fibonacci(f)
		fmt.Printf("No.%d fibonacci is %d \n", f, fib)
	}
```

## Output Sample
~ $ go build -o main main.go  
~ $ ./main  
No.10 fibonacci is 55  
No.15 fibonacci is 610  
No.20 fibonacci is 6765  
No.25 fibonacci is 75025  
No.30 fibonacci is 832040  

## GitHub
https://github.com/GL-Kageyama/Go_Recursion_Fibonacci
AlgoliaのインデックスをFirestoreのサブコレクションで使いたい時

Algoliaって便利ですよね。

Firestoreを使っているサービスで全文検索が必要な時に役立ってくれます。

そんなAlgoliaですが、便利なことに、Firebaseの拡張機能が用意されており、下記の記事で使い方が解説されています。

https://qiita.com/mogmet/items/943c0450957298f007ac

便利に使わせてもらっていたのですが、あるときから、サブコレクションに対するインデックスにオブジェクトが作成されなくなりました。

今回は、Algoliaでサブコレクションを正しく紐づける方法について記します。

## 結論

下記は、親コレクションが、`users`、その子になるサブコレクションを`blogs`とする例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/70d1a9ad-c049-a3a0-b887-b00f56397537.png)

ミソは、`Collection Path`に `parentCollectionName/{parentId}/subcollectionName`のフォーマットで指定することです。
pythonで配列を任意の軸に沿ってシャッフル


2022年4月20日追記
コメント欄でご指摘して頂いている通り，
```python:
rng = np.random.default_rng()
a = rng.random((3, 3))
print(a)
# [[0.79327762 0.07504873 0.25900636]
#  [0.75265331 0.49884496 0.55722056]
#  [0.89652968 0.97670661 0.22210966]]

print(rng.permutation(a, 0))
# [[0.75265331 0.49884496 0.55722056]
#  [0.79327762 0.07504873 0.25900636]
#  [0.89652968 0.97670661 0.22210966]]
print(rng.permutation(a, 1))
# [[0.25900636 0.79327762 0.07504873]
#  [0.55722056 0.75265331 0.49884496]
#  [0.22210966 0.89652968 0.97670661]]
```
でいけます．

以下は上記の下位互換かつ非推奨らしいので読む必要なし．
---------------------
0次元目に沿ったシャッフルで良ければ，
```python:
import numpy as np
a = np.random.randn(3,3) #配列作成
print(a)
#array([[-1.53792152,  0.79386219,  0.48612455],
#       [-0.54037524, -0.00331165,  0.17748696],
#       [-1.77427981,  1.81990354,  0.9835304 ]])

np.random.shuffle(a)
print(a)
#array([[-0.54037524, -0.00331165,  0.17748696],
#       [-1.77427981,  1.81990354,  0.9835304 ],
#       [-1.53792152,  0.79386219,  0.48612455]])
```
でOK．
#### 任意の軸でシャッフルしたい
他の次元でシャッフルしたい時は，
```python:
def shuffle_along_axis(a, axis):
    idx = np.random.rand(*a.shape).argsort(axis=axis)
    return np.take_along_axis(a,idx,axis=axis)

print(a)
#array([[-0.54037524, -0.00331165,  0.17748696],
#       [-1.77427981,  1.81990354,  0.9835304 ],
#       [-1.53792152,  0.79386219,  0.48612455]])

a_axis1 = shuffle_along_axis(a, 1)
print(a_axis1)
#[[-0.00331165  0.17748696 -0.54037524]
# [ 1.81990354  0.9835304  -1.77427981]
# [ 0.48612455  0.79386219 -1.53792152]]
```
これでOK.
#### 参考

https://stackoverflow.com/questions/5040797/shuffling-numpy-array-along-a-given-axis
DatabricksにおけるADAMの使用

[ADAM \| Databricks on AWS](https://docs.databricks.com/applications/genomics/tertiary-analytics/adam.html) [2022/1/5時点]の記事です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

[ADAM](https://adam.readthedocs.io/en/latest/)はApache Sparkにおける遺伝子データ処理のライブラリです。BAM、SAM、CRAMファイルのような遺伝リードデータを処理するパイプラインの実装に用いられます。

DatabricksでADAMを使うには以下の手順を踏みます。

1. 以下の[Spark設定](https://qiita.com/taka_yayoi/items/8d951b660cd87c6c5f18#spark%E3%81%AE%E8%A8%AD%E5%AE%9A)を持つDatabricksランタイムクラスターを起動します。

    ```ini:ini
    # Hadoop configs
    spark.serializer org.apache.spark.serializer.KryoSerializer
    spark.kryo.registrator     org.bdgenomics.adam.serialization.ADAMKryoRegistrator
    spark.hadoop.hadoopbam.bam.enable-bai-splitter true
    ```

1. [クラスターライブラリ](https://qiita.com/taka_yayoi/items/d3a46efdc1ad01a581d0#2-%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA)をインストールします。
    - Maven: `org.bdgenomics.adam:adam-apis-spark3_2.12:<version>`
    - PyPI: `bdgenomics.adam`


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
GCE上にデプロイしたコンテナが起動時に割り当てるポートの指定

## 課題
GCEには 指定のコンテナをVMに適用する機能が存在する。
See: [VM と MIG へのコンテナのデプロイ ](https://cloud.google.com/compute/docs/containers/deploying-containers?hl=ja)

> [機能概要] <br> 要するに 1VMに 1コンテナを配置するだけの機能である。つまりGKE的な観点で言えばリソースを最大限に活用しているとは言い難い。しかしVM上に直接環境を作るのに比べれば コンテナの可搬性を活かせるので便利である。

> [利用法] <br> 対象のコンテナイメージを Artifact Registry にアップロードし、VM作成時にそれを指定すれば起動時にコンテナが勝手に立ち上がる。

しかし、コンテナにAPIサーバーを指定しても、**VM上からの curl で応答しない**ときがある。

**ポート公開に失敗**している風な挙動であり、`docker run -p 8080:8080 ${コンテナID}` で立ち上げ直せば無事疎通するのだが、VM起動時に自動的に立ち上がるコンテナには `-p` オプションを渡せない。一体どう指定すれば良いのだろうか？

## 解決

`EXPOSE`を明記した `Dockerfile`でイメージを再登録すると、起動時に指定のポートが割り当たる。 

`EXPOSE 8080` と指定すると VM起動時のポート割り当てが `-p 8080:8080` 相当になる。

普段 `docker run -p` オプションや `docker-compose.yml` 上のport属性で割り当てるので、省略しがちな `EXPOSE` だが、GCE上で稼働させるときはきちんと指定しないとハマるらしい。

> 以上は コンテナ・VM間の挙動だが、 VM外へのポート公開も暗黙的に行われるらしいので、そういう挙動と認識しておくのは重要な気がする。See:[コンテナポートの公開](https://cloud.google.com/compute/docs/containers/configuring-options-to-run-containers?hl=ja#publishing_container_ports)
シリアルの外出し

ルーターのシリアルを筐体の外に出すには、ケースの加工やコネクタが必要になります。あまりケース加工が得意ではないので、なにか他の方法がないかいろいろ思案していました。

かなり前に思いついたアイディアだったのですが、EthernetのRJ45の使っていないピンを利用して外に出す方法を試してみました。

ターゲットはAR7240のモジュールで、元のRJ45の足は

![写真（2022-04-15 7.34） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a980929f-f756-d777-371e-bd42de448330.jpeg)

で、右上が1で1,2,3,6が接続されてます。

4,5,7,8が未接続なので、これは利用できます。

こうしてみます。

![写真（2022-04-15 8.33）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/26821f41-7197-0ab8-3399-246e866f6185.jpeg)

![写真（2022-04-15 8.32）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a8e000a4-2e8f-eb4d-bca9-e9034130fd80.jpeg)

半田付けは丈夫なRJ45の足からするのがこつです。

|ピン|信号|
|:--|:--|
|4|TX|
|5|RX|
|8|GND|

これで筐体を閉じてもシリアルが利用できます。

ケーブルは古いCat4などを切って使うのが良いです。たまに4本しか接続されてないケーブルがあるので、ちょっと注意が必要です。

![写真（2022-04-16 8.04）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c3e0138f-6bd1-002f-89b8-0bb564267f1e.jpeg)


パターンからワイヤーで引き出していると、無理な力がかかってパターンをダメにしてまうことがあるので、一時的にもこうやって使った方が良いです。

FreeBSD上でリモートでflashのupdateもできるようにしてありますが、たまに失敗したりするので、シリアルは必要です。

このターゲットはコネクタも付いてませんし、ホールもなくピッチも2mmで変則なので、こうして使うのがベストと思います。

100でも4本しかピンがでてないとできません。

![写真（2022-04-15 16.44）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/94436c62-55b5-79f1-9d21-802b01ad48a7.jpeg)

またトランス内臓のRJ45の場合もできません。

100の場合はこれでいけますが、Gigaだと全ピンつかってるのでダメです。また間違えてGigaに接続すると機器が壊れると思われ、良い子はまねしないでね。
mint言語でGithub Pagesを作る

mint buildコマンドを実行する際、いくつかのオプションを追加する必要があります。

参照：https://github.com/mint-lang/mint/discussions/543

> このとき、index.jsをルートドメインから読み込もうとするので、--relativeフラグを追加する必要があります。つまり、完全なビルドコマンドは次のようになります。

```
mint build --skip-service-worker --relative
```

この記事は以上です。
CPU:ARM,OS:ubuntuのPCでEvolution Gym環境を構築する際に注意すること(エラー対応)

# 基本の進め方
公式tutorial
https://evolutiongym.github.io/tutorials/getting-started.html
基本は公式のtutorialどおりにやっていけばいいと思います。

## 罠1
ただ、

    pip install -r requirements.txt
でおそらく死にます。原因はgitのprotocolまわりのsecurity updateらしいです。
### 解決法
requirements.txtファイルを開いて、git+git:// となっている部分を、git+https:// に変更して保存し、再度実行してみてください。
#### 参考
https://note.com/mizuki_oka/n/n1719412f641b

https://zenn.dev/karaage0703/articles/8e2ee3eb49a96c

## 罠2
ARMアーキテクチャのCPUだと、cmakeの問題でopencvのビルドで死ぬということがあるらしいです。

    sudo apt-get install python-opencv
でopencvをinstallしてみるとうまくいきます。
#### 参考
https://teratail.com/questions/301644

## 罠3
いざ、　

    python setup.py install
してみると、

    Could NOT find GLEW (missing: GLEW_INCLUDE_DIR GLEW_LIBRARY)
というエラーメッセージが出て死ぬかもしれません。

    sudo apt install libglew-dev
でGLEWをinstallしてみるとうまくいきました。
#### 参考
https://stackoverflow.com/questions/34230853/how-to-fix-could-not-find-glew-missing-glew-include-dir-glew-library

## 以下システムエラーをとるためにやった途中の改変の備忘録
### RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method

run/ppoに以下のコードを追加
```
from torch.multiprocessing import set_start_method
try:
     set_start_method('spawn')
except RuntimeError:
    pass
```
#### 参考
https://stackoverflow.com/questions/48822463/how-to-use-pytorch-multiprocessing

### RuntimeError: CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa, opb, m, n, k, &alpha, a, lda, b, ldb, &beta, c, ldc)`
以下のコードでpytorch nightlyを使用
```
pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cu113
```
#### 参考
https://discuss.pytorch.org/t/cublas-status-execution-failed-when-calling-cublassgemm-handle-opa-opb-m-n-k-alpha-a-lda-b-ldb-beta-c-ldc/116740/9

### librt.soが無いと言われたとき
buildフォルダを消した上で
```
python setup.py install
```
すれば直る。

### No module named 'evogym
buildがミスってるので、buildフォルダを消した上でリビルドする
GCEでSSHを誤って閉じたときに復旧する方法【Google Compute Engine】

# TL;DR
1. Google Cloud Consoleから`SSH`ボタンを押す
2. 誤って閉じた端末の親プロセスIDを調べる
   ```bash
   ps auf
   ```
   ```bash
   USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
   osaka_n+   614  0.0  0.3   5748  3512 pts/3    Ss   05:08   0:00 -bash
   osaka_n+   618  0.0  0.2   9388  2988 pts/3    R+   05:08   0:00  \_ ps auf
   osaka_n+   594  0.0  0.3   5748  3424 pts/2    Ss   05:07   0:00 -bash
   osaka_n+   598  0.0  0.1   7816  1332 pts/2    S+   05:07   0:00  \_ ping 8.8.8.8
   ```

3. 親プロセスIDから復旧する
   ```bash
   sudo apt install reptyr
   sudo reptyr -T 594
   ```

# 再現方法
https://youtu.be/zVudUYuI3Wo

## SSHを誤って閉じる
![ezgif-5-443756d7fd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/f8f6f5c2-392f-467c-4422-4f2ed72b3171.gif)

## `SSH`ボタンを押す
![ezgif-5-f485279d67.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/6f8755bd-6bfc-4588-2776-7c46c638ee69.gif)

## 親プロセスIDを調べる
```bash
ps auf
```
親プロセスIDを調べます。pts/2が前に閉じた端末です。該当のPIDは594になります。
```bash
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
osaka_n+   614  0.0  0.3   5748  3512 pts/3    Ss   05:08   0:00 -bash
osaka_n+   618  0.0  0.2   9388  2988 pts/3    R+   05:08   0:00  \_ ps auf
osaka_n+   594  0.0  0.3   5748  3424 pts/2    Ss   05:07   0:00 -bash
osaka_n+   598  0.0  0.1   7816  1332 pts/2    S+   05:07   0:00  \_ ping 8.8.8.8
```
![ezgif-5-1613f5336b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/f7fead25-fea6-74c1-d9d2-b68c18ff56a8.gif)

## 親プロセスIDから復旧する
8分以内に復旧するようにしましょう。(SSHのタイムアウトのため)
```bash
sudo apt install reptyr
sudo reptyr -T 594
```
![ezgif-5-139ba49a53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/11a51ef6-9453-bed3-9493-283520452c07.gif)

# 参考
https://serverfault.com/a/1095878
pythonライブラリ networkx 使ってみた(Part1)

個人的に使い方に困ったpythonライブラリnetworkxの紹介をしたいと思います。
今回はとりあえずPart1ということで、発見があり次第、都度更新していこうと思います。
(間違ってたらすいません🙏)

```
# networkxライブラリをインポートする。
import networkx as nx
```

networkxがインストールされてないと、エラーが出るかもしれないです。その場合は以下の文言をターミナルで実行すれば解消すると思います。
```
\pip install networkx
```
とりあえず使ってみる
```
N_x = 5 # N_x：ノード数
m = 3 # m：結合数
t = 0 # シード値

# グラフを作成
graph = nx.gnm_random_graph(N_x, m, t)
```
graphの型を確認してみる。
```
type(graph)
==> networkx.classes.graph.Graph
```
個人的には初めて見た型でした、、
次に実際にgraphを描写してみます。
```
nx.draw_networkx(graph)
plt.show()
```
結果は以下のようになります。ノード数：5, 結合数：4になっていることが確認できます。
![networkx_graph5_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594605/612e690f-05a0-2688-7512-b48e66181b44.png)

次にノード数は変えず(N_x = 5)、結合数を全結合に変更してみます。
```
N_x = 5
m = N_x*(N_x-1) # 全結合は(N_x)×(N_x-1)
t = 0
graph_all = nx.gnm_random_graph(N_x, m, t)
```
先ほど同様に描写してみます。
```
nx.draw_networkx(graph_all)
plt.show()
```
結果は以下のようになります。ノード間が全て結合できていることが確認できます。
![networkx_graph5_all.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594605/b73c9496-5dfd-c431-697c-f1f83bcd48b6.png)

実際にgraphやgraph_allって中身どうなってるの？って疑問が湧きました。
そこで、graphやgraph_allの中身を見てみます。
中身を見るために、array型に変換します。(他の方法があるかもしれないですが、、、)
```
# 型をarrayに変換する
graph_array = nx.to_numpy_array(graph)
graph_all_array = nx.to_numpy_array(graph_all)

graph_array 
==>>
[[0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 1.]
 [1. 0. 0. 1. 0.]
 [0. 0. 1. 0. 1.]
 [0. 1. 0. 1. 0.]]

graph_all_array 
==>>
[[0. 1. 1. 1. 1.]
 [1. 0. 1. 1. 1.]
 [1. 1. 0. 1. 1.]
 [1. 1. 1. 0. 1.]
 [1. 1. 1. 1. 0.]]
```
中身を見ると、graphの正体は結合行列でした。
結合があれば"1" 結合がなければ"0" になっています。

networkxを使うと対称行列になってしまうのが少し不便かなと感じました(勘違いかもですが、、)