OmniAICreator/Qiita-1.07M huggingface dataset:
私の最近のベクトルタイルサイトの書き方

私の最近のベクトルタイルサイトの書き方をメモしておきます。最近は、ファイルを分ける傾向があります。また、福野泰介さんのスタイルを借りて、または盗ませていただいているところがあります。感謝します。

# ソース
この記事で紹介している書き方のソースは　[optgeo/hrlulc](https://github.com/optgeo/hrlulc/tree/main/docs) です。

# ファイルの構成
- index.html: 根となる HTML ファイルです。
- module.js: JavaScript プログラムです。
- style.css: HTML に適用するための CSS ファイルです。
- style.json: ベクトルタイルスタイル情報です。これは UNVT で生成します。

# index.html
```html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
<script type="module" src="module.js"></script>
</head>
<body>
</body>
</html>
```

# module.js
```js
import { YAML } from 'https://code4sabae.github.io/js/YAML.js'

const style = href => {
  const e = document.createElement('link')
  e.href = href
  e.rel = 'stylesheet'
  document.head.appendChild(e)
}

const script = src => {
  const e = document.createElement('script')
  e.src = src
  document.head.appendChild(e)
}

const init = () => {
  style('style.css')
  style('https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.css')
  script('https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.js')
  const map = document.createElement('div')
  map.id = 'map'
  document.body.appendChild(map)
}
init()

const showMap = async (texts) => {
  const map = new maplibregl.Map({
    container: 'map',
    hash: true,
    style: 'style.json',
    maxZoom: 17.8
  })
  map.addControl(new maplibregl.NavigationControl())
  map.addControl(new maplibregl.ScaleControl({
    maxWidth: 200, unit: 'metric'
  }))

  let voice = null
  for(let v of speechSynthesis.getVoices()) {
    console.log(v.name)
    if ([
      'Daniel',
      'Google UK English Male',
      'Microsoft Libby Online (Natural) - English (United Kingdom)'
    ].includes(v.name)) voice = v
  }

  const legend = {
    1: 'water',
    2: 'urban',
    3: 'rice paddy',
    4: 'crop',
    5: 'grassland',
    6: 'deciduous broad-leaved forest, or DBF',
    7: 'deciduous needle-leaved forest, or DNF',
    8: 'evergreen broad-leaved forest, or EBF',
    9: 'evergreen needle-leaved forest, or ENF',
    10: 'bare land',
    11: 'bamboo',
    12: 'solar panel'
  }

  map.on('load', () => {
    map.on('click', 'hrlulc', (e) => {
      let u = new SpeechSynthesisUtterance()
      u.lang = 'en-GB'
      u.text = legend[e.features[0].properties.a]
      if (voice) u.voice = voice
      speechSynthesis.cancel()
      speechSynthesis.speak(u)
    })

  })
}

const main = async () => {
  if (typeof maplibregl == 'undefined') {
    window.onload = () => {
      showMap()
    }
  } else {
    showMap()
  }
}
main()
```

# style.css
```css
body { margin:0; padding:0; font-family: sans-serif; }
#map { top:0; height: 100vh; width:100vw; position: fixed; }
```

# style.json
これは UNVT で生成します。地図によってそれぞれです。

スタイルを生成するためのコードの例としては、[style.rb](https://github.com/optgeo/hrlulc/blob/main/style.rb)があります。
EC2サーバー構築の概要【備忘録】

#はじめに
AWSの仮想サーバー構築用クラウドサービス「EC2」を用いて、PHPサイトを立ち上げた時に調べたことのまとめ。
全体の流れ・用語等についての記事であるため、具体的な手順については割愛しています。

#目次
- 全体の流れ
- 項目別の詳細
- 用語
- 参考文献

#全体の流れ
1. AWSにサインアップ
1. EC2インスタンスを作成
1. インスタンスをSSH接続で操作する
1. Apache・PHP・MariaDBをインストール
1. テスト用PHPファイルをアップロード
1. Elastic IPを割り当て
1. 各種設定を変更

#項目別の詳細
####1. AWSにサインアップ・2. EC2インスタンスを作成
　手順通りに進めるだけなので割愛。
####3. インスタンスをSSH接続で操作する
　作成したインスタンスを操作する際には、端末からSSH接続をする。
　SSHクライアントとして、今回はTera Termを使用する。
　接続画面ではホストにパブリックDNS、ユーザーにec2-user、認証方式にSSHを選択し、インスタンス作成時に取得した秘密鍵を指定する。
####4. Apache・PHP・MariaDBをインストール
　Tera Termのターミナル画面からApache、PHP、MariaDBをインストールする。
　まずはApacheから。

```
sudo -i                 // 管理者権限に切り替え（exitで戻す）
yum install httpd       //httpd（Apacheの別名）をインストール
systemctl start httpd   //Apacheを起動
systemctl status httpd  //動作状況を確認
```
　続いてPHP。

```
yum install php                        //PHPをインストール
sudo chown -R ec2-user /var/www/html   //指定されたDirの所有者をユーザーに変更
                                       //RオプションでDir下のすべてを変更できる
```
　MariaDB。

```
yum install mariadb mariadb-server    //MariaDBをインストール
systemctl start mariadb               //起動、こちらもstatusで状態を確認できる
```

####5. テスト用PHPファイルをアップロード
　お馴染みのindex.phpでハローワールドを出力してみる。

```php:index.php
<?php
 echo "Hello, World.";
```
　指定ホストにアクセスしてちゃんと画面に出力されれば成功。

####6. Elastic IPを割り当て
　インスタンスに割り当てられたパブリックIP,パブリックDNSなどは、定期的に行われる再起動によって変動する。その度にAWSコンソールに行ってホストをコピペするのは非合理的なので、その変動を吸収するためのElastic IPというものを設定する。
　インスタンスに紐づけることで、そのElastic IPからのアクセスが可能になり、IPが固定化される。
　なお、使用料金は紐づけたインスタンスが稼働している間は発生しない。細かい手順は割愛。

####7. 各種設定を変更
　最期に、実際に開発をするにあたり必要な機能や設定を変更する。

- インスタンス再起動時、ApacheとMariaDBを自動で起動するように設定

```terminal:TeraTerm
systemctl enable httpd
systemctl enable mariadb
```

- データベース設定

```terminal:MariaDB
update mysql.user set password=password('新しいパスワード') where user='ユーザー'; //ユーザーのパスワードを設定
grant all privileges on データベース.*to ユーザー@ホスト; //データベース内の全テーブルへのアクセス権を付与
flush privileges;    //設定変更を反映
```
- PDO使用設定

　デフォルトではPDOの設定が有効化されていないため、そのままPDOを使おうとするとエラーが出る。

```terminal:TeraTerm
sudo yum install php-pdo     //pdo.soをインストール
sudo yum install php-mysql   //mysqlのドライバをインストール
```

```ini:php.ini
extension=pdo.so           //追加
extension=pdo_mysql.so     //追加
```

#用語
　導入する中で様々な用語に出くわしたので、その備忘録。
####リージョン 
「地域」。物理サーバーの設置場所を指す。
####AMI（Amazon Machine Image）
　サーバー構築用のソフトウェア（OS,サーバーアプリなど）のセット。
####EBS（Elastic Block Store）
　インスタンスの内部ストレージ。HDDのようなもの。
####VPC（Virtual Private Cloud）
　利用者ごとに与えられる、仮想ネットワーク空間。
####yum
　UNIX系のパッケージ管理コマンド。
####セキュリティグループ
　EC2インスタンス内に適用できるAWSのファイアウォール。
####IAMユーザー
　IAM（AWSサービスへのアクセスを認可できるサービス）で設定されたユーザー。

#参考文献
[AWS EC2(Amazon Linux)にPHP7.4をインストール](https://qiita.com/nagahama/items/2fdc820791bee5d564ca)
[AWS EC2上にPHPサイトを立ち上げて、独自ドメインでアクセスできるようにするまでの全手順](https://qiita.com/harufuji/items/4fcd8f991fab5ad3354a)
[Elastic IPの設定](https://qiita.com/Jerid/items/d5dd3a29ed9a0e374493)
Herokuの読み込みが遅い問題をGASで定期リクエストを送ることによって解決する

# はじめに
Herokuは簡単にデプロイできる上に無料枠があるため、多くの人が使っていると思います。
しかし30分以上アクセスがないとDyno（Herokuで利用されるLinuxコンテナ）がスリープ状態に入ってしまい、読み込みが遅くなってしまいます。
今回は自分が起きている時間帯だけ常時起動させ、就寝中はスリープ状態にさせる方法を執筆します。
ちなみに就寝中にスリープさせるのは理由があります。
後述しますが、簡単に言えばクレジットカード登録なしの無料枠内で常時起動させるには時間に制限があるからです。
また、何らかのトラブルが発生した際は自己責任でお願いします。


# 前提
## 対象者
* Herokuにアプリケーションをデプロイ済み
* 完全無料で使いたい
* Herokuにクレジットカードを**登録したくない**
* GASを利用できる

## 注意事項
多くの人は[Dynoのフリープラン](https://jp.heroku.com/dynos)を使っていると思います。
DynoというのはHerokuで利用されるLinuxコンテナであり、皆さんはその上にアプリケーションをデプロイしているイメージです。
Herokuアカウントにつき`550Dyno時間/月`が備わっており、1ヶ月でDynoを550時間無料で動かすことができます。
クレジットカードを登録すれば`1000Dyno時間/月`まで増えます。
注意していただきたいのが、1ヶ月は`24時間*31日`で`744時間`ということです。
550時間というのは約22日です。
つまり、常時起動させていると約22日しかアプリを利用できないということになります。
言い換えれば1日あたり約7時間以上スリープさせれば、550時間内に抑えることができます
これが自分が就寝中の時スリープさせる理由です。
もちろん一日7時間以上スリープ状態にできれば就寝中にこだわる必要はありません。

また[こちらの記事](https://qiita.com/oedkty/items/3a8efddc910c78655dd5#%E7%84%A1%E6%96%99%E6%9E%A0)によれば、一つのアカウントで2つの以上のアプリケーションを起動させると合算になるので注意が必要とのことです。
今回は一つのアプリで1ヶ月550時間近く利用するわけですから、同じアカウントで他にアプリをデプロイして利用することは難しいことを念頭においてください。
もし同じアカウントで他にもアプリをHerokuで利用したい場合は、スリープ時間を増やして調整してください。


# 仕様
* 自分が起きている時間帯(午前10:00~深夜2:00の16時間)は30分おきにHerokuにリクエストを投げ、就寝中の8時間はリクエストを投げずスリープ状態にさせる。

Herokuにリクエストを投げるのはGASを使います。
GASにはスクリプトを定期実行させる機能があり、今回はGASの無料枠内で抑えることができます。
他にも選択肢はありましたが、

* `Heroku Scheduler`で工夫する....そもそもこのアドオンを利用するにはクレジットカードの登録が必要なので却下
* モニタリングツールで定期的にリクエストを投げる...このためだけにツールの登録をするのは気がひけるのと、GASの方が慣れているのでトリガーの設定や拡張がしやすいと思ったので却下

最終的に慣れているGASに決めました。


# GASの設定
１からGASの設定を説明するのは手間なので、要所をお伝えします。
コード自体は単純です。
適当なプロジェクトを作成し、`main.gs`に以下を記述します。


```js:main.gs
function fetchHeroku() {
  const isSleepingTime = checkSleepingTime();

  if(!isSleepingTime){
    const url = "あなたのherokuアプリのURL"
    UrlFetchApp.fetch(url);
  }
}

function checkSleepingTime(){
  const startSleepingTime = 2;
  const endSleepingTime = 10;
  const currentTime = new Date(); 
  const currentHours = currentTime.getHours();
  return currentHours >= startSleepingTime && currentHours < endSleepingTime
}
```
まず現在時刻を取得し、スリープする時間か否かでリクエストを送るか判断してます。
このURLに対応するアクションは処理が軽いものにしましょう。
ただ`hello`と返すようなアクションで十分です。

続いてトリガーを設定します。

**トリガーの保存ボタンを押すのは現在の時刻を確認して、必ずx時0分になるのを待って設定してください。**

<details><summary>クリックして理由を表示</summary><div>

:::note
このトリガーで３０分おきを設定するのですが、設定した時間から３０分おきになってしまいます。
今回のサンプルコードでは、10:00になったらアプリが起動して欲しいですよね。
例えば16:57にトリガーを保存したら、x時57分とx時27分に毎回実行されます。
そうすると当然ですが9:57分になった時にもスクリプトが実行されます。
この時まだスリープ状態であるため、リクエストを投げません。
次実行されるのは10:27分になるため、10:15分の段階でもスリープ状態のままになってしまいます。
これを避けるためにx時0分、あるいは1分許容してx時1分になったタイミングで保存ボタンを押してください。
:::
</div></details>

1.画面左の時計マークをクリックし、トリガーを追加
2.「実行する関数を選択」で`fetchHeroku`を選択
3.「実行するデプロイを選択」で`Head`を選択
4.「イベントのソースを選択」で時間主導型を選択
5.「時間ベースのトリガーのタイプを選択」で分ベースのタイマーを選択
6.「時間の間隔を選択（分）」で**30分おき**を選択
7.保存する

これで完了です！
ログを見てしっかりと機能しているか確認してください。

# 終わりに
これで起きている間は読み込みのストレスがなくDyno上のアプリにアクセスできると思います。
スリープ時間はHerokuにデプロイした他のアプリのことを考慮しながら適宜変えてください。
トリガーは簡単に削除できます。

GASの定期実行は本当に便利なので、是非試してください。


# 参考
* https://devcenter.heroku.com/articles/free-dyno-hours
* https://jp.heroku.com/dynos
AWSにデプロイ後、Vueファイルの更新が反映されない時の対処法

#EC2内のvueファイルを更新しても、ブラウザに反映されない。

既にAWSにデプロイ済みのLaravelで作成したプロダクトについて、git pullで変更点をEC2に持って来た際に、ファイル内のコードは変更が反映されているのに、ブラウザで見ると反映されない事態が発生しました。
phpのファイルは問題なく変更が反映されているのに、なぜvueは反映されないのか。
ローカルで確認すると、期待通りに表示できています。

#結論 app.jsの中身が更新できていませんでした。
よくよく確認するとmargeが前後した関係で、app.jsが古い状態になっていました。

レアケースかもしれませんが、一応シェアしておきます。
TEA5767 ラジオキットを改造しよう


(夏休み企画 10/20)

![IMG_20210814_153622.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2f57b40b-368c-eb0f-6f6b-542d2318cc5a.jpeg)

「TEA5767 ラジオキット」
https://qiita.com/nanbuwks/items/10e789ffd8f5c0c0ac35

回路構成がシンプルで、改造しやすい。いろいろと手を加えてみよう!
。

# スピーカーをコネクタ式にしよう

組み立てた時に、ここが罠でした。

> ケースのパーツにあらかじめスピーカーのコードを通しておかないといけなかったでした。

![IMG_20210814_152020.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9d50599f-00ba-5f89-3327-21bbc6bfc3f6.jpeg)

今後も取り外しなどを頻繁にするので、ここをコネクター化します。


![IMG_20210818_174004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2760c17e-67bd-c0ce-ec76-b29b5c85a07f.jpeg)


XHコネクタと、ケーブル付き端子を用意します。

![IMG_20210818_174025.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/371a9932-b190-d651-1380-4f0d3a0209e6.jpeg)
このようにつなげて、組み立て/分解しやすくなりました。

![IMG_20210820_172917.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7539f922-6b65-4af3-e6c4-95255a6b7417.jpeg)




# 外部入力端子をつけよう

回路図を見てみると

![IMG_20210814_153804.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b8dc285b-e305-28ef-611b-29dbe2a5d6cc.jpeg)

FMラジオIC の TEA5767 に LM386 がつながっています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bb1409dd-bc9a-84ac-e28d-10fbc9342012.png)


LM386 は定番のオーディオアンプICです。

LM386データシート(日本語)：

https://www.tij.co.jp/jp/lit/ds/symlink/lm386.pdf

LM386はシングルチャネルのアンプで、TEA5767 のステレオ出力のうちの右チャンネルのみを増幅しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4570884a-136e-463b-f881-4cbfcb551711.png)


LM386 は何かと工作に使えるので、このアンプ機能を活かせるように Line In 端子をつなげてみます。

秋月電子の「基板取付用３．５ｍｍステレオミニジャック」
https://akizukidenshi.com/catalog/g/gC-02384/
を用意します。

![IMG_20210820_175937.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2793438a-4496-a930-20e6-5934c808a53f.jpeg)

パターンをカットして。

![IMG_20210820_173405.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d54570e9-0f64-5513-d7f3-8ed580c18692.jpeg)

配線をします。

![IMG_20210820_190610.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b19e6fc3-3398-45a8-0c60-78a4e310cc18.jpeg)

このようにつなげると、プラグしていないときにはラジオ、プラグすると外部入力に切り替えとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/440cf537-c4e0-23e5-11b2-b1736e12be8e.png)

配線がちぎれないように気をつけて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/24fb6ba2-64fc-ce7c-abdc-cdf5a8fd19dc.png)

この位置にエポキシでしっかり固定しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8814cb24-46c1-24fa-3997-bb1c089809c5.png)



アクリルケースの該当位置を削ります。


![IMG_20210825_174926.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/023832e0-f4c3-2784-7984-e51a44b01b3f.jpeg)

PCにつなげてテストです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/75b79cba-04a0-8784-9568-e99f1e98a1a0.png)

本来ならこれで鳴ればケースをアクリルケースを組立て直してOKなのですが、鳴りません！！




トラブルシュート！ よく見ると、黒の配線をつなげたときに、半田がコンデンサに接触していました。
![IMG_20210820_192705.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/144b2677-a039-4ac9-943f-4cd8346e2cde.jpeg)
【Devise】本番環境でログインできないときの解決方法

#はじめに
deviseを使用したログインを本番環境で行ったが、再度ログイン画面へリダイレクトされてしまった。
結論、nginxの設定がうまくいっていなかったため、以下のように解決方法をまとめた。

#環境
rails  6.1.4
ruby   2.7.3
nginx  1.20.1
puma   4.3.8
devise 4.8.0

#解決方法
①nginx設定ファイルに「proxy_set_header X-Forwarded-Proto $scheme;」を追加

```
#/etc/nginx/conf.d/hoge.com.conf

upstream puma-production {
    server unix:/var/www/html/<app名>/shared/tmp/sockets/puma.sock;
}

server {
    listen       80;
    server_name  <ドメイン>;
    return 301 https://$host$request_uri;
}

server {
    listen  443 ssl;
    server_name     <ドメイン>;
    ssl_certificate       /etc/letsencrypt/live/<ドメイン>/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/<ドメイン>/privkey.pem;
    root   /var/www/html/<app名>/current/public;
    location / {
        try_files $uri @app;
    }
    location @app {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;  <---追記
        proxy_pass http://puma-production;
    }
}
```
②nginxを再起動

```
$ sudo systemctl restart nginx
```

#まとめ
リバースプロキシを使用していたため、nginxの設定に追記が必要だった。

#参考
https://stackoverflow.com/questions/30733375/devise-throws-401-unauthorized-and-redirects-only-in-production-staging
鍵の施錠で3万を失わないために

## やったこと

fitbit versa3でsesameのロックを解除できるように。

https://blog.chick-p.work/sesame-fitbit-app/

やったことはこちらの神サイトからforkしてきて

sdkのバージョンを6にしないと？versa3では動かなかったので6に変更

そこでマイグレーションするにあたって詰まったところを

https://dev.fitbit.com/build/guides/migration/

マイグレーションガイドはこのサイトにある

sdkのバージョンを4から5で

Button周りがかなり変わったぽく。

combo-button-hogehogeが軒並みエラーに


https://github.com/galigalikun/sesame-for-fitbit-versa


成果物はこちら


ここからは身の上話になぜこのようなことを始めたのかを


## あらすじ

2021年9月某日

ランニングを日課にしておりいつも通り、春日フライデースタイルで外に出た時。。
鍵を持って出なかったことに気づき。。

持っているものは、スマートウォッチだけ。

そして深夜22時、どうするか悩んだ末。

警察にヘルプを求めました。
結果として、鍵を開ける業者に連絡してもらい。
費用として3万ほど。。
ps5の資金が。

## どうすれば良かったのか

ここで家にはスマートロックは導入していたので
それで自動ロックがかかり鍵を持っていない状態でもロックされてしまったわけですが。。

警察の人のスマホで操作して貰えばと今更ながら気づきましたが、そんな思考にならなかったず。

そもそもスマートウォッチで開けられるようにしていれば今回のは防げていたのではと思い今回の作業ログとして。
HTML/CSSまとめ

 - HTML
  - nav →　リンクなどのまとめをする


 - CSS
  - カスケード：CSSの順番
    あと勝ちになる、!importantで最優先で指定できる ※importantはあまり推奨されない
  - スコアリング：インラインスタイル（HTML上に書くやつstyle）>id>class>何もない(h1)
  - inherit：親クラスのプロパティを継承する
  - initial：ブラウザのデフォルト値が適用される
  - unset：inheritがあったらinheritが適用され、なければinitialが適用される
  - all:unset:すべてのプロパティをクリアできる
  - ユニバーサルセレクター：＊などすべてに適用されるセレクター
  - ^ これは前方一致
  - * これは部分一致
  - $ これは後方一致
  - first-of-type:一番最初のやつにスタイル適用
  - nth-of-type(2):何番目か指定する事ができる
  - :hoverでマウスカーソルを当てたときに色がかわる
  - ::after 要素のあとになにか追加
  - ::before 要素の前になにか追加 
  - ::first-line 最初の行のみ
  - ::first-letter 最初の文字のみ
  - 子孫結合子をあまり長くするのは良くない
  - > 子結合子　直下のスタイリング
  - + 隣接兄弟結合子　次の要素からスタイリング的に書き方ができる、簡潔にかける、2番目の要素からスタイリングしたいときに使ったりする
  - 〜　一般兄弟結合子　前の要素のあとからスタイリング、あまり使わない
  - マージン相殺というものがある
  - box-sizing: border-box;を指定するとwidthとheightで指定した値でできる（padding,marginの影響を受けない）

 ブロック要素とインライン要素の違い
  ※display: inline;でインライン要素に変えることもできる
  ※display: block;でブロック要素に変えることもできる（imgはインラインなのでよく使われる）
  ※display: inline-block;でインラインとブロック要素に変えることもできる
  - 改行されるかどうか
  - ブロック要素にはwidth,height要素が効くがインライン要素には効かない
  - インラインはmargin,padding,borderがきたときに他の要素のことを考えません。
E資格ラビットチャレンジレポート　〜応用数学まとめ〜

#第一章　線形代数
##1) 固有値・固有ベクトル
ある行列$A$に対して、

```math
Ax =λx
```
となるλが固有値、$x$が固有ベクトル。

具体的にλと$x$求めるためには、

```math
(A-λE)x = 0
```

と変形してあげれば、det((A-λE))=0を計算してあげれば良いことがわかる。
理由：逆行列が存在してしまうと$x$=0となってしまうため。

det((A-λE))=0からλを計算して、そのλを(A-λE)$x$ = 0に代入することで、
対応する固有ベクトル$x$が求まる。

##2) 固有値分解
固有値を対角線上に並べた行列$ A $（それ以外の成分は0）と，
それに対応する固有ベクトルを並べた行列$ 𝑉 $を用意したとき，
それらは$ AV=VA $と関係付けられる。
($ A $の対角成分以外が0なことから、簡単に示せる)


$ AV=VA $と関係付けられることから、

```math
A=V𝛬V^{-1}
```

と変形できることがわかるが、
このように正方形の行列を上述の様な３つの行列の積に変換することを固有値分解という。
（Vは固有ベクトルから作っているので、逆行列が存在する点に注意）


##3) 特異値・特異ベクトル
ある行列が正方行列でなかった場合に、固有値、固有ベクトルで分解するような話。

```math
Mv=σu\\
M^T u=σ v
```
となる特異値σや特異ベクトル$ u,v $があれば、特異値分解できる。

##4) 特異値分解

```math
MV　= US\\
```

から

```math
M=USV^{-1}
```

実際に計算するときは、$M M^T$を計算してあげれば正方行列になるので、
それを固有分解してあげる。
すると、

```math
𝐴=V𝛬V^{-1}
```
の形にできるので、

```math
MM^T=USV^{-1}VSU^{-1}=US^2U^{-1}=V𝛬V^{-1}
```
となり、$U$と$S$の２乗がもとまる。

$V$も同様に$M^T M$を計算すれば良い。

#第二章確率・統計
##1) 条件付き確率
変数Xが値xの時に、変数Yが値yをとる確率

```math
P(Y=y|X=x)=\frac{P(Y=y,X=x)}{P(X=x)}
```

##2) ベイズ則
条件式確立の式を

```math
P(X=x|Y=y)P(Y=y)=P(Y=y,X=x)
```
と変形してあげれば、

```math
P(Y=y|X=x)=\frac{P(Y=y,X=x)}{P(X=x)}
=\frac{P(X=x|Y=y)P(Y=y)}{P(X=x)}
```



##3) 期待値・分散

```math
E(x)=\sum_{i=1}^n p_ix_i\\
V(x)=\sum_{i=1}^n p_i(x_i-\bar{x})^2
```

実際に分散を計算するときは、

```math
V(x)=E(x_i^2)-(E(x))^2
```

でやることが多いかもしれない。（計算が楽なので）

##4) 様々な確率分布
ベルヌーイ分布…２値
マルチヌーイ（カテゴリカル）分布…多値
二項分布…ベルヌーイ分布の多試行版
ガウス分布…釣鐘型の連続分布

#第三章情報理論
##1) 自己情報量・シャノンエントロピー
###自己情報量

```math
I(x) = -log(P(x)) = log(W(x))
```
ここでPは確率
確率は定義上、０〜１の間をとり、logは０〜１の間で常に負の値を取る点に注意。
必ず起きる事象（確率1の事象）に対しての自己情報量は、

```math
I(x) = -log(1) = 0
```
となっている。

###シャノンエントロピー
自己情報量の期待値

```math
H(x) = E(I(x)) = -E(log(P(x)))
```

##2) KLダイバージェンス・交差エントロピー
###KLダイバージェンス
Kullback-Leibler divergence ( KLダイバージェンス、KL情報量 )

```math
D_{KL}(P||Q) = E_{x\sim P}(log\frac{P(x)}{Q(x)})
```

###交差エントロピー

```math
H(P,Q) = -E_{x\sim P}(log(Q(x))
```

KLダイバージェンスの一部分を取り出したもの。
Qについての自己情報量をPの分布で平均している。
確かにQについての自己情報量をPの分布で平均しているあたり、交差している感じがある。
Numpyで平均差とジニ係数を求める

# Numpyで平均差とジニ係数を求める
検索しても微妙なものしかなかったので自分用メモとして

## 定義
1次元データ $x_1, x_2, x_3, \cdots , x_n$の散らばりの尺度として、データの各対ごとの隔たり$|x_i - x_j|$の平均  

$$\sum_{i}\sum_{j}|x_i - x_j| /n^2 \tag{1}$$

を考え、これを平均差という.また、平均差と平均値$\overline{x}\times2$の比を  

$$\sum_{i}\sum_{j}|x_i - x_j| /2n^2\overline{x} \tag{2}$$

のように定義し、ジニ係数という  

## 式展開
ここで$\sum_{j}|x_i - x_j|$について考えてみる  
展開すると
$$
\sum_{j}|x_i - x_j|=|x_i -x_1| + |x_i -x_2| +|x_i -x_2| + \cdots |x_i -x_j|\tag{3}
$$

となる
次に$\sum_{i}\sum_{j}|x_i - x_j|$の各項目を並べてみる  

```math
\sum_{i}\sum_{j}|x_i - x_j| \\
= |x_1 -x_1| + |x_1 -x_2| +|x_1 -x_3| + \cdots + |x_1 -x_j| \\
+|x_2 -x_1| + |x_2 -x_2| +|x_2 -x_3| + \cdots + |x_2 -x_j| \\
+|x_3 -x_1| + |x_3 -x_2| +|x_3 -x_3| + \cdots + |x_3 -x_j| \\
\vdots\\
+|x_i -x_1| + |x_i -x_2| +|x_i -x_3| + \cdots + |x_i -x_j|\tag{4}\\
```

このことから次の行列の各要素を足したものを求めれば(4)式が求まる

```math
\begin{pmatrix}
|x_1 -x_1| & |x_1 -x_2| &|x_1 -x_3| & \cdots &|x_1 -x_j| \\
|x_2 -x_1| & |x_2 -x_2| &|x_2 -x_3| & \cdots &|x_2 -x_j| \\
|x_3 -x_1| & |x_3 -x_2| &|x_3 -x_3| & \cdots &|x_3 -x_j| \\
&&\vdots\\
|x_i -x_1| & |x_i -x_2| &|x_i -x_3| & \cdots &|x_i -x_j|\tag{5}
\end{pmatrix}
```

ところで(5)式は絶対値を外せば


```math
\begin{pmatrix}
x_1 -x_1 & x_1 -x_2 &x_1 -x_3 & \cdots &x_1 -x_j \\
x_2 -x_1 & x_2 -x_2 &x_2 -x_3 & \cdots &x_2 -x_j \\
x_3 -x_1 & x_3 -x_2 &x_3 -x_3 & \cdots &x_3 -x_j \\
&&\vdots\\
x_i -x_1 & x_i -x_2 &x_i -x_3 & \cdots &x_i -x_j
\end{pmatrix}

\\ 
=\begin{pmatrix}
x_1  & x_1  & x_1  & \cdots & x_1 \\
x_2  & x_2  & x_2  & \cdots & x_2 \\
x_3  & x_3  & x_3  & \cdots & x_3 \\
&&\vdots\\
x_i  & x_i  & x_i  & \cdots & x_i
\end{pmatrix}
-
\begin{pmatrix}
x_1  & x_2  & x_3  & \cdots & x_j \\
x_1  & x_2  & x_3  & \cdots & x_j \\
x_1  & x_2  & x_3  & \cdots & x_j \\
& & \vdots \\
x_1  & x_2  &x_3  & \cdots & x_j 
\end{pmatrix}\tag{6}
```

となる。ここで
$$
A =\begin{pmatrix} x_1 & x_2 & x_3 & \cdots & x_n \end{pmatrix}\\
$$
とすれば(6)式は
$$
X =
\begin{pmatrix}
A, A, A, \cdots, A
\end{pmatrix} -
{}^t
\begin{pmatrix}
A, A, A, \cdots, A
\end{pmatrix}\tag{7}
$$
となるこれから、これらをnumpyを用いて求めると以下のようになる(コメントは無駄に多めになっています)  


```python
import numpy as np
# a = np.array([x1, x2, x3, x4, ..., xn])
# ここでは仮に(0,1,2,3,5,5,7,8,9,10)とする
# A を定義
A = np.array([0, 1, 2, 3, 5, 5, 7, 8, 9, 10])


def ave_diff_pre(a) -> int:
    """
    平均差やジニ係数の分子部分の計算
    :param a:配列
    :return:
    """
    n = len(a)
    # ここでrepeatを使いn回増やし、reshapeでn×n行の行列に変形し、(7)の右辺の1項目を求める
    x_1 = a.repeat(n).reshape(n, n)
    # X_1の転置行列を求め、(7)のXを求める
    x_2 = x_1.T
    x = x_1 - x_2

    # ユニバーサル関数を使用し、Xの各要素の絶対値を取った(5)式を出す
    b = np.abs(x)
    # 各要素の和(4)を求める
    c = b.sum()
    return c


def ave_diff(a) -> int:
    """
    平均差を求める
    :param a:平均差を求めたい配列
    :return:平均差
    """

    mol = ave_diff_pre(a)
    # n^2で割る
    n = len(a)
    return mol / n ** 2


def gini(a) -> int:
    """
    ジニ係数を求める
    :param a:ジニ係数を求めたい配列
    :return:ジニ係数
    """
    mol = ave_diff_pre(a)
    n = len(a)
    return mol / (2 * n ** 2 * np.average(a))


print(f"平均差は{ave_diff(A)}です")
print(f"ジニ係数は{gini(A)}です")
```
Raspberry Pi OS Upgrade

# はじめに
RapberryPiのOSサポートが切れていため更新対応しました。
色々調べながら実施したものの、
更新コマンド中のエラーに引っかかったので自分用にメモを残します。

# 環境
-  Raspberry Pi 3
-  Raspberry Pi OS (旧Raspbian) Jessie（Debian 8系）
-  /etc/apt/sources.list
```
deb http://raspbian.raspberrypi.org/raspbian/ jessie main contrib non-free rpi
```

# 手順
## 必要に応じて設定ファイルの確認やバックアップを実施
- 割愛

## 今あるパッケージ類を再新化しておく
### 1. sources.listに書いてあるサイトから最新のパッケージリストを取得
```sh
sudo apt-get update
```

### 2. インストール済みパッケージの更新
```sh
sudo apt-get update
```
- 私の環境では，sources.listが古すぎた(?)ため，下記のようなエラーが発生
    -  いくつかのパッケージが取得できませんでした
    -  サイズが適合しません
- ※記載のsources.listの手直しで修正後，1.からやり直しで対処

### 3. jessieとしての更新（jessie以前のパッケージなどの更新削除など？）
```sh
sudo apt-get dist-upgrade
```
- souces.listに，jessieと指定があるため，勝手にstretch(Debian 9系)にあがることはないようです

### 4. パッケージが壊れてないかなどを念のためチェック
```
dpkg -C
```
- 何も出なければOK
- 修復などの推奨作業が出た場合対応が必要

## sources.listを更新
### 1. sources.listを更新し、jessie(Debian8系)からstretch(Debian9系)にする
```sh
sudo sed -i /deb/s/jessie/stretch/g /etc/apt/sources.list
sudo sed -i /deb/s/jessie/stretch/g /etc/apt/sources.list.d/*.list
```

## jessie(Debian8系) ⇒ stretch(Debian9系)へアップデート
### 1. sources.listに書いてあるサイトから最新のパッケージリストを取得
```sh
sudo apt-get update
```

### 2. インストール済みパッケージの更新
```sh
sudo apt-get update
```

### 3. stretchとしての更新（stretch以前のパッケージなどの更新削除など含）
```sh
sudo apt-get dist-upgrade
```

### 4. パッケージが壊れてないかなどを念のためチェック
```
dpkg -C
```
- 何も出なければOK
- 修復などの推奨作業が出た場合対応が必要

### ※sources.listの手直し
```sh
sudo vi /etc/apt/sources.list
```
```sh
# deb http://raspbian.raspberrypi.org/raspbian/ jessie main contrib non-free rpi
deb http://ftp.jaist.ac.jp/raspbian buster main contrib non-free rpi
```
- もともとあった1行目を，先頭に`# `をつけてコメントアウト
- 下記から，つながりそうなミラーリストを参照し，2行目を追記（今回の例はjaist）
    -  http://www.raspbian.org/RaspbianMirrors




# buster(Debian10系)にする場合
- 上記手順の[sources.listを更新](#sourceslistを更新)にて、`jessie`⇒`stretch`，`stretch`⇒`buster`と読み替えれば同じ流れで実行可能

# 参考
- https://linuxconfig.org/raspbian-gnu-linux-upgrade-from-jessie-to-raspbian-stretch-9
社内ルーターのログをEC2に転送してみた

# やりたいこと
* 社内で使用しているYamaha RTX1200のログをEC2に転送したい

# 環境
* Windows10
* Teraterm Ver4.105
* RTX1200
* AmazonLinux2

# 前提知識
* AWSでVPCおよびVPNを作成できること
* Vim等のLinuxの基本操作ができること

# 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/21c15f1e-14ce-84b4-31d0-8fb4e009e4f9.png)

> [Yamaha公式サイトより引用](https://network.yamaha.com/setting/router_firewall/cloud/amazon_vpc/setup_rt)

# 手順
* RTX1200を初期化

```RTX1200
# cold start
Password:
RTFS formatting... Done.
Restarting ...
```

* RTX1200をセットアップ

```RTX1200
> administrator
Password:空白でOK
# console character ascii
⇒初期状態は文字コードがSJISで文字化けするのでASCIIに変更
# console lines infinity
⇒デフォルトだと表示する行数に制限がかかっているため制限を外す
```

* RTX1200をインターネットに接続する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/36f35d6c-7d3c-9934-d8af-e0b1c140a15b.png)

詳しい手順は環境によって変わるため割愛。
[CLIでもWeb画面でも設定はできる。](http://192.168.100.1/admin/index.html)
※PPPOE接続が必要な場合はISP情報が必要になるので用意しておくこと
最終的に画像のようにインターネットにつながっていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/facc92ff-1257-4855-3488-e984e7dba4ba.png)

* AWS（VPC）で作成したVPN接続のコンフィグを取得してRTX1200に投入する

※VPNの作り方はそのうち解説したいが今回は割愛

* コンフィグ投入前にAWS,RTXでTunnel 1&2がDownしていることを確認しておくこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/287e67fa-1ca4-b6cb-81bf-3899bd55b62a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/b82529af-6af6-1e34-1060-0b5e356a6d98.png)

* VPC　→　サイト間のVPC接続　→　あらかじめ作成したVPNを選択して設定のダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/28a54b2a-6a7e-210f-0c4f-60ac2e36cf4a.png)

* ダウンロードしたコンフィグの#が無い行+IPSECのローカルIP設定をRTX1200に投入
* 最終的に画像のようにTunnel1＆２がUpになっていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/71523a14-6238-daea-08be-6915bdd37802.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730991/88a97bb4-681d-0df2-f96c-d04cd9c14619.png)

# VPNで接続したVPC内にEC2を作成
* OSはAmazonLinux2、インスタンスタイプは好きなものを選択して起動。
* プライベートIPアドレスでログインできることを確認。

# syslogを設定
* AmazonLinux2にはrsyslogがプリインストールされているのでインストールは不要。
　※rsyslogはsyslogと互換性がある。
* /etc/rsyslog.confファイルの下記2行をアンコメントする。

```
module(load="imudp")
input(type="imudp" port="514")
# syslogはudpプロトコルで通信するためこの2行を有効化する必要がある
```

* /etc/rsyslog.d/フォルダの下に、下記内容のrtxlog.confファイルを作成。

```
local0.*           -/var/log/rtxlog.log
# "local0.*"と"/var/log/rtxlog.log"の間はスペースではなくTabを入力すること
# localの数字は0～7まで好きな数字を選択できる
```

* rsyslogを再起動、syslogが来るか確認。

```
sudo service rsyslog restart
tail -f /var/log/rtxlog.log
# syslogからの書き込みがあれば表示される。
sudo logger -p local0.info "Test Alerm"
# syslogが受信できているかテスト
```

# RTX1200のログをEC2に転送するよう設定変更
* RTX1200にシリアル接続して以下のコマンドを実行。

```
syslog host "EC2のプライベートIP"
syslog facility local0
```

* tail -fしたままになっているEC2でRTX1200からのsyslogが受信できていることを確認して作業完了。

* 今後はログローテーションなど他にも実装する必要があるものがあるので随時紹介していきたい。
opencvを使ってライフゲームを実装した(18行!!)

# はじめに
　暇つぶしにライフゲームを普通とは違う方法で実装しました。せっかくなので記事にしました。

# 実装
　実装したコードはたった**18行!!**モジュールはnumpyとopencvを使っています。

```python:lifegame.py
import cv2
import numpy as np

weight = np.array([
    [2.0, 2.0, 2.0],
    [2.0, 1.0, 2.0],
    [2.0, 2.0, 2.0]
], dtype=np.uint8)
_ = cv2.VideoCapture(-1)
size = 256
s = (np.random.rand(size, size) > 0.5).astype(np.uint8)
while True:
    s_ = cv2.filter2D(s, -1, kernel=weight)
    s = (s_ > 4).astype(np.uint8) * (s_ < 8).astype(np.uint8)
    cv2.imshow('LifeGame', 255 * s.reshape(size, size))
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

```

使用したルールは23/3です。以下のような場合に次の状態が1になります

* 対象セルが1かつ周辺2つが1(畳み込みの値は5)
* 対象セルが0かつ周辺3つが1(畳み込みの値は6)
* 対象セルが1かつ周辺3つが1(畳み込みの値は7)

対象セルの値と周辺で活性化しているセルの数に対して畳み込んだ値は一対一で対応してるので、畳み込みの値によって次のセルの状態が決定することになります。

次の活性化セルの条件を書き換えることでルールを簡単に変更できます。

# 結果
実際に動かした結果がこちらです。ランダムで生成します。
![スクリーンショット 2021-09-11 16.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179010/238b1ef7-7361-07d9-0ae1-a44679061bd0.png)

# 最後に
　私が使用しているPCはMacbookAirですが1024×1024でも余裕で動きます。ぜひ遊んでみてください。
make && make install 実行中に file cannot create directory: /usr/local/lib/pkgconfig.  Maybe need   administrative privileges.

## 概要

cmakeを使ってライブラリをbuildしていた際に
パッケージの説明に従って`make && make install`を実行したら
`file cannot create directory: /usr/local/lib/pkgconfig.  Maybe need   administrative privileges.`
と怒られた。

administrative って書いてあるのでsidoつければいいかなと思ったので
`sudo make && make install`に変えても同じエラーに、、

## 結論

&&使っているので両方のコマンドにsudoつけないとダメだった。。

`sudo make && sudo make install`

これで解決。
ディスクイメージを手元で仮想ドライブにマウントしてリサイズ（シュリンク）する

# ディスクイメージを手元でマウントしてリサイズ（シュリンク）する

## 概要
RaspberryPiなどのディスクイメージを，実際の環境に書き込むことなく手元で仮想的にマウントしてリサイズ（シュリンク）し保存する方法

## 背景
RasPiの実際に動かしているSDカードのイメージをバックアップや移植などの都合でddで（なにも考えず）コピーした場合，いらない空間までもれなくコピーされる．これが8GBや16GBならまあなんとかなるが，32GBとかになると流石に邪魔くさい
また，複製して焼くとなると，書き込み先のサイズが元のサイズ以上でないと問題が起こる．同一サイズでも微妙に内部的に使用可能なサイズが異なるせいで，書き込めたり書き込めないとうことが起こる
解決するために，わざわざ別のディスクに書き出して，リサイズして取り込むというのはかなり面倒なので，全部手元でやろうという話

## 前提
OS: Ubuntu20.04
対象ディスクイメージ: 稼働中のRasPiイメージ
以下RasPiのイメージを扱っている体でコマンドは表現する
その他諸元情報はこのとおり

  - SDカードは /dev/sdc に接続
  - ループバックデバイスはloop10へ接続
  - 内部のパーティションはloop10p1とloop10p2（RasPiのbootパーティションとrootパーティション）

## 手順
`sudo`権限については適宜実行する際に付けてください

1. イメージをまず手元に取り込む
   `dd if=/dev/sdc of=./image.img status=progress`
   - `if` : Input File ここでは/dev/sdcに接続されたSDカード．sdcのcは適宜変わる
   - `of` : Output File ここではカレントディレクトリのimage.imgファイルとして書き出す
   - `status=progress` : 進行状況を表示してくれる．無いと,どんだけかかるかわからんくて辛い

1. 取り込んだイメージのループバックデバイスを作成する
  `losetup -f -P --show ./image.img`
    - `-f` : 空いているループバックの番号を選択する
    - `-P` : パーティションを持つイメージの場合は自動的にそれらを`loop10p2`のように接続してくれる
    - `--show` : `-f`によって自動選択されたループバックデバイスの名前を表示する．今後の操作でどこに繋がれたのかわからんと困る

1. ファイルシステムのシュリンク
   まずパーティションを削る前に，念の為ファイルシステムを目的のサイズまで小さくする
   `resize2fs -p /dev/loop10p2 9G`
      - `-p` : 進捗表示
      - ファイルシステムを選択する必要があるので，パーティション番号まで選択すること
      - ここでは仮に9GBへリサイズすることにする
        - 表記は，K,M,G,Tが使える
      - ここで失敗する場合は`-f`のファイルチェックをせず強制実行するオプションをつける必要がある．（対象がループバックデバイスで，実デバイスではないせいか高確率（僕の環境では100％）で失敗するので，実質必須オプション）

2. パーティションの編集
   パーティション自体を操作する．
   `fdisk /dev/loop10`
   ここからは対話システムがたちがる．入力する手順は
   1. `p` : ディスクの状態を表示（サイズやパーティションのサイズが表示される）
        - 今回は2つ目のパーティションをシュリンクしたいので，2つ目のパーティションの開始セクタの番号をメモっておく
   2. `d` : パーティションを削除する
        - 削除と言っても，中身が消えるわけではなく，ただの管理テーブルが消去されるだけなので，実行して問題ない．また処理は最後に書き込みが実行さるまでは実行されない
   3. どのパーティションを削除するか聞かれるので数字を入力 (今回は`2`を選択)
   4. `n` : パーティションを作成
   5. パーティションの形式をプライマリ（`p`）か拡張（`e`）か聞かれるので選ぶ（今回はもとがプライマリなので`p`を選択）
   6. パーティションの番号を選択（元が２なので２を選択）
   7. パーティションの署名を削除するか聞かれるが`N`で削除しない（削除するとどうなるのかは未検証…よくわかってない）
   8. 開始セクタ位置を入力する．ここで先にメモったセクタ位置を使う
      - つまり，一度削除したパーティションの区切りを，同じ場所に作れば実質リサイズされたことになる…という手順である
   9. 終了セクタ位置を入力する．`+`記号を使うことで，実際に使いたい容量を入力することで設定してくれる（`+10G`とすると10GBの容量を持つ終了セクタを自動計算して使ってくれる．表記は，K,M,G,Tが使える）
   10. `w` : 実際に書き込まれる

3. ファイルシステムの再調整
   先にシュリンクしたファイルシステムを，シュリンクしたパーティションサイズに合わせる
   `resize2fs /dev/loop10p2`
   サイズ指定をしないと自動的に合わせてくれる．

1. ループバックデバイスの削除
   パーティションの編集が終わったので，イメージをループバックデバイスから外す
   `losetup -d /dev/loop10`

1. イメージファイル自体をシュリンク
   ここまでの作業でパーティションはシュリンクしたが，実際のイメージファイルは縮小していない．あくまで内部データが変化しただけなので，使ってない部分は切り落とす
   `truncate --size=$[(終了セクタ+1)*セクタサイズ] ./image.img`
      - 終了セクタ位置に念の為1を加えたものに，セクタ1つのサイズをかけることで，実際に利用されているサイズを計算する
      - セクタ１サイズは512（たいていのシステムは）
      - truncateコマンドで使われているサイズだけを切り取って，残りを切り落とす
      - ここをトチるとパーになる

1. これにて縮小したイメージファイルの完成
   あとは煮るなり焼くなりすきにしてください．



## おまけ
ループバックデバイスを作成後，ファイルシステムとパーティションの操作は，Gpartedが利用できればもっと楽にできるかもしれない    
  `gparted /dev/loop10`   
とすることでGpartedで編集ができる．ただし，高確率でresize2fsでエラーするので，Gpartedでの操作はできないと思われる．（というかできなくて，この七面倒臭い方法を行なったので備忘録として残している）

## まとめ
めんどくさいが，ループバックデバイスを駆使して，仮想でもファイルシステムやパーティションを操作できる
（気が向いたら，コマンドのログや画像を追加したい…が，Ubuntuを起動するのがめんどくさいのである）
10年後のために「私自身が」今勉強しておきたい技術〜Elixir, Nx, SIMD/ベクタ命令, GPU, FPGAプログラミングの高速化を極めたい！

Qiitaが10周年ということで，記念記事を書きました。「10年後のために今勉強しておきたい技術」という部門があるので，ちょうど良いので，10年後のために「私自身が」今勉強しておきたい技術というのを描いてみようと思います。

https://qiita.com/official-events/12fc7bacec894d33a981

# 背景と経緯

2017年以来，私はElixir(エリクサー)におけるコード生成・最適化を研究テーマの主軸にし続けていました。ElixirでGPGPUを実現するPelemay(ペレメイ)シリーズ(旧名称 Hastega: ヘイスガ)にずっと取り組み続けています。一番最初に Lonestar ElixirConf 2019で発表した講演と，Pelemayという新名称を発表したElixirConf US 2019のYouTubeをここで改めて紹介します。

https://youtu.be/lypqlGlK1So

https://youtu.be/uCkPyfFhPxI

その後，Pelemayのアプリケーションとして，人工衛星の画像処理というテーマをいただき，ElixirConf US 2020にて発表を行いました。その後，A-STEPトライアウトの研究助成をいただけることになりました。

https://youtu.be/9H0AsmAsxgk

2021年現在もこのような研究開発をしつこく続けています。

# Nxの登場

Elixirの作者のJosé Valim(ジョゼ・ヴァリム)自身が，PythonにおけるNumPyとTensorFlowのような位置付けである，[機械学習応用向けのライブラリ Nx https://github.com/elixir-nx/nx](https://github.com/elixir-nx/nx) を2020年に発表します。2021年になった現在も精力的に開発が続けられ，もうまもなくHexライブラリという形でリリースされる運びとなりました。

実はこれは，私の作ったPelemayで培った，メタプログラミングを元にしたJITコード生成の技術の影響を受けていて，かつPelemayとは異なるアプローチでJosé流に開発されたものなのです。Pelemayのとっているアプローチは，たとえば行列計算をElixirで書いたプログラムのパターンをメタプログラミングを用いて検出し，それに適合するC言語のプログラムを生成するというものでした。JoséがNxで取ったアプローチはそうではなく，Nxという標準ライブラリをJosé自ら提供し，Nxの流儀に準じたElixirコードをコンパイルするというものです。このようなアプローチは，私では実施し得ない，Joséならではのアプローチです。

またNxは，Pelemayが対象とした，Elixir標準の多倍長整数・浮動小数点数のリスト構造に対して高速化するのではなく，固定長整数・浮動小数点数のバイナリを用いた新たな構造体を定義し高速化を図っています。これはPelemayの性能上のボトルネックであった，型検査とリスト配列相互変換をなくすことができ，より高速化が図れることが期待できます。

他にもNxの特徴として，Googleの提供するXLAにコンパイルするEXLAというバックエンドを提供することで，GPUやTPU上で実行できるという点があります。これは標準的な方法に則っており，とても良い方法だと思います。

# 取り組みたいこと

しかしながら，コード最適化の専門家としては，より高速なNxバックエンドを作ってみたいという野心が私に芽生えました。

下記のGitHubレポジトリは，モノクロ画像フィルタを題材に，Nx(の標準バックエンドであるBinary Backend)と，NIF経由でのネイティブコード(Auto-Vectorizationによるものと，まだまだ拙いながら手でSIMDコードを書いたもの)の実行速度を比較するベンチマークです。

https://github.com/zacky1972/simd_sample

これを実行してみると，Nx(のBinary Backend)で実行したものに比べて，1000倍以上の高速化が図れる見込みがあることがわかりました。

一般に，CPUに比べてGPUがいつでも速いかというとそうでもなく，現状のGPUの弱点は，CPUとGPUの間のデータ転送が相互接続するバスの転送速度が上限となるので，一般的なPCIeバスの場合，ボトルネックになるという問題があるので，CPUの方が速い場合も多々あります。

したがって，今回提示したような高速化の可能性について研究する価値は大いにあると考えています。

# Elixir, Nx, SIMD/ベクタ命令, GPU, FPGAプログラミングの高速化を極めたい！

そういう関心事なので，このような高速化を極めたいと思っています。

近年のMPSoC技術により，マルチコアCPUとGPUやFPGAを組み合わせたMPSoCが多数市販されています。これらの性能をソフトウェアで最大限まで引き出すことに没頭したいと思っています。そして，CPUとGPU，FPGAをどのように使い分けると良いのかについて，指針を得たいと思っています。

今，現在，まだまだ最新CPUの最大性能を引き出すようなコンパイラ技術は未熟だと思っています。同時に，GPUやFPGAについても，まだまだ研究の余地は多々あると感じています。

下記のPelemay Meetupは，そのようなことを研究していく場にしていこうと思っています。2021年9月現在は毎週火曜日に，朝のSIMD勉強会と夕方のBEAM/OTP対話を交互に開催するというスタイルを取っています。今までの会合についてはほぼ全て録画していて，Pelemay YouTubeチャネルで公開しています。もしこの記事で書いたようなことに興味関心がある方は，是非来てください。

https://pelemay.connpass.com

https://www.youtube.com/channel/UCUTHJhKDmRPTgiR4jWKR6dA
Vueでテーブルを書く

# いきなり実装

```html:index.html
<head>
  <meta charset="UTF-8">
  <script src="lib/vue.js"></script>
  <script defer src="tet.js"></script>
  <title>VueTable</title>
</head>
<body>
  <div id="app">
    <table border>
      <tr>
        <th v-for="h in tableHeader" v-bind:name="h.id">{{h.text}}</th>
      </tr>
      <tr v-for="d in tableData">
        <td v-for="h in tableHeader" v-bind:name="h.id">{{d[h.id]}}</td>
      </tr>
    </table>
  </div>
</body>
```


```javascript:tet.js
var app = new Vue({
  el: '#app',
  data: {
    tableHeader: [
      { "id": "id", "text": "ID" },
      { "id": "name", "text": "商品名" },
      { "id": "fee", "text": "値段" }
    ],
    tableData: [
      { "id": "012", "name": "たこ焼き", "fee": "150" },
      { "id": "023", "name": "わたあめ", "fee": "100" },
      { "id": "034", "name": "りんご飴", "fee": "120" }
    ]
  }
})
```

```html:output
<body>
  <div id="app">
    <table border="">
      <tbody>
        <tr>
          <th name="id">ID</th>
          <th name="name">商品名</th>
          <th name="fee">値段</th>
        </tr>
        <tr>
          <td name="id">012</td>
          <td name="name">たこ焼き</td>
          <td name="fee">150</td>
        </tr>
        <tr>
          <td name="id">023</td>
          <td name="name">わたあめ</td>
          <td name="fee">100</td>
        </tr>
        <tr>
          <td name="id">034</td>
          <td name="name">りんご飴</td>
          <td name="fee">120</td>
        </tr>
      </tbody>
    </table>
  </div>
</body>
</html>
```

※イメージ

|ID|商品名|値段|
|--|--|--|
|012|たこ焼き|150|
|023|わたあめ|100|
|034|りんご飴|120|

# 説明
不要だと思うけど。
データ出力部分は、
行毎ループが`v-for="d in tableData"`
列毎ループが`v-for="h in tableHeader"`
でやってる。

おミソは、tableHeaderを配列にしたので、列の入れかえが死ぬほどかんたん。

```javascript:tet.js@順番入れ替え
tableHeader: [
  { "id": "name", "text": "商品名" },
  { "id": "fee", "text": "値段" },
  { "id": "id", "text": "ID" },
],
```

のように、配列内で順番を変えれば列位置も変えられる(だからなんだという感じはなくはない。)

単位もつけてみたいにぇ。

```html:index.html@単位対応
<td v-for="h in tableHeader" v-bind:name="h.id">{{d[h.id]}}{{unitName[h.id]}}</td>
```

```javascript:tet.js@単位対応
unitName: { "fee": "円" }
```

`@順番入れ替え`と`@単位対応`を行った結果※イメージ

|商品名|値段|ID|
|--|--|--|
|たこ焼き|150円|012|
|わたあめ|100円|023|
|りんご飴|120円|034|

いぇい

# 今後に向けて

* テーブルの編集機能作りたい
    * 表示機能と共存させると重くなりそうだけど、テーブル内容の編集・保存機能をつけたい
    * editableにしたり、編集した後の`tableData`のJSONを保存したりしたい。
        * サーバー側のを保存する機能は、サーバーサイドをがっちりしないとダメだろうから、いったん保留
* 属性もいじいじしたい
    * テーブルの幅だの、alignだのだっていじいじしたい。
    * `tableAttrib`とか作って`Header.id`で紐付けた配列にいろいろ持たせたやつを、JavaScriptで後からAddしてあげる感じか
        * `"tableAttrib":{"id":[{"align":"center"},{"width":"50"}],"name":[],"fee":[]}`
            * `align`属性はdeprecatedなのでまた別の方法かもしらん
            * つか、`th`と`td`指定の`name`指定(上記ならば)で、CSSでキメればいいのか
            * でも、WebStormくんが「`name`属性使うなってVue3.0がサジェストしとるで」って言うから、それもなんか違うのかしらん


そんなところです。
Jupyter Lab、ブラウザ変更の留意点。

Jupyter Lab を活用するための環境構築に、"Anaconda3"をインストールする。
インストール後、”Anagonda Navigator"からJupyter Labを起動する。
私の場合は、”Microsoft Edge"であったが、”Google Chrome"に変更したく…踠く。
結果、自身のPC起動時のブラウザの変更によって解決すると分かる。
が、分かるまで大変な時間と労力を費やす。
で、費やした例として”Jupyter Lab　ブラウザ　変更　”と検索する。
検索結果、１から２０までの記事を見るが…”自身PCの起動時のブラウザを変更する”との
記事はありませんでした。
で、私のような”アンポンタン”はいないと思いますが、如何せん世の中は広いので、
私のように、無駄な時間と労力を費やすことのないようにとも思い投稿します。
@IBDesignable, @IBInspectableなカスタムビューを実装する

# はじめに
どの画面に何のパーツがあるのか一目でわかるようにカスタムビューをIB上に表示したい時がありました。
`@IBDesignable`, `@IBInspectable`を使った実現方法を紹介します。

# 環境
`Xcode 12.5.1`
`macOS Big Sur 11.5.2`

# 完成形
完成すると動画のように変更がリアルタイムで確認できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/1eea1f64-4a89-b40f-ebbb-04f0870475ed.gif" width="400" />


# 大まかな実装手順
1. UIViewを継承したCocoa Touch Class(CustomView.swift)を作成する
2. xibファイル(CustomView.xib)を作成する
3. File's ownerでswiftファイルとxibファイルを紐付ける
4. `@IBDesignable`, `@IBInspectable`を使って`CustomView.swift`を実装する

次に`CustomView.swift`の実装について詳しく見ていきます。

# `CustomView.swift`
CustomViewでは受け取った文字列をUILabelに反映します。
文字列を画像のようにインスペクタ上で変更できるよう`@IBInpspectable`を宣言します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/06e37303-301d-f89f-3e82-7ab3567e8cc8.png" width="400" />

また、カスタムビューの変更をIB上に表示するためにCustomViewに`@IBDesignable`を設定します。

```swift:CustomView.swift
@IBDesignable
class CustomView: UIView {
    @IBOutlet weak var label: UILabel!
    @IBInspectable var labelString: String = ""
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        loadNib()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        loadNib()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        setupLabel()
    }
    
    private func loadNib() {
        guard let view = Bundle(for: type(of: self)).loadNibNamed("CustomView", owner: self, options: nil)?.first as? UIView else {
            return
        }
        view.frame = bounds
        addSubview(view)
    }
    
    private func setupLabel() {
        label.text = labelString
    }
}

```


# 最後に
カスタムビューがIB上で見えることで、どこに何があるか一目で分かります。
後からプロジェクトに入った方も実装を進めやすいと思いました。
【C#】文字の抜粋と配列

##文字列の抜粋





```C#:前提条件
//abcde と入力
string str = Console.ReadLine();
```
以降それぞれのパターンを記載します。
<br>
###配列の中身を抜粋する
---
####前から数えて抜粋
```C#:ToCharArray()
//インデックス2番目を始点と数え、4つ抜粋する
char[] chArray = str.ToCharArray(2, 4);

Console.WriteLine(chArray);
//cdef
```

```C#:str.Substring()
//同上別のパターン
Console.WriteLine(str.Substring(2, 4));
//cdef
```

```C#:SubstringByTextElements()
//同上別のパターン
using System.Globalization;
...(略)

StringInfo str2 = new StringInfo(str);
Console.WriteLine(str2.SubstringByTextElements(2, 4));
//cdef
```

```C#:範囲演算子（「..」と表記されているもの）
char[] chArray = str.ToCharArray();

//インデックス2番目から3番目までを抜粋する（2以上4未満）
Console.WriteLine(chArray[2..4]);
//cd
```
<br>

仮に…
インデックスじゃなくて、数えでの2番目～4番目を抜粋したい。
範囲演算子「..」を使用しない場合。


```C#:数えで2番目から4番目を抜粋（2以上4以下）
char[] chArray = str.ToCharArray(2 - 1, 4 - 2 + 1);
Console.WriteLine(chArray);
//bcd
------------

//入力あり ＋ 計算部分を置き換え

int num = int.Parse(Console.ReadLine());
//2
int num_2 = int.Parse(Console.ReadLine());
//4
char[] chArray = str.ToCharArray(num - 1, num_2 - num + 1)
//bcd
```


<br>

配列をコピーして抜粋

```C#:Array.Copy()
char[] chArray = str.ToCharArray();
char [] chArray_copy = new char[6];

//chArray[1]～の中身を、 chArray_copy[2]～[5]にコピー。
//（chArray_copyのインデックス2番目を含んだ、4つ分のインデックスにコピー）
//（つまりchArray_copy[2][3][4][5]の位置にコピーする）
 Array.Copy(chArray, 1, chArray_copy, 2, 4);

Console.WriteLine (chArray_copy);
//bcde
```
ちなみに、
`Array.Copy()`では参照元（コピー元）の値が変化しても影響を受けないです。
<br>
####後ろから数えて抜粋
```C#:^
//後ろから数えて2番目を抜粋
Console.WriteLine(chArray[^2]) ;
//d
```
<br>
---
###入力した文字列を1文字ずつ配列に入れる
```C#:
//例：a b c de f と入力
string str = Console.ReadLine();

char[] chArray = str.ToCharArray();
//[a][ ][b][ ][c][ ][d][e][ ][f]
```
空白ごと入ります。
<br><br>

```C#:
using System.Linq;
...（略）
char[] ch = str.ToArray();
//[a][ ][b][ ][c][ ][d][e][ ][f]
```
また、`ToArry()`でも同様に配列ができます。
この場合は`using System.Linq;`を追加します。
<br>


---

###入力した１文字が何番目にあるか探す
```C#:
//例；abcde　と入力
string str = Console.ReadLine();

char [] chArry = str.ToCharArray();

//探したい文字をひとつ入力
int str2 = Console.Read();
//b

 for (int i = 0; i < str.Length; i++) {
     if ((char)str2 == chArry[i]) {
Console.WriteLine(i + 1);
//2
      }
    }
```
bという文字が2番目にあることが分かります。
<br>
---
##参考にしたサイト
[String.ToCharArray メソッド](https://docs.microsoft.com/ja-jp/dotnet/api/system.string.tochararray?view=net-5.0)
[StringInfo.SubstringByTextElements メソッド0](https://docs.microsoft.com/ja-jp/dotnet/api/system.globalization.stringinfo.substringbytextelements?view=net-5.0)
[インデックスと範囲](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-8#indices-and-ranges)
[Array.Copy メソッド](https://docs.microsoft.com/ja-jp/dotnet/api/system.array.copy?view=net-5.0)
[M1 Mac] zshで用意してたzshrcなどがなにも読み込まれなくなった

## 原因

```
env |grep ZDOTDIR
ZDOTDIR=/var/folders/md/3c1mvffj38l1hbxcnr1xtnyw0000gq/T/.tmpAeFhHU
```

これがよく分からないところに設定されている。。。
なぜ？

## 解決策

```
/etc/zshenv
$ZDOTDIR/.zshenv
/etc/zprofile
$ZDOTDIR/.zprofile
$ZDOTDIR/.zshrc
/etc/zlogin
$ZDOTDIR/.zlogin
```

の順に読まれるとのことなので

`/etc/zshenv`に以下を追加。

```
export ZDOTDIR=$HOME
```
Unity Memory 削減したい。参考先一覧。勝手に順位つけた。

# 1位
https://www.slideshare.net/UnityTechnologiesJapan/unity-2017-82248953

シンプルに凄くためになる。

# 2位
https://www.crossroad-tech.com/entry/UnityAsset_MeshBaker


# Mesh Bakerの使い方
https://www.petitmonte.com/unity/MeshBaker.html

# あれ？？wasmじゃなくない？？
https://programming.sincoston.com/unity-build-wasm-asmjs/

そういえば3D Kit Lite いれた時変わってた気がする。orz((^ ^
Unity 攻撃基礎参考にしたもの一覧

動き
https://miyagame.net/vroid-unity-unity/

なんか色々
https://www.ame-name.com/archives/tag/%E6%94%BB%E6%92%83

# 3D Game Kit Lite とキャラの差し替えをした
https://hoshimi12.com/?p=20488#i-7
https://hoshimi12.com/?p=20503

## 3D game kit について
https://hoshimi12.com/?p=20488#i-7
Unityを始める際にみたサイトetc.

# VScode設定
https://qiita.com/GengroHirano/items/e2e72102446a810fa119
https://www.exceedsystem.net/2020/08/25/how-to-enable-intellisense-in-vscode-for-unity/
https://unity-yuji.xyz/vscode-unity-omnisharp-netframework-mono/


# class 参照けい
https://qiita.com/Teach/items/8d1cdb90a3b533707c9a
// 下重要
https://miyagame.net/other-script-method/
# onpress
https://t-stove-k.hatenablog.com/entry/2018/06/23/220823

# 動的色変更
https://qiita.com/Hal_mai/items/1469398078e81bc7ef27

# カメラ回転
https://mslgt.hatenablog.com/entry/2017/02/18/020630

https://qiita.com/TERRAIN_JP/items/57428f998bbdd13d7655
aws cli を docker で設定する

aws cli の docker イメージが公式から提供されていました。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-docker.html#cliv2-docker-aliases

``aws``コマンドで aws cli の docker コンテナを簡単に起動できるように設定してみます。

## 設定してみる

``aws``コマンドで docker コンテナが立ち上がるように、 alias を設定します。

```terminal
alias aws='docker run --rm -it -v ~/.aws:/root/.aws amazon/aws-cli'
```

alias が設定できているか確認します。

```terminal
$ aws --version
aws-cli/2.2.37 Python/3.8.8 Linux/4.19.128-microsoft-standard docker/x86_64.amzn.2 prompt/off
```

``~/.aws``に認証情報がない場合は、``configure``コマンドで作成します。

```terminal
$ aws configure
AWS Access Key ID [None]: dummy
AWS Secret Access Key [None]: dummy
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

ホスト側に認証情報が作成されているか確認します。

```terminal
$ cat ~/.aws/credentials
[default]
aws_access_key_id = dummy
aws_secret_access_key = dummy
```

## おわりに

docker コンテナで aws cli の設定できるのは便利ですね。aws cli のバージョンが今後上がったとしても、docker image のバージョンを変えるだけで任意のバージョンに簡単に変更できるので、使い道は多そうです。
C++ 正規表現　サンプル

# introduction
C++ で正規表現を使うことがあったので、サンプルとして提供します。

下のWebアプリを作った際、MySQLのコマンドを書くときに使用したものです。

https://find-que.com

# MySQL について
軽くMySQLについて説明しておきます。
以下のURLに記されているように文字の中でも**特殊文字エスケープシーケンス**と呼ばれるものがあります。
「**'**」や「**"**」 などの文字ですね。これらをMySQLコマンドに載せたい場合は「\'」「\"」のように書く必要があります。

https://dev.mysql.com/doc/refman/5.6/ja/string-literals.html#:~:text=%E8%A1%A8%C2%A09.1%C2%A0%E7%89%B9%E6%AE%8A%E6%96%87%E5%AD%97%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9

# C++ で正規表現を使う
**regex**というライブラリを使います。またC++11の生文字リテラルを使用します。

https://cpprefjp.github.io/reference/regex.html

https://cpprefjp.github.io/lang/cpp11/raw_string_literals.html

```ruby
#include <iostream>
#include <regex>
#include <string>

string sqlText(string text) {
    std::regex re(R"("|'|\\)");
    const std::string fmt = R"(\$&)";
    string formated_text = std::regex_replace(text, re, fmt);
    // cout << "ss == " << formated_text << endl;
    return formated_text;
}
```

sqlTextの一行目で正規表現で探したいものを設定します。今回は「'」「"」「\」を探すことにしました。

https://www.megasoft.co.jp/mifes/seiki/meta.html

fmtで何を入れ替えるか明示します。今回はreで探した文字を先頭にバックスラッシュをつけた状態にします。

std::regex_replaceを用いて実際の処理をします。

以上
OpenID Connect RP-Initiated Logout メモ

* 業務でSLOの検討をする必要があったため、その学習内容をメモする。

## RP-Initiated Logout

* RP が、ユーザーエージェントをOPのログアウトエンドポイントにリダイレクトすることにより、OPがエンドユーザーからログアウトすることを要求するための機能。

### 処理の流れ


1. RP は OP から RP-Initiated Logout 用に提供された URI に、ユーザーエージェントをアクセスさせる。このとき、ログアウト後の遷移先となる RP のURI （`post_logout_redirect_uri`）などのパラメータをクエリ指定してもよい。
   * このタイミングでRP側をログアウトさせてもよい。
2. OP は渡されたパラメータを検証する。
3. OPはユーザーに「ログアウトしてもよいか」確認し、同意された場合にログアウトする。
   * SSO中の他のRPにログアウトを通知する方法については、以下を参照のこと。
     * OpenID Connect Session Management 1.0 
     * OpenID Connect Front-Channel Logout 1.0
     * OpenID Connect Back-Channel Logout 1.0
4. `post_logout_redirect_uri` にRPからのリダイレクトで受け取った`state`を付与してリダイレクトする。
5. RPは`state`を検証する。

![RP-initiated_logout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/29f81b8f-b92f-24de-9878-ff89bf963a1a.png)


- `id_token_hint`
  * 推奨。
  * OPによって以前にRPに発行されたIDトークン。
  * エンドユーザーのクライアントとの現在の認証済みセッションに関するヒントとしてログアウトエンドポイントへ渡す。
  * RPがOPによるログアウトを要求しているエンドユーザーのIDを示すために使用する。
- `post_logout_redirect_uri`
  * オプション。
  * ログアウトが実行された後、RPがエンドユーザーのユーザーエージェントのリダイレクトを要求するURL。
  * `https`スキームを使用する必要があり、ポート、パス、およびクエリパラメータコンポーネントを含めることが可能。コンフィデンシャルクライアントタイプで、OPがhttp RP URIの使用を許可している場合は、httpスキームを使用可能。
  * OPに事前登録必要。
  * 本パラメーターが含まれている場合は、`id_token_hint`も必要。
- `state`
  * オプション。 
  * `post_logout_redirect_uri`パラメーターで指定されたエンドポイントへのログアウトリクエストとコールバックの間で状態維持するためにRPによって使用される値。
  * ログアウトリクエストに含まれている場合、OPは、ユーザーエージェントをRPにリダイレクトするときに、`state`パラメーターを使用してこの値をRPに返却する。
- `ui_locales`
  * オプション。 
  * UI用のエンドユーザーの優先言語とスクリプト。
  * 優先順に左から指定。

## 参考

* [OpenID Connect RP-Initiated Logout 1.0 - draft 01](https://openid.net/specs/openid-connect-rpinitiated-1_0.html)
[Ruby] AtCoder過去問 C - Alchemist

##はじめに
AtCoder過去問C問題をRubyで解いてみました。

問題はこちらから確認してください。↓

https://atcoder.jp/contests/abc138/tasks/abc138_c


##C - Alchemist

なんだかゲームとかで使われそうなアルゴリズムですね。
入力受け取りから書いていきます。

```ruby
n = gets.to_i
worth = gets.split.map(&:to_i).sort!
```

ちなみに私の解き方では1行目のnは使いません。
2行目は複数の値をworth(価値)という変数に配列として代入しています。
また```.sort!```をつけてます。これは配列の中身を昇順に並び替えています。


この問題の肝は、どの順番に合成していけば最大価値を持ったの具材が作れるかです。

その条件は小さいものから、処理を行うことです。

配列を昇順に並び替えたのはそのためです。
shiftメソッドがかなりいきてきます。
ちなみにshiftの使い方はこちらにまとめております。↓

https://qiita.com/minhee/items/cfaa0d8e196f97a1f1dc

```ruby
n = gets.to_i
worth = gets.split.map(&:to_i).sort!

ans = worth.shift

while worth != []
  ans = (ans + worth.shift)/2.to_f
end

puts ans
```

問題文の足して2で割るという処理は合成された時のみなので一番初めの元となる具材には適用しません。
ですのではじめにansに一番小さい要素（配列の先頭）を代入しておきます。


while文の条件式に配列worthが空になるまで処理を繰り返すようにします。
処理の中身はworthの中で一番小さい要素(配列の先頭)を取り出して、ansに足して、２で割ってansに代入です。

worthの中が空になったらansに一番価値が大きい方法で合成された具材の価値が入っているはずです。
vscode エラーのポップアップ表示の仕方

## ホバーした時にエラーをポップアップで表示

カーソルを合わせた時にエラーメッセージのポップアップを出すやり方がわからなかったのでメモ

1. 設定 -> 「hover」で検索
2. Editor > Hover:Enabledにチェックを入れる<br>
<img alt="error-show.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250620/9d71d489-e934-90b3-553f-228abc47688d.png" width="500">

赤線の箇所をクリックするとエラーが表示される
<img alt="popup.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250620/73c78cf0-0891-475f-9766-30aad71dcdcf.png" width="500">