OmniAICreator/Qiita-1.07M huggingface dataset:
VSCode Remote Developmentの反応が悪いと思ってたらLANケーブルがぶっ壊れてた話

# 前書き

自宅での趣味用途でUbuntu22.04をインストールしたPCがあります。
自分が普段使用しているのはMacでして、Dockerを使おうとすると重くて使いにくいなんかの理由で、Ubuntuの方にDockerをインストールしてVSCodeのRemote Developmentでつないで開発しております。

話はちょっと戻ってUbuntuを22.04にしたのは今月の初めとかでした。
その頃からどうもRemote Developmentの動作が重く、あれ？アップデートしたからかな？とか思ってました。
調べても特に似たような症状の人も見つけられなかったので、重い腰を上げて原因を調べることにしました。

# パッケージインストールが遅い

思い返してみると、アップデート後からパッケージのインストールなんかが酷く遅かったりしていました。
なんで放置して作業してたのかと思いますが、所詮趣味用途なので時間も取れず、というのが言い訳です。
後は、サーバー側が遅かったりするのかな仕方ないなとか思っていました。

# pingも遅い

そもそもネットワーク環境どうなってるんだと思ってローカルLAN内でpingしてみると数100msec、たまにTimeoutが発生する有様。
なんじゃこりゃ？となり少し調べてみるとipv6を使わなきゃいいみたいな話が出てきました。そう言えば前にもそんな話あったなあと思い、調べた所に書いてあった通りに無効化しました。が、全然改善されず。

# ルーターですかね？

たまにルーターさんもご機嫌ななめなことがあったりするので、設定で改善するかなあ？と調べたらしましたが情報は特になく、リセットしたり、電源切って放置してから起動したりしましたが特に改善もされず。
そもそも他の機器が問題無いのでこのPCだけルーターに嫌われるというのも考えにくい気がするなぁと思いながら別の原因を探ることに。

# ネットワークインターフェイスは？

このPC、有線LANのIFが二つ、無線LANのIFが一つあるのですが、はてどれを使ってたっけ？と見てみると有線LANを使ってました。
もう一方の有線LANにしても改善されず。
無線LANを使いたいわけでは無かったのでもうちょい調べてみることに。

# 結局原因は

よく見るとLANのコネクタがぐらぐら…
お前かー！と思い、別のケーブルを持ってきて入れ替えました。

するとどうでしょう。
あんなに遅かったpingの速度が匠の技で数msecになったではありませんか！
恐る恐るVSCodeを確認してみると、ああなんと快適な反応速度！
今までなんだったのでしょうか。

そういえばOSのアップデートをしたのも配置換えのついでみたいな軽い気持ちで、LANケーブルもその時にその辺にあったやつをとりあえず繋いだのでした。
まさか壊れかけてるとは夢にも思わず。

# おわりに

教訓: 壊れかけのLANケーブルは開発体験に著しく悪影響を及ぼす＆ポエムを書きたくなる。

皆様もどうかお気をつけあれ。
P2Pとは

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# P2Pとは
P2P(ピアトゥーピア)とは、Peer to Peerの略でネットワーク上で機能間が接続・通信する方式の1つです。機能が同じ端末同士が対等な関係で直接に接続し、互いの持つデータや機能を利用し合う方式のことを指します。詳しく書くと、`P2Pは各ピア(対等な立場にあるノードや通信相手)がデータを保持し、他のピアに対して対等にデータの要求やアクセスを行う自律分散型のネットワークモデル`です。
これに対して、一般的に広く用いられているシステム方式は __クラサバ型__ です。クラサバ型とはクライアントサーバーの略で、データーを保持し提供するサーバーと、それに対してデータの要求やアクセスを行うクライアントで構成されています。

# P2Pのメリット
- __ゼロダウンタイム__ の実現
クラサバ方式であれば、例えばアクセスの集中により回線への負荷が高まることで、サーバーがダウンする可能性があります。しかしP2Pでは、1つのサーバーに負荷をかけるわけではないため、ゼロダウンタイム(サーバーダウンが発生しないこと)を実現することができます。
- 匿名性の確保
ネットワーク上に分散してデータを管理できるため、すべてのノード情報を確保することは難しく、匿名性を確保しやすくなっています。


# P2P方式を用いたサービス
一般的なサービスはほとんどが、クラサバを採用しています。しかし、一部のシステムでは主に __サーバー負荷の減少__ を目的として、P2P方式を採用しています。
- LINE
LINEでは、ユーザーIDなどのアカウント情報は管理していますが、データファイルやトーク履歴などはLINEのサーバーを介さずに、ユーザーどうしが直接管理しています。
- Skype
Skypeでは、ユーザー登録やログイン時のユーザー認証用に少数のサーバーが存在します。しかし、通話時の通信やノード間のルーティングといった、Skypeネットワークの中核機能はサーバーではなく、各ノードが担当します。


# 終わりに
P2Pのメリットを前述しましたが、P2Pでは最大のデメリットはセキュリティリスクがあることです。もしも悪意のあるウイルスに感染した場合、ノード同士で通信を行うために感染拡大につながってしまう可能性があります。普段よく使用しているシステムの通信方式やセキュリティ対策について調べてみることで、システムを継続して使用するかを決めてもいいかもしれません。


最後までお付き合いくださりありがとうございました。
C言語で色々する(短め)

今日は、、、
---
C言語を使って色々やります

1 hello world!
---
```c:hello, world!
#include <stdio.h>

int main(void) {
    printf("%s\n", "Hello, world!");
    return 0;
}
```
私はvoidとか入れる派です

2 変数
---
```c
#include <stdio.h>

int main(void) {
    int x = 5;
    int y = 3;

    printf("%d\n", x + y);

    return 0;
}
```
変数の型は
``int`` ``char`` ``float`` ``double``
などとあります　つかいわけましょう

3 変数2 - 文字列やポインタ
---
```c
#include <stdio.h>

int main(void) {
    char *text;
    text = "hello, world!";

    printf("%s\n", text);

    return 0;
}
```
私は未だに「*」や「&」の細かい意味をわかりきっていません((

4 配列
---
```c
#include <stdio.h>

int main(void) {
    int point[] = {80, 73, 72, 90, 79};

    for (int i = 0 ; i < sizeof(point) / sizeof(point[0]) ; i ++) {
        printf("%d\n", point[i]);
    }

    return 0;
}
```

でもこんなこともできます

```c
#include <stdio.h>

int main(void) {
    char text[16] = "こんにちは";

    printf("%s\n", text);

    return 0;
}
```

5 mallocでメモリ確保
---
```c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *p;
    char text[] = "hello, world!";
    p = (char *)malloc(sizeof(char) * sizeof(text));

    sprintf(p, text);

    printf("%s\n", p);

    free(p);

    return 0;
}
```
freeで開放することも忘れずに

6 構造体
---
```c
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char name[20];
    char my_job[20];
    char my_hobby[20];
    int age;
} User_profile;

const User_profile user_list[] = {
    {"田中 太郎", "IT関連", "料理", 24},
    {"山田 聡", "教師", "けん玉", 31},
    {"鈴木 健太", "営業", "旅行", 22},
    {"佐藤 次郎", "警備員", "将棋", 44}
};

int main(void) {
    int i;
    char text[80];

    for (i = 0 ; i < sizeof(user_list) / sizeof(user_list[0]) ; i ++) {
        sprintf(text, "名前: %s\n年齢: %d\n職業: %s\n趣味: %s\n", user_list[i].name, user_list[i].age, user_list[i].my_job, user_list[i].my_hobby);

        printf(text);
        printf("%s\n", "----------------");
    }

    return 0;
}
```
sprintfやsizeofは便利なので、覚えておいて良いかもです

まとめ
---
色々やってみました。意外と面白いです。
みなさんもたまにはC言語も使ってあげてはいかがでしょうか？
mermaid の graph/flowchart を良い感じに書く

こういう謎のmermaidがあるとします

```
graph TD

A("犬"):::mammalian --> B("猫")
B --> C("ハムスター"):::mammalian
B:::mammalian --> D("亀"):::reptiles

classDef reptiles fill:red,color:white,stroke-width:0px;
classDef mammalian fill:blue,color:white,stroke-width:0px;
```

図にするとこうです

```mermaid
graph TD

A("犬"):::mammalian --> B("猫")
B --> C("ハムスター"):::mammalian
B:::mammalian --> D("亀"):::reptiles

classDef reptiles fill:red,color:white,stroke-width:0px;
classDef mammalian fill:blue,color:white,stroke-width:0px;
```

それを以下のように書くとdiffが発生した時に見やすい。と思う。皆さんどう思いますか。

```
graph TD

%% 要素を定義する部分
A("犬"):::mammalian
B("猫"):::mammalian
C("ハムスター"):::mammalian
D("亀"):::reptiles

%% 関係を定義する部分
A --> B
B --> C
B --> D

classDef reptiles fill:red,color:white,stroke-width:0px;
classDef mammalian fill:blue,color:white,stroke-width:0px;
```
文系の統計検定3級合格記

## 目次
- 試験について
- 学習について
    - 学習開始時点でのレベル
    - 学習に使った書籍
    - 学習方法
- 受験の所感
    - 試験時間の不足
    - 出題範囲の見直し
    - 最後に

## 試験について
試験名：統計検定3級
問題数：30問程度
出題形式：4～5肢選択問題
試験時間：60分
合格基準：65点/100点


>大学基礎統計学の知識として求められる統計活用力を評価し、認証するために検定を行います。
>（1）基本的な用語や概念の定義を問う問題（統計リテラシー）
>（2）不確実な事象の理解、2つ以上の用語や概念の関連性を問う問題（統計的推論）
を出題します。

※[公式サイト](https://www.toukei-kentei.jp/exam/grade3/)より抜粋


## 学習について
#### 学習開始時点でのレベル
統計学という学問を学んだ経験はなく、今回の受験で初めて触れました。
数学についても、高校時代は文系で数学ⅠⅡ・数学ABまでは履修済み、
大学時代はほとんど数学を使わない状態でした。

昨年よりデータ分析の仕事に就き、統計検定の受験を決めました。

#### 学習に使った書籍
1.[改訂版 日本統計学会公式認定 統計検定3級対応 データの分析　](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%89%88-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A%E5%AF%BE%E5%BF%9C-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%88%86%E6%9E%90-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A/dp/4489023324/ref=pd_lpo_2)
※公式テキスト
2.	[日本統計学会公式認定 統計検定 3級・4級 公式問題集](https://www.amazon.co.jp/%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A-3%E7%B4%9A%E3%83%BB4%E7%B4%9A-%E5%85%AC%E5%BC%8F%E5%95%8F%E9%A1%8C%E9%9B%86-2018%E3%80%9C2021%E5%B9%B4/dp/4788925567/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2OHE95207FBOR&keywords=%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A&qid=1664196416&qu=eyJxc2MiOiIyLjY3IiwicXNhIjoiMS45MSIsInFzcCI6IjEuNzAifQ%3D%3D&s=books&sprefix=%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A3%E7%B4%9A%2Cstripbooks%2C255&sr=1-1
)
3. [完全独習 統計学入門](https://www.amazon.co.jp/%E5%AE%8C%E5%85%A8%E7%8B%AC%E7%BF%92-%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80-%E5%B0%8F%E5%B3%B6-%E5%AF%9B%E4%B9%8B/dp/4478820090/ref=asc_df_4478820090/?tag=jpgo-22&linkCode=df0&hvadid=295700463796&hvpos=&hvnetw=g&hvrand=1262254725389066949&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028853&hvtargid=pla-525667509974&psc=1&th=1&psc=1)


#### 学習方法
学習は、まず公式問題集を見ることから始めました。出題範囲の中にはすでに学生時代に習っていて分野もあったため、まずは優先して進めるべき分野の特定をするためです。
比較的楽に学習を進められた分野は下記の項目になります。

 ※公式テキスト「改訂版 日本統計学会公式認定 統計検定3級対応 データの分析」の目次から抜粋

-	データの種類とグラフ表現
-	量的変数の要約方法
-	確率
-	変数データの分析
-	データの収集：実験・観察・調査

上記については学生時代に学んでいた、もしくはテキストを1度読むだけで理解ができた分野です。
公式テキストを読んでもあまりぴんとこないときは「完全独習 統計学入門」を読んだうえで再度テキストに挑戦すると、比較的理解が深まった印象です。

一方で、テキストを何度も読んでも理解が難しく、時折公式の暗記も必要だった分野もあり、
- 回帰直線と予測
- 確率変数と確率分布
- 統計的な推測

などはかなり時間をかけて学習を進めました。

基本的には、使った書籍は上記でご紹介した3冊ですが、その3冊を何度も繰り返し解いて学習を進めていました。
特に理解が進まなかった苦手分野は、過去問題集に加えて公式テキストの例題で基礎を学びました。
また、問題集を解く中で、ある程度使う公式は限られているということが分かったので、
もし解き方がわからなかったらよく使っている公式を当てはめてみるという強行突破をしていました（笑）

## 受験の所感
#### 試験時間の不足

受験時間にあまり余裕はなく、全問解き終わり見直しをしている途中で時間切れとなってしまいました。
検算などはひとまず後回しにして、一旦すべての問題に目を通し解答することが大事だと感じました。


#### 出題範囲の見直し

実は、試験直前まで出題範囲を間違って認識していました…
というのも、2020年度の受験から出題範囲が変わる（※「相関と回帰」、「確率分布」、「統計的な推測」が追加された）という情報を見落としてしまっていたためです。
2019年実施までの過去問題集を解いていたため、途中まで全く気付かずに学習を進めてしまっていました。
新たに追加された「相関と回帰」、「確率分布」、「統計的な推測」が多く出題された印象だったので、学習マストな分野かと思います。

    
#### 最後に

次は統計2級を狙っていますが、すでに3級の知識が薄れてしまっている気がするので、改めて3級の学習から始めたいと思います。
こちらの記事がこれから統計学習を検討されている方の参考になれば幸いです。
Hyper-V上にDocker環境を構築してDockerDesktopから乗り換える（実行環境で）

DockerDesktopが有料化されて久しいですが、今更ながらWindows10環境でDockerDesktop環境をCommunityEdition環境に移行できたのでメモ。
表題だけの記事になっているが、特にLAN内からDockerDesktop上で実行しているWEBアプリコンテナにアクセスして利用していたケース、つまりネットワークがからむケースでは回り道を減らせると思うので参考慣れば幸いである。

# TL;DR
* WSL2にインストールしたUbuntuなどにdockerを構築するのは、事例はたくさんあるけど開発環境用だからIP指定やポートフォワーディングで詰むよ。
    * IPの固定方法とか調べれば出るけど、結局うまくいかないので、素直に方向転換しよう。
    * 充分なメモリとCPUを割り当てれば仮想マシンでもそんなに遜色はないハズ。
* 古の手順でVagrant使う手順とかあるけど、性能出るのはHyper-VだからHyper-Vで素直に構築したほうがいいよ
* CoreOSとか洒落たものを使おうとしてもナレッジ無いから慣れたディストリで組むといいよ
* 仮想スイッチマネージャーで外部接続スイッチ作って、ゲストOS上でIP設定すればいいよ
* でかいディスクにイメージ作ってた場合は物理ディスクを仮想マシンにマウントするといいよ
* データの転送？エクスプローラー？うるせぇWinSCPで転送しやがれ。
* GUIで管理したい？忘れろ。

# Hyper-Vの有効化
# ゲストOSのセットアップ
# 実ディスクを仮想マシンに追加する。
* ディスクの管理で対象ディスクをオフラインにする
* マシンの設定から物理ディスクを選択する。
* マシンを起動して、常時マウントにする。
# IPアドレスの設定
# dockerおよびdocker-composeのインストール
# 旧環境のデータを転送する。
# 起動確認
【Swift】UIKitでPreviewを使いながら開発をする

# はじめに
Xcode11で導入されたXcode Previewはいままで表示速度や意味不明なエラーで使い物になりませんでしたが、Xcode14で割と快適に使えるようになりました。
UIKitで使用してみたのでやり方と感想を書きます。

# 表示するView
今回はViewControllerが表示された事がわかれば良いので背景色を赤にしてるだけです。
```swift
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }
}
```

# 実装
```diff_swift
import UIKit
import SwiftUI

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }
}

struct ViewControllerPreview: PreviewProvider {
    struct Wrapper: UIViewControllerRepresentable {
        func makeUIViewController(context: Context) -> some UIViewController {
            ViewController()
        }
        func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        }
    }
    static var previews: some View {
        Wrapper()
    }
}
```

# 表示されない？？
コードの実装はできたけど表示されない。。。
「Canvas」のチェックを外します。
![スクリーンショット 2022-09-26 22.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/fc6da96a-515b-f253-0ccd-84a196defff3.png)

再度、「Canvas」にチェックを入れます。
![スクリーンショット 2022-09-26 22.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b208f2b3-4616-3ed3-3b9a-389c7f36b640.png)

表示された！！
![スクリーンショット 2022-09-26 22.35.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/63e8b8b6-7ea8-fd1f-4eb1-218ba00010cc.png)

# おわり
プレビュー上で画面操作もできちゃうのでマジで高速で開発できます。
快適になったXcode Preview最強！！

# 参考記事
https://engineering.mercari.com/blog/entry/2019-12-13-155700/
ログイン認証時のパスワード比較(Golangで実装)

### はじめに
DBにパスワードを平文のまま保存してはいけません。万一、情報漏洩した場合、不正利用されないにパスワードを暗号化する必要があります。今回は、Golangでどう実装するのかを残していきたいと思います。

### 概要
まず、パスワードを生成します。その後、パスワードを特定されにくくするため、ソルト値を付与。最後に暗号化を実施するという流れで暗号化していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/da173c17-35a8-0748-83bf-88d3ebac7866.png)

### 実装

```go:main.go
package main

import (
	"fmt"

	"golang.org/x/crypto/bcrypt"
)


func main() {

	solt := "1234567890"
	// パスワードのハッシュ化
	hash, err := EncryptPassword("password"+solt)
	if err != nil {
		panic(err)
	}
	fmt.Println(hash)

	// パスワードの比較
	comparedResult := CompareHashAndPassword(hash, "password"+solt)
	if comparedResult{
		fmt.Println("一致")
	}else{
		fmt.Println("不一致")
	}
}

/** パスワードの暗号化 */
func EncryptPassword(password string) (string, error) {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	return string(hash), err
}

/** パスワード比較(DB格納値とリクエスト値の比較) */
func CompareHashAndPassword(hash, password string) bool {

	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))

	return err == nil
}
```

```:実行結果
~/go/src/jikken$ go run main.go
$2a$10$7HPPxNgVjRgS8KPjg4mIcuyVw/QZg9uE87SHoNbMo3o.31tBpbJoy
一致
```

ちなみに下記が一致しない場合の実行結果。
```:実行結果
~/go/src/jikken$ go run main.go
$2a$10$dynJb6kvVDcoOqC4sNdYaecKnhMfGQ6/SQHYhxLLeVUKgtyiE1q6.
不一致
```
意外と簡単ですね！！！
「恐怖のOOM killerを召喚」をやってみた

### 参考動画

https://www.youtube.com/watch?v=o7SbjLpm5-c

### 動画の要点

- 意図的にOOMを発生させるのはひと手間かかる
- なぜなら、使い切るレベルのメモリ獲得はOSにより阻止されるため
- dmsegでカーネルログを見ればOOMが発生したかがわかる
 

### 視聴後の調査
#### そもそもOOMとは？を調べた
OOMとはメモリ確保時にエラーを出す説や、

> OOMとは、コンピュータプログラムの代表的な実行時エラーの一つで、必要なメモリ容量を確保できず、それ以上処理を続行できないこと。システムの空きメモリが足りないために起きる。

https://e-words.jp/w/OOM.html

メモリを使い果たした際にエラーが出る説があり、

> 通常、このメッセージは、システムがスワップ空間 (仮想メモリー) を使い果たしたことを示します。

https://docs.oracle.com/cd/E19455-01/806-2720/msgs-668/index.html

文脈からどちらの意味が適しているかを忖度してあげる必要がありそう。動画では後者をOOMとして捉えているようです。共通して言えることはOOMが発生している = システムにメモリが足りていない

#### OOMを意識するケースは？
- 不可解なプロセスの突然死 ( OOMが発生したから、OOM Killerによってプロセスが殺された説 )
> Linux上で重要なアプリケーションのプロセスが突然死んだけど、アプリケーションのログを見ても何もエラーが出力されていない、という経験はありませんか？そのような場合、システムのメモリ枯渇によりOOM Killerがそのプロセスを停止させた可能性があります。


#### 他にOOMが発生した方法を確認する方法はあるか
- centos の場合は `/var/log/messages` にも記録されるようです。 ~~ubuntu ってデフォルトでは /var/log/messages が無いのか。~~
> OOM Killerによるプロセス停止のログが/var/log/messagesに出力されるので、まずはそれを確認します。

https://aegif.jp/alfresco/tech-info/-/20201119-alfresco/1.3


#### 広い意味での対策
言語や、OOMの意味（確保の失敗 or 使い切り)によりやるべきことも変わるので網羅は難しい。とりあえず、見つけたのは以下。


- プロセス毎にOOM Killerによるプロセス停止の優先度を設定する

https://aegif.jp/alfresco/tech-info/-/20201119-alfresco/1.3

- OOMが発生した際の調査方法 (JVM用)

https://atmarkit.itmedia.co.jp/ait/articles/1004/13/news094.html
JWT とは

## 勉強前イメージ

jsonのなんかやった気がする

## 調査

### JWT とは

JSON Web Token の略で、
JSON形式の属性情報などを安全に送受信できるようにした標準規格になります。
データはデジタル署名で改竄がわかるようになっており、暗号化をしてデータの安全性が担保されています。
RFC7519に記載されています。

認証などについての情報はJSON形式で記述してトークンを生成します。
そのトークンとサーバとクライアント間でやり取りしてデータを読み取ります。
メッセージ認証コードなどで改竄やなりすましが行われていないかを確認することが出来ます。

### JWTの仕様

JWTの形式には以下2つの仕様があります。

- JWS形式
	- JSON Web Signature の略
	- JSONの署名に関する仕様

- JWE形式
	- JSON Web Encryption の略
	- JSONの暗号化に関する仕様

## 勉強後イメージ

json形式でやり取りするってことね。

## 参考

- [JWT 【JSON Web Token】](https://e-words.jp/w/JWT.html)
- [JSON Web Token（JWT）の紹介とYahoo! JAPANにおけるJWTの活用](https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/)
【忘備録】VSCodeやChromeの便利だと感じたショートカットキー

<h2>VSCodeで使えるショートカット
<p>

コピー　：　__⌘(command)　＋　c__

ペースト　：　__⌘(command)　＋　v__

保存　：　__⌘(command)　＋　s__

行の先頭/最後に移動　：　__⌘(command) + ←/→__

単語ごとに移動　：　__option + ←/→__

上記のショートカットと __shift__ を同時に押すと、その行を選択できる。

<h2>Chromeで使えるショートカット
<p>

新しいタブを開く　：　__⌘(command)　＋　t__

タブを閉じる　：　__⌘(command)　＋　w__

ページのリロード　：　__⌘(command)　＋　r__

タブの移動　：　__⌘(command)　＋　option　＋　←/→__

指定のタブへ移動　：　__⌘(command)　＋　1,2,3 ~ 9__ 

ページの進む/戻る　：　__⌘(command)　＋　←/→__

検索欄に移動　：　__⌘(command)　＋　option　＋　↑__

<h2>個人的なショートカット
<p>

Run Python File in Terminal　：　__shift ＋ option ＋ p__

Terminal: Focus Terminal　：　__shift ＋ option ＋ ＠__

<p>忘備録として投稿しておきます
vue2 composition-api + tsx でv-modelとemit

Vue2 composition-api + tsxで、v-modelとemitする

```hoge.tsx
import { defineComponent, reactive } from "vue";

export const Hoge = defineComponent({
  props: {},
  setup(props) {
    // v-model + 双方向バインディング v-model する場合、reactive使うと良さげ
    const condition = reactive({ msg: "message1", msg2: "message2" });
    return { condition };
  },
  methods: {
    clicked() {
      this.$emit("clicked", "hoge");
    },
  },
  render() {
    return (
      <div>
        Dummy
        <input v-model={this.condition.msg}></input>
        {this.condition.msg}
        <input v-model={this.condition.msg2}></input>
        {this.condition.msg2}
        <button onClick={this.clicked}>hoge</button>
      </div>
    );
  },
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60267/7f7f2e3e-806d-f8c4-c82c-872275823f74.png)
JupyterLabのインストール

#  Anacondaと一緒にJupyterLabをインストール

#### 1. Anaconda Installersまでスクロールし、該当リンクを押下

https://www.anaconda.com/products/distribution

- M1Macの場合`64-Bit (M1) Graphical Installer (316 MB)`

#### 2. 「続ける」を押下しインストール
![スクリーンショット 2022-09-26 21.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/a92e8a39-bba8-57f7-125c-9bd1a96006b4.png)


#### 3. コマンドで起動
```terminal
$ jupyter lab
``` 

```terminal:例
(base) sample@SampleMBP ~ % jupyter lab
NumExpr defaulting to 8 threads.
[I 2022-07-09 17:40:06.008 ServerApp] jupyterlab | extension was successfully linked.
[I 2022-07-09 17:40:06.094 ServerApp] nbclassic | extension was successfully linked.
[I 2022-07-09 17:40:06.094 ServerApp] panel.io.jupyter_server_extension | extension was successfully linked.
[I 2022-07-09 17:40:06.114 ServerApp] nbclassic | extension was successfully loaded.
[I 2022-07-09 17:40:06.115 LabApp] JupyterLab extension loaded from /opt/anaconda3/lib/python3.9/site-packages/jupyterlab
[I 2022-07-09 17:40:06.115 LabApp] JupyterLab application directory is /opt/anaconda3/share/jupyter/lab
[I 2022-07-09 17:40:06.116 ServerApp] jupyterlab | extension was successfully loaded.
/panel-preview/ /panel-preview
[I 2022-07-09 17:40:06.117 ServerApp] panel.io.jupyter_server_extension | extension was successfully loaded.
[I 2022-07-09 17:40:06.118 ServerApp] ローカルディレクトリからノートブックをサーブ: /Users/username
[I 2022-07-09 17:40:06.118 ServerApp] Jupyter Server 1.13.5 is running at:
[I 2022-07-09 17:40:06.118 ServerApp] http://localhost:8888/lab?token=866a58aef7189a70be07e944b9dc8194ce21c8eefb085669
[I 2022-07-09 17:40:06.118 ServerApp]  or http://127.0.0.1:8888/lab?token=866a58aef7189a70be07e944b9dc8194ce21c8eefb085669
[I 2022-07-09 17:40:06.118 ServerApp] サーバを停止し全てのカーネルをシャットダウンするには Control-C を使って下さい(確認をスキップするには2回)。
[C 2022-07-09 17:40:06.121 ServerApp]

 To access the server, open this file in a browser:
     file:///Users/username/Library/Jupyter/runtime/jpserver-86004-open.html
 Or copy and paste one of these URLs:
     http://localhost:8888/lab?token=866a58aef7189a70be07e944b9dc8194ce21c8eefb085670
  or http://127.0.0.1:8888/lab?token=866a58aef7189a70be07e944b9dc8194ce21c8eefb085670
[I 2022-07-09 17:40:08.980 LabApp] Build is up to date
```

#### 4. コマンドを実行するとブラウザ上で立ち上がる
![スクリーンショット 2022-09-26 21.37.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e5a7c6d7-bad4-1a1a-9f1a-ac13f83648a8.png)


#### 5. ファイルを作成する場合はNotebookの`Python 3`をクリック

:::note
先にディレクトリをクリックしておくと、そのディレクトリ配下にファイルが作成される
:::

# 基本操作

### ショートカット

- モードの切り替え
    - `y`（Codeモードになる）
    - `m`（Markdownモードになる）
    - `r`（Rawモードになる）

- 実行
    - `shift + enter`
    - `command + enter`

- セル
    - `a`（選択状態のセルの上に追加）
    - `b`（下に追加）
    - `c`（コピー）
    - `v`（貼り付け）
    - `x`（切り取り）
    - `dd`（セルの削除）

- 保存
    - `command + s`

- JupyterLabの終了
    - terminalで`control + c`
        - 5秒以内に`y`を入力

# 関連
https://qiita.com/rexid/items/8b2f0dd4f7ca03c13a7a
[SOA対策]Cloud Watch

# CloudWatchとは
AWSリソース、アプリケーション、オンプレのモニタリング、監視の集約、ログの分析、トラブルシュート、自動アクション、運用状況の把握が可能

# CloudWatchの機能
![スクリーンショット 2022-09-25 9.01.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841868/a5234a23-ad63-6d97-bfed-f687a9b52ab4.png)

## CloudWatch Metrics
- メトリクス
    - CloudWatchに発行された時系列のポイントのセット
    - CPU利用率などのメトリクス名を持つ
    - タイムスタンプと測定単位を持ち、作成されたリージョンのみ存在
- 名前空間
    - CloudWatchメトリクスのコンテナとなり、異なる名前空間のメトリクスは相互に切り離される
    - AWS/service名
- ディメンション
    -　 インスタンスなどのメトリクスを識別するユニークなID
-　メトリクス値
    -　色々なメトリクスのデータの生成は基本は１分、カスタムメトリクスの高解像度を利用して最短で1秒
    -　　基本のメトリクスの間隔はサービスごとに異なる。基本モニタリングと詳細モニタリングがある。
    - メトリクスデータの粒度で使用期間が決まる（１分間未満：3時間、１分：１５日）　　
- Metrics Math
    - 数式を使用して新しいメトリクスを作成
- スナップショットグラフ
    - GetMetric WidgetImage APIを使用してグラフのPNG画像を取得可能
    - Wiki、チケットシステム、チャットアプリ等への連携
    - CloudWatch Alarmsと組み合わせて異常通知にグラフを添付
- CloudWatch カスタムメトリクス
    - 標準メトリクス以外のドクズメトリクスも監視可能
    - CLIの”Put-metric-data”でデータ登録
    - 高解像度なメトリクスを発行可能

### CloudWatch で利用できるエージェント/プロトコル
- 統合CloudWatchエージェント
    - メトリクスとログの両方を単一のエージェントで取得
    - クラウドでもオンプレでも利用可能
    - Windowsの両方に使える
    - agent、metrics,Logsの3つのセクションを持つJSonファイルで、取得対象などを設定
    - 全て取得するとコスト増なので、必要なデータのみ取得する
-　StatsD,Collectdのサポート(OSSの数値レポーティングツール）
    -　カスタムメトリクスを取得
    -　Collectdソフトを使用して、メトリクスをCloudWatchエージェントに送信


## CloudWatch Alarms
条件を指定して、自動アクションの実行が可能。
アラームの状態はOK（正常値）、ALARM（異常値）、INSUFFCIENT_DATA（判定不能）の３種類。
INSUFFCIENT_DATAはデータ不足で発生するので、必ずしも障害を表すステータスではない。
また、Billingアラームで課金状況を監視できる。

### M out of N（N個中、M個）のアラーム設定
不安定なデータに対して、評価期間内に閾値を超えたデータポイント数で評価。
短時間で変化が大きいメトリクスで誤報を抑制する。

### CloudWatch Alarmsのアクション機能
状態変化した際に、以下をアクションとして連携できる
- SNS：トピックを発行して、サブスクライブにEmailを指定してメール通知や、Lambdaを指定して、処理を実行できる。
- EC2：インスタンスを自動停止、終了、再起動、復旧する。Auto Recoveryを利用。
- EC２ Auto Scaling：負荷に応じてリソースを調整

## CloudWatch Logs
システムのログファイルの監視、保存、アクセスが可能。ログデータの保存期間を設定可能。（１日〜永久）S３へのエクスポートも可能。

### CloudWatch Logsメトリクスフィルタ
ログデータから特定の文字列のフィルタリングが可能。
メトリクスに一致したパターン数を記録。アラーム作成やSNS連携も可能。
（例えばerrorをフィルターにかけるなど）

### CloudWatch Logs サブスクリプションフィルタ
ログをフィルタフィルタパターンに応じてリアルタイムに、Kinesis Data Streems/Kinesis Data Firehose/lambdaに転送する。1つのロググループにつき、1つのサブスクリプションフィルタを設定可能。
CLIからのみ設定できる。

### S3へのログデータのエクスポート
コンソールからCLIより設定。タスクの完了には数秒から数時間かかる。
ログ調査のために、一部データをアドホック（特定の）に取得するパターンに活用。継続的に転送するなら、↑のKinesis Data　Firehoseを使う方が良い。

### CloudWatch Logs Insight
CloudWatch Logsのデータを検索して分析できる。
専用のクエリ言語と、コマンドを提供している。
Visualizationで可視化機能を提供しており、時間軸に沿ったトレンドやパターンを特定・分析する。

## CloudWatch Dashboards
カスタム可能。AWSが推奨するベストプラクティスに基づいたダッシュボードを自動生成する”Automated Dashboard”がある。

## CloudWatch Events
リソース変更のイベントや定期実行に応答してアクションを実行。
ルールの有効化・無効化が可能。
【M1 Mac版】Python3のインストール手順まとめ

# 手順
:::note warn
Homebrewがインストールされていること
:::

## 1. pyenvのインストール
```terminal
$ brew install pyenv
$ pyenv -v
```

```terminal:実行結果
pyenv 2.3.0
```

## 2. pyenvのPathの設定

- 下記コマンドを1行ずつ実行

```terminal
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc
$ source ~/.zshrc
```

:::note
[pyenvのGitHub](https://github.com/pyenv/pyenv#set-up-your-shell-environment-for-pyenv)に実行するよう記載されている。
**Set up your shell environment for Pyenv**の**For Zsh**を参照
:::


## 3. pyenvでインストールできるPythonのバージョンを確認
```terminal
$ pyenv install --list
```

## 4. Pythonのインストール

```terminal
$ pyenv install 3.10.6
```

:::note
listで確認した最新バージョンをインストール（当時**3.10.6**が最新）
:::

:::note warn
上手くいかない場合はこちらも試す
```terminal
$ arch -arch x86_64 env PATH=${PATH/\/opt\/homebrew\/bin:/} pyenv install 3.10.6
```
:::

## 5. インストールされているPythonを一覧で確認
```terminal
$ pyenv versions
```

```terminal:実行結果
* system (set by /Users/username/.pyenv/version)
  3.10.6
```

```terminal
$ python -V
```

```terminal:実行結果
Python 2.7.16
```

:::note warn
インストールはできたが、このままではMacに最初からsystemとして入っているPythonが指定されている為、使用するPythonのバージョンを設定する必要がある。
:::

## 6. 使用するバージョンを設定して完了
```terminal
$ pyenv global 3.10.6
$ pyenv versions
```

```terminal:実行結果
  system
* 3.10.6 (set by /Users/username/.pyenv/version)
```

```terminal
$ source ~/.zshrc
$ python -V
```

```terminal:実行結果
Python 3.10.6
```
Rails6,  SQL Serverでinsert_allが使えない問題

Rails6でのSQLServerにて```insert_all!```は使えるが```insert_all```が使えなく、調査したのでメモ。
出るエラーは以下

```Bash
Model.insert_all([{name: 'test'}])
ArgumentError: ActiveRecord::ConnectionAdapters::SQLServerAdapter does not support skipping duplicates
```

## 環境

```lock
activerecord-sqlserver-adapter (6.0.0)
activerecord (~> 6.0.0)
```

## Railsのコードを読む

結論を先に言うと、```ActiveRecord#insert_all```は以下で```on_duplicate: :skip```という主キーが重複するレコードをスキップする引数をデフォルトで渡しているが、```activerecord-sqlserver-adapter```ではこれをサポートしていないのが原因。

```Ruby
def insert_all(attributes, returning: nil, unique_by: nil)
  InsertAll.new(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by).execute
end
```

https://github.com/rails/rails/blob/984c3ef2775781d47efa9f541ce570daa2434a80/activerecord/lib/active_record/persistence.rb#L146

少し深堀りすると、```ActiveRecord#insert_all```の```initializer```の中でサポートしているアダプタをチェックしている

```Ruby
def initialize(model, inserts, on_duplicate:, returning: nil, unique_by: nil)
  ## 省略

  ensure_valid_options_for_connection! # ← ここ
end
```

```ensure_valid_options_for_connection!```の中身を見てみると、一番最初に書いたエラーを吐いている部分があり、これによって使えないっぽい。

```Ruby
def ensure_valid_options_for_connection!
    ## 省略
    if skip_duplicates? && !connection.supports_insert_on_duplicate_skip?
        raise ArgumentError, "#{connection.class} does not support skipping duplicates"
    end
end
```

```supports_insert_on_duplicate_skip?```の中身を見てみると、サポートしているアダプタはtrueを返すようになっている。
trueを返すのは```mysql, sqlite3, postgresql```だけなので、sqlserverは使えず、ここでraiseされて使えないことがわかる


## insert_all!は何故使える？

```insert_all!```は```on_duplicate: :raise```になっている

```Ruby
def insert_all!(attributes, returning: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: :raise, returning: returning, record_timestamps: record_timestamps).execute
end
```

これによって、先ほどの```ensure_valid_options_for_connection!```の条件がfalseになり、また重複行があった場合は```ActiveRecord::RecordNotUnique```が発生するので問題なく使える。

https://github.com/rails/rails/blob/984c3ef2775781d47efa9f541ce570daa2434a80/activerecord/lib/active_record/persistence.rb#L214


## Issueがあった

実はもうIssueが立っていて、上に書いたことが説明されている

https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/847

修正しようとしたPRもあるが、Draftなのでまだ使えなそう。。。

https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/869



v7.0.0のリリースノートを見てもon_duplicateに関することは書いていないので、まだ使えなそうです。

https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/5f020fd7e645f3fec6ff33de11b961658d5203fb/CHANGELOG.md
Unity NetcodeをチュートリアルしてThirdPersonサンプルに適用した話

# 概要
2022/06/27に Netcode for GameObjects 1.0.0 がリリースになりました🎉

https://unity.com/ja/products/netcode

> Netcode for GameObjects は、Unity ゲームエンジン用に構築されたネットワーキングライブラリ

以前はMLAPIという名前だったらしい
「DOTS Netcode」とは別にGameObjectに対応しているため「for GameObjects」

これをUnity Third Personサンプルに適用してマルチ同期3Dアクションを作るのが今回の目標です

## テスト環境
Unity : 2021.3.6f1 Personal
Netcode for GameObjects : 1.0.1


# 成果物
コード : https://github.com/tsune2ne/NetcodeTP

![SS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/11fea3fd-711e-4872-4cfe-5de020991efb.png)

アニメのOPみたいですね



自分がHost、他2体がClient接続してます
ServerもビルドしてClient接続できました

コントローラー対応もされてるのでThirdPersonモックとしてもいい感じに使えます

# 前提知識
オンラインゲームではListenサーバー形式とDedicatedサーバー形式があります

Listenサーバー
    クライアントとサーバーが一つのプログラムで一緒に動作する
    サーバーはHostと呼ばれ、他クライアントはHostにアクセスして同期する
    気軽に作れる半面、Hostの処理が過剰になりボトルになるので重い処理には向かない

Dedicatedサーバー
    専用サーバーを用意し、すべてのクライアントが専用サーバーにアクセスして同期する
    専用サーバーでは専用の処理が実行されるため、Listenサーバーよりも重い処理に向いている

Unity NetcodeではListenサーバーで簡単に作れつつ、
UnityのDedicated ServerビルドでDedicatedサーバーも作れます

## やったこと
- ゲーム開始時にGUIによる初期化処理
- NetworkManagerを作ってPlayerPrefabにPlayerArmatureを設定
  - StarterAssetInputsを実行時に操作キャラに設定
  - PlayerFollowCameraを実行時に操作キャラに設定
    - 理由は後述
- ThirdPersonControllerのUpdateで位置と回転を他端末に同期
- ThirdPersonControllerのアニメーションイベントを他端末に同期
  - Animator操作頻度が増えるので別クラスに分離


## ハマったこと
### HelloWorldチュートリアルが動かない
https://docs-multiplayer.unity3d.com/netcode/current/about/index.html
「Your First Networked Game」→「Module One」→「Module Two」
の順番でやるとOK

ただいくつかバグがあるので注意
- ClientNetworkVariableは使わないので削除
- 「Click + to create a slot.」は嘘。Unity2021では「Player Prefabs」に設定するだけで「Network Prefabs」は不要

### NetworkManagerのPlayerPrefsの扱い
起動時にClient別でPlayerPrefabが生成される
入力やカメラ追従は自分管理のPlayerPrefabにだけ設定されるようにしないといけない

TPサンプルではデフォでPlayerArmatureに設定されるので
調整する必要があった

### ClientかServerか判別したい
- NetworkManager.Singleton.IsClient
- NetworkManager.Singleton.IsServer
を使う

| 端末 | 概要 | IsHost | IsClient | IsServer |
|:---:|:---|:---:|:---:|:---:|
| None | 未設定 | false | false | false |
| Host | P2Pの主 | <b>true</b> | <b>true</b> | <b>true</b> |
| Client | 1メンバ | false | <b>true</b> | false |
| Server | Server起動する場合の主 | false | false | <b>true</b> |

IsHostの扱いを間違えやすい
    → Listenサーバー形式の知識が足りてなかった
IsLocalもあるが今回は除外

### 自分操作キャラと同期キャラで処理を分けたい
<b>NetworkManager.Singleton.IsOwner</b> を使う
自端末がそのPlayer Prefabを操作しているかが分かる
入力を伝播させるか、親同期を無視するかに使う


### NetworkVariableはなに？
HostからClientに変数を同期してくれる
ServerRPCで送る必要がないので簡単

Triggerを送る場合はServerRPCで送ったほうがよい

### Serverを起動したい
UNITY_SERVER時にStartServerする
```c#
    void Start()
    {
#if UNITY_SERVER
        NetworkManager.Singleton.StartServer();
#endif
    }
```

あとはPlatformを <b>DedicatedServer</b> にしてビルドするとServerバイナリができる
（ServerBuildがなくなってDedicatedServerになったっぽい）

Serverバイナリを起動するとServerとして起動できる
Clientバイナリから接続できる

# まとめ
同期通信を実装したのは初めてだったが簡単に対応できた
ThirdPersonサンプルに入れれると簡単にモックが作れるので便利

# 今後やりたいこと
- 通信チューニングの設定やドキュメントのありかを調べる
- ネットワーク設定してないので外部公開する場合の作業しりたい
  - NetworkManagerのConnectionDataでできそう
- Serverでも描画負荷がかかってるので軽減したい
- DOTS Netcodeもやりたい


# 参考
https://qiita.com/pakiln/items/e2a971260479385cd928
三角形の角の二等分線「2017年大分大学・経済第３問」をsympyでやってみたい。

△ABC において ... ∠A の二等分線...

オリジナル

https://ameblo.jp/mathisii/entry-12766078400.html

上と同じです。大学入試数学問題集成＞【3】＞数学入試問題様、入試の軌跡数学様

https://mathexamtest.web.fc2.com/2017/201710921/2017109210100mj.html#top-0104

# sympyで,できる方法。
(勉強中)

# sympyで,できませんでした。
sympyの世界では、正しいのかもしれません。
```python
from sympy import *
t=Symbol('t', real=True,positive=True)
A=Point(0,0)
B=Point(5,0)
C=Point(3*cos(t),3*sin(t))
P=Line(B,C).intersection(Line(A,Point(1,1)))[0]
D=Line(A,P).projection(C)
E=Line(C,D).intersection(Line(A,B))[0]
print("#(1)",B.distance(E))
print("#(2)",(Rational(1,2)*(B+C)).distance(D))
print("#(3)",A.distance(D)/D.distance(P))
#(1) Abs(3*sqrt(2)*sin(t + pi/4) - 5)
#(2) sqrt((3*sin(t)/2 - 3*sqrt(2)*sin(t + pi/4)/2)**2 + (-3*sqrt(2)*sin(t + pi/4)/2 + 3*cos(t)/2 + 5/2)**2)
#(3) 3*sqrt(2)*Abs(sin(t + pi/4))/(2*sqrt((3*sqrt(2)*sin(t + pi/4)/2 + 15*sin(t)/(3*sqrt(2)*cos(t + pi/4) - 5))**2))
```



# sympyで,都合のいい値C(0,3)を入れたらできました。
```python
from sympy import *
A=Point(0,0)
B=Point(5,0)
C=Point(0,3)
P=Line(B,C).intersection(Line(A,Point(1,1)))[0]
D=Line(A,P).projection(C)
E=Line(C,D).intersection(Line(A,B))[0]
print("#(1)",B.distance(E))
print("#(2)",(Rational(1,2)*(B+C)).distance(D))
print("#(3)",A.distance(D)/D.distance(P))
#(1) 2
#(2) 1
#(3) 4
```

# 参考
中学でお馴染み？

https://ja.wikipedia.org/wiki/%E4%B8%AD%E7%82%B9%E9%80%A3%E7%B5%90%E5%AE%9A%E7%90%86

https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%8D%E3%83%A9%E3%82%A6%E3%82%B9%E3%81%AE%E5%AE%9A%E7%90%86
ABC071 C - Make a Rectangle を自力で WA => AC まで持ち上げてみた


# [問題](https://atcoder.jp/contests/abc071/tasks/arc081_a)
一発目の WA はコチラ。
```abc071.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int main() {
	int N,A; cin >> N;
	map<int, int>nums;
    //入力 受け取り
	for (int i = 0; i < N; i++) {
		cin >> A;
		nums[A]++; // 入力で map を生成 , 各要素の重複数をカウント
	}

	vector<long long>area; // 正方形 用の要素を格納
	vector<int> factor;    // 長方形 用の要素を格納
	for (auto x : nums) {
		if (x.second >= 4) // 要素が 4 つあれば正方形に利用
			area.push_back(x.first);
/*bat */else if (2 <= x.second && x.second <= 3) // 要素が 2 以上 3 以下であれば
			factor.push_back(x.first);           // 長方形に利用
	}

	long long square = 0;
	if(area.size()>0){//そもそも　4つも重複していない可能性がある
		sort(area.begin(), area.end(), greater<long long>());
		square = area[0] * area[0]; // 最大の辺を使用
	}
	long long rectangle = 0;
	if(factor.size()>1){//そもそも 長方形用の要素が無いかも
		sort(factor.begin(), factor.end(), greater<int>());
		rectangle = (factor[0] * factor[1]); // 最大の辺を使用
	}

	cout << max(square, rectangle); // 大きい方を output
	//while (1) {}
	return 0;

}
```

テストケースを探したが見当たらなかった、残念。

https://www.dropbox.com/sh/nx3tnilzqz7df8a/AAAYlTq2tiEHl5hsESw6-yfLa?dl=0

だが、上記で/*bat */と記述した点に違和感をおぼえた。なぜなら
**正方形の要素としてカウントしたものも、長方形としても検討して良い**からだ。

その他にも、他のミスが無いか検討したが、
見当たらないので以下で提出したが、**WA**.
(少し視認性を上げた。。)

```abc071.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int main() {
	int N,A; cin >> N;
	map<int, long long>nums;
	for (int i = 0; i < N; i++) {
		cin >> A;
		nums[A]++;
	}

	vector<long long>factor_S;// 正方形 用の要素を格納
	vector<long long>factor_R;// 長方形 用の要素を格納
	for (auto x : nums) {
		if (x.second >= 4)
			factor_S.push_back(x.first);
/*bat */else if (x.second >= 2)
			factor_R.push_back(x.first);
	}

	long long square = 0;
	if(factor_S.size()>0){
		sort(factor_S.begin(), factor_S.end(), greater<long long>());
		square = factor_S[0] * factor_S[0];
	}
	long long rectangle = 0;
	if(factor_R.size()>1){
		sort(factor_R.begin(), factor_R.end(), greater<long long>());
		rectangle = (factor_R[0] * factor_R[1]);
	}

	cout << max(square, rectangle);
	//while (1) {}
	return 0;

}
```

御覧の通り /*bat */ でミスを発見。
if ~ , else if だと、条件にはまる何れかを実行。
いやいや、正方形の要素、長方形の要素 を同時に取り込んで欲しい。
つまり、if ~ , if ~ が正解だ。

そこに気付いて以下で AC.

```abc071.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int main() {
	int N,A; cin >> N;
	map<int, long long>nums;
	for (int i = 0; i < N; i++) {
		cin >> A;
		nums[A]++;
	}

	vector<long long>factor_S;
	vector<long long>factor_R;
	for (auto x : nums) {
		if (x.second >= 4)
			factor_S.push_back(x.first);
		if (x.second >= 2)
			factor_R.push_back(x.first);
	}

	long long square = 0;
	if(factor_S.size()>0){
		sort(factor_S.begin(), factor_S.end(), greater<long long>());
		square = factor_S[0] * factor_S[0];
	}
	long long rectangle = 0;
	if(factor_R.size()>1){
		sort(factor_R.begin(), factor_R.end(), greater<long long>());
		rectangle = (factor_R[0] * factor_R[1]);
	}

	cout << max(square, rectangle);
	//while (1) {}
	return 0;

}
```
Apache2.4 タイムアウト関連項目を1枚にまとめてみた

# はじめに

* Apache v2.4 をリバースプロキシとして利用した場合のタイムアウト設定項目を視覚的にわかるよう図にしました。
* 各設定項目については [こちらの記事](https://qiita.com/kazukikudo/items/96f77f1648b8ce47dc06 "Apacheでリバースプロキシ、タイムアウトを上手にコントロール") を参考にさせていただきました。
* 一部OSの設定も記載しています。
* 対象設定ファイル
    * httpd.conf
    * /proc/sys/net/ipv4

# Apache 2.4 タイムアウト関連設定項目
![処理シーケンス_20220803追記.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741587/f6ce6714-f170-1283-dd0c-2d41272bdbb4.png)

# 参考情報
* Apache Core Features
https://httpd.apache.org/docs/2.4/en/mod/core.html
* Apache Module mod_proxy
https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html
* Apacheでリバースプロキシ、タイムアウトを上手にコントロール
https://qiita.com/kazukikudo/items/96f77f1648b8ce47dc06
LaravelでGroupByしてその中の最新取ってきてさらにjoinして最後にOrderBy!!!!!!!!

# [<font color="#333">1.はじめに</font>](#-1.はじめに)
 タイトルの通りですが何を言ってるのかわからない。
しかし、絶対にこれをやりたい時が来るはずです。
自分はいつも詰まる。
例えば以下の機能があったとする。

「顧客がいて、顧客がレストランを予約する。」
顧客テーブル(customers)
予約テーブル(reserves)

一応、modelでリレーション張るとしたら以下の感じ
```Customer.php
//一人の顧客はたくさんの予約を持つ。
public function reserves()
  {
    return $this->hasMany(Reserve::class);
  }
```

```Reserve.php
//予約は一人の顧客に属する(一つの予約が複数の顧客idを持つわけがない)
public function customer()
  {
    return $this->belongsTo(Customer::class);
  }
```

こちらreserves_table
|id  |customer_id  |restaurant_id  |updated_at|created_at|
|---|---|---|---|---|
|1  |1  |3  |2022-11-05 16:34:29.000 +0900|2022-11-05 16:34:29.000 +0900|
|2  |3  |1  |2021-05-09 11:01:14.000 +0900|2021-05-09 11:01:14.000 +0900|
|3  |1  |5  |2022-05-21 16:51:14.000 +0900|2022-05-21 16:51:14.000 +0900|
|4  |2  |4  |2021-9-22 09:41:09.000 +0900|2021-9-22 09:41:09.000 +0900|

ほんでcustomers_tabel
|id  |customer_name  |age |updated_at|created_at|
|---|---|---|---|---|
|1  |chaki  |34  |2021-01-06 16:34:29.000 +0900|2021-01-06 16:34:29.000 +0900|
|2  |hoge  |19  |2021-02-09 07:23:11.000 +0900|2021-02-09 07:23:11.000 +0900|
|3  |ketu  |22  |2021-9-02 09:22:39.000 +0900|2021-9-02 09:22:39.000 +0900|


どんな時にタイトルのような訳のわからない事をしたくなるかと言うと。。。
次の様な要件。
・顧客ごとの予約件数を取得したい
・それを予約の新しい順で並べ替えたい。
意外とシンプル。
以下の様に取得したい感じ。

|customer_id  |customer_name| 件数|updated_at|created_at|
|---|---|---|---|---|
|1  |chaki |2|2022-11-05 16:34:29.000 +0900|2022-11-05 16:34:29.000 +0900|
|2  |hoge |1|2021-9-22 09:41:09.000 +0900 |2021-9-22 09:41:09.000 +0900|
|3  |ketu |1|2021-05-09 11:01:14.000 +0900|2021-05-09 11:01:14.000 +0900|

どうすれば良いかというとGroupByしてその中の最新レコード取ってきてさらにjoinして最後にOrderBy!!!!
タイトルの通りです。
サブクエリ使います。

```query.php
$subSql =  CustomerTransfer::select(DB::raw('customer_id, MAX(created_at) as latest(名前自由)'))
          ->where('deleted_at', null)
          ->groupBy('customer_id')
          ->toSql();
        return $query->select(DB::raw('*'))
          ->joinSub($subSql, 'reserves', function ($join) {
            $join->on('customers.id', '=', 'reserves.customer_id');
          })->orderBy('latest', 'desc');//昇順ならdescをascに変更
```


素のSQLで書けば楽かもですがLaraveでクエリビルダから脱却しようとすると色々めんどくさいです。
ページネーションの「->pagenate()」とか子テーブル取ってくる時の「->with()」とかくっつけられなくなるので。
素のSQL書かなきゃいけない時はテーブル設計を見直したほうが早いかもです。
ただ、コードにテーブル設計合わせるよりテーブル設計ありきのコードだとも思うのでなんとも言えませんが。
影響範囲や保守性とかの兼ね合いですかね。

ちなみでガチで生のSQL使いたければ以下の様な感じ。
SQLインジェクションとか意識しないといけないので使うのめんどくさいと思いますが。
```query.php
$sql = <<< SQL
    SELECT
        c.name,
    FROM
       customers c 
    INNER JOIN
        reserves r 
    ON
        c.id = r.customer_id
    WHERE
        c.deleted_at = null
SQL;

$names = DB::select($sql);
```

ありがとうございました。
ITのベトナム語

どなたかがITの中国語について記事を書いておられましたが、実はベトナムも漢字文化圏であり、
漢字語由来のベトナム語が大量に存在しています。それは漢越語と言われ、純粋なベトナム語を純越語といいます。
純粋なベトナム語は20世紀前半までチュノムという漢字応用文字を使ったり、音の同じ漢字を当てたりして文章を作成していたため、ベトナムの歴史的な文書はすべてこれらの文字を使ったものとなります。
最近急に日本で存在感を増してきたベトナム人、彼らのベトナム語を耳にするとまるで宇宙人が喋っているみたいですが
実は日本語、中国語と縁戚関係にあり、50％近くは漢字語なんです。
今回はQiitaということで、IT関連のベトナム語を旧漢字、チュノムを使いつつ紹介します。


漢字	chế độ 8086 ảo	制度8086幻	仮想86モード
漢字	chế độ bảo vệ	制度保衛	プロテクトモード
漢字	chế độ thực	制度実	リアルモード
漢字	chế độ địa chỉ ảo được bảo vệ	制度地址幻得保衛	保護仮想アドレスモード
漢字	chương trình	章程	プログラム
喃字	cổng	𨶛	ポータル、ポータルサイト
漢喃	cổng thông tin điện tử	𨶛通信電子	Webポータルサイト
喃字	cổng	𨶛	ポート、TCPポート
漢字	hệ điều hành	系調行	オペレーティングシステム（OS)
漢喃	không gian hai byte	空間𠄩byte	全角スペース、ダブルバイトスペース　　　　　.
漢喃	Kỹ sư phát triển phần mềm	技師発展份𣠳	ソフトウェア開発エンジニア
漢喃	loạn chữ	乱𡨸	文字化け、乱字、乱筆
漢字	loạn ký tự	乱記字	文字化け、乱字、乱筆
漢喃	máy chủ	𣛠主	サーバ
漢喃	máy chủ truyền thông	𣛠主伝通	メディアサーバ
漢喃	máy ảo	𣛠幻	仮想マシン
漢喃	người quản trị	𠊛管治	アドミニストレータ
漢喃	người quản trị hệ thống	𠊛管治系統	システムアドミニストレータ
漢喃	người thảo chương	𠊛草章	プログラマ
漢字	ổ （一文字）	塢	ディスク
漢喃	ổ đĩa cứng	塢𥐨𠠊	ハードディスク
漢喃	ổ cứng	塢𠠊	ハードディスク、SSD（ソリッドステートドライブ）
漢喃	ổ đĩa mềm	塢𥐨𣠳	フロッピーディスク
漢喃	phần mềm	份𣠳	ソフトウェア
漢喃	phần cứng	份𠠊	ハードウェア
漢字	quản tri viên	管治員	管理者、アドミニストレータ
漢字	quản tri viên hệ thống	管治員系統	システム管理者
漢字	quản tri viên miền	管治員沔	ドメイン管理者
漢喃	tên lệnh	𠸛令	コマンド名
喃字	tên máy	𠸛𣛠	ホスト名
漢喃	tên miền	𠸛沔	ドメイン名
漢字	thanh tìm kiếm	錆尋検	検索バー、検索窓
漢字	thảo chương	草章	プログラミング、プログラム
漢字	thời gian đáp ứng	時間答応	レスポンスタイム
漢字	thời gian thử việc	時間試役	試用期間
漢字	thời gian thực	時間実	リアルタイム
漢喃	thời gian trả lời	時間𠭤唎	レスポンスタイム
漢字	thuộc tính	属性	属性、プロパティ
漢字	trang chủ	幀主	ホームページ、メインページ
漢字	trang web	幀web	ウェブページ
漢字	ứng dụng	応用	アプリ、アプリケーション
漢字	ứng dụng web	応用 web	ウェブアプリケーション
漢字	thư điện tử (E-mail)	書電子	Eメール
漢字	tin tặc (hacker)	信賊	ハッカー
喃字	mạnh 	𦀴 	ネット、インターネット
漢喃	vòng lặp vô hạn	𤥑㕸無限	無限ループ

ベトナム語に少しでも興味のある方は、当方が「夢幻の越南辞典」というベトナム語を全て漢字・喃字に変換した
他にない辞典をインターネットで公開しているので是非御覧ください。
CloudWatch Logs に特定の文言が出力されていたら通知する方法

CloudWatch Logs に保存したログに**特定の文言**が出力されていたら通知する方法を調べていたら、CloudWatch Logs の**サブスクリプションフィルタ**という機能を使えば実現できることが分かったので、メモとして残しておきたいと思います。

## 構成

構成としては、CloudWatch Logs の**サブスクリプションフィルタ**という機能を使い、サブスクリプションフィルタで検知したログの内容を Lambda に送り、Lambda から SNS トピックにパブリッシュするという構成になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/d09cc5f4-6ebd-7603-0704-5adf521adcef.png)

ロググループごとに、最大２つのサブスクリプションフィルタを設定することができるようです。
また、今回は、Lambda に送っていますが、Amazon Kinesis や  Amazon KinesisData Firehose などへ送ることもできるようです。
[サブスクリプションを使用したログデータのリアルタイム処理 - Amazon CloudWatch Logs](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/Subscriptions.html)

## 構築

**AWS CDK（v2）** を使って構築を行います。
CDK コード一式は [こちら](https://github.com/y-okamon/cdk-subscription-filter-demo) から取得できますので、必要に応じてご利用ください。

デプロイすると、「SNSトピックとサブスクリプション」「Lambda」「サブスクリプションフィルタ」が作成されます。
サブスクリプションフィルタを設定する CloudWatch **ロググループ**は、CDK で作成するのではなく（別の手段で作成した）既存のモノを使用するようにしています。
もしも、CDK で新規作成する場合は、以下のようなコードになります。

```typescript
const logGroupNew = new LogGroup(this, 'SubscriptionFilterLogGroup', {
    logGroupName: 'your-log-group-name',
    retention: RetentionDays.THREE_MONTHS
})
```

今回はログデータに「Start」「START」「start」いずれかの文言が出力されていたら、通知が上がるように設定しています。

```typescript
new SubscriptionFilter(this, 'LogSubscriptionFilter', {
  logGroup,
  destination: new LambdaDestination(logProcessingFunction),
  filterPattern: FilterPattern.anyTerm('Start', 'START', 'start')
});
```

## デプロイ

`cdk deploy` コマンドを実行する際に、`-c` オプションを使って、「**通知メッセージを受けるメールアドレス**」と「**サブスクリプションフィルタを設定する（既存の）ロググループ名**」を指定します。

```bash
cdk deploy -c notification_email="<your-mail-address>" -c log_group_name="<your-log-group>"
```

`-c` オプションについてはこちらの AWS 公式ページに記載があります。
[Get a value from a context variable - AWS Cloud Development Kit (AWS CDK) v2 (amazon.com)](https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/get_context_var.html)

## 動作確認

デプロイが完了すると、おなじみの SNS サブスクリプションの確認メールが届くので、`Confirm subscription` をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/cc333aba-f67a-32fe-d873-4eb32e4d8cc2.png)

サブスクリプションフィルタを設定したロググループ に、「Start」「START」「start」のいずれかの文言を含むログが出力されると、指定したメールアドレス宛に通知メッセージが届きます。

・CloudWatch Logs の内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/71795fbe-1d2c-653e-949a-c6b077eaf6cd.png)

・通知メールの内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/eb098978-4592-e433-7a4a-37f32eb29483.png)

## 後始末

後始末は `cdk destroy` コマンドで行います。
デプロイ時と同じ様に、`-c` を付与して実行します。

```bash
cdk destroy -c notification_email="<your-mail-address>" -c log_group_name="<your-log-group>"
```

## 参考ページ

今回の記事を書くにあたって以下のページを参考にしました。

- [CloudWatch Lamba Subscription Filter (CDK-Demo) | by Duleendra Shashimal | Towards AWS](https://towardsaws.com/cloudwatch-lamba-subscription-filter-cdk-demo-f0eb571547c6)
- [CloudWatch Logs を文字列検知してログ内容をメールを送信してみた サブスクリプションフィルター版 | DevelopersIO (classmethod.jp)](https://dev.classmethod.jp/articles/notification_cloudwatchlogs_subscriptoinfilter/)
- [CloudWatch Logs のサブスクリプションフィルタを使って特定文字列を検知したログをEメール通知する - Qiita](https://qiita.com/kooohei/items/b638cbb71ac9a7e87c5e)
Control キーの単発押しで Esc キーを押したことにする (Windows/Linux)

# 概要
- Vimを使っていると, Ctrlキーと Escキーを多用します
- 一般的なキーボードでは, Escキーは左上,Ctrlキーは左下に配置されていることが多く,どちらもホームポジションから大きく外れて押しづらいです
- SandS(スペースキーとの組み合わせ)でEscを実行するなどのアプローチも可能ですが,自分は CapsLock の位置にCtrlとEscを両立する方法を愛用しています
- 具体的には,以下のようなキー配列で操作できるようにしています
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170422/b6ac4d8d-b7be-4a08-cd09-a03cd0077c3d.png)
- `L_Ctrl / Esc` と書いたキーは,他のキーと一緒に押すとCtrlキーとの同時押しになり,他のキーを押さずに離すとEscキーを押したことになります
    - 自分はVimでの用途が多いけれど,他のシチュエーションでも便利に感じる機会は多いと思います

# 前提条件
- 一般的なキーボードでは今回 `L_Ctrl / Esc` と定義したキーの位置にはもともと CapsLockキーがあるので,レジストリ変更などによってL_Ctrlに置換しています

# 実現方法

## Windows
- AutoHotKey を使うといい感じに設定できそうで,既に他のキーで実現している方が居られた
    - https://github.com/karakaram/alt-ime-ahk
        - こちらは alt キーを単押しするとIME切り替えを実行するもので,日本語配列のキーボードを使用している場合は非常に便利そうです
        - 今回はこちらを参考に Ctrlキーを単押しした場合にEscキーを発行するようにして実現できた

## Linux
- `xcape` コマンドを使うといい感じにできる
- 起動時の自動実行コマンドに登録しておくと便利

```.sh
$ xcape -e 'Control_L=Escape'
```


## Mac
- はっきりと把握していないけれど Karabiner を使うと実現できそう
Sphinxで縦書きの電子書籍を作成する設定について

## 概要

Sphinxで電子書籍を作成する方法を調べている際に、「縦書きの電子書籍を作成できないか？」と思いました。

調べてみたところ、方法が用意されていました。

## 縦書きのための設定

`conf.py`に以下を追記します。

    epub_writing_mode = 'vertical'

上記の設定だけで文字が縦方法になり、更にページ送りが右に変更されます。

## EPUBの出力結果

Sphinxで縦書きのEPUBをビルドして、Kindle Previewerで確認しました。

### 漢字、ひらがな、カタカナ: 問題なさそう

実際に設定してEPUBの出力結果を見てみたところ、漢字、ひらがな、カタカナは問題なさそうでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544399/ee79b8b0-1e09-6c89-f2fc-e19610b662c0.png)

### 数字: 注意が必要

数字は注意が必要です。以下のパターンで試してみました。

* 半角アラビア数字
* 半角アラビア数字、半角のカンマ区切りあり
* 全角アラビア数字
* 全角アラビア数字、全角のカンマ区切りあり
* 漢数字

結果は以下のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544399/c081e31e-4892-88f6-2670-c30344480d6d.png)

縦書きにおける数字については、一般には漢数字を用いるのが良いと考えます。出版社が出版している書籍を見ると、漢数字を用いているケースが大半です。ただ、原則は漢数字を用いつつも、西暦の年号（4桁）や1・2桁の数字については、アラビア数字を用いている書籍もありました。この辺は出版元で定めた規則が存在していて、規則に合わせて原稿を組んでいるものと思われます。

よって、Sphinxでも原則は漢数字を使い、アラビア数字を縦書きにしたい場合は全角アラビア数字を使うことで対応する、という方法は考えられると思います。

ただし、漢数字を使った時点でその原稿は実質的には縦書き専用の原稿となってしまいます。例えば、ビルドを替えてHTMLに変更した時も、漢数字で記述した部分はそのまま漢数字で出力されます。ここが両立できるとありがたいケースはあるかも知れませんが、そこは割り切るべきかも知れません。

### 英字: 注意が必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544399/a95fd5ad-c2a3-283c-2779-d2fbc99f4141.png)

英字は半角ですと横向きのまま、全角では縦向きになります。

英単語や英文を縦書きの文章内に混在させたい場合は、半角で記述して横向きのままにした方が良いと思います。

なお、「ジョン・Ｌ・スミス」のように、間に1文字の英字を含めるような場合は、全角で書いて全体が縦書きになるようにしても良いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544399/20c44634-914f-1e24-9389-ef2ae8276f2b.png)

縦書き用に半角・全角の使い分けを行うことで、その原稿が実質的には縦書き専用の原稿になってしまう点は、数字についての注意点と同じです。
tan(75 °)「2015年富山大学・経済第1問」をwolframAlphaとsympyでやってみたい。

オリジナル ますいしい様

https://ameblo.jp/mathisii/entry-12766078000.html

上と同じです。大学入試数学問題集成＞【１】

https://mathexamtest.web.fc2.com/2015/201510341/2015103410100mj.html

# wolframAlphaで

https://www.google.com/search?q=tan(75+%C2%B0)&rlz=1C1CHBD_jaJP908JP908&oq=tan(75+%C2%B0)&aqs=chrome..69i57j0i22i30l9.1613j0j7&sourceid=chrome&ie=UTF-8

**(1) tan(5/12*π)**

https://www.wolframalpha.com/input?i=tan%285%2F12*%CF%80%29&lang=ja

厳密な結果 2 + sqrt(3)
近似値　　 3.73205080(以下省略)

**(1別解)** ますいしい様の図より
√3+2

**(2)**
√(n)<tan(5/12*π)<√(n+1)

https://www.wolframalpha.com/input?i=%E2%88%9A%28n%29%3Ctan%285%2F12*%CF%80%29%3C%E2%88%9A%28n%2B1%29&lang=ja

整数解 n = 13




# sympyで(ますいしい様の手順で)
勉強中 “ｔａｎの加法定理”,“逆辿り法”


# 参考

https://qiita.com/mrrclb48z/items/c2e38d2717b1bc0d7600
Google UXデザイン：公平性を重視したデザインを深掘る

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

#  公平性を重視したデザインとは

公平性を重視したデザインとは、デザインされた製品のあらゆる側面を考え、その製品がすべての人にとってアクセスしやすく、公平であり、さらに、社会的地位が低く、排除されている人々にも配慮したデザインが必要です。

公平性について意識する対象：
- 人種
- 性別
- 能力
- 年齢
- 社会経済的地位

# サンプル１：性別記入欄

**_あなたなら、性別欄の入力フォームをどのように設計しますか？_**

次の欄しかなかったとしたら、どう思いますか？
-　男性
-　女性

公平性を意識した場合、次のようにすると良いでしょう。
-　男性
-　女性
-　<font color="Teal">その他</font>

# サンプル２：公共トイレ

**_もし、男性用トイレと女性用トイレが同じ数のストールが平等に提供されていたら、それは公平でしょうか？_**

男性とも女性とも言えない人たち（これまで社会的に排除されてきたグループ）にとっては、どちらを使うべきか迷うことがあります。そして、選択した結果トラブルになることがあります。

<font color="Teal">性別に関係なく使えるトイレ</font>は、すべての人を公平に扱うように設計された物理的空間の一例です。性自認に関係なく、誰もが同じように各トイレを使うことができるのです。

# サンプル３：Goole音声アシスト機能

Googleで初めて音声アシスタントが導入されたとき、主に英語を母国語とする男性の声で訓練されました。

＜結果＞
- 男性の声を容易に理解し、反応した。
- 女性の声は音程が高く、訛りが強いため、反応が悪かった。

このように、<font color="Teal">多様なユーザーを対象にしたテスト</font>が、いかに製品の改善につながるかを示しています。

# さいごに

わたしたちは、公平性を重視したデザインを考える、自分自身の偏見やその他の要因に気をつける必要があります。どのように対処すべきかは別途記事にします。
GitHubActionsで効率化した結果を視覚化したい調査編

## はじめに

GitHubActionsでいろいろワークフローを作り自動化するわけですが、設定のBilling And Plansから確認できる情報では、個人や組織全体の実行時間しか見れず、少々不便です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/7a1c068f-f647-275b-5e23-ac1259299065.png)

やりたいのはリポジトリ単位で、どのワークフローが月にどれくらい実行され、手間が削減されているのかを視覚化したい。

## 調べたこと

また後日、以下の情報を利用してアクションのジョブサマリーなんかに出力できるワークフローでも作ってみようと思いますが、備忘録として使えそうなAPIなどを記します。

公式ドキュメントにあるAPIだと以下を組み合わせれば、リポジトリのワークフロー一覧を取得しワークフローごとの実行時間の集計ができそうです。

https://docs.github.com/en/rest/actions/workflows#list-repository-workflows

https://docs.github.com/en/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run

上だけで十分かもしれませんがこれも使えるかも

https://docs.github.com/en/rest/actions/workflow-runs#get-workflow-run-usage

また実際に同じようなことをすでに挑戦している先人もいるようで、アプローチは異なりますがこちらも参考になるかも

https://tech.kusuwada.com/entry/2020/12/05/053300

https://developers.lighthouse-frontier.tech/entry/2022/01/19/102207