OmniAICreator/Qiita-1.07M huggingface dataset:
CXL (Compute Express Link) その6 - CXLデバイスとホストCPU間の通信

私はメモリデバイスの不揮発性メモリ制御やホストIFなどを扱うソフト屋です。
仕事でCXL(Compute Express Link)まわりの技術に関わっています。
CXL技術に関連するメモ書きを残していこうと思います。
ホストのCPUとOS/Applicationまわりの経験・知識共に乏しいので、親切な方は教えて下さると幸いです。
また、間違い、アドバイス、その他、ご意見やご要望ありましたらお気軽にどうぞ。

#1. CXLデバイスとホストCPUとの通信
「CXLその1」で言葉が出てきましたが、CXLの仕様書では、以下の3種類のプロトコルが規定されています。

- CXL.io
PCIeをベースとしたプロトコル。CXLデバイスのレジスタの読み書きにはCXL.ioのプロトコルが使用されます。初期化、デバイスの動作設定、割り込み、エラー情報やヘルス情報の取得等が使用目的となります。全てのCXLデバイスでサポートが必須(Mandatory)となっています。基本的にCXL.ioのプロトコルでのデータのやり取りでは、低レイテンシと広帯域での通信は求められていません。

- CXL.cache
ホストCPUのキャッシュと、CXLデバイスのキャッシュのコヒーレンシを管理するためのプロトコル。Type1とType2のデバイスで使用されるプロトコルです。CXL.cacheのプロトコルでのデータのやり取りは、低レイテンシと広帯域での通信が要求されます。

- CXL.mem
ホストCPUがCXLデバイスのメモリへの読み書きを行うためのプロトコル。
キャッシュのコヒーレンシを管理するためのプロトコル。Type2とType3のデバイスで使用されるプロトコルです。CXL.memのプロトコルでのデータのやり取りは、低レイテンシと広帯域での通信が要求されます。

CXLの仕様書で規定されているFlex Busの階層を下図に示します。
下図に示す通り、CXL.ioとCXL.cache/CXL.memとは、別のTransaction LayerとLink Layerとなっています。CXL.ioは従来のPCIeベースのプロトコル、CXL.cache/CXL.memは新しくCXLで規定されるプロトコルとなっています。
![FlexBusLayers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292852/f8b78867-6f01-71f0-db2e-c276f7828317.png)
CXL.ioとCXL.cache/CXL.mem、それぞれのプロトコル取り扱われるデータは、別のTransaction LayerとLink Layerを経て、同じFlex Bus上の物理層に流されます。同じ物理層に、PCIeとCXL、それぞれで定義される異なる構造、異なるサイズのデータが流れることになります。

自分の興味は、Type3デバイスなので、以降、Type3で使用されないCXL.cacheプロトコルの詳細には、ほぼ触れません。

#2. CXL.memのコマンド
CXL Type3デバイスに実行指示されるコマンドを以下の表に示します。

| Command | Device Response | 概要 |
|:---|:---|:---|
| MemRd/MemRdData | Data       | メモリのデータ読み出しと、メタステートの更新。  |
| MemInv/MemInvNT | Completion | メタステートの読み出しと、メタステートの更新。  |
| MemSpecRd       | None       | メモリのデータの投機的読み出し。　　　　　　　  |
| MemWr/MemWrPtl  | Completion | メモリのデータ書き込みと、メタステートの更新。  |

コマンドで読み書きされるデータのサイズは、基本的には、ホストCPUのキャッシュラインサイズに合わせて64B単位です。

MemRd/MemRdDataでは、CXLデバイスのメモリからデータの読み出しが実行されます。MemRd/MemRdDataの応答は、CXLデバイスのメモリから読み出された64BのデータのみがホストCPUに返ります。

MemInv/MemInvNTでは、CXLデバイスで管理されているキャッシュラインの状態(メタステート)の読み出しが実行されます。MemInv/MemInvNTの応答は、実行結果としてメタステートの情報が含まれるコンプリーションがホストCPUに返ります。

MemSpecRdでは、CXLデバイスのメモリ(不揮発性メモリやDRAM)から、CXLデバイス内部のキャッシュ/バッファ(SRAMなど)にデータが読み出されます。ホストCPUは、CXLデバイス内部のキャッシュ/バッファに読み出されたデータに対して、低レイテンシでアクセスすることができます。ホストCPUが投機的な読み出しを行う際に使用されます。MemSpecRdの応答は、ホストCPUに返りません。

MemWr/MemWrPtlでは、CXLデバイスのメモリへのデータの書き込みが実行されます。MemWrでは64B単位でデータが書き込みが実行され、MemWrPtlでは64B未満の書き込みが実行されます。MemWr/MemWrPtlの応答は、実行結果としてコンプリーションがホストCPUに返ります。

CXLでは、デバイスのキャッシュはMESIプロトコルでコヒーレンシが取られており、メタステートで、キャッシュラインがいずれの状態にあるかが管理されています。
Type2のデバイスの場合は、キャッシュにはMESIプロトコルが適用されるため、それぞれのコマンドで受信したメタステートの更新には、MESIプロトコルに従い、CXLの仕様で定められた対応がなされます。
Type3のデバイスの場合、キャッシュを持っていたとしても、MESIプロトコルでコヒーレンシを管理する対象となっていません。Type3のデバイスで扱われるメタステートは、CXLの仕様の対象外とされています。

#3. CXL.memプロトコルのデータ転送単位
CXL.cache/CXL.memでは、Flitと呼ばれる単位でコマンドとデータが転送されます。
Flitの概要を下図に示します。
![Flit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292852/d5f5c7f0-11f5-cccd-e387-7a0ca5111800.png)
Protocol Flitは、先頭に32bitのFlit Headerが付いたFlitで、1つのHeader Slotと3つのGeneric Slotと16bitのCRCで構成さています。
All Data Flitは、4つのData Chunkと16bitのCRCで構成されています。

Protoclo FlitのHeader Slotにはコマンド、Generic Slotにはコマンドもしくはデータが入ります。
All Data FlitのData Chunkにはデータが入り、4つのData Chunkで合計64Bのデータを転送することができます。

---
次回は、Flitの詳細について書こうと思っています。
Prism コードサンプル学習：16-RegionContext

# Prism コードサンプル学習：16-RegionContext

## はじめに

以下の記事の続きです。
<https://qiita.com/mngreen/items/c56d4d327850ca8ef2af>

## 16-RegionContext

本サンプルは、RegionManager.RegionNameを用いてコントロールを割り当てたときに、その挿入したコントロールのDataContextに対してバインディングを行うためにRegionContextを用いている例です。
実際にRegionManager.RegionContextを利用している箇所は以下です。

```xml
<UserControl x:Class="ModuleA.Views.PersonList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid x:Name="LayoutRoot" Background="White" Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <ListBox x:Name="_listOfPeople" ItemsSource="{Binding People}"/>
        <ContentControl Grid.Row="1" Margin="10"
                        prism:RegionManager.RegionName="PersonDetailsRegion"
                        prism:RegionManager.RegionContext="{Binding SelectedItem, ElementName=_listOfPeople}"/>
    </Grid>
</UserControl>
```

（実際に動作確認したところ、RegionNameで割り当たったContextに対して、通常通りDataContext={Binding SelectedItem, ElementName=_listOfPeople}としてもバインディングできませんでした。）

RegionManager.RegionContextプロパティは添付プロパティで、アタッチされるとコールバックメソッドである[OnRegionContextChanged](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/RegionManager.cs#L175)メソッドを実行します。
その後の流れがつかめきれなかったのですが、サンプルを例にとると、いったんContentControlが保持し、PersonDetailコントロールを割り当てなおすときにBehaviorでそのオブジェクトを渡しているようでした。
おそらくその役目は[BindRegionContextToDependencyObjectBehavior](https://github.com/PrismLibrary/Prism/blob/7f0b1680bbe754da790274f80851265f808d9bbf/src/Wpf/Prism.Wpf/Regions/Behaviors/BindRegionContextToDependencyObjectBehavior.cs)が担っていると思われます（正直繋がりがよくわかっていません）。

## おわりに

今回は、RegionContextについての使い方とそのコードの裏にあるものを自分なりに読み解いてみました。RegionManagerというstaticクラスをFacadeにすることでユーザーに何の意識もさせず、DataContextの情報を送受するためにBehaviorをうまいこと利用している点が上手い仕組みになっているなと感じました。
次回、[17-BasicRegionNavigation](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/17-BasicRegionNavigation)について見ていこうと思います。
ブルートフォース とは

## 勉強前イメージ

総当たり攻撃？

## 調査

### ブルートフォース とは

パスワードを破るための攻撃方法としての1つとして使われるブルートフォースアタックですが、
日本語で「力任せ」「強引な」という意味があり、総当たり攻撃とも呼ばれます。
パスワードや暗号に関してありえるパターンをすべて入力し、突破する方法です。

ブルートフォースアタックの手口は上記の方法で、
時間は入力されうる文字列と数字の数によって以下のように変わりますが
コンピュータの処理能力によって時間も短くなってきています。

| 種類           | 4桁   | 6桁    | 8桁     | 10桁      | 
| -------------- | ----- | ------ | ------- | --------- | 
| 英字           | 約3秒 | 約37分 | 約17日  | 約32年    | 
| 英字+数字      | 約2分 | 約5日  | 約50年  | 約20万年  | 
| 英字+数字+記号 | 約9分 | 約54日 | 約1千年 | 約1千万年 | 

### ブルートフォースの被害

被害としては以下になります。
これだけではないですが、情報をすべて見られてしまうのでデータを不正に引っこ抜かれたりします。

- 金銭面的な被害
- 個人情報や機密情報などの情報漏えい
- SNSに操作

### ブルートフォースの対策

対策としては以下になります。

- 8桁以上のパスワードを設定する

数字だけだとしても8桁にすると1億通りになるので効果的です。

- 意味のあるパスワードにしない

意味のあるパスワードは多くの人が使ってると言われているので
ランダムな文字列のほうがセキュリティ強度としては高くなります。

- 試行回数を設定する

サーバ側の設定ですが、ログインの試行回数を設定するのが効果的です。
指定回数ログインを失敗すると一定時間入力できなくなる設定にすると対策として効果的になります。

- 2段階認証の設定をする

IDとパスワード以外に認証コードの発行など用いると対策として効果的です。
また、2回目のログインは認証プロセスを必要ないようにすれば利用者側にもあまり負担にはなりません。

- ワンタイムパスワードを設定する

一度っきりのパスワードを発行し認証を行う方法で、毎回新しいパスワードになるので有効なセキュリティ対策になります。
安全性を求められる金融機関で使用されています。

## 勉強後イメージ

いつかは破れるやろなーって感じがしたけど、
4桁英字だけだと3秒？？？早いね

## 参考

- [ブルートフォースアタック（総当たり攻撃）とは？そのやり方・実際にかかる時間・対策方法は？](https://cybersecurity-jp.com/column/17426)
- [ブルートフォースアタックとは？ 効果的なセキュリティ対策と併せて解説](https://www.hitachi-solutions-create.co.jp/column/security/brute-force-attack.html)
超かんたん！Figmaの通知をSlackで受け取る設定をしよう！

この記事はエイチーム引越し侍 / エイチームコネクトの社員による、[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hikkoshizamurai-connect) 17日目の記事です。

https://qiita.com/advent-calendar/2021/hikkoshizamurai-connect


こんにちは！エイチーム引越し侍でデザイナーをしている[じょーじ](https://twitter.com/J0UJ1)です！
この記事では"Slack"と"Figma"の通知連携方法の解説をしていきます！

# はじめに
[16日目の記事](https://qiita.com/halkt/items/535077cc557a52deef17)で @halkt さんが触れていたように、
エイチームグループではチャットツールとしてSlackを利用することが決まりました。

様々なサービスとの連携ができるSlack、
「デザイナーも日頃使っているサービスと連携できるといいなぁ」と調べていると、
Figmaとの通知連携が可能ということが分かりました。

そうと分かればすぐに試そう！ということで、
個人アカウントで連携をしてみたのでその流れを解説していきます。

# 通知できる内容
流れの説明の前にどんな通知を送ることができるのかを確認しましょう。
通知することができるのは以下の内容です。

- 自分が投稿しているファイルへの新しいコメントやリプライ
- コメントで誰かが自分をメンションしたとき
- ファイル、プロジェクト、チームへの招待
- ファイル、プロジェクト、チームのediterまたはadminになった場合

また、コメントに関してはSlack上から返信をすることも可能なので、
質問への回答などを行う際にとても便利ですね。

# 連携方法
それでは設定を始めていきましょう。
...とは言ったものの実はこの2サービスの連携、びっくりするほど簡単です！
誇張抜きで5分で終わるので、速攻で終わらせてしまいましょう！

### 1. Slack App Directoryから「[Figma and FigJam](https://slack.com/apps/A01N2QYSA81-figma-and-figjam?tab=more_info)」をインストール
Slackにサインインして、Slack App Directoryから自分のワークスペースに「[Figma and FigJam](https://slack.com/apps/A01N2QYSA81-figma-and-figjam?tab=more_info)」をインストールしましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640304/cb706031-726b-9010-2310-127e8f95fcba.png)

### 2. Slack Appに権限を付与する
インストールをすると権限のリクエスト画面に遷移するので付与を許可します。
Slackの権限と、Figmaの権限二つの付与が必要ですが、
自動で遷移するので両方許可しましょう。

▼Slack権限付与画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640304/9b3374a9-e308-496f-d6d2-9ddba4771e73.png)
▼Figma権限付与画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640304/a32fe0bb-7042-8ab0-ca02-825cb7d2e847.png)

### 3. Slackの画面にFigmaが追加されていることを確認する
正しくインストールがされていれば、サイドバーの一番下にあるAppの欄にFigmaが表示されています。
通知はこの場所に送信されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640304/f28bf1ba-e853-9671-c96f-c1283256ee5b.png)

### 4. 完了！！
これで設定は終わりです！！
自分以外のFigmaユーザーにコメントをしてもらい、実際に通知が行われていることを確認しましょう！

:::note warn
自分で自分宛のメンションをつけてコメントをしても通知されないので注意
:::

# おわり
こんなに簡単に設定できるなんてSlackに感謝ですね！

Figma側の公式ドキュメントはこちらなので、
詳細な設定で困った場合はこちらも参照してみましょう！
https://help.figma.com/hc/en-us/articles/360039829154-Receive-comment-notifications-in-Slack

# 明日
[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hikkoshizamurai-connect) 17日目の記事は、いかがでしたでしょうか。
明日は @hinora さんがtsかreactかページパフォーマンスについて書いてくれるようです。
お楽しみに〜〜〜〜〜〜〜！！！
気象庁ホームページのHSTS対応（2022-03-15予定）

気象庁では2022年3月15日にウェブサイトのHSTS化を予定しています。

http://www.jma.go.jp/jma/press/2112/16a/hp_encription_20220315.html

対象となるFQDNは次です。

* www.jma.go.jp
* www.data.jma.go.jp
* ds.data.jma.go.jp

HSTSとは、まあMDNでも見てください。HTTPでアクセスした場合、上記サイトはHTTPSのURLへのリダイレクトを返すようになります。ブラウザは次にHTTPSでアクセスしますが、その応答には Strict-Transport-Security: ヘッダが入るようになりますので、次回以後の HTTP でのアクセスが抑制されることになります。

https://developer.mozilla.org/ja/docs/Glossary/HSTS

普通のブラウザを使って目視閲覧する場合、そのことには気づかないで過ごせるはずです。インフラ作業というのは気が付かれなくて当然。

ひとつ例外は、TLS1.2以降に非対応のブラウザ、わかりやすくいうとガラケーですね、こちらからはアクセスできなくなりますが、もうすでにほとんどアクセスがない状態になっております。ご容赦ください。

もうひとつの例外が、自作のアプリケーションで読んでいる場合です。よろずスクレイピングはそうなりますが、特に気象庁が自作でやってくださいと言っているのが、気象庁防災XMLのPull型提供です。
https://qiita.com/e_toyoda/items/185c1dea055e230918b9

# XML Pull型提供のフィードは段階移行です

案内が掲載されました。
http://xml.kishou.go.jp/xmlpull.html
→ http://xml.kishou.go.jp/open_trial/pull_https.pdf

* HTTPSに対応しているクライアントの方は、なるべくはやくフィード取得URLを https: に変更しておくことをお勧めします。
* HSTS化に先立ち、3月10日（予定）からフィード内容の http: のリンクが https: に変わります。お使いのクライアントが HTTPS に対応していない場合、この時点で取得障害になります。
なお、2月1日から同じ内容のフィードを試行用として提供しますのでご参考になさってください。
* (2022-01-25追記) 3月10日のリンクの https: への変更の時に、 /feed/entry/id 要素値が https: に変わります。電文取得にあたってこの /feed/entry/id 要素で重複判定をして、 /feed/entry/link/@href を取りに行くのが本来だと思いますが、ちゃんとそれをしていても、一気に数十件の再取得が発生することになります。あんまり良くはないと思うのだけれど、正直、/feed/entry/id と /feed/entry/link/@href の使い分けがみんな出来ているかも確認できないので、これらを同一値にしておくことにしました。
* 3月15日のHSTS化により、フィードを HTTP で取得していると新たにリダイレクトが発生します。この日に取得障害が発生する場合、リダイレクトに対応していないものと思われます。
【PHP】ChromeDriverでPDFをダウンロードする方法

Selenium+ChromeDriverでWebブラウザの自動操作をする際、リンクが貼ってあるPDFを保存することが出来ずに詰まりました。
Pythonでの解決記事はいくつかあったのですが、PHPでの記事はなかった(気がする)ので、残しておこうと思います。

# PDFのリンクをクリックした時に直接ダウンロード
Google Chromeがデフォルトの設定のままだと、PDFファイルへのリンクをクリックした際、自動的にその内容がタブ内に表示される一方で、PDFファイルはローカルに保存されません。
よって今回は、PDFのリンクをクリックした際に直接ダウンロードするようにするChromeDriverのoption指定を紹介します。

```php5
$options->setExperimentalOption('prefs', [
    'download.default_directory' => $directory_path, //デフォルトのダウンロード先を変更(必須ではない)
    'plugins.always_open_pdf_externally' => true //これでPDFのリンクをクリックした際に直接ダウンロードされる
]);
```
# 実際に使ってみる
簡単なサンプルとして、セブン&アイのHP(https://www.7andi.com/sustainability/) からサステナビリティデータブックというPDFファイルをクリックしてダウンロードするものを作ってみました。
記事投稿段階では動きますが、サイトの構造が変わったりすると、XPathでfindElementしているところが正常に動かなくなると思うので、参考程度に見てください。
## ディレクトリ構成
>　├ vendor/ (composerでfacebook/webdriver)
　│　└　いろいろ
　├ download/
　│　└ ここにPDFがダウンロードされる
　├ sample.php (今回動かすサンプルプロググラム)
　├ chromedriver (windowsの方は.exe)

## サンプルプログラム
```sample.php
<?php
require_once(__DIR__ . '/vendor/autoload.php');

use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Chrome\ChromeDriver;

putenv("webdriver.chrome.driver=" . __DIR__ . "/chromedriver"); //windowsは.exe
$directory_path = __DIR__ . "/download"; //ダウンロード先

//オプションを指定
$options = new ChromeOptions();
$options->setExperimentalOption('prefs', [
    'download.default_directory' => $directory_path, //デフォルトのダウンロード先を変更
    'plugins.always_open_pdf_externally' => true //これでPDFのリンクをクリックした際に直接ダウンロードされる
]);

$caps = DesiredCapabilities::chrome();
$caps->setCapability(ChromeOptions::CAPABILITY, $options);

$driver = ChromeDriver::start($caps);
$driver->get('https://www.7andi.com/sustainability/'); //セブン&アイHPへ遷移

//クリックしてダウンロード
$element = $driver->findElement(WebDriverBy::xpath('//*[@id="pbBlock1024212"]/div/div/a'));
$element->click();

$driver->close();
```
## 実行結果
![スクリーンショット 2021-12-16 19.08.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2397215/78cfb9f0-12b9-b4c4-6123-7a52420aea2c.png)
ブラウザが開き、赤丸の場所をクリックさせます。
![スクリーンショット 2021-12-16 18.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2397215/ed79dfbf-3a19-ddc2-e3d6-a8786003dced.png)
ダウンロードされました！
# まとめ
今回は、PHPにおけるSelenium+ChromeDriverでWebブラウザの自動操作を行う際に、PDFのリンクをクリックしてダウンロードする方法を紹介しました。
サンプルプログラムで載せたような場合だと、curl等で直接ダウンロードすればいいじゃん！と思う方も多いと思いますが、JavaScriptでレンダリングされたサイトでログインした後でしかダウンロードできないものなどの場合は非常に使えると思います。
# 参考
https://qiita.com/ttn_tt/items/81d215683e7fbf0ebd81
マルチベンダー考

そうか、み〇ほはマルチベンダだからああいうことになってるのか…、
あ、よく考えたら俺の今いる現場もマルチベンダだ。
（なんか金のムダみたいなことばっかやってるな…と思ったら、それでか！笑）

３ベンダでうまくいかなくて、さあどうしようという局面で、
減るどころか逆に１つ増えた（NTT）のには超ウケた！

大方「渋沢が泣く」みたいなことを言うのだろうが、
逆に「渋沢のDNAが災いしてる」と言う人はいないのか？

私にとってマルチベンダは忌み言葉なので（笑）報告書などでは極力ほかの言葉に変えている。

まじめな話、Chief Information Officerが機能してないんだろう。
マルチベンダだから機能しないのか、それとも
機能しないからマルチベンダなのか。

書いといてなんだが、マルチベンダの是非はQiitaに書き込むIT技術者（私を含む）が論じてもどうにもならないので、Qiitaの記事としてなじまない（なんで書くんだよ笑）。

IT技術者なのにこういう話を喜々としてしてくる人は多分仕事ができない（偏見。笑）
点字メーカープログラムの動画レビュー Part 3 - Rubyプログラミング問題にチャレンジ！ －改訂版・チェリー本発売記念－

## この記事は何？
Qiita Advent Calendar 2021「Rubyプログラミング問題にチャレンジ！ －改訂版・チェリー本発売記念－」で投稿してもらったコードを出題者である僕、伊藤淳一が動画でコードレビューしてみました。この記事はその第3回です。

https://qiita.com/advent-calendar/2021/ruby-challenge

第1回と第2回のレビュー動画はこちらです。

https://qiita.com/jnchito/items/26e8bd7c635e3d32e620

https://qiita.com/jnchito/items/d5f71c9ad90f2890647e

### アドベントカレンダー参加者のみなさんへ

ネタバレになってしまうので、自分の投稿が完了するまでこちらの記事（動画）は見ないようにお願いします〜 :pray: 

### レビュー対象の記事はこちら！

今回レビューさせてもらったのは以下の11日目から15日目の記事です。投稿してくれたみなさん、どうもありがとうございました！

@universato さん

https://qiita.com/universato/items/b127d12d2a7494abcd0e

@ktanoooo さん

https://qiita.com/ktanoooo/items/11786a9c57420d4c3e02

@matsuken314 さん

https://qiita.com/matsuken314/items/a3ef5a5f39ec4bb32f49

@yukoono さん

https://qiita.com/yukoono/items/a11b37dbb8624fd98786

@mf_ham さん

https://mfham.hatenablog.com/entry/2021/12/15/235739

## 動画でコードレビューしています

今回のコードレビューは動画で実施してみました。だいたい1投稿あたり5分〜10分ぐらいでさーっとコメントしています。
（あまりしっかりレビューできなくてすいません🙇🏻‍♂️）

動画はこちらです 👇

https://youtu.be/mCT4fsv_Qsg

「それは好みの問題や！」みたいなコメントもあるかもしれませんが、何か参考になれば幸いです。

## まとめ

こんな調子でまたこの後の投稿についでもレビューしていきたいと思います。みなさん、どうぞよろしくお願いします〜！

### PR：改訂版・チェリー本が発売されました！🍒

「プロを目指す人のためのRuby入門 改訂2版（通称チェリー本）」が2021年12月2日に発売されました。この点字メーカープログラムを作る際にも役立つ知識が満載です。第1版を持っている方も持っていない方も、一度書店で手に取ってもらえると嬉しいです〜🍒

https://gihyo.jp/book/2021/978-4-297-12437-3

改訂版の見どころについては以下のブログにまとめていますので、こちらもあわせてどうぞ 💁‍♂️

https://blog.jnito.com/entry/2021/12/02/072804
IM-LogicDesignerの個人的なつぶやき

## 序文
社内のintra-martシステムの運営においてちょっとした機能をLogicDesignerにていくつか実装しました。
その時の主観にまみれたよしなしごとをそこはかとなく書きつくります。


###ローコード開発とは言え（ロジックフローが長い）
ロジックフローに並べる箱が多すぎると視認性（可読性）が悪くなる。
フロー定義画面で縦に長いフローや折り返しが発生するフローよりは
「フロー呼び出し」を駆使する等で短いフローを連ねた方が良いと思われる

###ローコード開発とは言え（マッピングが複雑）
一つの箱に複数の処理を詰め込むと視認性（可読性）が悪くなる。
マッピング設定の関数は多くて２つ程度にとどめるのが理想系かと思われる

###ローコード開発とは言え（命名規約）
ローコードツールって事で適当に作っておりましたが、
フロー定義ID、フロー名、カテゴリ名のルールを決めないとカオスな環境が完成します。
フロー内の変数や定数、箱の名前も同様ですね。

###ローコード開発とは言え
プログラムをGUIで作れるのが目的のなのでプログラムを作る素養はそれなりに必要なのかな？
systemdでマウントする順序をコントロールする方法 

最近のLinuxディストリビューションでは、systemdが使われている関係で、
OS起動時の挙動がパラレルに行われることが多くなり、それに伴った問題点が
出てくることがあります。
今回はfstab から２つのファイルシステムをマウントする場合に起きること
がある、タイミングの問題を解決する方法を紹介します。

###テストした条件
RHEL8
/dev/sdb  /にある /mountpoint1 へマウント
/dev/sdc  /mountpoint1/mountpoint2 へマウント
ファイルシステムは ext4

###一般的なfstabの設定例

```/etc/fstab
/dev/sdb /mountpoint1 　　　　　　　ext4 defaults 1 1
/dev/sdc /mountpoint1/mountpoint2 ext4 defaults 1 1
```

このfstabの設定でOSを再起動した際に、sdbはマウントしても、
sdc がマウントされないと言うことが稀に発生します。

###マウントする順序をコントロールする unitファイルの書き方

```/etc/systemd/system/mountpoint1.mount
[Unit]
Description=sakini-mount
Requires=tmp.mount
After=tmp.mount

[Mount]
Want=/dev/sdb
Where=/mountpoint1
Type=ext4

[Install]
WantedBy=multi-user.target
```

```/etc/systemd/system/mountpoint1-mountpoint2.mount
[Unit]
Description=atokara-mount
Requires=mountpoint1.mount
After=mountpoint1.mount

[Mount]
Want=/dev/sdc
Where=/mountpoint1/mountpoint2
Type=ext4

[Install]
WantedBy=multi-user.target
```

設定を有効にする

```
# systemctl daemon-reload
# systemctl enable mountpoint1.mount
# systemctl enable mountpoint1-mountpoint2.mount
OSを再起動する
```

Where= に指定しているマウントポイントとUnitファイルの名前を同じにしなくては
いけないというルールがあるものの、2番目の例のようにマウントポイントに / が入っ
ている場合にどのように記載するかは man には書かれていない。　
これは systemd generatorが作ったunitファイル(/run/systemd/generatorの下）
を見ていた時に / は - となることがわかった。

別な解決方法としては、2番目にマウントするファイルシステムをautomount に
することで、マウントするタイミングを後ろにずらすことができる。
(x-systemd.automount でautomount してもtimeoutはしないので、マウントした状態が
継続する）

```etc/fstab
/dev/sdb /mountpoint1 　　　　　　　ext4 defaults 1 1
/dev/sdc /mountpoint1/mountpoint2 ext4 noauto,x-systemd.automount 1 1
```
参考
systemd.mount(5)
systemd.automount(5)

変更履歴
12月16日:初版
12月16日: [Install] section を追加
ORDBMS初心者がM1 MacでPostgresSQLの学習を初める#1

## はじめに          
転職を機に、PostgresSQLの勉強をはじめました。
学習を進める中で、得た内容を整理し今後の自分自身の備忘録として
さらには同じような境遇の方々の為になるような記事を書けるようになりたいと思っています。
間違い等は是非ご指摘ください。



## 目次
- 環境
- PostgresSQLのインストール
- サンプルデータベース(dvdrental)のセットアップ
- 参考資料

## 環境
MacOS Monterey version 12.0.1
psql (PostgreSQL) 14.1

## PostgresSQLのインストール
M1 Macの上記バージョンを使用しているが、Apple Silicon Montereyも既にサポート対象に入っている。
(https://formulae.brew.sh/formula/postgresql より)

```
$ brew install postgresql
```

## サンプルデータベース(dvdrental)のセットアップ
下記リンクに、**PostgreSQL tutorial**が提供しているdvdrentalというサンプルのデータベースが公開されている。
まずは下記リンクからサンプルのデータベースをダウンロードする。

[dvdrental sample db](https://www.postgresqltutorial.com/wp-content/uploads/2019/05/dvdrental.zip)

ダウンロード後、terminalで保存先へ移動し .tarファイルに展開する。

```
$ cd /your_target_dir
$ unzip dvdrental.zip
```

PostgresSQLデータベースを起動する。

```
$ pg_ctl -D /usr/local/var/postgres start
```

対話型のSQL実行ツール**psql**を実行する。 (データベース名:postgres)

```
$ psql postgres
```

上記コマンド実行後は、**postgres=#**のように　
データベース名(postgres)及びsqlプロンプト(=#)が表示される。

新規にdvdrentalという名前のDBを作成する。

```
postgres=# CREATE DATABASE dvdrental;
#CREATE DATABASE
```

psqlを抜ける。

```
postgres=# \q
```

pg_restoreツールを用いて、ダウンロードしたサンプルDBをdvdrental databaseにロードする。

```
$ pg_restore -U postgres -d dvdrental.tar
#-U postgres  : PostgreSQLにログインするpostgresuserを指定
#-d dvdrental : ロードするターゲットDBを指定
```

以上の手順により、Sample DBがダウンロードされている。
psqlツールを使って、データベース:dvdrentalへ接続する。

```
$ psql dvdrental
```

下記のように、dvdrentalデータベースへ接続が完了し、対話型プロンプトに入ることができる。

```
psql (14.1)
Type "help" for help.

dvdrental=#
```

表を一覧表示する。

```
dvdrental=# \d
```

下記のように[DVD Rental ER Model](https://www.postgresqltutorial.com/postgresql-sample-database/) に定義されている表の一覧表示を確認できる。

```
                           List of databases
                     List of relations
 Schema |            Name            |   Type   |  Owner
--------+----------------------------+----------+----------
 public | actor                      | table    | postgres
 public | actor_actor_id_seq         | sequence | postgres
 public | actor_info                 | view     | postgres
 public | address                    | table    | postgres
 public | address_address_id_seq     | sequence | postgres
 public | category                   | table    | postgres
 public | category_category_id_seq   | sequence | postgres
```

以上、サンプルデータベースのセットアップとデータベースの接続を行うことができた。
今後は、以下に良さそうなチュートリアルを見つけたので、この内容に沿って学習を進めていく。
https://nuitrcs.github.io/databases_workshop/


## 参考資料
PostgreSQL Tutorial:
https://www.postgresqltutorial.com/

Homebrew postgresql: 
https://formulae.brew.sh/formula/postgresql

Load PostgreSQL Sample Database:
https://www.postgresqltutorial.com/load-postgresql-sample-database/
[Rails]Cookieとセッションの違い

#はじめに
現在プログラミングスクールに通っています。
就活を始めるにあたって質問されそうなことを言語化しておきたく自分なりにまとめました。

```
①　簡単な説明
②　１行に要約する
③　3行に要約する
```

#Cookieとは


WebサーバーがクライアントPC(クライアントサイド)に預けておく小さなファイルのことです。
クライアントPCが、あるWebサーバーに初めて接続した際に、Webサーバー（サーバーサイド）がクライアントPCの中に、そのWebサーバー専用のCookieファイルを作成します。

クライアントPCがWebサーバーに接続したときには、WebブラウザがそのCookieをWebサーバーに送信します。このような仕組みによって、Webサーバーは、個々のクライアントコンピュータが前回使用していた情報を読み取ることができるようになります。

###Cookieには、Webサーバーによってどのような情報でも格納できる
**例**
・ユーザー名などの接続情報
・ショッピングサイトなどで購入する商品を一時的に保管する“買い物かご”の情報
・氏名や住所、電話番号などの一度登録した会員情報
###1行で言うと

```
サーバーサイドがクライアントサイドに預けておく小さなファイル
```
###3行で言うと

```
サーバーサイドがクライアントサイドに預けておく小さなファイルがCookieです。
次回クライアントサイドからサーバーサイドに接続する時にCookieがサーバーサイドに送信されます。
サーバーサイドがCookie（前回使用していた情報）を読み取る事ができます。
```
#セッションとは


アクセスの開始から終了までの一連の通信のことです。
終了には「ブラウザを閉じる」、「ログアウトする」「時間によって通信が切れる」事があります。
セッションが用いられるのは主にアクセス解析の場面がほとんどです。

###セッションの流れ
クライアントがWebサイトにアクセスしページの情報を取得するように信号が発せられます。
その信号を受信したサーバーはページをクライアントへ送信します。
サーバーはクライアントとの通信が行われたと認識するのです。
クライアントが他のページに移行する場合セッションは継続中です。
サーバーサイドが「このクライアントとの通信はまだ終わっていない」と認識することで、これが**一連の通信**となり、セッションとなるのです。

セッションの間はそのクライアントの情報は保持されています。
###1行で言うと

```
アクセスの開始から終了までの一連の通信
```
###３行で言うと

```
アクセスの開始から終了までの一連の通信のことです。
終了には「ブラウザを閉じる」、「ログアウトする」、「時間によって通信が切れる」事があります。
セッションが用いられるのは主にアクセス解析の場面がほとんどです。
```

#Cookieとセッションの違い
###１行で言うと
```
保存場所と保存期間と無効にできるかできないか
```
###3行で言うと
```
クライアントサイドで保存するのがCookie、サーバーサイドでも保存できるのがセッション
永続的に保存できるのがCookie、一連の通信のみ保存できるのがセッション
無効できるのがCookie、無効できないのがセッション
```
scikit-learnを使った基本となる機械学習手法


##Scikit-learnとは
[Scikit-learn公式HP](https://scikit-learn.org/stable/getting_started.html)には**Scikit-learnはオープンソース教師あり、教師あり両方の機械学習用ライブラリであり、モデルフィッティング、データ前処理、モデルの選択や評価、ほかの多くのツールを提供している。**とあり、pythonの機械学習を行うときに便利なライブラリです本記事ではscikit-learnの基本的なモデルを調べまとめてみました詳細、厳密な解説は参考にさせていただいたページを見るとわかりやすいと思います。

#1.SGD(stochastic gradient descent　確率的勾配降下法)
　パラメーターを最適化するために勾配が最も大きい方向に進み損失関数を小さくさせる手法(降下法)のうちの１つで、降下法はイメージ的には山でとりあえず坂を上にのぼれば頂上に着くようなものに近いと思います。（実際に山で遭難したときにはこの方法では確実につく方法ではないので来た道をたどってください)。
イメージ的には参考にしたこの[ページ](https://yaju3d.hatenablog.jp/entry/2017/08/27/233459)の[画像](https://cdn-ak.f.st-hatena.com/images/fotolife/Y/Yaju3D/20170917/20170917223314.png)が分かりやすいと思います
　降下法の中でも代表的なものとして、最急降下法とSDGがあり、最急降下法はすべてのパラメータを変え関数を計算し損失関数を考えるのに対し、SGDはランダムに決めた１つのパラメータを変え損失関数を計算します。SDGの特徴として、この方法によって最小の損失でない点にとどまることがかなり少なくなるようです。(詳しくは[ここ](https://qiita.com/koshian2/items/028c457880c0ec576e27)の記事で詳しく記載されています)
　この方法でscikit-learnのSGDClassifierでクラス分けする超平面のパラメータやSGDRegressorの損失関数を決定しています。
#2.SVC(サポートベクターマシーン)
分類に使える手法であり、境界線に近いデータ（サポートベクトル)と境界線の差(マージン)が最小になるように境界線を引き、更新する手法です。
[参考ページ](https://aiacademy.jp/media/?p=248
)のこの[画像](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR9v9-WY3KqLSOvmNowrM3PCK-CMcLaS3pJwg&usqp=CAU)がイメージがつきやすくわかりやすいと思います
直線の境界線はLinearSVCを、非線形の境界線を書きたいときはSVCを使います。

#3.KMeans（K平均法)
 データをk個に分割する手法で、クラスタリング(データのグループ分け)に使える手法です、まずデータにランダムなグループ番号を割り振り、一つのデータ番号を重心が近いデータ番号に変え、更新し続けることで似た特徴を持つデータを集めることができます。
[参考にしたページ](https://qiita.com/g-k/items/0d5d22a12a4507ecbf11)のこの[画像](https://camo.qiitausercontent.com/17889ee26e9c1ae738839620d4643b23c8dfd574/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3339353233302f66363930656132302d386538332d363339642d396264352d3733396135653366653537632e706e67)が分かりやすいと思います
#4.Kneighber(k-最近近傍法)
 今回紹介した手法の中では最も単純な方法で、予測したいデータと近い(ユークリッド距離などで)特徴量を持つk個のデータから多数決で決められた結果を予測結果として出力します分類問題に利用できます、一般にkが大きいほどノイズに強く、小さいほどにノイズに弱い特徴を持ち、シンプルで分かりやすいですが、高次元のデータを扱うには不向きです。



#参考
ディープラーニング(深層学習)を理解してみる(勾配降下法：最急降下法と確率的勾配法)https://yaju3d.hatenablog.jp/entry/2017/08/27/233459
確率的勾配降下法のメリットについて考えてみた https://qiita.com/koshian2/items/028c457880c0ec576e27
SVM（サポートベクターマシン）とは　https://aiacademy.jp/media/?p=248
k-最近傍法 – クラス分類 http://taustation.com/sklearn-knn-classifier/
scikit-learnHP https://scikit-learn.org/stable/index.html
WordPressファイル権限付与手順

#WordPressファイル権限付与手順

## 目的
特定のファイルをWordPressで更新しようとした場合に、権限不足で以下のようにエラーを出力する場合がある。

:::note alert
変更を保存するには事前にこのファイルを書き込み可能にする必要があります。詳しい情報は
ファイルパーミッションの変更を参照してください。
:::

この問題を解消する為に、特定のファイルに対して必要な権限を付与する事が目的。

## 前提
* rootに変更する為のパスワードを把握できていること。
* [対象ファイル]は権限を付与するファイルとして、パスを把握できていること。
* WordPressは一般的なインストール方法にて構築されていること。

## 手順
### 1. rootユーザになる
以降の操作は全てrootユーザで行いますので、必ずrootに変わってください。

```
su -
```

### 2. パスワードの入力
パスワードの入力を求められるので入力する。

### 3. WordPressの対象ファイルに書き込み権限を付与

以下の2つのコマンドを投入ください。

```
chown apache.apache [対象ファイル]
```

```
chmod 777 [対象ファイル]
```

### 4. WordPressよりコンテンツを更新する
コンテンツの更新作業を行う。

### 5. WordPressの対象ファイルから書き込み権限を削除

```
chmod 554 [対象ファイル]
```

### 6. ログアウトする。

TeraTermはログアウトしてください。

以上です。
サーバ数千台規模のクラウド基盤を６年以上運用して分かってきたこと


# 本記事のサマリ

* NTTドコモ クロステック開発部では、**低コスト・ロングライフをコンセプト**に、2015年頃からOSSベースのクラウド基盤（以下、本クラウド基盤）を開発・運用中であり、現在では、数千台のサーバ・十数リージョン規模まで拡大している
* 本クラウド基盤は、**コスト効率化を追求**して開発・運用されており、パブリッククラウド利用に対して大幅なコスト優位を実現している
* 自社でクラウド基盤を持つために重要なことは、パブリッククラウドとの**差別化ポイントを明確**にし、そのポイントを**追求し続ける**ことであると考えている

# 自己紹介

株式会社NTTドコモ　クロステック開発部の浦野と申します。2018年より本クラウド基盤担当に着任しました。物理・仮想リソースのキャパシティプランニングや本クラウド基盤に関わるTCO・コスト戦略などを担当しております。

# 本クラウド基盤紹介と拡大戦略

## 本クラウド基盤概要
本クラウド基盤はOSSベースで構成されており、数千台のサーバ、数十万vCPU、全国各地に合計十数リージョンといった規模である。単一ユーザのみにリソース提供するのではなく、マルチテナントとして複数ユーザがリソース共有をしている。

## 森と木の拡大戦略

規模拡大のきっかけとなったのは、とある大規模社内システムであった。当該システムは、それまで専用ハードウェアを用いていたが、EOLに伴う移行先として、本クラウド基盤が採択された。当該システムは、数万vCPU単位の検証環境・本番環境を持つような大規模システムであるがゆえに、遊休リソースが存在していた。我々は、この遊休リソースに着目し、クラウド基盤上の仮想リソースの有効活用に努めた。具体的には、遊休リソースを他の中小規模プロジェクトに開放し、１つの基盤に用途の異なる複数テナントが混在する形でリソースを提供することとした。まさに、**森（大規模システム）を作って、多種多様な木（中小規模システム）を植える**という戦略の結果、現在の規模まで拡大できたと考えている。

## テンプレート提供による開発効率化
本クラウド基盤上でのアプリケーション開発効率化のために、Web3層モデルなどのシステム構成を自動構築するテンプレートを提供している。本テンプレートを用いることで、仮想サーバ・仮想ネットワークはもちろんのこと、Web3層モデルであれば、Webサーバ・APサーバ・DBサーバを構成する上で、検証済みミドルウェアまでが自動構築される。さらに、これらシステム構成やミドルウェアは、社内のセキュリティ基準の大半を満たすように設計されているため、ユーザにとってアプリケーション開発に資源集中できるような環境を提供している。


# 設計思想

本クラウド基盤の特徴は、低コスト・ロングライフとしてバプリッククラウドなどと差別化しているところにある。

![ポジショニング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295522/347651ea-abcd-205e-4f58-4738f4f62698.png)


これらを実現するために、下記3点のポイントを徹底している。

1. OSSのAs-Is利用
2. SLAおよび責任分解モデルのユーザ同意
3. ハードウェア・ソフトウェアのEOL/EOS対策の工夫

ここでは、```1.```と```2.```における**割り切り**ついて説明する

## OSSのAs-Is利用

クラウドシステムとしての機能および提供テンプレートについて、ゼロスクラッチでソフトウェア開発するのではなく、OSSを組み合わせることで実現している。
OSSにバクがあった場合は、そのバクそのものを直す（ソースコードを変更する）のではなく、バグを避けるような対処（運用対処・代替手段の利用）として割り切りしている。


## SLAおよび責任共有モデルの同意

SLAを99.95%（年間約4時間20分）と定め、99.95%以上の信頼性や可用性を求める場合には、アプリケーション（ユーザ）側でカバーしてもらう取り決めをしている。そのために、ユーザにはシステム構成の冗長化を推奨し、さらに、地理的に異なるリージョンを跨いだDR構成をとることも可能としている。
仮想リソースの提供に関して、基盤側はIaaSレベルまでの責任を持ち、それよりも上のレイヤはアプリ側に責任を持ってもらう、責任共有モデルを取っている。なお、先に述べたテンプレートを利用しているユーザには、一部ミドルウェアのサポート（運用対処・代替手段の提供）をしている。
ユーザとは、これら取り決めに対して、事前に**同意書**を取り交わす形で、基本的に、基盤側は同意書を逸脱した対応はしないこととしている。

![責任範囲.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295522/0af2a066-3bd2-3549-2481-01fa82c3df1c.png)

# 終わりに
現在、パブリッククラウドがメジャーな存在である一方で、これらと差別化ポイントを確立することは、自社クラウド基盤を運用する上で欠くことはできない。差別化ポイントの徹底した追求により、ようやく自社クラウド基盤を持つ意義が生まれると考えている。
Astro+Reactで爆速な開発して、爆速なスタティックサイトを作ってみました。

# 背景
最近自分のHPをそろそろ更新しようと思ってました。
使いまわせるパーツが多いし、SPAフレームワークが大好きし、なるべく[DRY](https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself)にもしたくて
SPAで作り直そうかと思いました。

しかし、
自分のHPはスタティックなコンテンツしかなくて、
SPAにすると余計にJSがはいってしまいます。。

SSG・SSRとかを使えばHTMLが生成されますが
無駄に複雑になるし、
結局JSが入ってしまうので何かいいツールがあるかなと探し始めました。

そこで、[Astro](https://astro.build/)というツールを見つかりました。

# Astroとは？

[ドキュメンテーション](https://docs.astro.build/ja/getting-started/)によりますと、
Astroはモーダンな静的サイトジェネレーター(SSG)です。

SSGはいろんなライブラリーがありますが、
AstroはSPAで記述して、プレーンなHTMLが生成されます。

他のSSGと比べると、
[Gatsby](https://www.gatsbyjs.com/)・[Gridsome](https://gridsome.org/)と似たような__記述方法__と、
[Jekyll](https://jekyllrb.com/)・[Hugo](https://gohugo.io/)と似たような__結果が生成__されます。

# コンセプト

https://docs.astro.build/core-concepts/component-hydration/index.html#concept-island-architecture

AstroはIsland Architectureというコンセプトがあって、
サイトを一つなアプリにすることではなく、
画面に必要な部分をアプリ化して、
最低限のJSで画面を実装するということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285534/e977a784-34ac-0786-f424-8303213b4280.png)

# 爆速で開発
v0.21にAstroのビルドツールが[Vite](https://vitejs.dev/)に変更されました。
Viteにより`npm run dev`を実行すると秒でサーバが立ち上がれるし、
HMRも対応しているので変更した内容が一瞬ブラウザに反映されます。

# 記述方法

Astroは独自の記述方法（`.astro`）を持っていますが、SPA（React、Vue.js、Svelte）の記述も対応しています。

## Astro

Astroの記述は、Markdown + JSXが組み合わせた記述になっています。
Typescriptも対応しているようです。

```md:sample.astro
---
// 「---」内のものはビルド段階しか実行されていない

const thisWorks: number = 42;
console.log('ビルド実行する際にログが出力される', thisWorks);
---
<div class="example-1">
  <h1>Hello world!</h1>
</div>
```

## SPA

仮としてReactコンポーネントを使いたい場合は普通にインポートすれば使えます。

```md:index.astro
---
import ReactComponent from './components/ReactComponent.tsx';
---

<div>
  <ReactComponent name="hoge" />
</div>
```

```tsx:ReactComponent.tsx
type Props {
  name?: string;
}
export default function ReactComponent({ name }: Props) {
  return (
    <>
      <h1>Hello from React Component</h1>
      <h3>Hello {name ?? "world"}</h3>
    </>
  );
}
```

# ビルド

ビルド（`npm run build`）を実行するとこんな結果になります。

```html:index.html
<div>
  <h1>Hello from React Component</h1>
  <h3>Hello hoge</h3>
</div>
```

ビルドのディレクトリを見ると、JSファイルは一切入っていないです。

```
dist/
├── assets/
│   └── logo.svg
├── favicon.svg
├── index.html
├── manifest.json
├── robots.txt
└── sitemap.xml
```

## 動的コンテンツを有効

せっかくSPAを使っているので、完全に静的HTMLを生成せずに、
コンポーネントのプロップスに`client:load`を指定すると動的コンポーネントにすることもできます。

```md:index.astro
<div>
  <ReactComponent client:load />
</div>
```

`client:load` を指定すると、ページ読み込み完了する際にJSが起動されます。
さらにパフォーマンス向上したい場合は`client:visible`によりコンポーネントがブラウザに現れるとJSが自動されます。

# And more

自分が使っている機能はこれぐらいしかないですが、
他のパッケージを導入せずにAstroは以下の機能も付いています：

- Markdownファイル → HTMLに生成
- Markdownファイルにコンポーネントを使用
- Fetch APIでデータを読み込んでページを生成
- ページネーション
- RSSファイル生成
- コンポーネント内にスコープ付きCSSを記述

興味があればぜひお試してください！
日本語のドキュメンテーションがあるようですが、
まだ翻訳されていないページが多数なので英語の方がおすすめです。

https://docs.astro.build/getting-started/
【Python3】テキストファイルに書き込む方法

# はじめに
[前の記事](https://qiita.com/Matcha_5428/items/b165ff31d4a84b9edb23 "前の記事")で、[テキストファイルの内容を取得する方法](https://qiita.com/Matcha_5428/items/b165ff31d4a84b9edb23 "前の記事")をまとめたんですけど、この記事では書き込む方法をまとめときましたので参考になれば幸いです。

## 動作環境
Python 3.10.0

Mac OS Monterey

# 準備
こんな感じのファイルを作ります。

test（フォルダー）

（フォルダー内に）
main.py
test_text.txt

今回は```test_text.txt```に文字列を書き込むプログラムを作っていきたいと思います。

# 本編
### ファイルの読み込み
これは[前の記事](https://qiita.com/Matcha_5428/items/b165ff31d4a84b9edb23 "前の記事")と大きくは変わりません。
ですが、末尾も文字が書き込みの際は上書き保存の場合は```"w"```になり、ファイルの末尾に追記するだけの場合は```"a"```になります。

```上書き保存の場合.py
file_open = open("test_text.txt", "w")
```

```追記の場合.py
file_open = open("test_text.txt", "a")
```

### 書き込み

```py
file.write("書き込みたい文字列")
```

変数からでも可能です。
こんな感じで活用できます。

```py
# ユーザーに書き込みたい文字列を入力させる。
write_text = input("書き込みたい文字列：")

# 書き込み
file.write(write_text)
```

###ファイルを閉じる
内容の取得と変わらないです。

```py
file_open.close()
```

# サンプルコード
上書き保存バージョンです。

```file_write.py
# Coding : utf-8

# ファイルを開く
file_open = open("test_text.txt", "w")

# 書き込み
file.write("書き込みたい文字列")

# ファイルを閉じる
file_open.close()

# 完了ログ
print("書き込みが完了しました。")
```

# さいごに
訂正等あればコメントからお願いします。

前記事のリンク↓
[【Python3】テキストファイルの内容を取得する方法](https://qiita.com/Matcha_5428/items/b165ff31d4a84b9edb23)
【Python3】テキストファイルの内容を取得する方法

#はじめに
今回はPythonからテキストファイルの内容を取得し、変数に代入する方法を紹介します。

##動作環境
Python 3.10.0

Mac OS Monterey

#準備

まず、このような感じのファイルを作ります。

test（フォルダー）
   main.py
   text.txt

今回は```text.txt```の内容を取得するプログラムを作っていきたいと思います。

#本編
###ファイルの読み込み

```python
open = open("text.txt", "r")
```

"r"は読み込み（read）を表しています。

###変数に代入

```python
data = file_open.read()
```

###ファイルを閉じる

```python
open.close()
```

この三つを組み合わせることでテキストファイルの内容を取得することができます。
以下、サンプルコード。

```file_read.py
# Coding : utf-8

# ファイルの読み込み
open = open("test_text.txt", "r")

# 変数に代入
data = open.read()

# ファイルを閉じる
open.close()

# 出力
print(data)
```

ファイルの内容が出力されます。
```ちなみに予めテキストファイルに文字列を代入しておく必要があります。```

# さいごに
書き込みの方法も別記事でまとめています↓
[https://qiita.com/Matcha_5428/items/e5523b518cd970ce9510](【Python3】テキストファイルに書き込む方法)

訂正などあればコメントからお願いします。
【Atcoder】ARC129 A - Smaller XOR を解いていこう！《C++，解説》

#初めに
　皆さんこんにちは！ 競プロの問題の理解を深めるために解説記事を書いていこうと思います！今回は **ARC129 A** です！
 気に入っていただけたら**LGTM**して頂けるとうれしいです！
何かあれば**コメント**や[Twitter]{https://twitter.com/python05238919}からお願いいたします!
 それでは解いていきましょう！

#[A - Smaller XOR](https://atcoder.jp/contests/arc129/tasks/arc129_a)
####問題概要
 $A \leq B \leq C$
####制約
・$1 \leq N \leq 10^{18} $
・$1 \leq L \leq R \leq 10^{18} $
・入力はすべて自然数

##考察
まずXORについて述べます．
####XORとは？
 XORとは排他的論理和といい，以下の真理値となります．つまりどちらかが真のときは真であり，どちらも真もしくは偽のときは偽になります．

|$x$|$N$|出力|
|:---:|:----:|:---------:|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|0|

####入力例2で考えてみる．
　入力は以下になります

```
10 2 19
```
10を2進数にすると $10 = 1010_{(2)}$ となります．2進数で$N$と$x$が1の桁数が条件である$(x \oplus N ) < N$を満たします． 実際に$x=1aaa_{(2)}$のとき

```C++:
1000 xor N = 0010 // < N
1001 xor N = 0011
1010 xor N = 0000
1011 xor N = 0001
1100 xor N = 0110
1101 xor N = 0111
1110 xor N = 0100
1111 xor N = 0101　//8個が満たす
```
 
　このように8個の整数が条件を満たすことがわかります．
　これにより$N$で１の桁数が条件を満たします．また$x$は範囲が決まっているのでそれを考慮すると条件を満たす整数の数は1の桁を$i$すると範囲$R$まででは
$min(R, 2^{i+1}-1) - (2^{i}-1)$
となります．差をとっているのは$i$の桁を数を求めています．
実際に$i = 3$のとき代入すると
$15 - 7 = 8$
　より上記と一致します．
同様に$i = 1$のとき
$3 - 1 = 2$
これより
$8+2=10$
よって答えが一致することがわかります．

実際には$L$では差をとり，$R$では和をとることで答えが導きます．
それでは実装していきましょう！

##実装
$N$を2進数にはせず，bitを用いることにより$0$か$1$か見ていきます．これにより計算量は$O(log_2N)$となります.
各桁で整数を数えたときに負の数にもなりうるので
$max(0, min(R, 2^{i+1}-1) - (2^{i}-1))$
このようにして実装します．
また**$L$は範囲内に含まれる**ので$0$から$L$より小さい範囲を$0$から$R$の範囲を引くことで答えを出します．

##正解コード
正解コードは以下になります．

```C++:
#include <bits/stdc++.h>
using namespace std;
 
int main(){
//入力
    long long N, L, R, ans = 0, cntR = 0, cntL = 0;
    cin >> N >> L >> R;
    for(int i = 63; i >= 0; i--){
        if((1LL << i) & N){
        //Rでの条件を満たす
            cntR = min(R, (1LL << (i+1))-1);
            cntL = (1LL <<i)-1;
            ans += max(0LL, cntR - cntL);
            cntR = min(L-1, (1LL << (i+1))-1);
            cntL = (1LL << i) - 1;
            ans -= max(0LL, cntR - cntL);
        }
    }
    cout << ans << endl;
}
```
PCにのみhoverを設定したい場合のSCSSのmixin

リンクやボタンなどに対して**CSSでhoverを設定する**場合、すべてのデバイスに一律で適用してしまうと、スマホやタブレットではタップ後もhover状態が残ってしまったり、2回タップしないと反応しないといった**不具合が発生**してしまうことがあります。

そのためhover設定はPCのみ（スマホやタブレット以外）を対象としたいときの設定方法について、4つのステップを踏みながら、あらためて考えてみたいと思います。

# Step1
まずは**Media Query**によって横幅1024px以上のデバイスのみに実装してみます。
※pxの数値はあくまでも一例です。

```scss:scss
.hoge {
  @media (min-width: 1024px) {
    &:hover {
      color:red;
    }
  }
}
```

しかし数えきれない種類やサイズのデバイスが巷にあふれかえる昨今、横幅だけで判定してしまうのは、いささか大雑把でこころもとない感じがします。

# Step2
メディア特性の**hover特性**を使えば、対象デバイスが**hover可能か否か**を判定できます。
※ついでにmixinにします。

```scss:scss
// mixin
@mixin hover {
  @media (hover: hover) {
    &:hover {
      @content;
    }
  }
}

// 使用例
.hoge {
  @include hover {
    color: red;
  }
}
```
# Step3
**pointer特性**を利用すれば、**マウスなどの正確性のあるポインターデバイスを使用しているか否か**も判定でき、さらに対象デバイスの絞り込みの精度をあげることができます。

```scss:scss
@mixin hover {
  @media (hover: hover) and (pointer: fine)  {
    &:hover {
      @content;
    }
  }
}
```

# Step4（完成）
IE11に対応しなければならないケースもまだあると思います。
しかし残念ながら**IE11はhover特性に対応しておりません。**

今回はJavaScriptを使わずにCSSだけで完結したかったので、`-ms-high-contrast`という**IEにしか対応していないメディア特性**を利用します。

ユーザーが高コントラストモードをオンにしている場合も考慮して、オンオフ両方（none,active）をフォローします。

実はこのメディア特性はIEだけでなくEdgeにも適用されてしまうのですが、Chromium版Edge（2020年1月〜）からは適用されないので、Edge最新版だけを動作対象としている場合は問題ないかと思います。

```scss:scss
@mixin hover {
  @media (hover: hover) and (pointer: fine)  {
    &:hover {
      @content;
    }
  }
  // for IE11
  @media (-ms-high-contrast: none), (-ms-high-contrast: active) {
    &:hover {
      @content;
    }
  }
}
```
# まとめ
接続された複数のデバイスの中に少なくとも一つ以上該当するものがあるかどうかを判定する`any-hover`,`any-pointer`というメディア特性もあります。

しかしタッチスクリーンにペンタブをつないでいるような場合、ユーザーがタッチするのかペンを使うかまではわかりませんし、ここからは**「沼」の予感**がいたしましたので、今回はとりあげませんでした。

また機会（と興味）があれば調査してみたいと思います。

mixinにしておけば実装も楽になり、効率アップするのでおすすめです。

# おまけ
今回とりあげたメディア特性についての補足です。

### `hover: hover`
キーワード値：none, hover
[hover - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/@media/hover)
>CSS の hover メディア特性は、第一の入力機構が要素の上でホバー (停止) することができるかどうかを検査するために使用することができます。

### `pointer: fine`
キーワード値：none, coarse, fine
[pointer - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/@media/pointer)
>pointer は CSS のメディア特性で、ユーザーが（マウスなどの）ポインティングデバイスを持っているか、もしそうならば、主要なポインティングデバイスにどれだけの正確性があるかを調べます。

### `-ms-high-contrast`
キーワード値：none, active, black-on-white, white-on-black
[-ms-high-contrast - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/@media/-ms-high-contrast)
>CSS のメディア特性で、 Microsoft 拡張であり、アプリケーションが高コントラストモードで表示されているかどうか、どの配色で表示されているかを記述します。

# 参考サイト
https://dev.opera.com/articles/media-features/
https://zenn.dev/tak_dcxi/articles/2cc1828e9c1fe2
https://blog.tomoyukikashiro.me/post/ja/consider-hover-effect-for-table/
https://texst.net/ie11-css-hack-ms-high-contrast-now-useful/
ppkキーしかない場合に踏み台サーバを経由してSSH接続したいとき

# 背景
踏み台サーバーを使用している環境で、目的のサーバーにSSH接続したいときに、情報が少なく接続できなくて困っていたが、解決できたので記事として残しておく。ppkキーしか手元にない状態でVScodeから踏み台サーバー経由→目的のサーバーに接続する手順を記載する。

pemキーの説明
https://qiita.com/one_punch_man/items/2ad8b4664ed012bee5a7

# 接続構成
VScode → 踏み台サーバー → 目的のサーバー（図にしたい）

# 手順
大きく分けて以下２つの手順を踏むことになる。
１．pemキーの生成
２．VScodeからSSH接続の設定


#### １．pemキーの生成
まず、pemキーを生成するためにputtygenをダウンロードする。
https://www.puttygen.com/download.php?val=49
上記URLにアクセスするとputtygen.exeのダウンロードが始まる。

ダウンロードしたputtygen.exeを立ち上げ、Loadを押して、ppkキーを読み込む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/2178a4fe-b23c-e022-e1c3-aff37f586989.png)

Conversionsメニューをクリックして、「Export OpenSSH key (force new file format)」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/a7d936d6-9a2d-84af-f06f-d42b10a72c14.png)

ポップアップは「はい」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/3731ced9-8ce2-79e6-860b-a60718c99b64.png)

ファイル保存のダイアログがでるため「pemkey.pem」などと名前を付けて保存する。


#### ２．VScodeからSSH接続の設定

VScodeの拡張機能で「remote」と検索し、Remote Developmentをインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/5d6e2fe1-e151-dd78-b0b2-29d28f253eb1.png)


VScodeの左側にリモートエクスプローラーのアイコンができるため、クリック後、上部のプルダウンでSSH Targetsを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/954ecb53-a625-665f-e80d-1fd577f93f27.png)


SSH TARGETSと表示されている辺りにマウスを持ってくるとメニューが出てくるため、歯車マークをクリック。上部にプルダウンが出てきて、以下を選択
C:\Users\[ユーザー名]\.ssh\config
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/58a3f49a-0c73-7422-ad6c-c3d4de218341.png)

configファイルに以下のように記入する

```config:config
# 踏み台サーバー
Host Hop_server  # 任意の名称
    HostName xxx.xxx.xxx.xxx  # サーバー情報
    Port xxx  # ポート番号
    User user_name  # ユーザー名
    IdentityFile ~/Documents/ssh/pemkey.pem  # 作成したpemキーを指定

# 目的のサーバー
Host Target_server  # 任意の名称
    HostName xxx.xxx.xxx.xxx  # サーバー情報
    Port xxx  # ポート番号
    User user_name  # ユーザー名
    IdentityFile ~/Documents/ssh/pemkey.pem  # 作成したpemキーを指定
    ProxyCommand ssh -W %h:%p Hop_server  # 踏み台を経由させるコマンド、最後に踏み台サーバーに付けた名称を記載
```

configを記載して保存すると左側に反映されるため、接続したいサーバーをクリックすると新しいウィンドウで接続が開始される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/2e9a1642-43a6-333b-3137-48f0f279e8b9.png)

パスワードを求められたら入力し、接続が成功するとVScodeの左下に緑色でSSHと表示され、Terminalを使えたりディレクトリにアクセスできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359451/1891619c-81c9-2d49-52da-b0899442f2ba.png)

以上
Workload Identityを使ってJSONキーなしでGitHubActionsからGCPにアクセスする(Terraform編)

以下の記事でgcloudコマンドを使って作成していたWorkload Identity系のリソースをTerraformでも作成してみました。

https://qiita.com/shiozaki/items/9d50f28d38f027c6beb3


```terraform
variable "project_id" {
  default = "プロジェクトID"
}

variable "repo_name" {
  default = "ユーザー名/リポジトリ名"
}

resource "google_service_account" "github-actions" {
  project      = var.project_id
  account_id   = "github-actions"
  display_name = "A service account for GitHub Actions"
}

resource "google_project_service" "project" {
  project = var.project_id
  service = "iamcredentials.googleapis.com"
}

resource "google_iam_workload_identity_pool" "github-actions" {
  provider                  = google-beta
  project                   = var.project_id
  workload_identity_pool_id = "gh-oidc-pool"
  display_name              = "gh-oidc-pool"
  description               = "Workload Identity Pool for GitHub Actions"
}

resource "google_iam_workload_identity_pool_provider" "github-actions" {
  provider                           = google-beta
  project                            = var.project_id
  workload_identity_pool_id          = google_iam_workload_identity_pool.github-actions.workload_identity_pool_id
  workload_identity_pool_provider_id = "github-actions"
  display_name                       = "github-actions"
  description                        = "OIDC identity pool provider for GitHub Actions"
  attribute_mapping = {
    "google.subject"       = "assertion.sub"
    "attribute.repository" = "assertion.repository"
  }
  oidc {
    issuer_uri = "https://token.actions.githubusercontent.com"
  }
}

resource "google_service_account_iam_member" "admin-account-iam" {
  service_account_id = google_service_account.github-actions.name
  role               = "roles/iam.workloadIdentityUser"
  member             = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github-actions.name}/attribute.repository/${repo_name}"
}
```
株式会社UnReactの闇を語ります


こんにちは、株式会社UnReactアドベントカレンダー、本日12/16日を担当させていただきます酒井です。
[![Image from Gyazo](https://i.gyazo.com/f9825fd1d1ab1456f989ebaef3deaa79.png)](https://gyazo.com/f9825fd1d1ab1456f989ebaef3deaa79)

今回は自分がUnReactに潜入してわかったUnReactの「闇」を大きく3つ語っていきたいと思います。ウヘヘ...

それではレッツラご！

## 第一の闇：夜中の公園に現れる筋トレ軍団
![photo-1491319669671-30014eb16b8d.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830281/b7cc39a3-2b5e-eea4-5ccf-74ea1862c2ba.jpeg)
UnReactでは毎晩、夜ご飯を食べた後、みんなで公園に行き、筋トレをするイベントがあります。
特になんの変哲もない公園で各々が筋トレをするのですが、各々の種目がなかなか闇です。

ある1人は、何かに取り憑かれたように、延々と逆立ちを繰り返し、
ある1人は、公園の目の前の道を、ものすごい形相で全力疾走し、
ある1人は、ブランコを鉄棒がわりに、物理法則を無視した懸垂をしています。

ふと俯瞰して見てみると、結構な恐怖軍団だなと思います笑

これは闇ですね。

## 第二の闇：大家族もびっくりの買い出し量
![photo-1n483985988355-763728e1935b.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830281/a2028421-565d-f317-9b34-176b4df04408.jpeg)

UnReactでは週に一度買い出しがあります。
みんなで近くのスーパーまで自転車を漕いでお買い物をするのですが、
なんと言っても買い物の量がヤバいです。

買い物カート二台、計４個のカゴが満帆になるほど食材を詰め、それをカバンにぶち込んでそそくさと会社へと帰ります。

長ネギやらなんやらが飛び出したパンパンのリュックを背負った男達が、一生懸命自転車をこいで坂を駆け上がるその姿は、街でも「恐怖の光景だ」と話題になっているそうです(嘘)

闇ですねぇ〜。

## 第三の闇：伝家の宝刀、黒瀬のスパイス
![photo-1558538337-aab544368de8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830281/ac5655bc-d243-c5d9-e62b-db608551c98d.jpeg)

UnReactの社長であるノブユキ・ニシカワには、ある一つの口癖があります。
それは、「薄ぃ〜」です。

彼にとって、この世の料理は二種類に分けられます。
味が濃い食べ物と、味が薄い食べ物です。

なので、UnReactにはどんな料理も必ず濃い味にしてしまうスパイスが常備されています。
「[黒瀬のスパイス](https://www.amazon.co.jp/%E9%BB%92%E7%80%AC%E9%A3%9F%E9%B3%A5-%E9%BB%92%E7%80%AC%E3%82%B9%E3%83%91%E3%82%A4%E3%82%B9-%E8%A9%B0%E3%82%81%E6%9B%BF%E3%81%88%E7%94%A8-%E9%BB%92%E7%80%AC%E3%81%AE%E3%82%B9%E3%83%91%E3%82%A4%E3%82%B9-%E3%83%90%E3%83%BC%E3%83%99%E3%82%AD%E3%83%A5%E3%83%BC/dp/B071LS8KY4/ref=asc_df_B096RW7ND9/?tag=jpgo-22&linkCode=df0&hvadid=529727097983&hvpos=&hvnetw=g&hvrand=11726449146837124878&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009721&hvtargid=pla-1345818178221&th=1)」です。
これをかけるとどんなものでも必ずこの味になります。笑

かっぱえびせん、肉料理、白米、等々...
UnReactの愉快な仲間達は、あらゆるものにこのスパイスをかけ、健康的な食生活を送っています。

闇ですねぇ〜。

## まとめ
これ以上ないくらいのカルピス記事になりましたが、UnReactの闇を語れて良かったです。
この記事を読んだ方がUnReactにより親近感を持ってもらえると嬉しいです！！

それではまた！
ポストモーテム輪読会を運営してみた

##はじめに
こちらは[mediba Adventカレンダー2021](https://qiita.com/advent-calendar/2021/mediba)の17日目のエントリーです。

社内のポストモーテム輪読会を半年ほど継続したので振り返ってみます。
これから始めるか悩んでる方に参考になれば嬉しいです。


##ポストモーテム輪読会
**ポストモーテムとは**
medibaではポストモーテムを"障害の時系列、どう対策したか、どのような教訓を得られたのかを内部向けに残す報告書"としてヒヤリハットや障害発生時に書いてます。チームの中に残すのはもちろん、別のチームがポストモーテムを読み返すことにより参考になることも目的です。

medibaではSREメンバーと品質管理メンバーが合同で企画して21年3月から取り組み始めており、"個人の責任追求の場にしない"など大事な精神についてポストモーテムを説明する時にまず伝えてます。また、初めは各サービスの振り返りの場に同席したりして広めていきました。


**なぜ輪読会か。始めてみた理由**
輪読会は共通の書籍をみんなで読んで意見交換する勉強会のスタイルです。
各サービスで書いてもらったポストモーテムを活用していこうと2021年6月から始めました。

一番の目的は"振り返りの文化定着"です。
輪読会によりサービス間、部署間を超えて障害対応の知見を活用していくことがより当たり前にと考えて始めました。

もう一つは違う職種の人の考えを得られる場や、新しい繋がりのきっかけになればということです。新入社員として入った時、社内イベントの出会いから気軽に話せる人が増えて助かった記憶もあり、堅苦しくならず対話・意見交換を楽しんでもらえる運営を心がけてます。


##運営について
**運営スタイル**
・月に1回、1時間枠
・全社に向けて告知、誰でも参加OK
・ビデオ会議ツールで開催
・SREメンバーと品質管理メンバーが合同で運営

続けることを重視して負担になりすぎない月１にしてます。

**事前準備**
①開催日を決める
②題材として良さそうなポストモーテムをピックアップ
③社内告知(slackの全社グループ・グーグルカレンダー等)


**当日**
①主旨説明　
②各自で読む時間 5分
③4~5人に部屋を分けて会話　15分~20分
④対象案件が2つある場合、上記2-3を繰り返す
⑤最後に一言(学び・感想)書いてもらう


##初回~最新回までの振り返り
###第1~2回目 初めてみた期
・”技術的知見ある人いないと理解追いつかないことある。"との声
・初めてきてくれたけど中々話さずに終わってしまう人もいた。
・広報/準備も足りず、直前告知になってしまった。


###第3~4回目 改善していく期
・初めて参加した人がなかなか発言しにくい。
→運営側が話しすぎないようにする。ファシリテート役に回って話を振る。

・技術的知見ある人いないと理解追いつかないことある。
→書いてくれた当事者に直接声をかけて呼んでみる。
　題材を選ぶ時にもチーム内用語などないかチェックする。


・広報/準備も足りず、直前告知になってしまった。
→1ヶ月前に日を決めて、全社カレンダーに追加して予定を通知する。

・1時間だと来にくい人いる？(仮説)
→1時間枠を分割して30分枠を月2で実施してみる。


###第5~7回目 安定してきた期
・会の回し方定着してきて、多少のトラブルあってもアタフタしなくなった。
・初めて参加してくれる人少しずつ増えてきた。
・1回フィーバーした回あって盛り上がった。

##やってみて
**良かったこと**
・地道な活動の可視化
これまでサービス内部で行われていた活動が可視化され、より広い人に伝わる機会になった。

・違う角度での意見
ありがたいことにディレクター、エンジニア、データ分析している方など職種を超えて参加してくれる人も増えてきました。同じものを見ても違う角度から意見が飛んできたりするのですごくいいと感じました。

・当事者の視点に踏み込んで会話できた。
"自分でもこの場合、XXを信用してしまうかも"など実際の対応する人の考え方まで会話が進み、人としてかかりがちなバイアスを発見できる機会がありました。
正論として"こう対策すべき"に留まらずに、当事者視点で会話にできるのは1つの収穫と感じました。



**個人的な学び**
・0から人を呼ぶのは大変。(サービスでも何でも一緒・・・)
これまで自分が何気なく参加したイベントの凄みを感じました。

・大勢の前で話すの苦手だけど、10人くらいの前での説明や5~6人のファシリテートするの好き。
オンラインだと余計にプレッシャーを感じなくてよかったです。

##これから
・継続的に2~3回参加してくれる人増やしていきたい。
・オフラインでの開催(🍕でも囲みながら）

・ポストモーテム以外でも社内で輪読会開いてみたい。
・社外の人とポストモーテム輪読会してみたい(願望)

ポストモーテム輪読の活動自体はなかなか効果が測りやすいものではないですが、文化として定着するために着実に続けていきたいと思います。

##宣伝
medibaでは輪読会以外にもさまざまな自主活動、サークル活動もしています！
また各ポジションで鋭意募集中です。
少しでも興味持った方ぜひ一度見てください。

https://hrmos.co/pages/mediba/jobs/360000001
PlayWright利用メモ

PlayWrightをPythonで利用してみまして、今回使ってみた「値の取り方」や「値の設定の仕方」を今後のサンプルになるかも？と思ったので、載せておきます。

PlayWrightでは、↓の前の記事でも書いた通り、Codegenを使ってブラウザ操作をコード化できるのですが、そのまま動かないことも多いのです。

https://qiita.com/jun_higuche/items/296ebd4db1484e8f477e

そのため、結局、自分でロケーターで指定しなければならないわけです。まぁ、Seleniumもそうでしたしねｗ
ロケーターの基本的な使い方は、↓のページなど参考にしました。

https://note.com/shift_tech/n/nb86761c14c9e#oIRoD

ただのメモなので、ちょっと雑な書き方になっているのはごめんなさいm(__)m

#インラインフレーム（iframe）の取得

インラインフレーム「\<iframe id="main_content" scrolling="yes"\>\</iframe\>」を取得するやり方

```python
main_frame = page.wait_for_selector("#main_content").content_frame()
```
インラインフレーム取得後は、Pageオブジェクトと同じように「fill」や「click」などで要素取得ができるようです。
↓FrameクラスのAPIドキュメント

https://playwright.dev/python/docs/api/class-frame


#値の取得

テキストフィールド「\<input id="in_d_kaishitime_1" ～ \>」で入力されている値の取得

```python
input_value_starttime = main_frame.inner_text("#in_d_kaishitime_1")

# または以下のやり方でも取得できる。
input_value_starttime = main_frame.query_selector("#in_d_kaishitime_1").input_value()
```

プルダウン「\<select id="in_kyukakbn" ～ \>」で選択されている値の取得

```python
input_value_kyukakbn = main_frame.query_selector("#in_kyukakbn").input_value()
```

その他表示値、例えば「\<span id="disp_sta_intime" ～ \>」なども以下で取得できます。

```python
disp_sta_intime = main_frame.inner_text("#disp_sta_intime")
```

#値の設定

HTMLのinputタグ（テキストフィールド）に値を設定

```python
page.fill("input[name=\"auth_user_id\"]", userId)
page.fill("input[name=\"auth_user_password\"]", userPw)
# userID, userPWは文字列です。
```

```python
main_frame.fill("#in_d_kaishitime_1", "文字列"))
```


プルダウン「\<select id="in_kyukakbn" ～ \>」で値を設定

```python
main_frame.select_option("#in_kyukakbn", "40")
```


#クリック

ログインボタンクリック

```python
page.click("input:has-text(\"ログイン\")")
```

```python
main_frame.click("button:has-text(\"送　信\")")
```

リンクのクリック

```python
main_frame.click("a:has-text(\"文字列\")")
```

#ダイアログボタンの存在確認してボタンクリック

```python
if(page.query_selector("#Modal1_ok_btn") != None and page.query_selector("#Modal1_ok_btn").is_visible()):
            page.click("#Modal1_ok_btn")
```


#最後に
ここで書いた以上にもさまざまな要素の取り方があるので、もし、上手くいかなかった場合には、他のやり方をいろいろと試してみるとよいでしょう。
私のやり方としては、「Visual Studio Code」で開発しているのですが、デバックモードで実行して、対象の要素が表示される状態のときにブレイクポイントを貼っておいて、止め、そのときに「ウィッチリストでいろんなやり方を試してみて、値を取れるかを評価してみる」という方法で開発を進めていました。

良かったら参考にしてください。