OmniAICreator/Qiita-1.07M huggingface dataset:
filter_input関数（メソッド）の分かりやすい？記事

# 概要
filter_inputってどうやって渡ってくるんだっけ？
忘れちゃうなーって思ったので記事にしました。
# バージョン
- php 8.1

# html

``` html
<form action="signin_post.php" method="post">
                    <div class="form-group">
                        <label for="name">Name</label>
                        <input type="text" class="form-control" id="name" name="name">
                    </div>
                    <div class="form-group">
                        <label for="password">Password</label>
                        <input type="password" class="form-control" id="password" name="password">
                    </div>
                    <button type="submit" class="btn btn-secondary">Sign in</button>

```
こちらはphpファイルでhtmlを書いています。

ログインでボタンを押すと処理が流れ、signin_post.phpに情報が渡ります。


# filter_input

filter_inputは

INPUT_GET、INPUT_POST、 INPUT_COOKIE、INPUT_SERVER  INPUT_ENV のうちいずれかを使いますが、
最初はINPUT_GET、INPUT_POSTだけ覚えておけば大丈夫です。


``` php
filter_input(INPUT_POST,"name");
```
早速INPUT_POSTを使用しています。

カンマのあとに来ている"name"は、
``` HTML
<input type="text" class="form-control" id="name" name="name">
```
のnameのnameを取得します。（ややこしい）




passwordならば
``` php
filter_input(INPUT_POST,"password");
```
nameのpasswordを取得します。
``` html
<input type="text" class="form-control" id="password" name="password">
```

# 取得してからどう動くか

現在filter_inputは、htmlから送られた値を持っています。

例えば上記のhtmlで、emuriと打てば、filter_input関数は、emuriという値を返します。

それを
``` php
$name = filter_input(INPUT_POST,"name");
```
$nameに持たせることもできます

値を確認するときはvar_dumpを使って値が来ているか確認しましょう

# 結論

関数はよく忘れるので、イメージをしながら復習をするのが一番です。
そうすると頭に定着しやすいですからね
TestClientを用いてFastAPIのテストをする

FastAPIはPythonで高速なAPIサーバーを立てられるので人気ですね。
今回はFastAPIでテストをする方法を試してみました。

# FastAPIとは

https://fastapi.tiangolo.com/ja/

FastAPIとはPythonでAPIサーバーを構築できるフレームワークで、以下の特徴があります。

- 軽量
- Pythonとしては高速
- Pythonに型定義を実装できる
- 非同期通信を簡単に実装できる

# FastAPI標準のテストツール: TestClient
https://fastapi.tiangolo.com/ja/tutorial/testing/

FastAPIで標準で用意されているテストツールに`TestClient`というものがあります。
これはテスト内でFastAPIで作ったAPIサーバーのクライアントとして振る舞うことができるものです。

例として以下の`main.py`があるとします。
```python:main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/health")
async def check_health():
    return {"msg": "Hello World"}
```

これをローカルで立ち上げたとき、以下の結果が返ってくることが期待されます。
```
% curl http://localhost:8000/health
{"message":"Hello World!"}
```

この動作を`TestClient`を使って、ユニットテストとしてテストしたいです。

これをテストする`test_main.py`は以下のように書くことができます。
```python:test_main.py
from fastapi.testclient import TestClient
from main import app # main.pyで作ったapp = FastAPI()をimport

client = TestClient(app) # テスト用クライアントの生成


def test_check_health():
    response = client.get("/health")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}
```


この`test_main.py`は`pytest`を用いて以下のようにテストすることができます。
```
% pytest test_main.py
========================== test session starts ===========================
platform darwin -- Python 3.11.2, pytest-7.4.0, pluggy-1.2.0
rootdir: /path/to/directory
plugins: mock-3.11.1, anyio-3.7.1
collected 2 items

test_main.py ..                                              [100%]

=========================== 1 passed in 1.19s ============================
```

このようにして、`main.py`で作ったAPIサーバーの振る舞いを簡単にテストすることができます。

# クエリパラメータを使う
`main.py`に以下のように`/hello`のエンドポイントを追加したとします。
```python:main.py
@app.get("/hello")
def hello(name: str):
    return {"message": f"Hello {name}!"}
```
期待される動作は以下の通りです。
```
% curl "http://0.0.0.0:8000/hello?name=Bob"
{"message":"Hello Bob!"}
```
これをテストする関数は次のようになります。
```python:test_main.py
def test_hello():
    response = client.get("/hello", params={"name": "Bob"})
    assert response.status_code == 200
    assert response.json() == {"message": "Hello Bob!"}
```

クエリパラメータを伴うエンドポイントをテストしたいときは、`client.get()`の中で、`params`に対し辞書型でパラメータを与えることでテストできます。

# POSTのテスト
ここまでGETメソッドを見てきましたが、POSTメソッドについても示します。

まず`main.py`に以下を追記します。
```python:main.py
from pydantic import BaseModel

## 中略

class Message(BaseModel):
    sender: str
    message: str


@app.post("/send")
def send(msg: Message):
    return {"message": f"{msg.message} sent by {msg.sender}"}
```
このAPIで期待される動作は以下の通りです。

```
% curl -X POST http://localhost:8000/send \
> -H "Content-Type: application/json" \
> -d '{"sender": "Bob", "message": "Hi, Alice."}'
{"message":"Hi, Alice. sent by Bob"}%
```
テストは以下のように書けます。
`content`に`body.json()`を渡すことで、POSTのリクエストボディにJSONを渡すことができます。
```python:test_main.py
from main import app, Message # 追記

## 中略

def test_send():
    body = Message(sender="Bob", message="Hi, Alice.")
    response = client.post("/send", content=body.json())
    assert response.status_code == 200
    assert response.json() == {"message": "Hi, Alice. sent by Bob"}
```


# おわりに
`TestClient`を用いることで、FastAPIでAPIとしての振る舞いを簡単にテストすることができます。
ここで試した以外にも、ヘッダーやCookieなどの付与も簡単にできるので、様々なAPIをテストすることができそうです。
JavaでMapの存在チェック

# Mapの存在チェック
こんにちは。島根と言えば出雲蕎麦ですが、15時くらいには閉まるので行かれる方はお昼がおすすめです。

さて、今日は自分的に 結構良いんじゃないかなあ!? と思う処理を思いついたので、どっかで使うためにおいておきます。
使い所はよくわかってません。

**追記**
@yoshi389111 さんに頂いたアドバイスの内容を追記しました。
:point_right:[コード3](#コード3)

# コード
普通?というか単純な私がぱっと思いつくのはこんなコードです。
```java
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		map.put("thx", "Thank you");
		map.put("azs", "Azasu");

		System.out.println(mapCheck(map));
	}

	private static Boolean mapCheck(Map<String, String> map) {
		Boolean exist = true;

		if (!map.containsKey("thx")) {
			exist = false;
		}
		if (!map.containsKey("azs")) {
			exist = false;
		}

		return exist;
	}
```
```
実行結果 -> true
```
別にこれで悪いわけじゃないと思うのですが、今回思いついたのは以下のコードです。
# コード2
```java
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		map.put("thx", "Thank you");
		map.put("azs", "Azasu");

		System.out.println(mapCheck(map));
	}

	private static Boolean mapCheck(Map<String, String> map) {
		// 必須のKeyの存在チェック結果を追加
		List<Boolean> list = new ArrayList<Boolean>(){
			{
				add(map.containsKey("thx"));
				add(map.containsKey("azs"));
			}
		};

		// false の存在チェック結果を返却
		return !list.contains(false);
	}
```
```
実行結果 -> true
```
"thx", "azs" はmapにあるので true になりました。

次に map に存在しない値をリストに追加してみます。
```java
	private static Boolean mapCheck(Map<String, String> map) {
		// 必須のKeyの存在チェック結果を追加
		List<Boolean> list = new ArrayList<Boolean>(){
			{
				add(map.containsKey("thx"));
				add(map.containsKey("azs"));
				add(map.containsKey("danke"));
			}
		};

		// false の存在チェック結果を返却
		return !list.contains(false);
	}
```
```
実行結果 -> false
```
"danke"はmapにないので false が返ってきました。

# 今後に期待
どうでしょう?
もし値が増えても add を増やすだけでいいので、視線移動が少なくて良いのかなと思います。

また、これは Map でなくても add に Boolean を返す処理を書けば流用できるので、利便性もそんなに変わらないんじゃない？ってとこもオキニです。

特定の値がない場合は処理を終了させたいときにも有効ですし、この処理を挟めば後続の処理では存在チェックをする必要がなくなります。

と、いろいろ書いてみましたが これだ！！ という活用方法は自分自身浮かんでないのでこの子の未来に期待します。

# コード3
・`List.of()`を使用してインスタントにリストを生成する方法
・`containsAll()`を使用してリストの値をまとめて検索する方法
を紹介していただきました。かなりスッキリして感動です:laughing:
```java
	private static boolean mapCheck(Map<String, String> map) {
    	return map.keySet().containsAll(List.of("thx", "azs"));
	}
```
`keySet()`で取得したキーの一覧に、`List.of()`で生成した存在確認したいキーの一覧が含まれているかを`containsAll()`を使ってまとめてチェックするという方法です。
キーの一覧に対して存在チェックをしたいということが各メソッド名でわかりやすくなりましたし、スッキリ書くことができました！

Boolean型とboolean型についても勉強になりました:writing_hand:
>また、直接関係ないですが Boolean はラッパークラスで無駄なオートボクシングが発生するので、今回のメソッドの戻り値としてはプリミティブ型の boolean の方が良いと思います

**参考**

https://qiita.com/yoshi389111/items/7ea0f9b9483b0138ecdf

https://qiita.com/yoshi389111/items/1ce067cbaf868f6d4565

\-- @yoshi389111
新卒SEがAWS資格取得してみた

今回は新卒SE2年目の僕がAWS CLFを合格した方法について書いていこうと思います。

## 現状
筆者のAWSスペックこんな感じです。
･理系情報学部出身
･Python歴2年
･今年4月に初めてAWSに仕事で関わる
･やっとマネージメントコンソールに見慣れてきた
･EC2,S3,Cloudwatch,codecommitの操作経験有

## 学習時間
今回の学習時間は平均的な50時間程度だと思います。
7/15までに受験すると1回目落ちても再受験が無料とのことで、急いで7/1に申し込んで2週間みっちり勉強しました！
7/1までは別の資格を受験したこともあり教材の1/4程でストップしていました💦


## 学習方法
#### Udemyの動画教材
[【2023年版】これだけでOK! AWS認定クラウドプラクティショナー試験突破講座（豊富な試験問題290問付き）](https://www.udemy.com/share/103mIg/)

たまたまセールだったので購入しました！
購入したのは4/1だったんですけど、7/1に申し込むまでで進んだのが'EC2について'までなのでほぼ進んでませんでした笑

①視聴
まずはこれを7/8までに終了させました🔥

②講義資料
動画内では資料のすべてを説明しているわけではないので、思っていたよりも大事な工程でした！
なので資料に一通り目を通しました。

③練習問題
各セクション終わりに付いている練習問題を全問正解するまでやりました！

④模試 
最後についていた模試をやりました。
結果は画像の感じです笑
ひどい笑

１個目の模試
![IMG-0633.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/14354cdb-1b7b-d129-de7e-7a8b0e865117.png)

２個目の模試
![IMG-0632.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/7cbc2370-a76d-e8e0-5ac3-6ab0ef50803c.png)

#### 問題演習
[AWS認定資格 無料WEB問題集＆徹底解説 クラウドプラクティショナー](https://aws-exam.net/clf/)
を全部とりあえず解きました！！
問題数が４００問以上あるのでやり直しはしませんでした。
コメント欄があるので、そのコメント欄でみんなの覚え方とかを参考にしながら学習を進めました。

#### 問題集アプリ
[AWS認定 クラウドプラクティショナー模擬試験](https://apps.apple.com/jp/app/aws%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC%E6%A8%A1%E6%93%AC%E8%A9%A6%E9%A8%93/id1509436492)
という緑色のアプリを使いました。
無料枠だけ利用しましたが、中々難易度が高くて全然正解できませんでした。

## 試験当日
試験はオンライン受験で14時からにしました。
当日は10時ごろに起床して、講義資料のその他サービスをひたすら暗記していました。
13時からwebテスト環境が整っているかテストをして、その後13時半にチェックインをして試験を開始しました。

## 試験を受けてみた感想
実際のテストは試験監督がいたこともあり緊張しました。
なので少し難しく感じました。
受験時間の半分あたりで解き終わり、10分くらいかけて見直しをして合格点に届いているか皮算用して大丈夫そうだったので終了しました！

## 結果
結果はすぐ表示され**合格**でした！！
点数はわかりませんがひとまず安心しました。

試験結果はAWS Training and Certificationにサインインして、認定→試験履歴から5営業日以内に確認できます。

気になる点数は、、、、
**789/1000**
でした！！
ほぼ8割だったので2週間の割には余裕をもって合格できたかなと思います。


## 感想
試験自体は模試で解いていた内容より難しい問題もあれば、簡単でこれでいいのか？となるサービス問題もありました。
またCLFは主に記憶メインと聞くほどやはり暗記がとても多かったので、Udemyのハンズオンはあまり効果はなかったかなと思います。ただハンズオンをした方が覚えやすいという人もいると思うのでマネージメントコンソールを触ってみてもいいかもしれません。
このAWSの知識が鮮明なうちにAWS　SSAを受験します！！
MF4の中身を見る(車輪の再開発)

# シンプルにメッセージとシグナルを表示する

```python
import asammdf
mdf = asammdf.MDF("BusLogging_xxxx.MF4")

for g in mdf.groups:
    print(g.channel_group.acq_name)
    for c in g.channels:
        print("  ", c.name)
```

# ipytreeを使ってツリー表示
```python
import asammdf
from ipytree import Tree, Node
mdf = asammdf.MDF("BusLogging_xxxx.MF4")

nodes = []
for g in mdf.groups:
    acq_name = g.channel_group.acq_name
    node = Node(acq_name, [Node(c.name) for c in g.channels])
    node.opened = False
    nodes.append(node)

root = Node('root', nodes)
root.opened = False

tree = Tree()
tree.add_node(root)
display(tree)
```

# メッセージがたくさんある場合、接頭語でグループ化してツリー表示

```python
import asammdf
from ipytree import Tree, Node

other_name = 'Other'
keys = 'AAA BBB CCC'.split()
node_hash = {other_name: []}
for k in keys:
    node_hash[k] = []

mdf = asammdf.MDF("BusLogging_xxxx.MF4")

for g in mdf.groups:
    acq_name = g.channel_group.acq_name
    key_name = other_name
    for k in keys:
        if k in acq_name:
            key_name = k
            break
    node = Node(g.channel_group.acq_name, [Node(c.name) for c in g.channels])
    node.opened = False
    node_hash[key_name].append(node)

root_nodes = []
for name, nodes in node_hash.items():
    node = Node(name, nodes)
    node.opened = False
    root_nodes.append(node)

root = Node('root', root_nodes)
root.opened = False

tree = Tree()
tree.add_node(root)
display(tree) 
```

# 複数ソースがある場合のメッセージ、シグナルの情報収集
```python
import asammdf
mdf = asammdf.MDF("Recorder_AllSignal_*.mf4")

info = []
for gi, g in enumerate(mdf.groups):
    for ci, c in enumerate(g.channels):
        if c.source is not None:
            info.append((gi, g.channel_group.acq_name, ci, c.name, c.source.path))
        else:
            info.append((gi, g.channel_group.acq_name, ci, c.name, None))

source2msgs = {}
for gi, gn, ci, cn, s in info:
    if s is None:
        continue
    h = source2msgs.get(s, set())
    h.add((gi, gn))
    source2msgs[s] = h

source2sigs = {}
for source, msgs in source2msgs.items():
    source2sigs[source] = {}
    for gi, gn in msgs:
        source2sigs[source][gi] = dict(name=gn, sigs=[])
        sigs = []
        for ci, c in enumerate(mdf.groups[gi].channels):
            sigs.append((ci, c.name))
        source2sigs[source][gi]['sigs'] = sigs

```

# ソース別メッセージのツリー表示
```python
from ipytree import Tree, Node

source_nodes = []
for s in source2msgs.keys():
    node = Node(s, [Node(gn) for gi, gn in source2msgs[s]])
    node.opened = False
    source_nodes.append(node)
    #print(s)
    #for gi, gn in source2msgs[s]:
    #    print("  ", gi, gn)


root = Node('sources', source_nodes)
root.opened = False

tree = Tree()
tree.add_node(root)
display(tree) 
```
SEのみなさん、そのあなたの思い（ロジック）デベロッパさんPGさんに伝わってます？

# はじめに
markdownで内部設計書を起こす際に、ロジック的にごちゃごちゃしているのをまとめるときにすべてフロー図ではちょっとめんどうなので、テキストでロジックを表現しようとするとします。システムエンジニアになってしまうと、もう実装の現場から離れてはやうん年、いまから最新の実装言語でロジックを書こうにも、細かいところはよくわからない。古い言語で書くとなんか若いコにばかにされそうな気がする。そんな、あなたに耳よりなロジック記述方法があります的なお話です。

# 概要
日本語ロジック仕様記述言語 Re:Mind（リマインド）は[オープンな設計言語仕様](https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94)で、どなたでもこの記法を使いロジックを記述することができます。
制御構文の開始シンボルとして、◇、〇、□、・などの全角記号を用い、箇条書きされた日本文としての体裁を日本語トランスコンパイラ言語 Re:Mindの構文と共有しています。◇は分岐構文、〇はループ構文の開始と終了を表し、冗長な日本語表記がなくてもフロー図の表現に慣れている方が直感的に認識できることを考慮しています。


# 言語仕様（抜粋）
## 変数
```mind:Re:Mind

    ・整数 年齢 = 34

    ・文字列 名前 = "花子"

    ・ブール値 特待区分 = true 
```
□全角文字の中点に続いて、型名を記述し、空白に続いて変数名を記述します。
・型名は一般的なプログラミング言語の半角型名でも可。
・半角等号で初期値を宣言できます。

## 制御構文
### 分岐

```mind:Re:Mind
    ◇i > 0 の場合
        //todo
    ◇ここまで
```
□全角記号のひし形◇が条件分岐の開始となります。
・続いて論理式を書きます。半角かっこは不要。
・続いて「の場合」と書きます。半角で書かれた論理式とはくっついていても可。
・全角記号のひし形◇が条件分岐の終了となります。
・つづいて「ここまで」と書くことができます。省略も可。

```mind:Re:Mind
    ◇i > 0 の場合
        //todo
    ◇他に i < 0 の場合
        //todo
    ◇他に
        //todo
    ◇ここまで
```
◇途中で最初の論理式とは排他的な条件をつづける場合は、全角ひし形◇に続いて「他に」と書いて、論理式を書いて、「の場合」と書きます。
・論理式の前後の空白は、論理式を半角で書いている場合は省略できます。
◇最後に例外条件を明示する場合は、全角ひし形◇に続いて「他に」と書きます。

### 繰り返し


```mind:Re:Mind
    〇i=0,i<10,i++ 繰り返す
        //todo
    〇ここまで
```
□全角記号の丸印〇が繰り返しの開始となります。
・続いてカウンタ論理式をカンマ区切りで書きます。カウンタ変数の型名と半角かっこは不要。
・続いて「繰り返す」と書きます。半角で書かれた論理式とはくっついていても可。
・全角記号の丸印〇が繰り返しの終了となります。
・つづいて「ここまで」と書くことができます。省略も可。
```mind:Re:Mind
    〇繰り返す
        //todo
    〇ここまで
```
□全角記号の丸印〇に続いて「繰り返す」と書いた場合は無限ループになります。
```mind:Re:Mind
    〇繰り返す
        //todo
        ◇j==0 の場合 やめる
        //todo
    〇ここまで
```
・繰り返し構文内で条件分岐文を書いて「やめる」と書くと、直接のループを脱出します。

```mind:Re:Mind
    /** index */
    〇int インデックス=0,インデックス<10,インデックス++ 繰り返す
        //todo
    〇ここまで
```
・繰り返し構文のカウンタ変数をインラインで日本字で宣言することもできます。

# おわりに
意外とシステム開発の現場では、複雑なロジックのモジュールの場合、デベロッパさんとの意思疎通がうまくいかず、SE的な目線的な表現としてはデベロッパさんの爆走を看過してしまい、できあがったモジュールの出来をみたら、こんなんじゃなかった的なことは、（暗によくあるのではといいたいところですが）まったくご経験されたことのないあなたは超優秀マネージャです！
Qiita記事見出しのリンクマークがクリックしづらい

Qiita記事の見出し左端に表れるリンクマークがクリックしづらくてイライラします。その対処法を見つけたので、ご紹介です。

# 見出し左のリンクマークにポインタを重ねようとすると消えてしまう
正直、嫌がらせとしか思えません。Qiitaの記事の見出しは、マウスポインタを重ねると、左端にリンクマークが表れます。ところが、このリンクマークにマウスポインタを移そうとすると、見出しから外れたとして、マークは消えてしまうのです。

![qiita_2307001_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128949/1c2596fd-77f0-010b-091d-33c8a04054a3.png)

何度か試みて、たまたまクリックできることもあります。けれど、そうでないときは、このデザインをした人物に軽く湧き上がってくる○意が抑えられません。この問題が環境によることも考えられます(macOSです)。ただ、そこまで確かめる寛容さを残念ながらもち合わせません。


# 見出しを右クリックすればリンクマークは消えない
しかし、ようやく対処法を見つけました。見出しを右クリックすると、コンテクストメニューが開いて、リンクマークは消えないのです。これで、心穏やかにリンクマークをクリックできるようになりました。

まぁ、スクロールさせれば済む話ですし、右カラムに見出しのリストもあります。しかし、本来使えるべき機能が使えないというのはストレスです。同じように心の平穏を求める人のお役に立つことを願います。
若手が会議で発言できるまでに意識したこと

## はじめに
「会議に出ても発言できない...」これは多くの若手に共通する悩みではないでしょうか？

「発言がないのは居ないのと同じ(価値ゼロ)」とはよく聞きますが、以前の自分はまさにその状態でした。。そこから少しずつ発言量を伸ばしていくうえで意識していたことをシェアします。

~~...という立場になって少し偉そうに語ってみます(実はまだまだ自分もひよっこです)~~ 

## 発言できない原因とその対策
- __知識量が足りていない__ 
ここは基本的なところですが、そもそも会議で話されている内容を理解できていなければ発言のしようがありません。そうならないためには __事前調査が重要です。__ 
議題に関連する用語、技術を洗い出して、意味を調べておきましょう。もし当日わからない言葉が出た場合はその場でこっそりググる、もしくは思い切って質問してみましょう。
内容を理解しないままただ時間だけが過ぎていく、これは自分にとっても会社にとっても不利益でしかありません。これが一番の罪です！

- __会話スピードについていけない__ 
その場で話されている内容をなんとか理解できても、話の展開が早く議論についていけず、発言する余裕はない...というのもよくあります。考えている間に話題は次へ...のパターンです。頭の回転が比較的スローペースな私はここで苦労しました。
ここで有効なのは __発言パターンを用意しておくこと。__ 詳しくは後述しますが、スピード感に慣れないうちは型に当てはめて考えるようにしましょう。続けているうちに自分のモノになり、派生した型も身に付いてくるはずです。

- __物怖じしている__ 
結局はここが一番大切だと思います。最初は皆Lv1からスタートして、気の利いたことなんか言えません。ただそれを理由に発言を避けているといつまで経っても経験値が貯まらず成長しません。はじめは __無理にでもいいからとにかく喋ってみる。__ HPを削られることもたくさんあるかと思いますが、そうした失敗が人を強くするものです。

## 若手でも貢献できる発言パターン
発言の型を自分の中で用意していくことで、考えがまとまりやすくなります。まずは型を身につけること。地道ですが、守破離の守から徹底していきましょう。

- __知らない用語の意味、理解できない内容について質問する__
まずはこれから始めましょう。「こんな初歩的なことを聞くのは...」と憚られるかもしれませんが、聞けば意外と親切に答えてくれるモノです。
同じ疑問を抱いていた同席者にとってはありがたいことこの上ないですし、議論に一呼吸置くという意味では会議全体のリズムを整える効果もあります。

- __事前に調べた情報(ファクト)を共有する__
議題に関連する周辺情報を調査しておき、それを伝えられれば有益な情報の提供者となります。
加えて、事実を共有するだけでなく、自分なりの仮説も付け加えられるとベストです。例えば、「近年の△△市場は縮小傾向にあるとデータが出ていますが、これは××の影響によるものだと考えられます。」といった感じです。

- __若者視点で感じたことを伝える__
例えば、あるA案とB案のどちらを採用するか議論している場面があったとすると、自分ならどちらを選ぶか、率直に感じたことを伝えるだけで価値になります。自分からしたら「ただの感想」かもしれませんが、歳上の人からみると「若者視点の"貴重な"感想」に早変わり。若手のうちに使える武器です。これで発言量を稼いで自信をつけましょう。

## おわりに
書きながら思いましたが、結局... __事前にどれだけ準備できたか__ というよくある結論に帰着してしまいます。それほど準備は大切だと言うことでしょう。
- 発言の型を身につけて
- 会議前に事前調査して
- 勇気を出して喋る
これができたら、あとは場数をこなすのみです。
ソフトウェアテスト技法を学ぶ ～ デシジョンテーブル

:::note info
この記事は筆者の学習をまとめたものです。
:::

# ソフトウェアテストテストを学ぼう

- 開発者も積極的にテストをしよう
- テスト専門家とコミュニケーションできるようになろう

という考えでソフトウェアテスト技法について学んでいきます。

- [同値分割法と境界値分析](https://qiita.com/blue32a/items/0bd02910356144b63cc2)
- デシジョンテーブル（本記事）
- [状態遷移テスト](https://qiita.com/blue32a/items/ffa33b7e812b2d8d971e)
- [組み合わせテスト](https://qiita.com/blue32a/items/f6c4ee2db82be8ed8e5c)

# テスト技法：デシジョンテーブル

デシジョンテーブルは、条件の組み合わせに対してどのように動作するのかを表にまとめたものです。
また、デシジョンテーブルは決定表ともいいます。

# 例）映画のチケット料金

映画のチケット料金を例にデシジョンテーブルを作成してみます。

:::note info
チケット料金は通常1,800円です。
ただし、小人は800円の割引、学生は300円の割引になります。
また、上映が20時以降のレイトショーについては、学生は更に200円の割引、一般は500円の割引になります。
:::

## 作成したデシジョンテーブル

条件はY(Yes)とN(No)で表現しています。条件に対応する動作はXで表現しています。

|||1|2|3|4|5|6|
|---|---|---|---|---|---|---|---|
|条件|小人|Y|Y|N|N|N|N|
||学生|N|N|Y|Y|N|N|
||一般|N|N|N|N|Y|Y|
||レイトショー|N|Y|N|Y|N|Y|
|動作|1,000円|X|X|-|-|-|-|
||1,300円|-|-|-|X|-|X|
||1,500円|-|-|X|-|-|-|
||1,800円|-|-|-|-|X|-|

このような表にすることで、条件に対する動作が漏れていないかを確認することができます。

## 条件を削減したデシジョンテーブル

表を見ると、小人の料金はレイトショーに関わらず一律で1,000円であることがわかります。
もしロジックが小人かどうかを先に判定しるような場合は、条件を削減できるかもしれません。

|||1|2|3|4|5|
|---|---|---|---|---|---|---|
|条件|小人|Y|N|N|N|N|
||学生|N|Y|Y|N|N|
||一般|N|N|N|Y|Y|
||レイトショー|-|N|Y|N|Y|
|動作|1,000円|X|-|-|-|-|
||1,300円|-|-|X|-|X|
||1,500円|-|X|-|-|-|
||1,800円|-|-|-|X|-|

小人の場合、レイトショーは結果に影響しない条件としてハイフンで表しています。これにより組み合わせが 6 -> 5 に減りました。
ロジックに依存することなってしまいますが、テスト項目を削減したい場合はこのような形で削減を考えることができます。

## 条件を「顧客」と「レイトショー」にしたデシジョンテーブル

条件を見直してみると、、顧客区分に当てはまるのは必ず１つだけであることがわかります。
条件の「小人」「学生」「一般」を「顧客」にしてみましょう。

|||1|2|3|4|5|6|
|---|---|---|---|---|---|---|---|
|条件|顧客|小人|小人|学生|学生|一般|一般|
||レイトショー|N|Y|N|Y|N|Y|
|動作|1,000円|X|X|-|-|-|-|
||1,300円|-|-|-|X|-|X|
||1,500円|-|-|X|-|-|-|
||1,800円|-|-|-|-|X|-|

このようにY/N以外でも表すことができます。

# まとめ

- デシジョンテーブルは条件の組み合わせと、それによる動作をまとめた表
- 表形式にまとめることにより、仕様の漏れや抜けを確認することができる
- ロジックを把握していれば条件を削減を検討できる
- Y/Nといった記号だけではなく、実際の値などを使って表現することもできる

# 参考

https://gihyo.jp/book/2020/978-4-297-11061-1

https://www.shoeisha.co.jp/book/detail/9784798130606
macアプリをリリースするときに忘れがちなこと

# はじめに
macアプリをリリースするときに、忘れがちなことがあります。
それは、カテゴリーの設定です。
Xcodeでカテゴリーを設定していない状態でアプリをアップロードしようとすると、エラーが出てしまいます。

# カテゴリーの設定方法
カテゴリーは、以下の手順で設定します。（*Xcodeのバージョンは14.3を使用しています）
1. Xcodeでxcodeprojファイルを開く
2. TARGETS > アプリ名 > General > Identity > App Categoryを選択する

各カテゴリーの詳細は、[こちら](https://developer.apple.com/jp/app-store/categories/)を参照してください。

カテゴリーをきちんと設定すると、アップロードできるようになります。

# おわりに
頻繁に忘れてしまうので、気をつけたいです。
cscの作法 その413

# 概要
cscの作法、調べてみた。
AutomationElementは、ライブラリーから、どう見えるかによるので、それを見てからでないと、進まない。腐ってる。
感覚としては、スクレイピングに似てる。

# 練習問題
c#で書いたformを叩け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5410eebe-2e03-52ed-c351-4e62d82a78a4.png)

# サンプルコード

```

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Automation;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace App
{
	class Program {
		private static IEnumerable<AutomationElement> FindElementsByName(AutomationElement rootElement, string name) {
			return rootElement.FindAll(TreeScope.Element | TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, name)).Cast<AutomationElement>();
		}
		static void Main(string[] args) {
			AutomationElement aeForm;
			Process app = Process.Start(@"ff10");
			Thread.Sleep(2000);
			aeForm = AutomationElement.FromHandle(app.MainWindowHandle);
			AutomationElement bo0 = FindElementsByName(aeForm, "Image").ElementAt(1);
			if (bo0 != null)
			{
				bo0.SetFocus();
				ValuePattern vp0 = (ValuePattern) bo0.GetCurrentPattern(ValuePattern.Pattern);
				vp0.SetValue("123");
			}
			AutomationElement bo1 = FindElementsByName(aeForm, "Frame").ElementAt(1);
			if (bo1 != null)
			{
				bo1.SetFocus();
				ValuePattern vp0 = (ValuePattern) bo1.GetCurrentPattern(ValuePattern.Pattern);
				vp0.SetValue("456");
			}
			AutomationElement bo2 = FindElementsByName(aeForm, "File").ElementAt(1);
			if (bo2 != null)
			{
				bo2.SetFocus();
				ValuePattern vp0 = (ValuePattern) bo2.GetCurrentPattern(ValuePattern.Pattern);
				vp0.SetValue("789");
			}
			Console.WriteLine("ok3");
		}
	}
}





```

以上。
playwrightデバッグのコツ


## codegenで生成

https://playwright.dev/python/docs/codegen-intro

詳しい説明は他の記事を参考いただきたく。
playwrightにはブラウザの操作からコード生成してくれる仕組みがあるので
まずこれでやりたい操作を作る。
八割九割出来上がるのでゼロから作るより遥かに楽。
残りの二割程度は手直しが必要。


```
$ pip install playwright
$ playwright install
$ playwright codegen https://qiita.com/
```

## スクリーンショットを取る

https://playwright.dev/python/docs/screenshots

Windowsで作ったあとLinuxに持っていき、うまく動かない原因は日本フォントが入っていないことでした。X関連のパッケージを入れておらず`Headless=True`の場合はスクリーンショットを撮ってみると一目瞭然です。

```py
page.screenshot(path="screenshot.png")
```

## HeadlessをFalseにする

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

どこで想定どおり動いていないのかを見つけるには上記のスクリーンショットを取る、もしくは`Headless=False`にして直接画面を見るのがよろしい。


## page.content()をファイル出力

https://playwright.dev/python/docs/api/class-page#page-content

やはり最後はプリントデバッグ。
要素が無いなど困ったときに現在表示中のソースを出力してしまえばよい。
ログインしていたつもりがログインできていなかったなどに気づけた。

```py
with open(path, mode='w') as f:
    f.write(page.content())
```
Pythonの venv 仮想環境内で環境変数を恒常的に設定する方法

# 問題提起
Pythonの venv 仮想環境を使って web開発を行っていると以下のように、ターミナルから環境変数にAPI Keyを登録することが多いかと思います。

```:zsh
export API_KEY="2urh932hf0efe43fof742jf..."
```

しかしこのようにターミナルで設定するやり方は仮想環境の立ち上げのたびに、環境変数の参照が切れてしまう問題がよく発生します。僕は毎回めんどくさいと思いながら設定し直していました...

# 解決方法
**python-dotenv モジュールを使う**

以下の手順に従ってpython-dotenv を使って環境変数を設定することでvenv 仮想環境内で環境変数を恒常的に設定することができます。

1 . venv 仮想環境に python-dotenv をインストールします

```
pip install python-dotenv
```

2 . プロジェクトのルートディレクトリに .env ファイルを作成します。このファイルに環境変数を定義します

```
touch .env
```

3 . .env ファイルを開き、以下の形式で環境変数を定義します

```
API_KEY="api key をここに指定してください"
```

4 . 最後に、Python スクリプトからこれらの環境変数をロードするには、load_dotenv 関数を使います

```:Python
from dotenv import load_dotenv
import os

load_dotenv()

api_key = os.getenv("API_KEY")
```

# まとめ
このように、python-dotenv を使うと、venv 環境を立ち上げるたびに手動で環境変数を設定する必要がなくなります。
**また、セキュリティの観点から、パスワードや秘密鍵などの機密情報を含む .env ファイルを共有したり、公開リポジトリにプッシュしたりしないように注意してください。**


# 最後に

特定のファイルをgitのバージョン管理から外す方法については以下の記事で解説しているのでご参照ください。

https://qiita.com/yutosa3/items/25ab031c8061e8c9a4c4
HappinessChainに入会して3週間が経過しました

# はじめに

本記事を閲覧いただきありがとうございます。
都内でSEをしておりますhirokiと申します。
今話題のプログラミングスクール[HappinessChain](https://happiness-chain.com/)に入会して３週間が経過したので、その感想を書こうと思います。


# 自己紹介
四年生の文系大学を卒業後、メーカー営業職にて３年半、ITソフトの営業職にて１年間従事しました。特に２社目では、地獄のノルマが課されていて、１日テレアポ１００件、飛び込み営業５０件などを行い、そこでかなりメンタルが鍛えられたのではないかと思います、、笑
このままでは心身が持たないと感じ、スキルを高めて、「時間を切り売りする心身をすり減らす労働」から脱したいと志し、未経験からのSEへの転職を目指して某プログラミングスクールに入会しました。
２ヶ月間の学習を経て、２０２２年４月に都内の受託開発企業にSEとして入社して、現在まで働いている形になります。

# 未経験入社〜独学期間

自身２ヶ月という短い期間でスクールを卒業し、`スキルが低いまま`で転職活動をし、エンジニアとしてのレベルが低くても採用される会社に入社してしまいました。

入社した会社の特徴として
* ほとんどコードは書かず、雑用が業務の大半
* VSコードより、エクセルを開いてる時間の方が長い
* ごく稀にコードを書いても当然のことながらコードレビューはなし
* VBAを使って動かしているシステム多数ある
* 秘伝の継ぎ足しソースコード（~~クソコード~~）で動いてるシステムがほとんどなので、バグが多発
* 上記バグを修正すると別の場所でバグが発生

当然こんな状況でスキルも上がらず、焦りと不安が蓄積していきました、、、！
ただこれもスキル不足のまま転職活動をした自己責任。このままではいけない、なんとかしなければと思い、業務時間外にて独学を開始しました。


独学にて、学習を開始したはいいものの、下記の点で苦しみました。
* プログラミングといっても範囲が膨大すぎて、何から手をつけていいのか分からない
* 分からないところがあっても、聞ける人がいないので、挫折率が高くなる
* 今やっている学習が正しい方向に進んでいるのか分からないので、モチベが維持できない
* 一人でやるとついついサボって楽な方に流れてしまい、安定した学習をすることができない

と言った有様で、当然スキルが積み上がるはずもなく
積み上がったのは不安、焦りと年齢だけという状態でもがき苦しんでいるおりました、、、


# Happiness Chain入会のきっかけ

独学状態でもがき苦しむ中、ある日Qiitaを眺めてると、
`HappinessChainに入会して⚫︎ヶ月`、`HappinessChainを卒業しました`という記事を何件か目にする機会がありました。（以下 HC）
独学に限界を感じ、再度スクール入会を検討をしていましたが、某スクールにて大金を払ったもののスキルを高めることができなかったという経験もあり、動けずにいました。
しかし、上記に挙げた記事を見ていると　
* 課題の難易度は高く、長期間に及ぶ学習が必要。
* 現役エンジニアメンターがコードレビューしてくれる。
* 完璧なロードマップが用意されており、それに沿って地道に進めていければ、スキルを高められる。

という3点に強く魅力を感じました。
特に１点目の`難易度が高く、時間はかかる`という形でしっかりと**プログラミングの甘くない現実**が書かれたいた点が自分に深く刺さりました。
最初に入会した某スクールにて、情弱の自分は`2か月でエンジニアになれる`というフレーズに引かれて、入会しました。その根本にあったのは`楽して、手っ取り早く稼げるようになりたい`という甘々な考えでした。
それが、間違っていたということを身をもって知ることになり、今度は`苦しい思いをして少し時間がかかっても、着実にスキルを高めたい`という思いが強かったこともあり、HCに強く惹かれたのではないかと思います。
また代表者の[ゆうだいさん](https://twitter.com/yudai_on_rails)が発信されてるツイート内容も、今の自身の価値観に相違ないと感じたので入会を決めました。

# 実際に入会してみて

結論から申し上げると
### もっと早く入会しとけばよかった！！！！！！

です。

その理由を下記にまとめました



**1 プロが作ったロードマップがあるので、迷いなく目の前の学習に集中できる**

独学時代は、まず何から始めていいかも分からず、様々な教材にちょっと手をつけては挫折を繰り返しておりました。
当時の自分の心理状況を分析すると「このやり方で本当に合ってるのかな、、、」だと思います。その根底にあった思いが、学習の継続を妨げていたのではないかなと感じております。
このロードマップを使えるというだけでもHCに入会する価値はあるのではないかなと感じております。

**２ 他のメンバーが勉強しているのをみて、やらなければという気持ちになる**

HCに入会するとSlackのチームチャンネルに、その日学習した内容の「日報」を提出することが義務付けられています。そうなるとしょぼい日報を提出したくないと思い、自然と勉強しなければという気持ちになります。また、他メンバーの提出する日報の内容も見ることができるので、それもまた刺激になります。
また、月に１度オンライン or オフラインにてミートアップがあり、そこで志を共にする仲間と交流が図れるのも大きいですね。
人間は周囲の人間、環境に強く影響を受けるのだということを身をもって知ることになりました。

**３ 遊ぶことに後ろめたさを感じなくなる**
HCに入会すると環境の力によって自然と学習に全力を注げるようなります。そうするとダラダラする時間が減り、時間を有効活用できるようになってきます。以前までは休みの日にも何かやり残したことがあるような気がして気が休まることがなかったですが、HCに入会してからは、普段から全力で勉強しているために、遊ぶときも後ろめたさを感じることがなくなります。


以上が入会して３週間で感じたことですが、まだコードレビューを受ける段階までいってなくてもこれだけの恩恵を受けることができております。
これから、ロードマップを進めていけば、確実に自分を変えることができると感じることができた３週間だったと思いました。

# 終わりに
まだまだ、自分はHC全体のロードマップに２%もこなせていないところです。だから、これから難度の高い課題と向き合っていくことになると思いますが、失敗から学んだ、`苦しい思いをして少し時間がかかっても、着実にスキルを高める`ことを軸にして日々の学習に邁進していきたいと思っております。
拙い文章ではありましたが、閲覧いただきありがとうございました。
これからは、Qiitaでは技術的なことを中心に発信をしていけたらと考えているので、よろしくお願いします！！
Ubuntuでキーマップを変更する

# 前説
サークルのLT会で発表した内容を再編集して投稿します．

US配列キーボードのCapsLockを全角半角に割り当て直す試みをもととしています．

# Ubuntuの事情
Ubuntuのデフォルトのディスイプレイサーバーが，数年前からX window systemからWaylandに変わっているため．情報の多いxmodmapやxkbの設定ファイルの構成といった方法は動作しない．そのため，キーマップの変更にあたっては，X window systemでもWaylandでも問題なく動作するudevを用いた方法を勧める．

# 参考サイト

http://iranoan.my.coocan.jp/essay/pc/202104020.htm

上記サイトが詳しい．上記サイトに記載がなかった情報は[さいごに](#さいごに)にまとめる．

# 実際の変更手順

## Udevでkeymapを変更する流れ

1. キーボードを特定する
2. キーを特定する
3. 設定ファイルを作る
4. 設定を再読込する

以下ではCapslockを全角半角に変えてみます．

## 1.キーボードを特定する

```
cat /proc/bus/input/devices
```
を実行する．

![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283963/9d49b180-d028-9aff-ba05-c03210c9509b.png)

こんなのがいっぱい出てきます．そのなかから，キーボードっぽいやつを一つ選んで(Name や Handlersに注目)，

`I: Bus=0003 Vendor=.... Product=.... Version=....`

をメモ.ちなみにUSBキーボードなら`Bus=0003`です.

## 2.キーを特定する

`evtest`を使おう．`apt`で落とせます．以下のようにコマンドを打てばインストールされます．
```
sudo apt install evtest
```
インストール後

```
sudo evtest
```
で，インプットイベントをモニタするか聞いてくれます．
キーボードっぽいやつを選んでCapsLockを押してみよう．
![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283963/6f893089-3b6d-ac41-f60f-d72fcda6ce3f.png)


うまく行かなかったら，他のキーボードっぽいイベントを試してみましょう．多分どれかがちゃんと動きます．

動いた様子：

![image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283963/7d953729-9c66-8a5e-0cec-5f5b2577c26a.png)

ここの，"value"の値をメモっておきましょう．

## 3.設定ファイルを作る

`/etc/udev/hwdb.d`に設定ファイルを作ります．
名前は拡張子が`.hwdb`なら何でもOK.
内容はこんな感じ:

```/etc/udev/hwdb.d/*.hwdb
evdev:input:b....v....p....*
    KEYBOARD_KEY_....=zenkakuhankaku
```

`b....v....p....*` のところは，キーボードを特定のところでメモったBus,Vendor,Productの値を入れます．`*`はワイルドカードなのでそのまま．

`KEYBOARD_KEY_....`のところは，キーを特定のところでメモったValueの値を入れましょう

## 4. 設定を再読込する

端末で

```bash
sudo systemd-hwdb update
sudo udevadm trigger
```

と打てば完了

# さいごに

私の環境では，この設定を反映した状態でCapsLockを押してもなんの反応もありませんでした．
`xev`で確認してみるとkeysym(キーの役割)が消えていたのでzenkakuhankakuは割り当てられない様子．

https://hal.freedesktop.org/quirk/quirk-keymap-list.txt

に使用できる可能性のあるキーがまとまっているので，この中から地道に試して，ZenkakuHankakuの代わりの都合の良いキーを探してみると，
Hiraganaが割り当てられ，CapsLockを置き換える目的が達成されました．
可読性の高いクラスの作り方

# クラスとは
複雑な責務をクラス単位に分離することで、その関係性をシンプルに表現できる概念です。
巨大な仕様をプログラムにする際に、Main関数の中にすべての処理を詰め込むのは現実的に考えて不可能なので、我々はモジュールやクラスを使って責務を分離することで、複雑な仕様に対処します。

:::note
クラスとモジュールは、責務の範囲が違うだけなので、これからお話しする内容はどちらに対しても適用できます。
:::

# クラスのメリット・デメリット
メリット
* 修正箇所、および修正に対する影響範囲の特定が容易になる
* 仕様と実装の紐づきがわかりやすく可読性が上がる

デメリット
* メリットが活かせない場合がある

# クラスのメリットを活かすためのポイント
1. 責務を分離できていること
1. クラス名が責務を表現していること


以下はポイントに違反した、従業員と、顧客情報を扱うクラスの例です。
```C#
class EmployeeService
{
    public CustomerRepository _customerRepository;
    
    public EmployeeService(CustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public void AddEmployee(Employee employee)
    {
        _customerRepository.AddEmployee(emplyee)
    }

    public void AddCustomer(Customer customer)
    {
        _customerRepository.Add(customer)
    }
}
```
## 1. 責務を分離できていない
従業員情報を扱うEmployeeServiceクラスに、消費者を追加する関数が入っています。
言い換えると、EmployeeServiceクラスは従業員追加の責任と、顧客追加の責任の2つを持っています。

### 問題点
* 消費者に関する修正が、従業員の処理に影響を及ぼす可能性がある。(その逆も然り)
* 従業員と消費者の関係に、特別な仕様があると勘違いが発生する。
* 修正が発生した際、修正対象のクラスを探す手間が発生する。
* 従業員に関する実装の中に、Customerという単語が出てくることが混乱を招く。

## 2. クラス名が責務を表現していない
EmployeeServiceというクラス名で消費者追加の責務を持っている。  
CustomerRepositoryというクラス名で従業員追加の責務を持っている。

### 問題点
* 修正が発生した際、修正対象のクラスを探す手間が発生する。
* 従業員に関する実装の中に、Customerという単語が出てくることが混乱を招く。


以下に責務ごとにクラスを分離した例を示します。
```C#
class EmployeeService
{
    public EmployeeRepository _employeeRepository;
    
    public void AddEmployee(Employee employee)
    {
        _employeeRepository.Add(emplyee)
    }
}

class CustomerService
{
    public CustomerRepository _customerRepository;

    public void AddCustomer(Customer customer)
    {
        _customerRepository.Add(customer)
    }
}
```
分離した責務
* EmployeeServiceは従業員という概念に対する責務
* EmployeeRepositoryは従業員の情報を保持する責務
* CustomerServiceは消費者という概念に対する責務
* CustomerRepositoryは消費者の情報を保持する責務

こんな感じに4つの責務に分離してあげると先ほど挙げた問題は全て解消します。


## クラスのまとめ
プログラミング界隈では、責務が正しく分離されていることを「凝集度」という指標で呼んだりします。  
クラス設計には、仕様の理解と、システム設計の理解、言語や技術の習熟度が関係してきます。  
経験から言えるのは、最初からすべて把握できる人はいないので、責務の分離にも限界があります。  
開発中にそれらの理解が進み、もっと良い分離の仕方に気づきます。  
気づいたとき、その都度リファクタリングしていくことが大事です。
CastCraftのScreen機能の出力をNDI経由/バーチャルカメラ経由と切り替える方法

## CastCraftは便利
各視聴者を覚えたり、初見を見分けたりできる機能だったり、コメントに連動したUnityエフェクトを出したりする機能があるのでYouTubeでライブ配信する人は一度は試した方がいい
- CastCraft[公式サイト](https://castcraft.live/ "CastCraft")
- 運営[Twitter](https://twitter.com/cast_craft "運営Twitter")

## Screen機能のOBSへの出力方法
そのUnityエフェクトを出したりする機能が「Screen」というのだが、OBSに出力するための方法が二つある。
- 仮想カメラ経由での出力
- NDI経由での出力

デフォルトだとVirtual Camera経由での出力になっている

## 仮想カメラ経由でOBSに出力
デフォルトの状態であれば、
1. OBSの「映像キャプチャデバイス」ソースをシーンに追加
1. 映像キャプチャデバイスのデバイス選択の部分で「CastCraftScreen」を追加

するだけで設定完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516181/e507d478-1c39-7bcf-7915-6a16e728ccd9.png)

仮想カメラはWindowの古いコードを使っていたり、他の仮想カメラとバッティングするなどで問題が起きやすい。
そのため、まれに上記の映像キャプチャデバイスの選択肢に「CastCraftScreen」が現れないことがある模様。

そのために、NDI経由での出力が用意されてある。

## NDI経由でOBSに出力
NDI経由での出力には、下記の手順が必要。
1. NDIのランタイムとプラグインをインストール
1. ScreenのOutputを「VirtualCamera」から「NDI」に変更
1. OBS上で、シーンに「NDI Source」を追加
1. NDI Sourceのソース名で「<端末名>(CastCraftScreen)」という選択肢を選択

順を追って見ていく。
### NDIのランタイムとプラグインをインストール
https://github.com/Palakis/obs-ndi/releases/
上記リンクから、最新バージョンのNDIのランタイム・プラグインを見つけてダウンロードし、それぞれをダブルクリックして実行する。

[バージョン4.11.1](https://github.com/obs-ndi/obs-ndi/releases/tag/4.11.1)では、下記の二つに当たる
- [ランタイム](https://github.com/obs-ndi/obs-ndi/raw/d462e9f83f0e06837a83331b1f71053b2132e751/runtime/NDI%205.5.3%20Runtime.exe)
- [プラグイン](https://github.com/obs-ndi/obs-ndi/releases/download/4.11.1/obs-ndi-4.11.1-windows-x64-Installer.exe)

インストール後、PCを再起動しないといけない場合もあるようだ。


### ScreenのOutputを「VirtualCamera」から「NDI」に変更
CastCraft内の「Screenタブ」の左上にあるメニューバーから開いて、OutputをNDIに切り替える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516181/602c2d6f-2c6a-6389-c8ca-1bc8094e8aee.png)
**仮想カメラ経由に戻すときはここのOutputを「VirtualCamera」にする必要があるので注意。**

### OBS上で、シーンに「NDI Source」を追加
NDIのランタイムとプラグインが正しくインストールできていたら、OBSのソースに「NDI　Source」という選択肢が出てくるはずなので、それを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516181/1f6f98ba-3ec6-eb85-ae09-807e56fd33ee.png)

### NDI Sourceのソース名で「<端末名>(CastCraftScreen)」という選択肢を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516181/56ff95fe-4cd4-015c-9aa8-6b82bcdc0189.png)

これで完了。

### 配信が捗る
文字スタンプの機能とか楽しいので使ってみてほしい

<iframe width="560" height="315" src="https://www.youtube.com/embed/wG7UgXKueBQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


（関連記事/出典）
https://castcraft.live/tutorial
https://castcraft.live/tutorial/screen-ndi-obs/
リーダブルコード 5~6章「コメント」

## テーマ選定の理由
- 会社の先輩にコードしていただき、柔らかく「コードが読みづらいから勉強しろ」とご指摘頂いた。
- 特に、「コメント」が下手らしい。
- リーダブルコードの「コメント」を再読したので、その学びを記事にする。


## コードへの 「コメント」に関するポイント
- なぜコメントするのか？
- 何をコメントするか？
- どうやって（何を使って）コメントするか？

### なぜコメントするのか？
これは一択で、
- **読み手に意図を伝える**

ため。

###  何をコメントするか？

- 書き手の意図（設定値）
- 全体像（条件分岐）
- 逆の立場だったら、疑問に思う点
- 伝えたいこと（xxはテストした、未来へ）

### どうやって（何を使って）コメントするか？

1. コメントしない
    a. 変数名で十分なこともある
    a. 名前付き引数の利用
1. できる限り短く、明快で、文章
1. 例


#### その他
- 未来へのメッセージ
    - TODO: あとでやる
    - FIXME: 既知の不具合がある
    - HACK: きれいではない解決策
    - XXX: 危険がある
- 気になった用語
    - ヒューリスティック：経験則の判断
    - ブルースフォース：総当り攻撃
    - ナイーブソリューション：単純で、ひねりのない解決策（良し悪しではない。）

## さいごに

無思考にならず、「読み手に意図を伝える」ことを忘れずにコメントする！

逐次コメントする！
【Ruby】combinationメソッドで重複のない組み合わせを作る

Rubyを使ったアルゴリズムについて学習しています。
今回はcombinationメソッドを使ったロジックの実装についてまとめました。

# やりたいこと
数字(n個)の配列から、重複のない２個の組み合わせを選択するロジックを作成する。


# 出力例

```ruby
n = 6 とした場合の出力例

[
 [1, 2], [1, 3], [1, 4], [1, 5], [1, 6],
 [2, 3], [2, 4], [2, 5], [2, 6],
 [3, 4], [3, 5], [3, 6],
 [4, 5], [4, 6],
 [5, 6]
]
```

# combinationメソッドとは？
今回のロジックは、combinationメソッドを使うことで簡単に作れます。

> サイズ n の組み合わせをすべて生成し、それを引数としてブロックを実行します。

引用： <a href="https://docs.ruby-lang.org/ja/latest/method/Array/i/combination.html">Ruby 3.2 リファレンスマニュアル</a>

https://docs.ruby-lang.org/ja/latest/method/Array/i/combination.html


# 完成コード

```ruby
n = 6
p (1..n).to_a.combination(2).to_a
```

# コードの解説
- このコードは、`1からnまでの数値`を組み合わせて、それぞれ`2つずつの組み合わせを全て作る`もの。

- `(1..n).to_a`で1からnまでの数値を配列化している。この例だと`n=6`なので、`[1, 2, 3, 4, 5, 6]`って配列が作られる。

次に、その配列に対して`combination(2)`メソッドを使っている。`combination(2)`は、配列の要素から2つを選び出す全ての組み合わせを生成するメソッド。この場合だと、`[1,2], [1,3], [1,4], [1,5], [1,6], [2,3] ・・・`という具体的な組み合わせの配列が生成されることになる。

最後に、`to_a`メソッドで結果を配列として出力している。これにより、生成された全ての組み合わせが配列として出力されることになる。



# 参考サイト

https://docs.ruby-lang.org/ja/latest/method/Array/i/combination.html

https://magazine.techacademy.jp/magazine/21232
SpringBootアプリケーションにおけるトランザクションロールバック失敗の調査と解決

## 発生した問題

トランザクション管理において環境依存の問題が発生：
- 検証環境: トランザクションが正常にロールバック
- 本番環境: ロールバックが失敗し、意図せずコミットされる

## システム環境

### 共通構成
- SpringBoot 2.7
- データベース: Azure SQL Database

### 環境別構成

| 項目 | 検証環境 | 本番環境 |
|------|----------|----------|
| アプリケーションサーバ | Tomcat 9 | Open Liberty 22.0 |

## 問題の調査

### 調査プロセス
1. 開発環境（Tomcat）での動作確認
   - 問題の再現せず
2. 環境差分の特定
   - アプリケーションサーバの違いに着目
3. 開発環境でのOpen Liberty検証
   - 問題の再現に成功

### エラー内容
```java:スタックトレース
org.springframework.transaction.TransactionSystemException: UOWManager transaction processing failed; 
nested exception is com.ibm.wsspi.uow.UOWException: java.lang.LinkageError:
com/ibm/websphere/uow/UOWSynchronizationRegistry.registerInterposedSynchronization
```

## 原因分析

トランザクションマネージャーの競合が発生：
- Spring組み込みトランザクション管理機能
- Open LibertyのJTAトランザクション管理機能
- 両者が同時に有効化され、競合状態に

## 解決策

### 設定変更
JVM引数に以下を追加し、SpringBootのJTA自動構成を無効化：

```properties
# jvm.options
-Dspring.jta.enabled=false
```

## 技術解説

### Java Transaction API (JTA)
- Jakarta EE（旧Java EE）の標準API
- 分散トランザクション処理を実現するためのインターフェース
- 主な機能：
  - トランザクションの開始・コミット・ロールバック
  - 複数のXAリソース間でのトランザクション調整
  - トランザクション境界の管理

### SpringBootのトランザクション管理
- 宣言的トランザクション管理（`@Transactional`）
- プログラマティックトランザクション管理（`TransactionTemplate`）
- JTAとの統合オプション

## 教訓

1. 環境差異の重要性
   - ミドルウェアの違いによる影響を事前確認
   - 各環境での動作検証の必要性

2. トランザクション管理の設計ポイント
   - フレームワークの重複を避ける
   - 明示的な設定の重要性
   - 環境依存の考慮

## 参考
https://spring.pleiades.io/spring-boot/reference/io/jta.html

https://spring.pleiades.io/spring-framework/reference/data-access/transaction/programmatic.html
Bing Chat Enterprise がプレビューになったので有効化した

2023 年 7 月 19 日、Bing Chat Enterprise が発表されました。
朝起きて Twitter 見たらなんかすごいことになってるじゃん…

みんな大好き AI、今をときめく AI を個人の検証環境で触ってみたのでやったことを記載します。

# ライセンス

https://blogs.microsoft.com/ja/blog/2023/07/18/furthering-our-ai-ambitions-announcing-bing-chat-enterprise-and-microsoft-365-copilot-pricing/

> Bing Chat Enterpriseは、本日よりプレビュー版が開始され、Microsoft 365 E3、E5、Business Standard、Business Premiumに追加費用なしで含まれます。将来的には、1 ユーザーあたり月額 5 ドルのスタンドアロンサービスとして利用できるようになる予定です。

私は E5 を持っているので、現時点では費用なしで使用できています。
プレビュー版は無償だけど GA したら月 5 ドルかかるのか、それとも上記ライセンスに含まれているのかについては、日本国内のユーザーでも解釈がいろいろと違うようです。公式見解をを待ちましょう！

# Bing での Microsoft Search‎ 設定 を有効にする

https://admin.microsoft.com/

Microsoft 365 管理センターより、[設定] > [検索とインテリジェンス] > [構成] を開きます。
[‎Bing での Microsoft Search‎ 設定] の [変更] をクリックします。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335429/c77e6583-41cd-fd1d-a76b-9dba78bdf239.png)
と思ったんですが、私の環境では規定で有効（アクティブ）になっていました。
また、[窓の社](https://forest.watch.impress.co.jp/docs/news/1517403.html "Microsoft、「Bing Chat Enterprise」を発表 ～業務にもAIチャットのパワーを") によると、

>なお、2023年8月17日には既定で有効化されるため、この操作は不要となる見込み。逆に、組織で「Bing Chat Enterprise」を展開したくない場合は、手動で無効化する必要がある。

とのことです。この記事をご覧になっている方にはあまり需要がないかもしれませんが、お気を付けください。

この状態で、[https://aka.ms/TurnOnBCE](https://aka.ms/TurnOnBCE "https://aka.ms/TurnOnBCE") からオプトインを行います。

# オプトインする
画面中央部の英文を機械翻訳すると
> このボックスをオンにすることで、組織を代表して Bing チャット エンタープライズ補足条件を確認し、ここに同意し、Bing チャット エンタープライズ (BCE) オプションの接続エクスペリエンスを組織内で利用できるようにしたいと考えています。

となります。検証の場合や、組織全体で利用してよい場合はチェックボックスにチェックを入れて [Turn On] > [Conform] します。（っていう意味だよね？）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335429/346b3107-3f92-9ff9-9e37-e02c30148c90.png)

# 待つ

テナントで有効化されるまでに少し時間がかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335429/e1380120-55a4-b819-5337-d3c388632340.png)

# 使う！
私の場合、Microsoft Edge の右上の Bing ボタンよりすぐに使用できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335429/085e4177-b6c2-44cf-fac6-56f291d6fbae.png)
**このチャットでは、個人と会社のデータが保護されています**
最高ですね。ガシガシ使っていきたい。

ちなみに、個人の Microsoft アカウントでサインインした Microsoft Edge では以下のようになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335429/a29442e3-1375-b338-9622-cf0b88436682.png)

楽しんで使っていこうと思います！地味に初投稿でした。
はじめて読む486　第3章 オペレーティングシステム

# 3. オペレーティングシステム

## 3.1 オペレーティングシステムの役割

- オペレーティングシステム
    - 他のプログラムを実行するための基盤となるソフトウェア
    - ソフトウェアの動作を支援し、コンピュータをより有効に活用する仕組みを提供する
        - プロセス管理
            - アプリケーションソフトウェアの実行支援と管理
            - 本格的なオペレーティングシステムでは、マルチタスク機能を備えている
        - メモリ管理
            - プログラムの要求に応じて、メモリを割り当てる機能
            - デマンドページングや仮想記憶などの仕組みでメモリを有効活用
        - ファイルシステム
            - ディスク装置などの記憶媒体の管理を支援する機能
            - ファイル名での呼び出しや階層構造で整理可能になる
        - 入出力管理
            - 様々な周辺機器を接続し、アプリケーションソフトウェアから利用できるようにする機能
            - 機械に固有な制御をプログラム化したドライバと呼ばれるソフトウェアを組み込み、アプリケーションソフトウェアからどの機器も同じ方法でコントロール可能になる

## 3.2 プロセス管理

- マルチタスク機能
    - プロセス管理機能のうち、複数のプログラムを同時に並行して実行する機能のこと
    - CPUの実行するプログラムを高速で切り替えることで、すべてのプログラムが同時に連続して実行しているように見える仕組み
    - 切り替える際は、タスクの状態（レジスタの内容）をメモリに保存し、また同じタスクを再開するときに前回のタスク状態をメモリからレジスタにセットする
    - システム全体の処理効率の向上ができる
        - タスク実行ごとの（入出力の完了などの）待ち時間をシングルタスクでは有効活用できない
- イベント駆動方式
    - ユーザーの操作をイベントとして扱って、その種類にお応じて処理を選択する
- プリエンプティブなマルチタスク
    - 入出力のタイミングだけでなく、一定時間経つと強制的にタスクを切り替えてしまう方式
    - すべてのタスクが他のタスクに影響されることなく独立に実行を進めていけることから、「完全なマルチタスク」とも呼ばれる
    - ランダムな瞬間にタスクが切り替わってしまうことを前提にオペレーティングシステム内で適切に排他制御を行わなければならないため、比較的高度な機能

## 3.3 メモリ管理

- オペレーティングシステムのメモリ管理機能の主要な役割
    - メモリ割り当て
        - 複数のタスクにメモリを分配する方法を管理する
        - タスク起動時にプログラムをロードするために必要な分を空きメモリから割り当てる
        - アプリケーションソフトウェアからプログラムを実行するために必要なメモリの要求があった際にメモリを割り当てる
        - メモリが不要になったり、ソフトウェアの実行が終了すると、メモリが返却され、再び空きメモリとして管理される
    - メモリ保護
        - タスク内で実行されるアプリケーションソフトウェアがアクセスできるメモリ領域を制限する
        - 誤ってシステム領域のメモリに書き込んでしまうようなミスを防ぐ
    - 仮想記憶
        - 以下のような仕組みで実際に搭載しているメモリ容量よりも多くのメモリがあるように見せる機能
            1. 論理アドレスに対応する物理アドレスがない場合（存在確認欄がOFF）にMMUがアドレス変換を行う代わりにCPU実行ユニットに割り込み信号を送る
            2. 割り込みによりオペレーティングシステムのメモリ管理モジュールが呼び出される
            3. あまり使われていない物理メモリが探され、この内容をディスク装置に格納した後、論理アドレスへの割り当てから解放する（存在確認欄OFF）
            4. 解放された物理アドレスを最初にアクセスのあった論理アドレスに割り当てる
- MMU（Memory Management Unit）
    - メモリ管理のための特殊機能を持ったハードウェア
    - オペレーティングシステムがメモリ割り当て時に変換表を作成しMMUに設定すると、MMUはこの表をもとにアドレスを変換する
    - 486/386ではCPU内にMMUを内蔵しているため、アドレス変換などは高速に実行される
    - タスク切り替えの際にタスク状態の保存・復元と同時に、MMUに設定されるアドレス変換表も保存・復元される
- アドレス変換
    - プログラムがアクセスするメモリアドレス（論理アドレス）と、実際にメモリチップにアクセスするアドレス（物理アドレス）を変換すること
    - アドレス変換をすることで、物理アドレス上は不連続な領域でも、論理アドレスが連続した領域として扱うことができるようになる

## 3.4 特権レベルと保護機能

- 特権レベル
    - オペレーションシステムとアプリケーションソフトウェアの特権レベル（特殊命令やI/Oポートのアクセスの実行が可能）を分離することで、オペレーティングシステムのプロセス管理やメモリ管理、入出力の働きがより安全になる
    - 486は4段階の特権レベルを持つ
- 保護機能
    - メモリ管理
    - 特権レベルによる実行可能な命令の種類の制限
    - システム資源の独占を防ぐための、タスク機能によるプログラム切り替え
UiPath初心者向け：実務でよく使うVB.NET集

# 1.はじめに
初心者(市民開発者)が実務でよく使うVb.netをまとめてました。

# 2.If文の条件分岐でよく使用するもの
### (1)特定の記号や文字があるかどうか
　・構文
　　対象の文字列.Cotains("特定の記号や文字")
　・使用するタイミング
　　メールアドレスに"@"があるときに処理したい。
　　⇒**対象の文字列.Contains("@")**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/3e6df494-e940-9126-2751-02867eac4e13.png)

　　住所に"東京都"があるときに処理したい。
　　⇒**対象の文字列.Contains("東京都")**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/b575c516-e46a-06dd-ee54-de88b9ced84c.png)
　　余談ですが、"神奈川県横浜市港北区小机町3300"は日産スタジアムです。
　　7/29,30はUVERworldがライブするので記念にいれておきました。
　　
　　ちなみにデータテーブルをフィルターにも"Contains"があります。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/ade7ac02-46e8-014f-5036-2362514563e2.png)


### (2)空であるかどうか
　・構文
　　String.IsNullOrEmpty(対象の文字列)
　・使用するタイミング
　　データテーブルのある項目が空がどうか。

# 2.代入でよく使うもの
### (1)置き換え
　これは使用することが多く便利なので覚えておいた方がいいです。
　・構文
　　文字列.Replace("変えたい文字や記号","変更後の文字や記号")
　・使用するタイミング
　　電話番号(090-XXXX-XXXXX)の"-"を消したい。
　　⇒**文字列.Replace("-","")**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/06ed8f86-141f-958a-c11b-e0fc88da4a67.png)

　　日付の表記(2023_07_07→2023/07/07)に変えたい。
　　⇒**文字列.Replace("_","/")**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/5ff7824c-b52f-7d9b-5599-f6432f211193.png)


### (2)型の変更
　・構文
　　変更したい型.parse(変更前の型)
　・使用するタイミング
　　文字から数値に型を変更したい。
　　⇒**Integer.parse(文字列)**

### (3)日付の取得(yyyy_MM_ddの形式)
　・構文
　　DateTime.Now.ToString("yyyy_MM_dd")
　・使用するタイミング
　　ファイル名やフォルダー名の作成で使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/07173826-51b5-3594-854a-90b10b6b0573.png)

:::note warn
2023_9_2としたいときには、DateTime.Now.ToString("yyyy_M_d")とするといいです。
M、dそれぞれ1文字で大丈夫？と思いますが、安心してください。2桁になっても問題なくできます。
:::
### 前日の取得(yyyyMMddの形式)
　・構文
　　DateTime.Now.AddDays(-1)ToString("yyyyMMdd")
　・使用するタイミング
　　システムに売上の登録には過去日付を使用すると思います。
　　その時に使用します。
　　またファイル名やフォルダー名の作成で使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/58c49a3f-f8c4-4d32-89aa-15c0022c2d66.png)

:::note warn
月初の判定をしたいときにDateTime.Now.ToString("d")とすると"1"になりません。
このときはDateTime.Now.ToString("dd")にして、"01"となるので、判定条件は"01"にしたことがありました。
:::

:::note warn
Now.AddDays(-1).ToString("M")で今まで月を認識していましたが、急にできなくなったときあり、DateTime.Now.AddDays(-1).Month.ToStringしたところ、上手くいった事例もありあました。
:::


# 3.最後に
冒頭で記載したようにこの記事は更新していきます。
役に立つことができたら幸いです。
NetworkManager

default routeの自動設定をおこなうつーる
```
[linuxstudy@localhost ~]$ sudo systemctl status NetworkManager
[sudo] linuxstudy のパスワード:
● NetworkManager.service - Network Manager
   Loaded: loaded (/usr/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
   Active: active (running) since 水 2023-07-19 18:27:00 JST; 2h 16min ago
     Docs: man:NetworkManager(8)
 Main PID: 963 (NetworkManager)
    Tasks: 4
   CGroup: /system.slice/NetworkManager.service
           ├─ 963 /usr/sbin/NetworkManager --no-daemon
           └─6200 /sbin/dhclient -d -q -sf /usr/libexec/nm-dhcp-helper -pf /var/run/dhclient-ens33.pid -lf /var/lib/Ne...

 7月 19 20:37:37 localhost.localdomain dhclient[6200]: DHCPACK from 192.168.253.254 (xid=0x43e26b32)
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2026] dhcp4 (ens33):   address 192...139
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2035] dhcp4 (ens33):   plen 24 (25....0)
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2036] dhcp4 (ens33):   gateway 192...3.2
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2038] dhcp4 (ens33):   lease time 1800
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2039] dhcp4 (ens33):   nameserver ....2'
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2039] dhcp4 (ens33):   domain name...in'
 7月 19 20:37:37 localhost.localdomain NetworkManager[963]: <info>  [1689766657.2043] dhcp4 (ens33): state changed...und
 7月 19 20:37:37 localhost.localdomain dhclient[6200]: bound to 192.168.253.139 -- renewal in 803 seconds.
 7月 19 20:38:39 localhost.localdomain NetworkManager[963]: <info>  [1689766719.1017] agent-manager: req[0x5559938...red
Hint: Some lines were ellipsized, use -l to show in full.
```
送受信パケット数を表示

```
[linuxstudy@localhost ~]$ ip -s link show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:36:8c:6f brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast   
    47274414   63720    0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    8644685    39321    0       0       0       0       
[linuxstudy@localhost ~]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.253.139  netmask 255.255.255.0  broadcast 192.168.253.255
        inet6 fe80::7b18:ba6f:58cb:d149  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:36:8c:6f  txqueuelen 1000  (Ethernet)
        RX packets 63753  bytes 47276554 (45.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 39321  bytes 8644685 (8.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

```
【GitHub】GitHub Pagesがスタックしたときの対処法。

# 概要
GitHub Pages(以後Pages)が有効化されているリポジトリに何かしらの変更をコミットした際にPagesにコミットが適用されないという問題に出くわし、対処法が見つかりましたので共有いたします。
# 試したこと
調べながら実際に下記のことを試してみました。
- PagesをカスタムドメインにしていたためDNS関連の確認
- 二日放置
- 再コミット
- URLパラメータでコミットを指定して開く方法

ですがどれも効果なし...ダメもとで[こちらの記事](https://www.heiki-hecchara.net/post/github-pages-sync-problem/)(参考文献にも記載しています)に書いてあるサポートに問い合わせという手段に出てみました。
結論としては、問い合わせで解決しましたので下記に解決法を記載します。
# 問い合わせ手順
GitHubのユーザーアイコンから`GitHub Support`をクリックします。
![GitHub Support](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/57563816-b29b-6464-81ca-3f854892dc9c.png)
サイト下部までスクロールし`お問い合わせ`をクリックします。
![お問い合わせ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/cc479bfd-057b-5681-55c4-27f4f52e6074.png)
トピック選択画面になるので、`GitHub Pageのヘルプ`をクリックします。
![GitHub Pagesのヘルプ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/b5d8848b-b7a4-6fe3-cc67-9d265c2c91ee.png)
内容の選択になりますがあてはまるものがない為、私は`カスタムドメインのヘルプ`を選択しました。
![カスタムドメインのヘルプ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/c957aaff-bc4b-dc02-c406-6e5f870449bb.png)
この画面になったらやっと内容の入力です。
![GitHubについてのお問い合わせ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/5e891dc7-1df4-ccef-76bd-b45f86c4e32f.png)
# お問い合わせ内容
問い合わせ内容についてですが、以下のように入力しました。
タイトル:
> About commits in Github Pages

内容:
>Hello.
I have been using Github Pages for a few years now, but suddenly my commits are not being reflected on my site, even though I have been using it normally until now.
I did some research and found that some articles said that Github Pages commits can get stuck, so I contacted you.
Here is my site.
https://nomindev.net
The repository is here.
https://github.com/nomindes/nomindev.net
I hope it will be cured.

上記の内容で送信したところ、3時間くらいで返信が来ました。
> Hi Sena,
Thank you for getting in touch with GitHub Support!
I see there was a failed page build a few days ago, which appears to be what made it get stuck.
I have manually pushed a build through for you now, but please let me know right away if it gets stuck again and I will see what I can do on my end to investigate further for you!
I hope this helps, please let me know if you have anything else I can assist with.
Roy
GitHub Support
Please note: This ticket will automatically close after 3 days of inactivity, but it can always be reopened with a reply or follow-up.

というわけで無事解決しました。その後、`Thank you very much!`と返してチケットをCloseしました。
![Thank you very much!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510989/ad7b968a-279b-9e27-bd8a-fd4901bc194c.png)
# 最後に
GitHub Supportには数え切れないほどのチケットがあるはずなのに3時間で返信してくれるGitHubの運営に驚きました。この記事がお役に立てれば幸いです。
# 参考文献
https://www.heiki-hecchara.net/post/github-pages-sync-problem/