OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】Laravel実践開発備忘録 Algoliaインポートエラー

## 記事の目的

書籍「PHPフレームワーク Laravel実践開発」を学習する中で、おそらくまた同じ問題に引っ掛かるであろう部分をまとめた備忘録です。

## 困ったこと
モデルからAlgoliaへのインポート実行時、下記エラーが発生。
scout.php設定項目である「ALGOLIA_APP_ID」と「ALGOLIA_SECRET」の値は問題なかった。

### 実行コマンド
```php
php artisan scout:import "App\Models\person"
```

### エラー内容
```
Impossible to connect, please check your Algolia Application Id. 
{"exception":"[object] (Algolia\\AlgoliaSearch\\Exceptions\\UnreachableException(code: 0): Impossible to connect, please check your Algolia Application Id. at C:\\1_Project\\laravelapp\\vendor\\algolia\\algoliasearch-client-php\\src\\RetryStrategy\\ApiWrapper.php:196)
```

## 環境
OS:windows10
Laravel:8.40

## 対処法
1. 最新版のcacert.pemのダウンロード
   curlの公式サイトから[ Documentation ] - [ CA bundle ]と辿り、
cacert.pemファイルをダウンロードする。 

2. php.iniファイルの修正 
1.でダウンロードしたpemファイルを任意の場所に配置し、
絶対パスをphp.iniファイルの下記項目に記載する。

```
curl.cainfo = "C:\XXXXX\cacert.pem"
```

- [curl.cainfo](https://www.php.net/manual/ja/curl.configuration.php#ini.curl.cainfo)とは  
[CURLOPT_CAINFO](https://curl.se/libcurl/c/CURLOPT_CAINFO.html)のデフォルト値になる。
CURLOPT_CAINFOは、証明書のパスを設定する。

## 課題
証明書、curl、https周りの知識が不足していると感じたので、改めて学習したいと思います。

## 参照サイト
https://laracasts.com/discuss/channels/laravel/cant-connect-to-algolia?page=1

https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate
STM32 DMAを使ったUART通信ではまる

#はじめに

UARTでDMAを使いたかった。ところが...

送信時，どうも連続して送ろうとすると失敗する。

受信時，配列に最初の1このデータしか入力されない。

Mem側をIncrement指定しているのに，デバッガで止めてみると無視されている。
MINC=1になってほしいのに0になっている。

![GetImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/6747340a-2b08-485a-4dd2-ac7c0ed6fb0e.png)

レジスタを触って解決するのは何か気持ちが悪いので，解決方法を探ってみた。

https://community.st.com/s/question/0D50X0000Bmob3u/dma-not-working-in-cubemx-generated-code-order-of-initialization 

DMAをめぐるトラブルは結構あるみたい。 

https://community.st.com/s/question/0D50X0000BVnBhASQV/bug-report-dma-and-adc-initialization-order-changed-in-stm32f4-hal-v1241-causing-incorrect-adc-operation 

このあたりの情報で解決した。Device Configuration Tool - Project Manager - Advanced Setting で MX_DMA_Init を上の方にもっていく。 

# 見つけた解決法

以下，手順を覚書。

RX/TXでDMAを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/5bbf5202-1a70-4bf5-efdb-c9c7c2c661e3.png)

さらにこの画面で，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/adff8f12-f310-9849-3566-6c611bd04a23.png)

こんな感じにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/1c214e85-4dce-6695-a43a-2e0b0c6a48a5.png)

さらに USART2 global interrupt を有効にします。これをしないと，送信終了，受信終了がわかりません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/80c03834-287b-e058-60fb-161236bf612a.png)

main関数の前です。送信完了がわかるようにします。また，受信完了したら再度受信スタンバイします。ここではついでにLEDをToggleしてます。

```cpp:main.c
/* USER CODE BEGIN 0 */

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
	huart2.gState = HAL_UART_STATE_READY;
}

uint8_t UART2_RX_Buffer[8];

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
	if (huart->Instance == USART2) {
		HAL_UART_Receive_DMA(&huart2, UART2_RX_Buffer, 8);
	}
}
/* USER CODE END 0 */
```

そしてmain関数の序盤です。

- 送信完了を検知してから次のデータを送らないと，無視されてしまいます。
- 受信待機開始します。

```cpp:main.c
	/* USER CODE BEGIN 2 */

	HAL_UART_Transmit_DMA(&huart2, (uint8_t*) "Boot NUCLEO\r\n", 13);
	while (huart2.gState != HAL_UART_STATE_READY) {
	} // 送信完了を確認
	HAL_UART_Transmit_DMA(&huart2, (uint8_t*) "Type any key.\r\n", 14);
	while (huart2.gState != HAL_UART_STATE_READY) {
	} // 送信完了を確認
	HAL_UART_Transmit_DMA(&huart2,
			(uint8_t*) "Then toggle LED each 8 letters.\r\n", 33);

	HAL_UART_Receive_DMA(&huart2, UART2_RX_Buffer, 8);

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1) {
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
```

#補足

色々な事情で，NUCLEO-F303K8 (CPU:STM32F303K8) だけでなく，STM32G0 の CPU 2種類も，同様であることを確認しました。

また暫定ですが，ADCでDMAを使いたい場合も，DMA初期化をADC初期化の前に持ってくる必要がありそうです。

#参考URL

みなさんに感謝です！

https://qiita.com/toshidln/items/3bbda2a0ba826730e490

https://qiita.com/forest1/items/64f885570a4f32a4d5a0

http://meerstern.seesaa.net/article/445609716.html
PHP のエラーメッセージ Cannot access offset of type string on string in ...

エラーメッセージの意味がよくわからなくて苦労したので、備忘録として。（ネットで記事が見つからなくて困りました。特に日本語のもの。）
この記事は、PHP8.0 でのものですが、たぶん、もっと以前のバージョンでも同様です。

## メッセージの意味
このエラーメッセージは、
「文字列に対して【文字列型のオフセット】でアクセスすることはできません！」
という意味です。

## エラーの背景
PHPでは、配列に対して`[int|string]`型の「キー」を使って配列の要素にアクセスできると同時に、文字列に対しても、`[int]`型の「オフセット」と呼ばれる方法で、文字列中の特定の文字にアクセスすることができます。

(例)
1.配列の要素にアクセスする

以下の例では、`$arr[0]` は`xyz`、`$arr['イ']` は `1` となります。
```PHP
$arr = [
   0   => 'xyz',
   1   => 'abc',
  'イ' => 1,
  'ロ' => 2,
  'ハ' => 3
];

echo $arr[0];    // -> xyz
echo $arr['イ']; // -> 1
```
  
2.文字列の一部にアクセスする

以下の例では、`$str[0]` は`a`、`$str[1]` は `b` となります。
```PHP
$str = 'abcde'; // (訂正)以前は'あいうえお'でした。訂正してお詫びします。

echo $str[0]; // -> a
echo $str[1]; // -> b
```

## エラーの原因

上の2.の例で、`$str['イ']` などとすると、表題のエラーが発生します。（本来は、上の1.の例のような、「イ」キーを持つ配列の要素にアクセスしようとしていたのでしょう。）

```PHP
$str = 'abcde';

echo $str['イ']; // -> Cannot access offset of type string on string in ...
```

つまり、配列の要素に「文字列型のキー」でアクセスしようとしていたのに、間違って、文字列（が格納されている変数）に対して「文字列型のオフセット」でアクセスしてしまい、表題のエラーが発生したものと推測されます。
TsukuCTF 2021 -   shop 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/3e9d2c74-69c2-000d-7575-dc8d705fa161.png)

#解いてみた

動画を見てみるとイオンモールが映っていて道路を挟んで反対側に海か湖みたいなのが映ってる動画。
イオンモール内に無印良品やGUが映っていたけどどこでも入ってそうなので他の探しているとトヨタカローラがあった。

「イオンモール カローラ」などで調べるとイオンモール幕張新都心が出てきたのでいい感じでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d76a6471-7250-31c7-6677-d5885970a9e6.png)

これを入力してみると間違い。
検索結果の上から順番に地図を見ていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4e4637d8-155d-c905-2fb0-c89723d8f5e2.png)

ちょっと今回は答えをマスクするのが難しいですが、ここが正解でした。
図解USBの転送規格とコネクタ形状の関係

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43992/08ee07e7-e0b8-177b-1c04-4b8b9b2dce42.png)

自分が不勉強で、USB 3.2 やら USB Type-C やらがわけわかめだったので整理した。
混沌としすぎなんじゃよ君たち。

## 一言コメント
情報は全部 [Wikipedia](https://en.wikipedia.org/wiki/USB) に乗ってたよ。

### 転送規格
信号種別やらプロトコルやらあるけど、ユーザー目線で言うと転送速度。USB ロゴマークもおおむねそれに準拠した形になっている。

| Ver       | Name       | Data Rate                | logo |
|-----------|------------|------------              |------|
| USB 2.0   | LowSpeed - HighSpeed | 1.5 Mbit/s - 480 Mbit/s| <img src="https://upload.wikimedia.org/wikipedia/commons/6/67/USB_icon.svg" width=50px> |
| USB 3.0   | SuperSpeed      | 5 Gbit/s                 | <img src="https://upload.wikimedia.org/wikipedia/commons/a/a1/USB_SuperSpeed_5_Gbps_Trident_Logo.svg" width=50px> |
| USB 3.1   | SuperSpeed+     | 10 Gbit/s                | <img src="https://upload.wikimedia.org/wikipedia/commons/1/1c/USB_SuperSpeed_10_Gbps_Trident_Logo.svg" width=50px> |
| USB 3.2   | SuperSpeed+     | 20 Gbit/s                | <img src="https://upload.wikimedia.org/wikipedia/commons/d/d3/USB_SuperSpeed_20_Gbps_Trident_Logo.svg" width=50px> |
| USB4      | SuperSpeed+     | 40 Gbit/s                | <img src="https://upload.wikimedia.org/wikipedia/commons/4/4a/USB4_40Gbps_Logo.svg" width=50px> |

### コネクタ形状
大きく3グループに分かれる。

1. Type-A, B
2. Type-A, B SuperSpeed （別名「SS」「3.0」「青」）
3. Type-C

| Type           | Ver            | Pin |
|-----------     |------------    |------|
| Type-A, B      | USB 2.0        |<img src="https://upload.wikimedia.org/wikipedia/commons/7/7e/USB_Type-A_receptacle.svg" width=50px>|
| Type-A, B SuperSpeed | USB 3.0 & 3.1  |<img src="https://upload.wikimedia.org/wikipedia/commons/f/f4/USB_3.0_Type-A_receptacle_blue.svg" width=50px>|
| Type-C         | USB 3.2 & USB4 & Thunderbolt 3|<img src="https://upload.wikimedia.org/wikipedia/commons/0/07/USB_Type-C_Receptacle_Pinout.svg" width=50px>|

あくまでコネクタの形状なので、片方がType-Aで他方がType-Cとかはざらにある。当然、転送速度は低いほうにそろう（Type-C は一応 USB 2.0 にも対応してる）。
TsukuCTF 2021 -   ramen 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b6438b65-8619-5801-7093-986861f0477f.png)

#解いてみた

画像を見てみます。

![ramen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f98b3240-49f4-57ac-96c9-778abc78a419.png)

「ラーメン　ヤングコーン」とかで検索してると銀座篝という店が出てきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/834b9959-3f5b-2a40-99e3-2b5fdea0de6f.png)

インスタグラムIDが何なのか知りませんでしたが、名前みたいなところがそのままインスタグラムIDだったみたいです。
WindowsでCtrl + hでアクティブウィンドウを最小化する方法（AutoHotKey）

## 状況
MacのCommand + hみたいな感じでアプリを簡単にしまいたく、また他でCtrl + hも特に使ってないのでこのコマンドに割り当てたい状況でした。

## 結論
これをAhk2Exeでexeにコンパイルしてスタートアップフォルダにショートカットを置いて自動起動するようにしました。

```HideActiveWindow.ahk
^h::PostMessage, 274, 61472, 0, , A
    Return
```

参考：[AutoHotkeyでウィンドウ表示方法変更](http://autohotkey.s365.xrea.com/window_show.html#:~:text=%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%81%AE%E6%9C%80%E5%B0%8F%E5%8C%96,%E6%9C%80%E5%B0%8F%E5%8C%96%E3%81%99%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%E3%81%99%E3%80%82)
AtCoderログ：0122 - ABC 150 C

# 問題

https://atcoder.jp/contests/abc150/tasks/abc150_c

## 問題文
> 大きさ $N$ の順列 ($(1, 2, ..., N)$ を並び替えてできる数列) $P, Q$ があります。
> 大きさ $N$ の順列は $N!$ 通り考えられます。このうち、$P$ が辞書順で $a$ 番目に小さく、$Q$ が辞書順で $b$ 番目に小さいとして、$∣a−b∣$ を求めてください。

## 制約
> ・$2 \le N \le 8$
> ・$P, Q$ は大きさ $N$ の順列である。
> ・入力は全て整数である。

## 収録されている問題セット
- [AtCoder Problems Boot camp for beginners Easy 100](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) [#025]

# 回答
## 回答1 (AC)
順列の順序に関する問題なので、next_permutation() 関数を使用するのが簡単です。数列 $P,Q$ を順列として読み込んだ後、最も小さい順列 $(1,2,\dots,N)$ を初めとして next_permutation() によって小さい順に順列を生成し、$P,Q$ に等しいときはそのカウンタ値を記憶します。そして最後に2種類の記憶値の差を求めれば良いです。コードは以下のようになりました。

```C++:abc150c-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n;
  cin >> n;
 
  vector<int> p(n);
  for ( int i=0; i<n; i++ ) {
    cin >> p.at(i);
  }

  vector<int> q(n);
  for ( int i=0; i<n; i++ ) {
    cin >> q.at(i);
  }
  
  vector<int> r;
  for ( int i=1; i<=n; i++ ) {
    r.push_back(i);
  }
  
  int a, b, counter = 1;
  do {
    if ( p==r ) {
      a = counter;
    }
    if ( q==r ) {
      b = counter;
    }
    counter += 1;
  } while ( next_permutation(r.begin(),r.end()) );
  
  cout << abs(a-b) << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc150/tasks/abc150_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2020/01/11/144924)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc150/tasks/abc150_c/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/abc150/editorial.pdf)
回答1と同じ方針でした。


# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0121 - ABC 092 B](https://qiita.com/RoadLynton/items/60e3247a475e0f1a6c93)
NEDITの操作方法まとめ１


######　　　　以下は、ACOSの日本語エディタ（NEDIT)の操作方法を記載する自分のメモ
##　　　　　　　はじめに

  __<font color="blue">　【ACOS（Advanced Comprehensive Operating System）】</font>とは__　日本電気（NEC）製のメインフレームという大型の汎用機のOSです。

#####　　このメモは、ACOSで使用する対話情報処理システム(ATSS)の日本語エディタ（NEDIT)のコマンドまとめです。

###○<font color="blue">行サブコマンド</font>（操作したい行の1桁目～6桁目に記載する）

#####・指定した1行をコピーする
      K

#####・指定した範囲の行をコピーする
      KK～KK

#####・指定した1行を切り取る
      M

#####・指定した複数行を切り取る
      MM～MM

#####・指定した1行を削除する
      D

#####・指定した範囲の行を削除する
      DD～DD

#####・指定した行の下に貼り付ける
      P

#####・指定した1行をコピーして、下に貼り付ける
      KR

#####・指定した範囲の行をコピーして、下に貼り付ける
      KKR～KKR

#####・指定した行数分、空白行を追加する
      I(行数)

#####・文字を指定したX桁分右へ移動する
      )X

#####・))内の複数行の文字を指定したX桁分右へ移動する
      ))X

#####・文字を指定したX桁分右へ移動する
      (X

#####・((内の複数行の文字を指定したX桁分左へ移動する
      ((X


###○<font color="blue">サブコマンド</font>（SCMD ==> に記載する）


#####・保存
      W

#####・名前をつけて保存
      WR 'メンバー名'

#####・検索コマンド
      F /文字列/

#####・先頭行から検索コマンド
      F /文字列//F

#####・Grepコマンド
      GL /文字列/

#####・Grep解除コマンド
      L

#####・行番号から画面表示
      L n（行番号）

#####・置換コマンド(先頭行から最終行まで文字列１を文字列２に置換する)
      S /文字列１/文字列２/^:\

#####・指定した文字を含む行以外を削除するコマンド
      XD /文字列/

#####・右移動(位置指定)
      CS n（行数）

#####・先頭桁に戻す
      CS

#####・画面を二等分にする
      FN

#####・二等分の画面を元に戻す
      FF

##　　　　　　NEDITの操作方法まとめ２
　　　https://qiita.com/nano357/items/7401bceecf4663652c9b
Material UIのモーダル使用時に発生したエラー

# エラー内容
Material UIの`Modal`を使っていたのですが、自作のコンポーネントをModalの`body`の代わりに使おうとしたらエラーが発生しました。

以下、エラー内容です。

```
Warning: Function components cannot be given refs.
Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?
```

```
Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Modal)`.
Expected an element that can hold a ref.
Did you accidentally use a plain function component for an element instead?
```

このようなエラーが出てしまい「？」状態が続いていました。

# 解決方法
結局、冒頭に書いた通り<Modal></Modal>の中に、下記コードのように`自分で作ったコンポーネント`を当てはめていたことが原因だったみたいです。

```sample.tsx
<Modal>
  {<Body/>}
</Modal>
```
なので、同じファイルの中に`const = body()`を作り直し、それを`Modal`の中に当てはめることにしました。
そうすることで、エラーは消えました。

```sample.tsx
const body = (
  <div>
    <p>ほげほげ</p>
　　 -- もろもろ省略 --
  </div>
)

return (
  <Modal>
    {body}
  </Modal>
)
```

# まとめ
本来、[公式](https://material-ui.com/components/modal/)の方でも、直接Modalの中身を書いていたり、**Typography**などを用いていたので、しっかりそちらを参照するべきでしたね。

次から気をつけていきたいと思います。
【raspbian（Raspberry Pi）】Apache2で仮想ホストを追加する

現在使用しているRasPiに仮想ホストを追加する手順です。
既にApache2で仮想サーバが稼働しており、あたらしく仮想ホストを追加したい方向けになります。

##１．デフォルトの仮想ホスト設定ファイルを、任意の名前で複製
debian Apache2では、デフォルトの仮想ホスト設定ファイルは「/etc/apache2/sites-available/000-default.conf」です。

```vim:/etc/apache2/sites-available/
$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/laravel-sample.conf
```

##２．コピーした仮想ホスト設定ファイルを修正
複製した仮想ホスト「ポート番号」「ドキュメントルート」を修正します。

```vim:/etc/apache2/sites-available/
$ sudo vi /etc/apache2/sites-available/laravel-sample.conf

<VirtualHost *:60001>
    
    /* 略 */
    
    DocumentRoot /var/www/sample/public

    /* 略 */
    
</VirtualHost>

```

##３．仮想ホスト設定を有効化
修正した仮想ホスト設定をApache2に反映します。

```vim
$ sudo a2ensite laravel-sample.conf
```

##４．Apache2の待機ポートを修正
手順２で記述したポート番号をApache2の待機ポートに追加します。

```vim
$ sudo vi /etc/apache2/ports.conf

# laravel_sample 動作ポート
Listen 60001
```

##５．Apache2を再読み込み
変更した設定の読み込みを行います。

```vim
$ sudo systemctl reload apache2
```
Webシステムまとめ

#はじめに
今回はサービスを動作させるために必要なソフトウェアについてまとめてみました。

#プログラミング言語
Webアプリケーションで用いられるプログラミング言語は、主にJavascript,Python,PHP,Ruby,Visual Basic,C#など。それぞれの言語に長所や短所がある。

#サーバーのオペレーションシステム（OS）
基本的にOSはWindowsかLinuxの二種類。
__[Windows]__
Windowsの普及率の高さ方脆弱性が狙われやすくセキュリティ面でも懸念点がある。ライセンス料が高額。
GUI操作
__[Linux]__
LinuxはWindowsと操作が異なる。無償または安価にライセンスが購入できる。
CUI操作。

#ミドルウェア
OSとアプリケーションの中間に位置するプログラムをミドルウェアと呼ぶ。（サーバーソフトウェア）

__Webサーバー__

* Apache　無償　Windous/Linuxで利用可
* nginx　有償　Windous/Linuxで利用可
* llS　Windousのみ


__APサーバー__

* Tomcat　Windous/Linuxで利用可
* JBoss　Windous/Linuxで利用可
* llS　Windousのみ


__DBMS__

* Oracle高機能　かなり高価　　Windous/Linuxで利用可
* MySQL　無償　Windous/Linuxで利用可
* SQL Server　高機能　高価　Windousのみ
TsukuCTF 2021 -   Customization 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/67c8adc2-4b66-2db8-902d-69415fa05a84.png)

#解いてみた

問題文にあるURLにアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0725fd9c-e563-4b26-b992-99b68ee87b02.png)

目標の部分っていうのは真ん中のオレンジの部分ですよね。
カーソルを合わせてみると答えが載ってました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b13395d8-780e-bdfb-edc0-611c963b2044.png)
TsukuCTF 2021 -   TORItsukushi 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/75761264-7084-2181-8b29-1a69c2bc1005.png)

#解いてみた

添付ファイルをダウンロードしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f4a0205d-2b7f-aac4-d811-c87111c9849f.png)

問題文のとおり、TSUKUSHIを削除していけばよさそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/65267a6d-560b-8fef-3c83-e5bdae541dab.png)

できました。
C++のrandomで一様乱数をメルセンヌツイスターで作る例

- メルセンヌツイスターを利用して[0,1)の範囲の乱数を作る最小の例。C++のrandomを利用。



```C++
#include <iostream>
#include <random>

#define NSTEP 100

int main(int argc, char *argv[])
{

	//prepare random numbers
	std::random_device seed_gen;
 	std::mt19937_64  engine(seed_gen());
	std::uniform_real_distribution<> dist(0,1) ; 
	// [0,1) according to https://cpprefjp.github.io/reference/random/uniform_real_distribution.html
	// or https://www.cplusplus.com/reference/random/uniform_real_distribution/

  for(int i=0; i < NSTEP ; i++){
    std::cout << dist(engine)  << "\n" ; 
  }
}
```

<https://github.com/tnagai-github/RNG_uniform_distribution>
プログラミング学習　Day1

# プログラミングにも色々ある
- java:文法が厳しい。間違いが許されないプログラミングに使われる。
- javascript:UIが得意。ウェブサイトの画面などに使われる。javascriptを少し厳格にしたtypescriptなどもあり。
- python:文法が緩い。とりあえず動く。フロントエンドは苦手。ＡＩはpython一択。

# プログラミングの学習方法
- 何がわからないかをわかるのが第一歩
- 本を読むだけでは理解できない、作れない
- 人のプログラムを見てどんな動きをするか予測してみる
- 経験大事。優秀なエンジニアの経験による生産性は100倍の生産性の差に。

# 感想
- pythonはfacebookにも使われると聞いたのでfacebｏｏｋは全てpythonでできていると思っていた。
- 各プログラミンには思想があると聞いたので時間があれば調べてみたい
MakeShopの商品詳細画面で商品画像を切り替えたい

##やりたいこと
商品詳細ページで、色やサイズなどのオプションを選択し、それに応じた商品画像に切り替えたい。
amazonなどTシャツを買うときによくある機能。
※MakeShopの機能ではできなかった（調べた範囲では）
##やろうとしてつまずいてしまったこと
いつものように\<select>タグにidをつけて、getElementById('example').valueでオプションの値を取得しようと思っていたが上手くはいかなかった。
そう、MakeShopはタグによって動的にオプションを含んだ\<select>タグが生成されてしまうからだった（しかもidなしで）

##実装のため調査
MakeShop(以下、MS)では”タグ”と言うものでDBからのデータを引っ張ってきてHTMLを生成しレンダリングしている。PHPと似ている。
検証ツールで調べると\<select>タグにidはないがclass="select"とついていた。
**こ　れ　だ　！**

##実装のためにやったと
まず、


```js
const element = document.querySelector("select");
```
これでclass属性が"select"である\<select>タグにelementを定義する。次に

```js
element.id = "target";
```
この行で、\<select>タグに対してJSでidを付与する。
ここまでくればあとは

```html
<html>

<div id="main_image">
    <img src="*********">
</div>
<select class="select" id="target">
    <option value ="0">空色</option>
    <option value ="1">黄色</option>
　　　　  <option value ="２">菫色</option>
</select>

</html>
```

```html
<sctipt>
//elementが生成されているならば以下の処理を実行
if (element) {
  element.id = "target";
  var select = document.getElementById("target");
  const switchImage = document.getElementById("main_image");

//ここで初期表示されているsrcを保管する
  const restoreImage = switchImage.src;
　　
　　　　select.onchange = function (obj) {
　　　　　　　　switch(this.value):
  　　　　case "0":
  　　　　　switchImage.src = "******空色の画像URL*****";
　　　　　　　　break;

　　　　　　　　switch(this.value):
 　　　　 case "1":
 　　　　 switchImage.src = "******黄色の画像URL*****";
　　　　　　　　break;

　　　　　　　　switch(this.value):
 　　　　 case "3":
 　　　　 switchImage.src = "*****菫色の画像URL******";
　　　　　　　　break；
    }
}
　　
</script>
```

##感想
早く画像切り替え機能を実装していただきたい。
VSCode で Git


VSCode で Git

参考になったサイト

https://miya-system-works.com/blog/detail/128


https://qiita.com/toshibe/items/dcf3dd48fdc74c91b409


https://qiita.com/atsushi101011/items/96054ebbd876e378cac4

https://qiita.com/atsushi101011/items/078d736c1a4d26491682
ユビキタス言語のフォーマットサンプルを探してみた

[最近ユビキタス言語を策定した](https://zenn.dev/leaner_tech/articles/20210922-ubiquitous-language)んですが、どういう項目でどう管理するといいのか調べたのでそのメモです。

## 事例1

https://labs.septeni.co.jp/entry/20141217/1418778762

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290998/ee185b22-e808-9acc-3528-a244d0ce9723.png)

- 単語
- コード上で使う英語（単数・複数）
- 概要

おそらく一番メジャーなパターンではないでしょうか。

## 事例2

https://www.slideshare.net/AtsuoAoki/ddd-201811

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290998/f651fd30-adda-b991-ccc5-3c4d6b56aa14.png)


- 用語
- アクション
- 用語の候補と採用/却下理由


名称とアクション（振る舞い）を分けて定義するのもよく聞きます。
用語の意味ではなく採用理由を記載するのは面白いですね。
却下した用語とその理由を残すのもよさそうですね。
（具体的にどういうフォーマットで管理するのかまでは分からなかった・・ :sob:）

## 事例3

https://zenn.dev/leaner_tech/articles/20210922-ubiquitous-language

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290998/ed7ad7a7-b972-1ab9-202f-6da3d92e220f.png)

- 単語
- よくある間違い
- プロダクト内文言
- タグ
- 意味
- モデル名

Notion の Table View で管理しています。
よくある間違いがあるのはユニークですね。

## 事例4

https://qiita.com/tanaka9230/items/f6abcfcfc892bad976d6

- 名前(日)	
- 名前(英)	
- 備考

意味ではなく備考で、任意で埋めるようです。

## 事例5

https://note.com/alpinc/n/nab47ab9273c6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290998/1e388935-91ac-8bf1-968d-651170d6a3b3.png)

以下の項目を Notion で管理しているようです。

- コンテキスト
- ユビキタス言語
- ユビキタス言語（英名）
- 定義および注意事項

コンテキストをまたいで重複する単語も一つの表で管理できるのがいいですね。
週次でのユビキタス言語表の更新内容共有やドメイン勉強会はとてもいい取り組みですね。

# 事例6

https://creators-note.chatwork.com/entry/2021/12/22/153540

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290998/2798c693-d91b-29a8-2005-82f84ef4f066.png)

UI名称に一つ一つ名前をつけていくスタイル。

## 編集リクエスト募集

ユビキタス言語管理の知見を得たいんですが、具体例があまり見つかりませんでした。。 :sob: 

何か情報お持ちの方は、編集リクエストで教えていただけると嬉しいです！ :edit-request:
Terraform 0.14アップグレード時に出たエラーの対処

v0.12 => v0.13移行時に、えいや、で上げちゃったら、痛い目を見たので、
v0.14へのアップグレードを渋っていました。
気づいたら、もうv1.0が出ている・・・

こういうのは、ちゃんと自動テストを用意して、おかしくなってないか確かめられるようにしておくのがベストです。
やれてませんが！

今回はv0.14アップグレード時に出たエラーの話ですが、
どちらかというとバージョンを2つ一気に上げようとするとどうなるか、という話になります。
(タイトル詐欺っぽくて申し訳ないです)

## You must complete the Terraform 0.13 upgrade process before upgrading to later versions.

tfstateがv0.12の状態で、v0.14のterraformでinitしようとすると発生します。
[terraformの公式ドキュメント](https://www.terraform.io/upgrade-guides/0-14.html)は、バージョンは一つずつ上げてくれと言っています。
>Terraform supports upgrade tools and features only for one major release upgrade at a time, so if you are currently using a version of Terraform prior to v0.13 please upgrade through the latest minor releases of all of the intermediate versions first, reviewing the previous upgrade guides for any considerations that may be relevant to you.

v0.13からv0.14に上げる話をしているのに、なぜv0.12の話が出てくるのかというと、
v0.13にアップデートしたときにちゃんとやらなかったからです。

私の環境では、ある程度の粒度でterraformのディレクトリを複数に分割しています。
v0.13へアップグレードする際、更新のあったディレクトリだけアップグレードしていました。
結果として、更新のないディレクトリはv0.12の状態のtfstateのままになっていました。

そして今回、これまでの更新の反省を踏まえて、一気にv0.14に上げようとして、このエラーが発生しました。
アップグレードのやり方の違いによって、絶妙にかみ合ってしまいました。

対処法は、v0.13のterraformで `terraform apply` を実行するだけです。
もちろん、差分が出ないかは気を付けつつapplyしました。


## Error: state snapshot was created by Terraform v0.14.11, which is newer than current v0.13.5; upgrade to Terraform v0.14.11 or greater to work with this state

これは前述したエラーの対処として、v0.13のterraformで、terraform applyをした際に発生したエラーです。
dataでterraform_remote_stateを読み込んでいると発生します。

security_groupやsubnetidをtfstateのアウトプットから読み取っている部分があるのですが、そのtfstateが新しいバージョンだと、v0.13.5だと読み取れないといわれています。

複数のディレクトリに分割していると言いましたが、

```
terraform - dir1/xxx.tf (v0.14のtfstate)
          - dir2/yyy.tf (v0.12のtfstate) (xxx.tfのリソースを参照)
```

この状態なので、まずdir2のリソースはterraform v0.13へアップグレードする必要があります。
そこで前述した対処を行おうとすると、`data "terraform_remote_state" "xxxxx"` がv0.14.5のものだから読み込めずエラーとなります。

まとめると

* dir2をv0.13に上げなくてはならない
* dir2をv0.13に上げるためには、dir1のtfstateをv0.13に戻さなければいけない
* dir1のtfstateはすでにv0.14になっている

このような状態です。

ここでの対処は2通り考えられます。
一つは、dir2をコード上ではv0.14にしてしまって、`terraform import` を行っていくことです。
これはリソースがたくさんあるほどつらい思いをします。

もう一つはdir1のtfstateをv0.13に戻す方法です。
s3のバージョニングのおかげで戻せる状態になっていました。
参照先であるs3のバージョンを直接戻しても良かったのですが、ここでは古いバージョンをダウンロードしてきて、
参照先をlocalファイルとすることで対処しました

```terraform:before
data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "xxxxx"
    key    = "terraform.tfstate"
  }
}
```

```shell:旧バージョンをダウンロード
aws s3api get-object --bucket --key terraform.tfstate --version-id xxxxxxxxxx ./terraform.tfstate.network.v13
```

```terraform:after
data "terraform_remote_state" "network" {
  backend = "local"
  config = {
    path = "./terraform.tfstate.network.v13"
  }
}
```

そもそもなのですが、これはterraform_remote_stateではなく
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids
このようなデータソースを利用していれば、問題は発生しません。

利用し始めた初期のころはあまり意識せずリモートステートを利用していましたが、
最近だとこのような事態に陥るので、データソースを利用するようにしています。

## 結論

terraformのアップグレードとは、

「tfstateのterraformのバージョンの状態を、アップグレード後のバージョンにすることであって、文法をterraformのバージョンに合わせるだけでは駄目である」

applyするまでが、terraformのアップグレードです。
気を付けていきましょう。
Raspberry PI＋Ubuntu20.4.3でKubernetesが起動しなかったときのメモ

Raspberry PIでKubernetesをインストールして遊んでみようと思いましたが、インストール後の機動で幾度課失敗。

当初はRaspberry Pi OSで動かそうとしましたが[この記事](https://qiita.com/yasthon/items/c29d0b9ce34d66eab3ec)を参考にUbuntuに切り替えてチャレンジ。

インストール自体はできましたが、参考にした記事のときとバージョンが微妙に変わっているのかkubeletが起動せず。。。

色々調べた結果、kubeadmコマンド実行前までに下記を追記したら動作したので備忘のためのメモです。

### 環境

* OS:Ubuntu 20.4.3
* Docker:
* Kubernetes:

### 追加の対処

```/etc/systemd/system/kubelet.service.d/10-kubeadm 
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=cgroupfs"
```

上記のファイルの環境変数Environment="KUBELET_KUBECONFIG_ARGSの一番最後に下記の記述を追加しました。

```
--cgroup-driver=cgroupfs
```
これでKubeadmコマンドでMaster/Workerそれぞれを起動させることができました。
【C#】文字列を連結する[区切り文字で][拡張メソッドで][implode]

## はじめに

　C# には `String.Join()` がありますが、コレクションを Linq で操作する流れで、そのままメソッドチェーンにつなぎ、結合したいことがあります。

　`Split()` メソッドがあるのに、その逆の処理をする拡張メソッドが無い。

　標準の拡張メソッド `Join()` は違う用途なので、また違う名前にしなければいけません。例えば PHP の `implode()` のような名前に。

## サンプルコード

```cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace ImplodeTest
{
    static class Ext
    {
        /// <summary>
        /// リストの値を区切り文字で繋げて返す。
        /// </summary>
        /// <param name="source">繋げる対象のリスト</param>
        /// <param name="separator">区切り文字。規定値は空文字列</param>
        /// <returns>繋げた文字列</returns>
        public static string Implode<T>(this IEnumerable<T> source, string separator = "")
        {
            if (!(source?.Any() ?? false))
            {
                // 空のリストなら空白を返す。
                return "";
            }

            return string.Join(separator, source);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var theList = new List<string>() { "Apple", "Banana", "Citrus" };
            Console.WriteLine(theList.Implode(","));
            // 出力 -> Apple,Banana,Citrus
        }
    }
}
```

## メソッド名について

　デフォルト引数を含めて PHP に寄せてしまいました。

　.NET に慣れている人ならいっそ `StringJoin()` などの方が馴染み深いかもしれません。

　もし CSV データを作成したいなら `ToCsv()` や `ToSeparatedValue()` もいいかもしれません。

## 探してみた

　下記の記事に同じ発想で `ConcatWith()` という拡張メソッドの実装があります。

[C# コレクションを指定した文字で連結する - Qiita](https://qiita.com/pierusan2010/items/f5f1487c03561cf4ec9f)

　しかし一つのメソッドの中に二つの処理が含まれていることに、少々抵抗を感じます。私なら、以下のように書きたくなるかも。

```cs
var str = sqrts.FormatWith("0.000").ConcatWith(", ");
```
コンピュータとオセロ対戦8　～クリック1hand～

https://qiita.com/tt_and_tk/items/068f2afde6db637e189f

[前回](https://qiita.com/tt_and_tk/items/85b05b0eace25f31f73b)

# 今回の目標
一手先まで読んで返してもらいます。
今までのプログラムを組み合わせただけなので簡単な紹介だけしかしません。
なお今回も、プログラムの色を変えるため拡張子を「.c」と表記してますがProcessingです。
# ここから本編
## copyb
盤面をコピーするだけ。

```one_hand.c
void copyb(int[][] now){
  for (int i = 0; i < SIZE; i++)
    for (int j = 0; j < SIZE; j++)
      now[i][j] = board[i][j];
}
```
## mousePressed
[前回](https://qiita.com/tt_and_tk/items/85b05b0eace25f31f73b)と違い、自分が置いた後にコンピュータが置き返すようになりました。
自分が置いた後、

1. 相手が置けるなら、相手のターン
1. 相手が置けない場合、
  1. 自分が置けるならもう一度自分のターン
  1. 自分も置けないならゲーム終了

という動作をしています。

```one_hand.c
void mousePressed(){
  int line = (mouseY - COLT / 2) / COLT;
  int col = (mouseX - COLT / 2) / COLT;
  
  if (check(line, col, player)){
    put(board, line, col);
    printb();
    if (check_all(!player)){
      turn = !turn;
      turn_print("");
      computer();
    }else{
      if (check_all(player)) turn_print("not place. again, ");
      else count_last();
    }
  }
}
```

## think
C言語の時とほぼ同じです。

```one_hand.c
void think(){
  int i, j, num = 0;
  int score, max_score = - SIZE * SIZE;
  int[] line = new int[SIZE << 1], col = new int[SIZE << 1];
  int[][] board_leaf = new int[SIZE][SIZE];
      
  for (i = 0; i < SIZE; i++){
    for (j = 0; j < SIZE; j++){
      if (check(i, j, !player)){
        copyb(board_leaf);
        put(board_leaf, i, j);
        score = count(board_leaf);
        if (score > max_score){
          num = 0;
          line[0] = i;
          col[0] = j;
          max_score = score;
        }else if (score == max_score){
          num++;
          line[num] = i;
          col[num] = j;
        }
      }
    }
  }
  
  if (num != 0) {
    num = int(random(num + 1));
    line[0] = line[num];
    col[0] = col[num];
  }
  
  put(board, line[0], col[0]);
}
```
## computer
コンピュータが置くときの関数です。
mousePressedと同様、次のターンで、

1. 相手が置けるなら、相手のターン
1. 相手が置けない場合、
  1. 自分が置けるならもう一度自分のターン
  1. 自分も置けないならゲーム終了

という動作をしています。
mousePressedでのput関数がthink関数に変わり、「相手は置けないけど自分は置ける」とき、computer関数が追加されています。

```one_hand.c
void computer(){
  think();
  printb();
  if (check_all(player)){
    turn = !turn;
    turn_print("");
  }else{
    if (check_all(!player)){
      turn_print("not place. again, ");
      computer();
    }
    else count_last();
  }
}
```
# フルバージョン

https://github.com/TTaisei/osero
# 実際にやってみた

負け越しました。
# 次回は

nhand行きたいと思います。
[次回](https://qiita.com/tt_and_tk/items/79260b0859cd3a60062b)

https://qiita.com/tt_and_tk/items/068f2afde6db637e189f
[Python]Playwright ブラウザ操作自動化 メモ

## Playwrightとは

* Microsoft を中心に開発されているNode.js上からブラウザを操作するためのライブラリ。
* 特徴
  * ブラウザ操作しながらテストコードを自動生成
  * クロスブラウザテストが可能
    * 対象ブラウザ：Chromium / Firefox / WebKit 
  * Python以外にもNode.jsなど他言語にも対応



## 事前準備

* インストール

  ```shell
  pip install --upgrade pip
  pip install playwright
  playwright install
  ```

  

## コード生成

* 次のコマンドを実行し、ブラウザ操作を行う。

  * `Playwight Python`でGoogle検索を行い、検索結果の1番上のページにアクセスする場合

  ```shell
  playwright codegen google.com -o test_google.py
  ```

  ※操作後をブラウザを閉じることでコードが保存される。

* 生成結果`test_google.py`

  ```python
  from playwright.sync_api import Playwright, sync_playwright
  
  
  def run(playwright: Playwright) -> None:
      browser = playwright.chromium.launch(headless=False)
      context = browser.new_context()
  
      # Open new page
      page = context.new_page()
  
      # Go to https://www.google.com/?gws_rd=ssl
      page.goto("https://www.google.com/?gws_rd=ssl")
  
      # Go to https://www.google.com/search?q=Playwright+Python&oq=Playwright+Python&aqs=chrome..69i57.11242j0j4&sourceid=chrome&ie=UTF-8
      page.goto("https://www.google.com/search?q=Playwright+Python&oq=Playwright+Python&aqs=chrome..69i57.11242j0j4&sourceid=chrome&ie=UTF-8")
  
      # Click text=microsoft/playwright-python - GitHub
      page.click("text=microsoft/playwright-python - GitHub")
      # assert page.url == "https://github.com/microsoft/playwright-python"
  
      # Close page
      page.close()
  
      # ---------------------
      context.close()
      browser.close()
  
  
  with sync_playwright() as playwright:
      run(playwright)
  
  ```

  

## コード実行

* ブラウザ操作の再実行

  ```
  python test_google.py
  ```

* ヘッドレスモード実行したい場合

  ````python
  # headless = False →　True
  browser = playwright.chromium.launch(headless=True) 
  ````

* Safari(Webkit)/Firefoxでの実行

  ```python
  browser = playwright.webkit.launch(headless=False)
  # or
  browser = playwright.firefox.launch(headless=False)
  ```

* スクリーンショット取得

  ```python
  page.screenshot(path="./screenshot.png", full_page=True)
  ```



## 参考情報

* [Playwright for Python](https://github.com/microsoft/playwright-python)
* [playwright.dev/python](https://playwright.dev/python/)
OpenID Connect Front-Channel Logout 1.0 - draft 04 メモ

* OpenID Connect Front-Channel Logout 1.0 のドラフトバージョン4についてメモする。
  * RP起点でログアウトリクエストが行われ、OPからログイン中の各RPへログアウトリクエストを行う方法の一つ。

## Relying Party Logout Functionality

* RPはOPへのクライアント登録時にログアウトURIを登録する。

* ログアウトURI

  * ドメイン、ポート、およびスキームは、リダイレクトURIと同じ値
  * 絶対URI
  * application / x-www-form-urlencoded形式のクエリコンポーネントを含めることが可能

* 流れ

  1. OPは登録されたログアウトURIをソースとして持つページに<iframe src = "frontchannel_logout_uri">をレンダリングすることで、RP側でのログアウトアクションを起こさせる。
  2. ログアウトURIをiframeにレンダリングするリクエストを受信した際、RPはCookieやローカルストレージなど、ログインセッションに関連する情報をクリアする。
     1. ログアウトリクエストを受信したときにエンドユーザーがRP側で既にログアウトしている場合、ログアウト成功と見なされる。

* OPは、ログアウトURIをレンダリングするときに次のクエリパラメータを追加できる。

  | パラメータ | 説明                                                         |
  | ---------- | ------------------------------------------------------------ |
  | iss        | フロントチャネルログアウトリクエストを発行するOPの発行者識別子 |
  | sid        | セッションの識別子                                           |

  * RPは`iss`および`sid`パラメータがOPとRPの現在のセッションに対して発行されたIDトークンの`iss`および`sid`クレームと一致することを確認し、一致しない場合はログアウトリクエストを無視してもよい。

* RP側のレスポンスには`Cache-Control`ディレクティブを含める必要がある。

  * キャッシュされたレスポンスがその後のログアウトリクエストに干渉するのを防ぐため。



## OpenID Provider Logout Functionality

* HTTPベースのログアウトをサポートするOPは、ログインしたRP群を追跡しログアウトURIでどのRPに接続してログアウトさせるかを把握しておく必要がある。

* 一部OPでは、ログインした各RPのログアウトURIを動的に<iframe src = "frontchannel_logout_uri">レンダリングして構築したページを使用し、それらへ並行してリクエストを行う。

* OPがOpenIDConnect Discovery 1.0をサポートしている場合は以下のメタデータ値を使用してHTTPベースのログアウトをサポートすることが推奨される。

  | パラメータ                              | 説明                                                         |
  | --------------------------------------- | ------------------------------------------------------------ |
  | `frontchannel_logout_supported`         | OPがHTTPベースのログアウトをサポートするかどうかを指定するブール値。true＝サポート。省略した場合はfalse扱いとなる。 |
  | `frontchannel_logout_session_supported` | `frontchannel_logout_uri`が使用される場合に、OPが`iss`および`sid`クエリを渡して、OPとのRPセッションを識別できるかどうかを示すブール値。サポートされている場合、`sid`クレームはOPが発行したIDトークンにも含まれる。省略した場合、`false`扱いとなる。 |
  | `sid`                                   | セッション識別子。RPにログインしているエンドユーザーのユーザーエージェントまたはデバイスのセッションを表す。 |

  

## User Agents Blocking Access to Third-Party Content

* 一部のブラウザでは、（サイト間でユーザーのアクティビティを追跡するための）3rd パーティコンテンツ(Cookieなど)へのアクセスをブロックし始めている。
* OPからの通知により、RPのユーザーエージェント状態にアクセスしてローカルログアウトを実装できなくなる可能性がある。
  * iframeはOPのページとは異なるオリジンにある。
  * `frontchannel_logout_uri`は、iframe内のOPによってレンダリングされたときにRPのログイン状態にアクセスできない場合がある。

## 参考情報

* [OpenID Connect Front-Channel Logout 1.0 - draft 04](https://openid.net/specs/openid-connect-frontchannel-1_0.html)
Xamarin.FormsでAndroidでの実行時に android.support.v7.widget.Toolbar に問題あるという Android.Views.InflateException が発生した場合の対処方法

# はじめに

本稿は、C#でのXamarin.Formsでの開発時に、Xamarin.Formsを古いバージョンからバージョンアップする時に、発生する実行時エラーの対処方法の記録です。
(少なくとも Xamarin.Forms の Ver4.3.0から5.0.0へのバージョンアップ時に発生することを確認済みです)

# エラー内容

ビルドエラーはありませんが、Androidでの実行時に、以下のExceptionが発生します。

Exceptionの種類：Android.Views.InflateException
ExceptionのMessage：Binary XML file line #1: Binary XML file line #1: Error inflating class android.support.v7.widget.Toolbar

# 対処方法

以下のMicrosoftサイトのQ&Aにあるように、Toolbar.axmlというファイルの定義を修正することで解消できます。
https://docs.microsoft.com/en-us/answers/questions/186830/hemo-me-fix-this-androidviewsinflateexception.html

Toolbar.axmlとは、図の選択しているファイルのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/2e8107a0-0777-9762-fc89-46e0c58ee7ae.png)

以下の変更前の行を、変更後の行に変更することで解消できます。

```xml
<android.support.v7.widget.Toolbar ←変更前
<androidx.appcompat.widget.Toolbar ←変更後
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
```

また、以下のSyncfusion社でのQ&Aによると、Toolbar.axml だけでなく Tabbar.axml も変更するように書いてありました。
https://www.syncfusion.com/forums/155967/android-views-inflateexception-binary-xml-file-line-1-binary-xml-file-line-1-error

私の環境では、 Tabbar.axml は変更しなくても実行時エラーは発生しなくなりましたが、上記の記事の通りに、Tabbar.axml の以下の変更前の行を、変更後の行に修正した方が良さそうです。

```xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android" ←変更前
<com.google.android.material.tabs.TabLayout xmlns:android="http://schemas.android.com/apk/res/android" ←変更後
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/sliding_tabs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:tabIndicatorColor="@android:color/white"
    app:tabGravity="fill"
    app:tabMode="fixed" />
```
win10でLinuxコマンドを使いたくて

Apacheを勉強するためにLinuxコマンドを使える状態にしといたほうがいいよな～と思い、初心者なりに頑張ってWSL2を導入した。使用OSはWin10の21H1なのでコマンドからWSL2をインストールできそうだ。試行錯誤しつつぐちゃぐちゃな手順で導入したらなぜか動くようになってしまった。気になるのでUbuntuを一旦アンインストールした。再度入れ直そうとしたところ以下のようなエラーが出る。

```
WslRegisterDistribution failed with error: 0x800701bc
```

例の通りエラー文で検索すると「x64マシン用WSL 2 Linuxカーネル更新プログラムパッケージをダウンロードしろ」と出る。さっき導入時にダウンロードしようとしたけどMicrosoftの記事内にリンクが見当たらなかったから飛ばしたやつだ。最初にUbuntuをインストールした時には問題なく動いたから必要ないかと思ったけど、やはり必要なのか。

再度記事を見に行った。
https://docs.microsoft.com/ja-jp/windows/wsl/install#step-4---download-the-linux-kernel-update-package
しかしどこを見てもそれらしいURLがない。

さらに調べるとこんな記事が出てきた。
https://japan.zdnet.com/article/35150847/
カーネルの更新プログラムはWindows Updateに含めるよ～という記事だ。去年のものなのですでに採用されているものなのだろう。

しかしWSL2を入れる前にWindows Updateは最新に更新したし、あらかじめシステム設定でサブシステムも仮想マシンプラットフォームも有効にしてあるし、それなのにディストリビューションをアンインストしてインストールしたらいきなりおかしくなったんですけど？！とだんだん混乱してくる。

結局さらに検索し続けることで更新プログラムパッケージのDLリンクを発見し、最終的にUbunutuを問題なくインストールできた。
https://aimek-developer.blogspot.com/2021/03/wsl2.html
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
（※注意：ダウンロードリンク）

Microsoftの記事にリンクが掲載していなかったのはなぜだろう…Windows Updateに含めたからか…と思ったのだけど、さらにカーネルアップデートをコマンド対応した話が出てきた。
https://news.mynavi.jp/article/20200620-1059833/

```
wsl --update
```

これでカーネルアップデートを最新にできるようだ。これもあってダウンロードリンクを載せなくなったということだろうか（記事にも「コマンドで全部導入できるよ」の旨が記載してある）。手動で入れてしまったので上記の更新コマンドは試していないが。

どちらにせよ導入前にWindows Updateかけたんだけど、足りてなかったってこと？という疑問は残る。わかりません。
ORACLE MASTER Bronze(1Z0-085-JPN) 受験体験記、および学習方法

## この記事について
ORACLE MASTER Bronze(1Z0-085-JPN) 受験までの体験記を記載します。
今後、受験する方の参考になれば幸いです。

## 結論
初めに結論言ってしまうと、
学習方法は、合格するのが目的であれば、以下の参考書のみを繰り返し解けばOK。
理由は、章末問題/模擬問題と同じ問題や似た問題が、試験で6割(個人の感覚)出題されるため。

[オラクルマスター教科書 Bronze DBA Oracle Database Fundamentals](https://www.amazon.co.jp/dp/B08DXH6YBJ/ref=cm_sw_r_tw_dp_W5NNSTBJ7RZT5K98CTJN?_encoding=UTF8&psc=1 "問題集/参考書")
![オラクルマスター教科書 Bronze DBA Oracle Database Fundamentals](https://m.media-amazon.com/images/I/51l2kEaymKL.jpg "オラクルマスター教科書 Bronze DBA Oracle Database Fundamentals")

##私について
* SE5年目。
* Oracle社 Database 経験なし
  * 異動先のプロジェクトでOracle社のDatabaseと関わりが出来てしまった、本資格の習得を決意。
* 昨年、Java Silver に合格

##受験日、学習期間
<dl>
  <dt>受験日</dt>
  <dd>2021/9</dd>
  <dt>学習期間</dt>
  <dd>約1ヶ月</dd>
  <dt>学習時間</dt>
  <dd>基本：平日 約30分</dd>
  <dd>試験1週間前：毎日 約90分</dd>
</dl>

##学習方法
1. Oracle Databaseについて全く知識がなかったため、まずは「オラクルマスター教科書」の解説文(*)を読む。
2. 1を少し理解したところで、章末問題を解く。正答率が30%くらいで凹む。
3. 1と2を繰り返す。
4. 章末問題の正答率が80%ほどになったところで、模擬問題を説いてみる。正答率が50%くらいで焦る。
5. 章末問題→模擬問題 を2回ほどループ。
6. 模擬問題の正答率が95%くらいになったので、苦手箇所を重点的に繰り返し学習。


:::note info
(*)ちなみに「オラクルマスター教科書」の構成は、解説編→章末問題、最後に模擬問題 の構成になっている
:::


##試験問題について
* 「結論」に書いた通り、6割くらいは「オラクルマスター教科書」から似た問題が出題される。
* 日本語が怪しい問題があって混乱した。
* 「オラクルマスター教科書」に記載あったっけ？って問題が数問あった。

##まとめ
* 章末問題、模擬問題の答えを暗記するくらい学習を繰り返せば、なんとかなる。
* Oracle Database の知識が無い方は、解説文もしっかり読み込む。
【GitLab】rootで初回ログインできない場合の対処方法

### はじめに

<バージョン>
Centos: 8.2.2004 (Core)
GitLab: 14.3.0-ee


　EC2(AWS)のCentos8にGitLabをインストールして、初回ログインしようと試みましたが、
アクセスできませんでした。入力したログイン情報は以下です。

- Username: root
- Password: 5iveL!fe

パスワードをリセットする方法もあるらしいですが、別の方法を見つけたので紹介します。


### 1. ログイン用パスワードの確認

- ``/etc/gitlab/initial_root_password``にrootの初期パスワードが書いてありました。どうやら、このパスワードでもログインできなかったらパスワードをリセットするというのが手順なようです。

```text
[centos@ip-<ip addr> ~]$ sudo grep "Password:" /etc/gitlab/initial_root_password
Password: xxxxここがパスワードxxxx
```

### 2. GitLabへログイン

- 問題なくアクセスすることが出来ました。

![gitlab.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554812/39dd8b3f-499e-ea75-7fc1-da4ffa529c7b.png)

### 3. パスワード変更

1. ログイン後の画面の右上のアイコンから、``Edit profile``を選択します。
   ![gitlab_home.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554812/ccf68d39-c69f-7b12-f60c-3013b390d53a.png)

2. 左にある一覧の``Password``からパスワードを変更します。
3. パスワードが変更されると、強制ログアウトになるので再度ログインを実施します。

### 参考記事

[GitLab Documentation - Install self-managed GitLab](https://about.gitlab.com/install/#centos-8)
包除原理（Inclusion-exclusion principle）でProject Euler Problem 1を解く（その2）

### 集合が３つの時の包除原理

[前回の投稿](https://qiita.com/masa0599/items/45e622f7a1b4a31f4af3)では、集合が２つの時の[包除原理（Inclusion-exclusion principle）](https://ja.wikipedia.org/wiki/%E5%8C%85%E9%99%A4%E5%8E%9F%E7%90%86)を使って問題を解きましたが集合が3つになるとちょっと複雑になります。Wikiのリンクから3つの場合は以下のようになります。

```math 
\begin{align}
|A\cup B \cup C|&=|A|+|B|+|C| \\
&-|A\cap B|-|B\cap C|-|C\cap A| \\
&+|A\cap B\cap C|
\end{align}
```

したがって前回の問題に７の倍数を含めるようにすると。包除原理を使ったプログラムは解.４のようになります。（関数msumは前回のものを使う）

#### 問題２ 1000未満の、3か5か7の倍数となる自然数の和を求めよ

#### 解.４  3集合の包除原理を使ったプログラム

```python
print(msum(n,3)+msum(n,5)+msum(n,7)
  -msum(n,3*5)-msum(n,5*7)-msum(n,7*3)
  +msum(n,3*5*7))
```

これで分かるように偶数の数の積では引いて、奇数の数の積では足せばよいことが分かるので、互いに素な数が[3,5,7,11,13]のようにリストで与えられた場合のプログラムば以下のように書けます。規則性がつかめればプログラムにできるのでそれほど複雑には見えなくなりますね。

#### 解.５  N集合の包除原理を使ったプログラム

```python
import itertools
import numpy as np
n = 1000
pl = [3,5,7,11,13]

mulsum = 0
for p in range(1,len(pl)+1):
  for pp in itertools.combinations(pl,p):
    mulsum += (-1)**(p-1)*msum(n,np.prod(pp))

print(mulsum)
```
包除原理（Inclusion-exclusion principle）でProject Euler Problem 1を解く（その１）

* 本記事はProjectEulerの「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 1: ３か５の倍数

原文 [Problem 1: Multiples of 3 or 5](https://projecteuler.net/problem=1)

**問題の要約：1000未満の3か5の倍数となる自然数の和を求めよ**

これは一見単純な問題で以下のようなプログラムで解けると思いますが。さすがにProject Eulerの最初の問題だけあってよく考えると深い示唆が含まれています。

#### 解.１ すべての数をループでチェックする

```python
n = 1000
s = 0
for i in range(1,n):
  if (i % 3 == 0) or (i % 5 == 0):
    s += i
print(s)
```

#### 解.２ SETを使って和集合の要素の和を求める

```python
n = 1000
# addm: n未満のkの倍数の集合を返す
def setm(n, k):
  s = set()
  for i in range(k,n,k):
    s.add(i)
  return s

print(sum(setm(n, 3) | setm(n, 5)))
```

いずれも直感的に分かりやすいと思いますが、計算量が$O(n)$なので、nが大きくなると時間がかかることになります。

そこで[包除原理（Inclusion-exclusion principle）](https://ja.wikipedia.org/wiki/%E5%8C%85%E9%99%A4%E5%8E%9F%E7%90%86)の登場となります。この問題のように集合がA={3の倍数}とA={5の倍数}の2つであれば、$|A|$を集合$A$に含まれる数の和とすると以下のように表せます。

> $|A\cup B|=|A|+|B|-|A\cap B|$

n未満のkの倍数の和を返す関数msumを作ってこれをプログラムにすると、以下のように。

#### 解.３ 包除原理を使って和集合の合計を求める

```python
n = 1000
# n未満のkの倍数の和を返す（等差数列の和の公式を使用）
def msum(n, k):
  c = (n-1) // k
  return c*(c+1)*k//2

print(msum(n,3)+msum(n,5)-msum(n,3*5))
```

ポイントは和の計算に等差数列の公式を使っているのでnが大きくなっても計算量は変わらない（$O(1)$）になることです。Project Eulerの問題はこれからnがとてつもなく大きいもの出てきますから。このような考え方が必要になってきます。

[次回のその２](https://qiita.com/masa0599/items/32923278dc6087b3473d)では包除原理をもう少し詳しく見てみたいと思います。

以下に各々の解の計算時間を示します。nが大きくなるとその差は歴然となります。

|n|10<sup>3</sup>|10<sup>9</sup>|
|:---:|:--:|:--:|
|解-1|0秒|3分20秒|
|解-2|0秒|クラッシュ*1|
|解-3|0秒|0秒|

*1 Google Colab RAM不足のため
【Ruby on Rails】Captureメソッドを使ってテンプレート化をする方法

#対象者

* captureメソッドを使用したことない人
* テンプレート化を簡単に実行したい人


#目的

* captureメソッドを使用することで簡単にテンプレートを作成する

#実際の手順と実例
###1.captureメソッドとは

> captureメソッドを使用することで、テンプレートの一部を変数に保存することができます。保存された変数は、テンプレートやレイアウトのどんな場所でも自由に使用できます。
※Railsガイド参照

使ってみると使いまわしたい文章や表を簡単にテンプレート化できるなと考えて、使ってみました。


###2.メソッドの使い方

````index.html.erb
<% @greeting = capture do %>
  <p>ようこそ！日付と時刻は<%= Time.now %>です</p>
<% end %>
````

この時点では、ページに表示されません。
あとは<%= @greeting %>を自分の好きな箇所に設置すればOKです！



#参考にさせて頂いた記事

* [Railsガイド　6.5 CaptureHelper](https://railsguides.jp/action_view_overview.html#:~:text=6.5-,CaptureHelper,-6.5.1%20capture)
SlackとLINEを連携したい

Slack <-> LINEで相互にメッセージのやり取りをできるものを作りたいと思い、いろいろ調べて作れました。

参考としたURLとかを載せておくものなので、ほぼメモ書きです。
参考にさせてもらった記事も2年前とかなので色々変わっていたため、そのままではできなかったということもあったので。
pythonとかも初心者というか勉強しないままやってるので、常識的なこともわかっていませんのであしからず。

環境は以下です。

ローカルPC：windows10
python：3.9.6

第1　Line -> Slackの通知
参考URL1（環境準備）：https://kuri-megane.hatenablog.jp/entry/2019/10/28/190000
参考URL2（ソース、デプロイ）：https://kuri-megane.hatenablog.jp/entry/2019/11/07/190000
参考URL1に書いていないことで、不要かもしれませんがコマプロで作業するより、gitのコマンドライン使えるgit bash入れたほうがいいです。
参考URL：https://qiita.com/suke_masa/items/404f06309bb32ca6c9c5

あと、pythonの実行環境もあったほうがいいです。herokuしかないと、構文エラーとかも一度デプロイして動かした後のログを確認しないと何が起きたかわからないです。

困ったこと
・freezeがインストールできない
　そもそもできないが、「pip freeze」でpythonにインストールされているライブラリを表示してくれるので、それをrequirements.txtに記載しておく。
・herokuにpushできない。
　エラー内容をちゃんと見ること。躓いたのは、runtime.txtに記載するpythonのバージョン。
　現状herokuのスタックはheroku-20で、サポートしているpythonのバージョンは以下のURL参照。
　サポートしているpythonのバージョンをruntimeに記載する必要あり。
　参照URL：https://devcenter.heroku.com/articles/python-support
　
・デプロイ後に動かない
　参考URL2のとおりにやったら、動かない。
　原因はデプロイ後の環境変数をconfigコマンドで設定するところ。
　正しくは「heroku config:set 環境変数="設定値" --app アプリ名」で、設定値は「[AAA～～～]」ではなく「"AAA～～～"」。
　そのせいでinvalid_errorからぬけだせなかった。
　環境変数の宣言を間違ったら「heroku config:unset 環境変数 --app アプリ名」で削除可能

・画像が送信できない
　参考記事は以下。
　参考URL3：https://kuri-megane.hatenablog.jp/entry/2019/11/01/190000
　bot appへのパーミッション(Slack botではScope)を追加しないといけないが、
　該当するものがないので、それっぽいものを追加しておく。
　あと、記載のソースでは送信できず、以下のURLのjson部分を流用
　参考URL4：https://qiita.com/stkdev/items/992921572eefc7de4ad8
　あと、画像投稿先のSLACK_POST_CHANNEL_IDが急に出てくる。
　SlackのチャンネルIDは該当チャンネルのURL最後の部分になる。
　
・LINE BOTアカウントを友達登録しないとSlackに表示される名前がUnkwonにしかならない
　参考URL2の該当ソースはこれ
　profile = line_bot_api.get_profile('user_id')
　友達じゃなくても見れるようにするにはこれ。
　profile = line_bot_api.get_group_member_profile(group_id, user_id)
　そもそものソースでちゃんと発言されたときにgroupidもuseridも応答されて取得しているから、こっちのほうがいい。
　
Slack -> LINEの通知
参考URL4（ソース、デプロイ）：https://kuri-megane.hatenablog.jp/entry/2019/10/30/190000

困ったこと
・ひたすらにslacker_error:invalid_authが出て、デプロイできるけど動かない。
　多分以下このせいで、自分が作成したSlackのBot appではだめっぽい。
　参考：https://developerdk.tistory.com/96&prev=search&pto=aue
　結果、Slackに標準で用意されているBotsというappを使用する必要がある。
　Oauthも参考4URLに記載しているような自分が作成したBot appのものではなく、BotsのOauthを使用すること。
　これだけでうまいこと動くようになった。
　
【追加したい機能】
・ラインで投稿された動画を連携
　たぶんできるけどどうかな・・・
・SlackからLINEにメンション
　LINE Messaging APIにどうrequest投げればいいかをドキュメント検索中
　多分Slackから＠つけて投稿するときに、「＠表示名」を「mention.mentionees[].userId = ユーザID」に
　変換してAPIに渡せば行けるのかなと思っているが、LINEから来たメッセージからユーザIDとか拾っているので、
　それを保存して、表示名からユーザIDを特定するためのDB、関数が必要

【めんどくさいこと】
・返信のために、「reply グループID 」を入れないといけない
　ユーザ辞書登録でグループID単位に辞書登録しておけばよい。

2022年1月12日追記
ソースはGithubの下記の場所にあります。
色々直さないといけない部分はありますが、とりあえず動きます。
【ソースコード】
https://github.com/taka00234/Slack---Line

また、なんでかslackbotが常駐で動いているので、herokuの稼働時間が月末になると不足して動かなくなります・・・
破壊的メソッドと非破壊的メソッドの違い

破壊的メソッドと非破壊的メソッドの違いをちゃんと理解していなかったためmemoしておく。

## 非破壊的メソッドとは
```
gorira = "kojiro"
puts gorira.upcase 
puts gorira
```

```
#=>

KOJIRO 

kojiro
```
レシーバーである、gorira自体の値はそのままkojiroという小文字のままで保持される。

## 破壊的メソッドとは
それに対して破壊的メソッドはこんな感じ。

```
gorira = "kojiro"
puts gorira.upcase!
puts gorira
```

```
#=>

KOJIRO 

KOJIRO 
```

レシーバーである、gorira自体の値もKOJIROという大文字に変更してしまうことができる。

こんな感じ。
関数定義について(ES6)

# function

###使用例

```React:function
function helloMethod(object = "World"){ //引数がない場合、Worldが格納される
    console.log("Hello" + object)
}
```


### 特徴

* 基本的にはこの書き方を使う
* スタンダードな宣言方法なので読みやすい


# アロー関数

### 使用例

```React:アロー関数
const multiplication = (x, y) => {return x * y} 

const multiplication2 = (x, y) => x * y //{}は省略可能
```
### 特徴

* シンプルに書くことができ、行数の削減ができる
* 複雑になると読みにくくなってしまう

# レストパラメータ(可変長引数)

### 使用例

```React:レストパラメータ(可変長引数)
functiuon memo(first, second, ...rest) {
    console.log(first);
    console.log(second);
    console.log(rest[0]); //引数が3つあった場合でも表示される
}
```
### 特徴

* 特定のケースで使用できる

# まとめ

関数にはそれぞれのケースに合わせたものがある。

コードの読み手に変数や定数のニュアンスを伝えるために、適切な関数を行う事をを意識したい。
PowerToys


[Microsoft PowerToysのページ（インストール）はこちら](https://docs.microsoft.com/ja-jp/windows/powertoys/?fbclid=IwAR06BTAwmhL-38o5nq9hnI2PEYlj8cHjXTGVaqSlAEC6YGD4gDTKM3s3bLg)から！

2021年5月に、ビックカメラのパソコンStyleアカウントで使い方を紹介されていたのを拝見しWin10の社給PCにインストールして利用しています。

私が主に利用しているのは
> FancyZones（画面分割と配置）
>ColorPicker（RGB取得）

です。

管理者モードで使用しないと起動できないなど若干難がありますが
操作や調べる時間の短縮に役立っています。ちりも積もればなんとやらです。
使っていきましょう！

https://twitter.com/biccameraP/status/1398971199615426563


--------

10/23にWin11向けの放送がされました


https://twitter.com/biccameraP/status/1451879827762470914
awkで指定した行以降を出力する（文字列指定）

(ファイル名)
test.txt

(ファイルの中身)

```
google

amazon

facebook 

apple 

microsoft
```

(やりたいこと)
"facebook "の行以降を出力したい。

(コマンド)

```
awk '/facebook/',0 test.txt
```

(結果)
facebook

apple

microsoft