OmniAICreator/Qiita-1.07M huggingface dataset:
ansible導入手順

個人的な備忘録です。

# 流れ
1. OSインストール（今回は割愛）
1. OS初期設定([別記事参照](https://qiita.com/TurkeysDevTeam/items/d369d9cd61821fec3426))
1. ansibleインストール
1. ansible用ユーザ作成
1. ansible用ユーザ向けSSH公開鍵作成
1. ansible設定追加
1. 動作確認

# 環境
コントロールノード
+ OS：RockyLinux 8.5　
+ Python:Python 3.6.8
+ Ansible: ansible-core 2.15.3
+ ansible用ユーザ名:ansible

ターゲットノード
+ OS：RockyLinux 8.5　
+ Python:Python 3.6.8
+ ansible用ユーザ名:ansible

# ansibleインストール
下記コマンドを使ってインストールする

```bash:bash
sudo dnf install ansible-core
```
# ansible用ユーザ作成
useraddコマンドで作成する
```bash:bash
sudo useradd ansible
```

作成できたらパスワードも設定する
```bash:bash
sudo passwd ansible
```
# ansible用ユーザ向けSSH公開鍵作成
下記コマンドを使ってインストールする
```bash:bash
ssh-keygen -t rsa
```
色々聞かれるが特に設定せずEnter

作成できたらssh公開鍵を交換する
```bash:bash
ssh-copy-id -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa.pub <ターゲットノードのIPアドレス>
```
ターゲットホスト側でも鍵生成・交換をおこなう

# ansible設定追加
ansibleの設定ファイルにssh接続時のフィンガープリントのチェックを無効にする設定を追加する
```bash:/etc/ansible/ansible.cfg
[defaults]
host_key_checking = False
```

コントローラノード及びターゲットノードの宛先を記載したインベントリファイルを作成する
```bash:inventory.ini
localhost
<ターゲットノードのIPアドレス>
```

# 動作確認
下記コマンドを使って動作確認をおこなう
```bash:bash
ansible -i inventory.ini <ターゲットノードのIPアドレス> -m ansible.builtin.ping
```

下記の通り動いていれば正常に動作している
```bash:bash
[ansible@hogehoge]$ ansible -i inventory.ini <ターゲットノードのIPアドレス> -m ansible.builtin.ping
<ターゲットノードのIPアドレス> | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
```
Javaの型安全とOptional<T>を上手く使えば便利になるという話

## 概要
今回は、java.util.Optionalの便利さと使用方法についての内容です。

### 環境

- Windows 10
- Oracle JDK 17

## Optionalの利用が推奨される理由
値の取得時にnullが許容されない場合、Optional<T>を使用してnullを管理する方が、取得時に都度nullチェックを行うよりも優れている、というのが本稿の主旨です。

以前までは、「Optionalなど使用せずとも、受け取り側でnullのケースを処理すれば良い」と考えていました。
しかし、この``Optional<T>``は便利な機能を有しています。

Optionalを使用する最大の利点は、コードをコンパイルする際、開発者にnullの可能性を事前に意識させる暗黙のガイドを提供することです。
具体的には、Optional<T>を使用することで、戻り値がnullの可能性がある場合に、その値を使用する前にチェックを強制してくれます。
これにより、値がnullである可能性を事前に気づき、NullPointerExceptionを防ぐことができます。

### Optionalを使用しない場合
```java
public String findUsernameById(Long userId) {
    // ユーザー検索ロジック（省略）
    return null; // ユーザーが見つからない場合
}
```
上記メソッドは、ユーザー名を取得することを試みますが、ユーザーが見つからない場合はnullを返します。
このメソッドを使用する際、戻り値がnullである可能性を常に考慮する必要があります。
使用する際にnullチェックを忘れると、NullPointerExceptionの発生の可能性があるからです。

### Optionalを使用する場合
```java
public Optional<String> findUsernameById(Long userId) {
    // ユーザー検索ロジック（省略）
    return Optional.empty(); // ユーザーが見つからない場合
}
```
上記のメソッドはOptional<String>を返します。このため、開発者は値を直接使用する前に、値の存在を確認する必要があります。
```java
Optional<String> username = findUsernameById(userId);
username.ifPresent(name -> System.out.println("Username found: " + name));
```
上記のコードでは、ifPresentメソッドを使用して、usernameが値を含む場合のみユーザー名を出力します。
これにより、値がnullである場合のチェックを明示的に行い、NullPointerExceptionを防ぐことができます。

このように、Optionalを使用することで、値がnullである可能性に注意深くなり、そのような場合に適切に対応することがコンパイル時に促されます。
これにより、ランタイムエラーのリスクを低減することが出来ます。

## Optionalの使用例
### Optional.ifPresentOrElse()
Optional.ifPresentOrElse()は、値が存在する場合は引数で指定した1つ目の関数を実行し、存在しない場合は引数で指定した2つ目の関数を実行する。
```java
Optional<String> username = findUsernameById(userId);
username.ifPresentOrElse(
    name -> System.out.println("Username found: " + name), // 値が存在する場合に実行
    () -> System.out.println("No username found") // 値が存在しない場合に実行
);
```

### orElseThrow()
```java
try {
    // 値が存在しない場合に、NoSuchElementExceptionを投げる
    String username = findUsernameById(userId)
        .orElseThrow(() -> new NoSuchElementException("No username found for user ID: " + userId));
    System.out.println("Username found: " + username); // 値が存在する場合に実行
    // orElseThrowによって投げられるNoSuchElementExceptionをキャッチ
} catch (NoSuchElementException e) { 
    System.err.println(e.getMessage());
}
```

## 最後に
Optionalの使用により、値の取得時に都度行うnullチェックの場合と比べて、コードの堅牢性を向上させるとともに、NullPointerExceptionのリスクを効果的に低減できます。
より安全なコードを実現するために、Optionalの活用を積極的に行いましょう。

## 参考リンク
[Java JDK 17 ドキュメント](https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/Optional.html)
React公式ページで学んでみた③（備忘録）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
前回の続きです。今回は「インタラクティビティの追加」。被る部分もあると思いますが、後で振りかえって深掘りするきっかけになるのが理想です。細かく書くと大変なのであっさりめ。

https://qiita.com/mr_noppo/items/804a2489287ac4848ff4

# 使用したものや事前準備
・Macbook Pro
・Visual Studio Code

# 主に参考にさせていただいた記事
https://ja.react.dev/learn/adding-interactivity

# インタラクティビティの追加
※インタラクティビティ＝アクションを起こすことによって反応や変化を引き起こす

### state
時間の経過とともに変化するデータのこと

## イベントハンドラ
イベントハンドラは、onClickのようなクリックへの反応とか。
イベントハンドラ関数の命名は、「handle+イベントの名称」が一般的である。
例：クリックなら「handleClick」、マウスポインタが入ってきた時「handleMouseEnter」

```react
export default function Button() {
    //イベントハンドラ(handle〜）
    function handleClick() {
        return alert("test");
    }
  return (
    <>
        {/*OK:渡すことでイベントハンドラ関数がクリックに反応する*/}
        <button onClick={handleClick}>ボタン</button>
        {/*NG：()があるとレンダー後すぐに発火する*/}
        <button onClick={handleClick()}>ボタン</button>
        {/*アロー関数で定義するのも可能*/}
        <button onClick={() => {alert('test2')}}>ボタン</button>
    </>
  );
}
```

## イベントハンドラ関数をpropsとして渡す
イベントハンドラのプロップは「on+大文字から始まる好きな名前」で命名する。
```react
// イベントハンドラとchildrenを受け取るボタンタグ
function Button({ onPlay, children}) {
    return (
        <button onClick={onPlay}>
            {children}
        </button>
    );
}
// イベントハンドラ関数
function PlayButton() {
  function handlePlayClick() {
    alert(`test`);
  }

  return (
    {/*イベントハンドラのプロップは「on+好きな名前」で命名*/}
    <Button onPlay={handlePlayClick}>
      Play Movie
    </Button>
  );
}
// デフォルトエクスポート
export default function Toolbar() {
  return (
    <PlayButton/>
  );
}
```

## イベントハンドラの伝播を止める
・e.stopPropagation() 
ツリーの上側（親コンポーネント）のイベントハンドラが発火しないようにする。
下記は、e.stopPropagation() がない場合、子→親の順でアラートが発火する。
```react
function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick();
    }}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('アラートは出ない');
    }}>
      <Button onClick={() => alert('アラートが出る')}>
        Click
      </Button>
    </div>
  );
}
```
・e.preventDefault() 
イベントがブラウザデフォルトの動作を持っていた場合に、抑制する。
```react
export default function Signup() {
  return (
    <form onSubmit={e => {
      e.preventDefault();
      alert('再描画を防ぐ');
    }}>
      <input />
      <button>Send</button>
    </form>
  );
}
```

# 最後に
学べることが意外に多い:thinking:

# 次

https://qiita.com/mr_noppo/items/4e621111f6b26f563c62
【線形代数】線形空間・線形写像

# ０.はじめに
大学で線形代数の講義を受講している者です。
ざっくりと計算方法を個人的な備忘録としてまとめております。

##### 関連学習
[【線形代数】ベクトル](https://qiita.com/AkihideKato/items/f581ee500782b2272c0a)
[【線形代数】行列](https://qiita.com/AkihideKato/items/7d92b048d5bd392389e8)
[【線形代数】連立方程式](https://qiita.com/AkihideKato/items/6ddd947e438c4fae77a6)
[【線形代数】線形空間・線形写像](https://qiita.com/AkihideKato/items/2f03f8a996372525db6d)
[【線形代数】座標](https://qiita.com/AkihideKato/items/cda674d9fcf3f1fc00ba)
[【線形代数】固有値・固有ベクトル](https://qiita.com/AkihideKato/items/42a6bd7eec6ca66085c8)

# 空間
### 線形空間（ベクトル空間）															
和の性質とスカラー倍の性質が満たされるときになるもの													
- **``和の性質：a + b ∈ V（和a + b がVの要素）``**												
- **``スカラー倍の性質：αa ∈ V（スカラー倍αaがVの要素）``**										
															
### 部分空間（部分ベクトル空間）															
2つを満たしたときのＷであるもの														
- **``任意のa,b ∈ Wについて a+ b ∈ W``**													
- **``任意のa ∈ W. α ∈ ℝについて αa ∈ W``**
ℝ³→三次元空間として用いてWをxy平面として表す														

# 結合
### 一次結合（線形結合）															
ℝ³の3つあるベクトルx₁,x₂,x₃に対して														
x₁+2x₂+3x₃であるとき、x₁,x₂,x₃の一時結合である														
               
### 一次関係式（線形関係式）															
上記の一次結合の和が0のもの	

### 自明である/自明でない															
- 自明である：一次関係式であるもの														
- 自明でない：そうでないもの	
													
# 関係性
### 一次独立（線形独立）															
一次関係式が成り立つ時のa₁,a₂...を一次独立という												

### 一次従属（線形従属）															
一次独立（線形独立）ではない場合、つまり一次関係式において少なくとも									
1つに「0」が存在するとき一次従属という

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581998/541043e1-d662-0e0d-7969-e3e8e65c9ac1.png)


### 図面から理解する			
二次元においての一従従属の考え方		
``pa + qb = 0``に対して ``p≠0,q≠0``であり``a= -q/p b`` もしくは ``b = -p/q a``と表される	
一次従属であるということは**どちらか一方が``0``ではない**ということ		
一次従属ということは二次元平面上では同一直線上に存在する		
三次元も同様で同一平面上にないものは一次独立となる	

### 一次独立か一次従属かを調べる場合		
１．a1+a2+a3=0といったような解が0である行列に変形する	
２．掃き出し法を行う	

# 基底							
線形空間Ｖの要素の組``[ a₁ a₂...]``が2つの条件を満たすときaの組をVの基底という						
							
# 次元（dim v)							
線形空間Ｖの基底を構成する要素の個数nを線形空間Vの「次元」という						
``dim V``と表す						
							
```math
n次元ベクトル全体の集合であるℝ^nの次元は						
```
```math
dim ℝ^n = n個である						
	
```

# 写像				
集合Ａ．Ｂがある場合、Ａのなかの任意の要素xに対して集合Ｂの要素yをただ			
一つ対応させる規則のことを集合Ａから集合Ｂへの「写像」という						
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581998/5cb7f1b8-6553-4f6a-477f-6af3e9d23390.png)

# 像（image のImで表す）				
``f : V→V'``とする線形空間V上の任意の要素xがfにより写される関数f(x)の集合を			
``m f = {f(x) ∈ V' | x ∈ V}``と表す。これをVのfによる像という						
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581998/c4d65457-c3a3-d40b-d841-bf9b36339ac9.png)
				
# 核 (Ker）
``kernel``の``Ker``で表す
線形写像``f : V →V'``に対して線形空間V上の要素xに対し``f(x) = 0'(0':V上の零ベクトル）``となるxの集合を	``Ker f = {x ∈ V | f(x) = 0'}``と表す。
これをVのfによる核という			
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581998/2c4cec84-82ec-5be7-9094-4b80ceb21ef3.png)

---
編集中
typedef を用いた構造体の定義（C言語）

**型名を省略する目的** で使われる`typedef` は、`struct` とセットで以下のように記述されることが多いです。

```cpp:Employee 型の定義
typedef struct employee {
    int id;
    string name;
} Employee;
```

上記は **構造体 `struct employee` を `Employee` という型名で省略できるようにした** という意味になります。

:::note info
`struct` の後の `employee` は構造体のタグ名と呼ばれます。
:::


## C言語の場合
`typedef` を用いない場合、`Employee` 型の変数を定義する際に`struct employee` と記述する必要があり冗長です。

```c:typedef なし
#include <stdio.h>

struct employee {
    int id;
    char* name;
};

int main(void) {
    struct employee e = {1234, "Taro"}; // 冗長...
    printf("%d\n", e.id);   // 1234
    printf("%s\n", e.name); // Taro
    return 0;
}
```

そこで、`typedef`を用いて`Employee` だけで定義できるようにします。

```c:typedef あり
#include <stdio.h>

typedef struct employee {
    int id;
    char* name;
} Employee;

int main(void) {
    Employee e = {1234, "Taro"}; // Employee のみで定義できる
    printf("%d\n", e.id);
    printf("%s\n", e.name);
    return 0;
}
```

もし `typedef`による型名の宣言をせず、`struct`のタグ名で定義しようとした場合は、コンパイルエラーになります。

```c:構造体のタグ名だけでは宣言できない（コンパイルエラー）
#include <stdio.h>

struct Employee {
    int id;
    char* name;
};

int main(void) {
    Employee e = {1234, "Taro"}; // エラー
    printf("%d\n", e.id);
    printf("%s\n", e.name);
    return 0;
}
```

エラー文を見ると、「`Employee` という型名なんて知りません、`struct` を使って参照しなさい」という内容になっています。
```
prog.c:9:5: error: unknown type name 'Employee'; use 'struct' keyword to refer to the type
    9 |     Employee e = {1234, "Taro"}; // エラー
      |     ^~~~~~~~
      |     struct 
```



## C++の場合

C言語の場合と同様に、`typedef`で構造体の型名を宣言できます。

```cpp:typedef を用いた構造体の定義
#include <iostream>
using namespace std;

typedef struct employee {
    int id;
    string name;
} Employee;

int main() {
    Employee e = {1234, "Taro"};
    cout << e.id << endl;    // 1234
    cout << e.name << endl;  // Taro
    return 0;
}
```

しかしながら、C++においては **`typedef` を使う必要がありません**。
実際、以下のプログラムは正常に動作します。

```cpp:c++では typedef 不要
#include <iostream>
using namespace std;

struct Employee {
    int id;
    string name;
};

int main() {
    Employee e = {1234, "Taro"};
    cout << e.id << endl;    // 1234
    cout << e.name << endl;  // Taro
    return 0;
}
```

C++では、
```cpp:
struct Employee {};
```
と
```cpp:
typedef struct Employee {} Employee;
```
は等価であると考えることができます（[stack overflowの記事](https://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c/612476)を参照）。

## 参考サイト

1. 山田 修司、プログラミングB (C言語) 構造体 [https://www.cc.kyoto-su.ac.jp/~yamada/programming/struct.html](https://www.cc.kyoto-su.ac.jp/~yamada/programming/struct.html)（参照日：2024/03/12）
1. stack overflow, "Difference between 'struct' and 'typedef struct' in C++?" [https://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c/612476](https://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c/612476) （参照日：2024/03/12）
【スクラム】Q.スプリント中に予定していたPBIが早めに完了した場合に何をすべきか

自社内の駆け出しスクラムマスターからの質問への回答。
（当時の回答は今の見解と異なっているので、今の自分の見解を書く）
※スクラムの実務経験がない個人の私見です

## 質問内容
スプリント中に微妙に手が開く場合、どう行動すべきか教えてください。
新しいPBIを進めた方が良いと考えていますが、正しいでしょうか。

### 前提
- スプリント中、プランニングしたPBI（プロダクトバックログアイテム）が早めに終わる見込み
- PJ全体の開発は遅延している

## 私の回答
### バッファでやること
バッファの期間で早めにやっておきたいこと（リファクタリングやスパイク、教育（ペアプロ・モブプロやスクラム理解促進など）など）がなければ次のPBIを進める、でいいと思います。
が、やるのであれば残りの期間で充分終えられるサイズのPBIをとるべきです。（PBIの持ち越しは避けたい）

### 遅延への対策
遅延自体に対する対策は別で考えたほうがいいと思います。
そもそもなぜ遅延が発生したのでしょう。
- スクラムチームのキャパシティとプロダクトのサイズから、リリースまでの期間は試算した？
    - 何かを見誤った？バッファを設けていなかった？
- POがリリースまでの計画を怠って、もしくは見誤って、間に合わないことに気付くのが遅れた？
- チームの生産性（ベロシティ）がなんらかの理由で低下した？
- ・・・

PJの途中で取れる策は限られます。
- 期限延期
    - 追加の費用がもらえないなら、支出が増えるだけなので避けたい
- スコープ縮小
    - 許されるならこれがいい
- 生産性向上
    - 不要な作業、割り込み作業をなくす、減らす
    - 非効率な作業はツールの導入などにより効率化する
    - ペアプロ、モブプロなどによるメンバーのスキルアップ
        - 即効性はない
    - 増員
        - 安易に取られがちな対策だが、1人増やして1人月分の生産性が出るまでには数ヶ月かかるのでこれも即効性はない（理解を得づらいのが悩ましいが）
    - ・・・

そもそも請負のような実装したいことと期限が決まりきった開発にスクラムは不向きとは思いますが。
プロンプトフローでWikipediaを用いたチャットAPIを爆速で作る

## はじめに
みなさんプロンプトフローは使ったことがありますか？

プロンフローとはLLMのフローの構築、評価、デプロイまでを一気通貫で構築できるAzureのサービスです。

今回はプロンプトフローのサンプルを使って爆速でWikipediaを用いたチャットAPIを作っていきます。

## 内容
### サンプルのクローン

Azure AI Studioのサイドバーからプロンプトフローを選択し、「+作成」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/b4ee536d-574f-7dd5-cba7-006295cd9fc9.png)

ギャラリーを探すから「Ask Wikipedia」を探してクローンします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/ab2c73b2-8260-1390-86db-ca02e2d97b7b.png)

すると以下のようにフローが構築されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/713805e1-4200-6ea5-c943-832a09d05832.png)

### プロンプトフローでのLLMの設定
LLMを使えるようにするため、実際のリソースとの接続を行います。(添付写真では接続対象をgpt-35-turboとしています。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/883fa568-4aba-f36b-52c1-49147b8a1e05.png)


### 実行のテスト

実行のためにランタイムを選択して起動します。ランタイムの起動には3分程度かかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/7ec01b15-0d89-cd4f-0187-659f543d2df8.png)

以下入力に好きな質問を入れて、ヘッダーの実行ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/bd8e53d9-bd54-2d84-2dc9-348f4c594d47.png)

すると以下のような出力が得られます。

> OpenAI announced GPT-4 on March 14, 2023. It was launched and made publicly available through various platforms, including the paid chatbot product ChatGPT Plus, OpenAI's API, and the free chatbot Microsoft Copilot. SOURCES:
https://en.wikipedia.org/w/index.php?search=GPT-4

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/91188e16-7b04-511f-4a31-9a3faf7b6f49.png)

ちゃんと確からしいことを言っている&URLまで表示してくれて偉いです。


出力のログは以下のようにわかりやすく吐き出されます。
経過時間や消費トークン数についても一目瞭然です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/3c04bcbe-c2d4-d5f9-654c-dea7edac8b93.png)


またプロンプトフローの各フローについても出力を確認できます。
（添付写真は`get_wiki_url`のフローの結果です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/8b6a8c6b-0b18-4d18-9086-6d2591e0642b.png)


### デプロイ
最後にデプロイします。
ヘッダーのデプロイボタンを押し、エンドポイント名やランタイムのスペックを選択したらデプロイできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/bc38bcab-fd2a-8225-12b1-6c6efaff71ff.png)

## おわりに
上記手順で驚くべきほど簡単にWikipediaを用いたチャットAPIを公開できます！

皆さんも触ってみてください！
AWS勉強備忘録2 - LANとIPアドレス

## LANの基本とIPアドレス管理

### LAN（Local Area Network）とは？

LAN（ローカルエリアネットワーク）は、限定された地理的範囲（例えば、一つの建物やキャンパス内）において、コンピューターやデバイスを接続するネットワークシステムです。LANには様々な技術やデバイスが関連しており、効率的な通信とリソースの共有を実現します。

### DHCP（Dynamic Host Configuration Protocol）

DHCPは、ネットワーク上のデバイスに自動的にIPアドレスを割り当てるプロトコルです。これにより、管理者は手動でIPアドレスを設定する手間を省け、デバイスのネットワーク接続がスムーズに行われます。DHCPサーバーは、IPアドレス、サブネットマスク、デフォルトゲートウェイ、DNSサーバーの情報をクライアントデバイスに提供します。
なお、DHPCには有効期限があり、期限が過ぎると振り直されます。そのため、パソコンやプリンタのIPアドレスは時々変わってしまいます。

### サブネット（Subnet）

サブネットは、大きなネットワークを小さな論理的なネットワークに分割するプロセスです。この分割により、ネットワークの管理が簡素化され、セキュリティが向上し、トラフィックの効率化が図られます。サブネット化は、特に大規模な組織やインフラストラクチャにおいて、重要なネットワーク管理戦略となります。

### サブネットマスク

サブネットマスクは、IPアドレス内でネットワークアドレス部分とホストアドレス部分を区別するために使用される数値です。これにより、同じサブネット内のデバイスが互いに通信できるかどうかを判断できます。サブネットマスクは、特にサブネット化を行った際に、どの範囲のデバイスがネットワーク上で直接通信可能であるかを定義します。

## IPアドレスとDNSの理解

### プライベートIPアドレスとグローバルIPアドレス

ネットワーク上のデバイスは、通信を行うためにIPアドレスを使用します。プライベートIPアドレスは、内部ネットワーク内でのみ有効で、インターネット全体で一意ではありません。一方、グローバルIPアドレス（またはパブリックIPアドレス）は、インターネット上でデバイスを一意に識別するために使用され、世界中で一意です。

### IPv6

IPv6は、IPアドレスの新しいバージョンで、より広範なアドレス空間を提供します。IPv4アドレスの枯渇問題を解決するために導入され、128ビットのアドレス長を持ち、膨大な数のデバイスに一意のIPアドレスを割り当てることが可能です。

### DNS（Domain Name System）とRoute 53

DNSは、人間が覚えやすいドメイン名（例：www.example.com）をコンピュータが理解するIPアドレスに変換するシステムです。AWSでは、Route 53というマネージドDNSサービスを提供してお

り、高可用性とスケーラブルなドメイン名管理を実現します。Route 53を使用すると、DNSクエリの応答時間を短縮し、アプリケーションの可用性と信頼性を向上させることができます。

### FQDN（Fully Qualified Domain Name）

FQDNは、インターネット上の特定のホストを完全に一意に識別するドメイン名です。FQDNは、ホスト名とドメイン名（およびそのサブドメイン）から構成され、インターネット上でのリソースの位置を正確に指定します。

これらの概念は、ネットワークやインターネット技術の基礎を理解する上で非常に重要です。

## DMZ（非武装地帯）
DMZ（非武装地帯）については、セキュリティ戦略の一環として、以下の記事で別途取りまとめています。

https://qiita.com/KM9973/items/2da06364bfd5e00d860e
【Flutter】XiaomiデバイスでのINSTALL_FAILED_USER_RESTRICTEDエラーの解決法

## はじめに
Flutterでアプリ開発していて、Xiaomiデバイスにアプリをインストールしようとした際に`INSTALL_FAILED_USER_RESTRICTED`というエラーが発生しましたので記事にしました。

この問題はFlutterの問題ではなく、デバイス側の設定が原因であることが多いです。

## 問題の発生
XiaomiデバイスにアプリをUSB経由でインストールしようとすると、以下のようなエラーメッセージが表示されることがあります。


```
Error: ADB exited with exit code 1 
Performing Streamed Install 

adb: failed to install /Users/user/****/build/app/outputs/flutter-apk/app-debug.apk: Failure [INSTALL_FAILED_USER_RESTRICTED: Install canceled by user]
Error launching application on M2101K6G.
```

## 環境
Apple M2 Pro
macOS Sonoma 14.2.1
Flutter 3.16.2
Xiaomi Redmi Note 10 Pro（M2101K6G）

## 対処法
### 1. MIアカウントへのログイン
XiaomiデバイスでMIアカウントにログインします。

### 2. MIUI最適化の無効化
MIUI最適化の無効化は以下の手順で行います。
##### ① まずは開発者向けオプションを出す
設定 > デバイス情報 > MIUIバージョンを連打
追加設定に開発者オプションが出てきます。

##### ② MIUI最適化の無効化
設定 > 追加設定 > 開発者向けオプション

- 「MIUI最適化」をオフにして再起動します

- 「USBデバッグ」をオンにします。

- 「USB経由でインストール」をオンにします

- デバッグ実行

https://komugiprograming.com/howtofixinstall_failed_user_restricted/

## 「MIUI最適化をオンにする」オプションがない!?!?!?!?
なぜかMIUI最適化の項目が消えてしまう場合があります。そんな時は以下の手順で表示出来るかと思います。

① 開発者向けオプションに移動します。
② 「自動入力」の「デフォルト値にリセット」を数回連打します。
すると「自動入力の開発者向けオプションをリセットしました」とポップアップが表示され、下に最適化の項目が出てきます。
③ オフになったMIUI最適化が表示されます。

https://mitanyan98.hatenablog.com/entry/2021/04/19/110453


## 参考

https://github.com/flutter/flutter/issues/65308

https://stackoverflow.com/questions/47239251/install-failed-user-restricted-android-studio-using-redmi-4-device
フリーWiFiで接続認証しないときの対処法

皆様、こんにちは。
takazonessです。

マックやスタバといった公衆WiFiを提供している施設に行き、PCからWiFiにつなごう！と思ったけど、つながらなかった経験ありませんか？

そんな時は下記のサイトを使ってみましょう！！
```http
http://www.AlwaysHttp.com
```
上記に載せたサイトはhttpsにしないことを公言したサイトです。

SSL証明書を取得しているサイトだと、認証画面（ログイン）画面まで行けないことが非常に多く、取得していないページだと接続ページまで行けることが多いためです。
（※試してないですが、一般的なhttpから始まるサイトでも大丈夫だと思います。）

以上です。
是非役立ててください！！
Raspberry Pi 5 + ROS2 Humble

# ハードウェアの準備

- PC
- Raspberry Pi 5
- micro SDカード
- ACアダプタ

# ソフトウェアの準備

## Raspberry Pi 5 の準備

### micro SDにRaspberry Pi OSを書き込む

PCにRaspberry Pi Imagerをインストール
https://www.raspberrypi.com/software/

Raspberry Pi Imagerを起動
![Screenshot from 2024-03-12 21-48-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/75051b5b-0eef-cea4-fe29-d085739fc23e.png)

［CHOOSE DEVICE］を押下し、Raspberry Pi 5を選択。
![Screenshot from 2024-03-12 21-48-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/47bf5efe-031b-a7d7-8822-f155136dd918.png)

続いて、［CHOOSE OS］を押下し、Raspberry Pi OS (64-bit)を選択。
![Screenshot from 2024-03-12 21-49-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/10dffee5-a324-5a85-600e-dd4f46630803.png)

最後に、［CHOOSE STRAGE］を押下し、差し込んだSDカードを選択。
![Screenshot from 2024-03-12 21-49-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/0cb58600-3638-b978-c8be-018ef97a6c34.png)

［CHOOSE STRAGE］を押下 → ［NO］ → ［YES］
![Screenshot from 2024-03-12 21-49-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/1d9e1041-74df-5051-6a62-09c661f61c74.png)
![Screenshot from 2024-03-12 21-50-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/431dcb38-9de3-a064-43f5-a63285ca7f89.png)

SDカードへの書き込みがスタートするので、完了するまで待つ。（所要時間: 約15分）
![Screenshot from 2024-03-12 21-50-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/f11650a9-bb78-e9a0-e86f-e46a1d909863.png)

完了したらSDカードを抜き取り、［CONTINUE］を押下して終了する。
![Screenshot from 2024-03-12 22-02-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/ef7fd38a-50f8-06e6-6064-ece808a544f3.png)

### Raspberry Piのセットアップ
SDカードを差し込んで起動する
［NEXT］を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/5f380d87-a856-e78b-5366-d9938038bb69.png)

以下の通りにセットアップし、［NEXT］を押下
- Country: Japan
- Language: Japanese
- Timezone: Tokyo
- Use English language: チェックつける
- Use US keyboard: チェックつけない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/138fb281-4b53-ae80-1809-400639651bc8.png)

ユーザ名・パスワードを設定し、［NEXT］を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/33340104-45e1-09cd-51f2-61f57cb9fa81.png)

Wi-Fiを接続する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/326146cf-c327-3499-338a-e3416cb1dfbb.png)

以下の通りにセットアップし、［NEXT］を押下
- Chromiumを選択
- Tick here to uninstall the unused browser: チェックつけない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/bc9fc243-fb21-74e0-3ec2-14e3cae8ea4d.png)

［NEXT］を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/9ba50325-fb0a-8dbb-afdd-19f36d182903.png)

ソフトウェアのアップデートが始まるので、完了するまで待つ。（所要時間: 約30分）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/803f4c30-f495-0d5b-d6ef-600520d9f3f2.png)

インストール完了。［Restart］を押下し、再起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/f7715531-3f51-6144-7fa1-ee232c6b4908.png)

### ROS2 Humbleのインストール
Jenkinsで使用しているJavaをアップデートする

## はじめに
Jenkinsで「Java 11 end of life in Jenkins」という警告が出るようになってしまったので、Javaのバージョンをアップデートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/fffeced9-cf2c-a04d-bcf9-4f749ea08902.png)

## 実行環境
・Windows 10 pro
・Jenkins Version 2.440.1
・Java(更新前) 11.0.10.9
・Java(更新後) 21.0.2.13

 ## Javaのインストール
[Jenkinsの公式サイト](https://www.jenkins.io/doc/book/platform-information/support-policy-java/)で、現在のJenkinsのバージョンと対応しているJavaのバージョンを確認します。
私の環境で動作しているJenkinsのバージョンは2.440.1ですので、Java 21をインストールしました。
|Supported Java versions  |Long term support (LTS) release  |Weekly release  |
|---|---|---|
|Java 11, Java 17, or Java 21  |2.426.1 (November 2023)  |2.419 (August 2023)  |
|Java 11 or Java 17  |2.361.1 (September 2022)  |2.357 (June 2022)  |
|Java 8, Java 11, or Java 17|2.346.1 (June 2022)|2.340 (March 2022)|
|Java 8 or Java 11|2.164.1 (March 2019)|2.164 (February 2019)|

Javaのインストーラは [こちらのサイト](https://adoptium.net/)からダウンロードします。
インストーラの指示に従ってJavaをインストールしたら、Windowsを再起動します。

再起動後に、Javaのフルパスをコマンドプロンプトで確認します。
このフルパスはあとで必要になります。
```console
C:\Users> where java
C:\Program Files\Eclipse Adoptium\jdk-21.0.2.13-hotspot\bin\java.exe
C:\Program Files\AdoptOpenJDK\jdk-11.0.10.9-hotspot\bin\java.exe
```

# Jenkinsのアップデート
万が一に備えて、JENKINS_HOMEのフォルダをバックアップしておきます。
JENKINS_HOMEは[Jenkinsの管理]-[システム情報]から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/756afa84-534e-70df-40d6-de314300a2c6.png)

次のURLにアクセスします。
```console
http://<jenkins server＞/safeExit
```

[Retry using POST]を選択して、Jenkinsをシャットダウンします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/37c5433b-0006-f74d-c8fd-a703e05074c4.png)

jenkins.exeと同じフォルダの中に、jenkins.xmlというファイルがあります。
初期設定では以下のフォルダにあります。
```console
C:\Program Files\Jenkins\jenkins.xml
```
そのファイルの以下の赤枠の箇所を、新しいバージョンのjavaのフルパスに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/df3496a8-8775-f8eb-d4ce-77f87ab67516.png)

Jenkinsを再起動します。
Jenkinsをサービスで起動している場合は、タスクマネージャーのサービスから起動できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/316ffb69-5d89-44f1-ed8f-3e8e78d7e003.png)

Jenkinsにログインしたら、警告が消えました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930094/412c0ab3-4bbf-8c72-a2f9-515d223d7fda.png)

## 参考サイト
この記事は、下記のサイトを参考にして作成しました。
https://www.jenkins.io/doc/book/platform-information/support-policy-java/
https://penpen-dev.com/blog/jenkins-java/
Gmailの整理を自動化する: Google Apps Scriptを活用したメール管理術

今日は、Gmailを整理した

***

## Gmailの整理を自動化する: Google Apps Scriptを活用したメール管理術

Gmailはプロフェッショナルや個人の日常生活において欠かせないツールの一つです。しかし、毎日届く大量のメールを手動で管理するのは時間がかかり、煩わしいものです。幸いなことに、Google Apps Script（GAS）を活用すれば、メールの自動分類やアーカイブを設定し、Gmailの整理を効率化できます。ここでは、特定の送信元のメールを自動で特定のラベルに分類し、受信トレイからアーカイブする方法を紹介します。

### ステップ1: Google Apps Scriptプロジェクトの作成

まず、[Google Apps Scriptのウェブサイト](https://script.google.com/)にアクセスし、「新しいプロジェクト」を作成します。プロジェクトにはわかりやすい名前をつけてください。

### ステップ2: スクリプトの作成

プロジェクトが作成されたら、エディタに以下のスクリプトをコピー＆ペーストします。このスクリプトは、指定した送信元のメールを特定のラベルに自動で分類し、受信トレイからアーカイブするためのものです。

```javascript
function autoLabelAndArchiveEmails() {
  // 特定の送信元からのメールを検索
  var query = 'from:sender@example.com';
  var threads = GmailApp.search(query);
  
  // 目的のラベルを取得（存在しない場合は作成）
  var labelName = '目的のラベル';
  var label = GmailApp.getUserLabelByName(labelName);
  if (!label) {
    label = GmailApp.createLabel(labelName);
  }
  
  // 各メールスレッドにラベルを適用し、受信トレイからアーカイブ
  for (var i = 0; i < threads.length; i++) {
    label.addToThread(threads[i]);
    GmailApp.moveThreadToArchive(threads[i]);
  }
}
```

`query`変数の値を検索条件に合わせて変更し、`labelName`変数にはメールを分類したいラベルの名前を設定してください。

### ステップ3: スクリプトの実行と認証

スクリプトを保存した後、実行ボタンをクリックして関数を実行します。初めてスクリプトを実行する場合、GoogleからスクリプトにGmailへのアクセス権を与えるよう求められます。画面の指示に従って、必要な認証を完了させてください。

### ステップ4: トリガーの設定（オプション）

スクリプトを一度だけ実行するのではなく、定期的に自動実行したい場合は、トリガーを設定できます。スクリプトエディタの「トリガー」ボタンから新しいトリガーを追加し、スクリプトの実行間隔を指定します。

### まとめ

Google Apps Scriptを使ったメールの自動分類とアーカイブは、Gmailの整理を効率化し、日々のメール管理を楽にする強力な方法です。初期設定さえ完了すれば、この自動化システムはあなたのGmailを整理し続け、重要なメールに集中するための時間を増やしてくれます。この方法は、特に定期的に同じ送信元から大量のメールを受信する場合や、特定のトピックやプロジェクトに関連するメールを一箇所にまとめておきたい場合に便利です。

***

### 注意点とトラブルシューティング

*   **認証エラーが発生した場合**：スクリプトを実行する際に認証プロセスを正確に完了させているか確認してください。Googleはセキュリティの観点から、定期的に再認証を求めることがあります。
*   **メールが期待通りに処理されない場合**：`query`変数の検索条件が正しいか、再度確認してください。また、ラベル名が既に存在しているものと正確に一致しているかもチェックしましょう。
*   **リソースの上限に達した場合**：Google Apps Scriptには実行時間や実行回数に上限があります。大量のメールを処理しようとすると、これらの上限に達することがあります。スクリプトの実行頻度を調整するか、処理するメールの数を制限することで対処できます。

### さらなる可能性

このスクリプトは基本的な自動化を実現しますが、Google Apps Scriptの機能はこれにとどまりません。例えば、メールの内容に基づいて自動的に応答するスクリプトを作成したり、特定の条件を満たすメールを特定の人に転送するといったことも可能です。Gmailだけでなく、GoogleカレンダーやGoogleドライブといった他のGoogleサービスとの連携も実現できます。

### まとめ2

Google Apps Scriptを活用したメールの自動分類とアーカイブは、日々のメール管理を効率化し、より生産的な作業環境を実現します。この入門ガイドが皆さんのGmail利用体験を向上させる一助となれば幸いです。挑戦を恐れず、自分だけのカスタマイズされた自動化ツールを作成してみてください。あなたのGmail生活がより快適なものになることを願っています。

***

イメージ画像

![](https://pbs.twimg.com/media/GIeNovVagAAjm_f?format=jpg\&name=medium)
【WordPress】GTranslateのウィジェットをcssでカスタマイズして好きなところに設置する

## Wordpressサイトに超お手軽に翻訳機能を搭載できる

GTranslate というプラグインとその使い方の記事が大量にあるのですが、
意外とウィジェットをカスタマイズして設置する方法が見つからなかったので書きます。

雑なスクショ&デザインで恐縮ですが、こんな感じで好きな翻訳ナビを作れます。

![スクリーンショット 2024-03-12 20.58.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733749/9146961d-b33c-e75e-05eb-f96a08c5b6be.png)



### [1].  wp管理画面側でプラグインを追加・有効化

「Translate WordPress with GTranslate」というプラグインです。
「今すぐインストール」して有効化します。


### [2]. 設定画面を開いて設定する
プラグイン > GTranslate > 設定 を開き、以下の設定をしていきます。
- **ウィジェット表示**： 言語コード
　後で整形しやすいように最もシンプルなものを選択します
![スクリーンショット 2024-03-12 20.59.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733749/5115a461-1487-4dc7-cbd5-c5acd4847f53.png)

- **メニューに表示**： なし
- **フローティング言語セレクタの表示**: なし
表示無しにしないと勝手に出てきます。

- **必要な言語を選択**
必要な言語のチェックボックスにチェックしていきます。

- **Wrapper selector CSS**: 任意のクラス名
初期値は `.gtranslate_wrapper` になっているかと思います。
お好みでFLOCSS仕様に変えたりできます。

- **忘れずに「保存」**


### [3]. 好きな場所に設置する

肝心の設置方法ですが、なんとたったこれだけです。

```html: php: 好きなページの好きな場所
<div class="gtranslate_wrapper"></div>
```
[2]で設定したクラス名を持つ要素を好きな場所にボーンと置くだけ。
「こんでええんかーい」て声出ちゃいました。


### [4]. いよいよスタイルをカスタマイズ

設置した場所を開発ツールで確認すると以下のようになってます

```html:html: 開発ツール
<div class="gtranslate_wrapper 中略">
    <a href="#" 中略 class="glink 中略">en</a>
    <a href="#" 中略 class="glink 中略">zh-CN</a>
    <a href="#" 中略 class="glink 中略">zh-TW</a> 
    <a href="#" 中略 class="glink 中略">ja</a> 
</div>
<!-- ※英語、简体字、繁體字、日本語を選択してた場合 -->
```


なので以下のようにcssを当てればOKですね
```css:css
.gtranslate_wrapper {
	/* 親のスタイル */
 }
 
.gtranslate_wrapper.glink {
    /* 子のスタイル */
}
```

### [5]. 表示される言語記号を変更する
今のままだと `en, zh-CN, zh-TW, ja` てなって微妙です。
javascript で好きな表記に変えてしまいましょう。
※ここ不安なのでもっと良いやり方があれば教えてくださいっ

```javascript: javascript
document.addEventListener( 'DOMContentLoaded', function() {
	const glinks = document.querySelectorAll( '.gtranslate_wrapper > .glink' );

    // ここに変更先の文字列を書いたらOK
	const langKeyConverter = {
		en: 'English',
		'zh-CN': '简体字',
		'zh-TW': '繁體字',
		ko: '한국어',
		ja: '日本語',
	};
	glinks.forEach( function( glink ) {
		const langKey = glink.getAttribute( 'data-gt-lang' );
		glink.textContent = langKeyConverter[ langKey ];
	} );
} );
```

## 感想
めちゃ簡単にできてビックリでした。
~~でもこれってわざわざサイトに実装しなくても最近のブラウザには...~~
PlantUML 備忘録


## シーケンス図
**書き方参考**
https://plantuml.com/ja-dark/sequence-diagram

```.wsd
' コメント方法
' コメント範囲を選択して [ctrl]+[/]
```

```.wsd
'participant Participant as Foo
'actor       Actor       as Foo1
'boundary    Boundary    as Foo2
'control     Control     as Foo3
'entity      Entity      as Foo4
'database    Database    as Foo5
'collections Collections as Foo6
'queue       Queue       as Foo7


@startuml
title ステージ画面
participant ステージマネージャー
actor ステージ資材
database ステージデータ


ステージマネージャー -> ステージデータ:リクエスト
ステージデータ -> ステージマネージャー:レスポンス

ステージマネージャー -> ステージ資材:スポーン


@enduml

```

## フローチャート

**書き方参考**
https://plantuml.com/ja-dark/activity-diagram-legacy

```.wsd

' (*)：開始と終了
' --> "次のフロー名"
' --> [説明] "次のフロー名"

' if文
' (*)  --> "check input"
' If "input is verbose" then
' --> [Yes] "turn on verbosity"
' --> "run command"
' else
' --> "run command"
' Endif
' -->(*)

@startuml
(*) --> "プレーヤーデータ生成"
--> "イベント待機"
if "イベント発生" then
  -->[true]"イベント処理"
    if "HP < 0" then
        -->[true] (*)
    else
        --> [false]"イベント待機"
    endif
else
  --> [false]"イベント待機"
endif

@enduml

```
yolov5のdetect.pyのオプション

-h, --help: このヘルプメッセージを表示し、終了します。
--weights WEIGHTS [WEIGHTS ...]: モデルのパスまたはトリトンのURLを指定します。
--source SOURCE: 入力のソースを指定します。ファイル、ディレクトリ、URL、globパターン、スクリーン、または0（ウェブカメラ）が使用可能です。
--data DATA: （オプション）データセットのyamlパスを指定します。
--imgsz IMGSZ [IMGSZ ...], --img IMGSZ [IMGSZ ...], --img-size IMGSZ [IMGSZ ...]: 推論時の画像サイズ（高さ、幅）を指定します。
--conf-thres CONF_THRES: 検出の信頼度の閾値を設定します。
--iou-thres IOU_THRES: NMS（Non-Maximum Suppression）のIoU（Intersection over Union）の閾値を設定します。
--max-det MAX_DET: 1枚の画像あたりの最大検出数を指定します。
--device DEVICE: 使用するCUDAデバイスを指定します。例えば、0や0,1,2,3、またはcpuを指定できます。
--view-img: 結果を表示します。
--save-txt: 結果を*.txtファイルに保存します。
--save-csv: 結果をCSV形式で保存します。
--save-conf: --save-txtでラベルに信頼度を保存します。
--save-crop: 検出された予測ボックスをクロップして保存します。
--nosave: 画像や動画を保存しません。
--classes CLASSES [CLASSES ...]: 特定のクラスによるフィルターを適用します。例: --classes 0 や --classes 0 2 3。
--agnostic-nms: クラスに依存しないNMSを使用します。
--augment: 推論を拡張します。
--visualize: 特徴を可視化します。
--update: すべてのモデルを更新します。
--project PROJECT: 結果を指定されたプロジェクト/名前に保存します。
--name NAME: 結果を指定されたプロジェクト/名前に保存します。
--exist-ok: 既存のプロジェクト/名前が存在してもOKです。インクリメントしません。
--line-thickness LINE_THICKNESS: バウンディングボックスの太さをピクセルで指定します。
--hide-labels: ラベルを隠します。
--hide-conf: 信頼度を隠します。
--half: FP16の半精度推論を使用します。
--dnn: ONNX推論のためにOpenCV DNNを使用します。
--vid-stride VID_STRIDE: ビデオのフレームレートのストライドを指定します。
AtCoder Beginner Contest 341 振り返り

# ABC341
## 概要
https://atcoder.jp/contests/abc341

## A - Print 341
__考えてたこと__
n回1,0の順番に足して最後にもう一回1を足したら解になります。

__提出したもの__
```c++:a.cpp
int main() {
    int n;
    cin >> n;
    string ans = "";
    for (int i = 0; i < n; i++) {
        ans += "1";
        ans += "0";
    }
    ans += "1";
    cout << ans << endl;
    return 0;
}
```

__振り返り__
特になし。

## B - Foreign Exchange
__考えてたこと__
左から全部右の通貨に変えていって最終的に一番最後の通貨を数える。

__提出したもの__
```c++:b.cpp
int main() {
    ll n;
    cin >> n;
    vector<ll> vec(n);
    rep(i, 0, n) {
        cin >> vec[i];
    }
    rep(i, 0, n - 1) {
        ll s, t;
        cin >> s >> t;
        vec[i + 1] += t * (vec[i] / s);
    }
    cout << vec[n - 1] << endl;
    return 0;
}
```
__振り返り__
一回intにしていてWA, longlongに変えてAC。

## C - Takahashi Gets Lost
__考えてたこと__
全部のマス、全部の移動パターンを考えても、h*w*nで500**3なので計算量足りると最初に気づいたので気楽に解けました。気合いで全探索。

__提出したもの__
```c++:c.cpp
int main() {
    int h, w, n;
    cin >> h >> w >> n;
    string t;
    cin >> t;

    char glid[h][w];
    rep(i, 0, h) {
        rep(j, 0, w) {
            cin >> glid[i][j];
        }
    }

    int ans = 0;
    // 各マススタート地点、n会の移動パターン、計算量h*w*n
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (glid[i][j] == '#')
                continue;
            bool judge = true;
            int h_now = i;
            int w_now = j;
            fore(a, t) {
                if (a == 'L')
                    w_now--;
                if (a == 'R')
                    w_now++;
                if (a == 'U')
                    h_now--;
                if (a == 'D')
                    h_now++;
                if (glid[h_now][w_now] == '#' || h_now < 0 || h <= h_now || w_now < 0 || w <= w_now) {
                    judge = false;
                    break;
                }
            }
            if (judge)
                ans++;
        }
    }
    cout << ans << endl;
    return 0;
}
```

__振り返り__
最初、スタート地点が海の時でもスタートするようにしてたのでテストケースでこける。そこの分岐を作成してAC、ちょっと反省。

## D - Only one of two
__考えてたこと__
解法がよくわからなくてどうせ解けないかな...となんとなくでやっていたら解けてしまった問題、そのため変数名がすごい適当。
方針としてはNとMの最小公倍数でループになるからK番目までに何回ループを通るか、ループの中の何番目かを考えて解く。

__提出したもの__
```c++:d.cpp
ll lcm(ll a, ll b) {
    return a * b / gcd(a, b);
}

int main() {
    ll n, m, k;
    cin >> n >> m >> k;
    ll lcm_num = lcm(n, m);
    // loupの個数で公倍にぶつかる、n=2, m=3とかなら(2-1)+(3-1)=3でループ (2,3,4) (8,9,10)
    ll loup = (lcm_num / n - 1) + (lcm_num / m - 1);
    ll start = k / loup * lcm_num;
    ll nokori = k - (k / loup) * loup;
    if (nokori == 0) {
        start -= min(n, m);
    } else {
        ll n_now = n;
        ll m_now = m;
        for (int i = 0; i < nokori - 1; i++) {
            if (n_now < m_now) {
                n_now += n;
            } else {
                m_now += m;
            }
        }
        start += min(n_now, m_now);
    }
    cout << start << endl;
    return 0;
}
```
__振り返り__
解答を見てみたらユーザー解説の別解と方針が同じそう。模範的な回答は二部探索...? 全然思いつかなかったです。とはいえ、解けたこと自体は嬉しい。

## 感想
お仕事とかでコードに触れることが多いせいか、知識足りなくてもその場で良い感じに回答できるようになってきた気がする。とはいえ、勉強不足であることの証明でもあるのでもっと座学もしていきたいです。
Cypress E2E - Udemy コースの勉強備忘録

Udemy コースの勉強備忘録
https://www.udemy.com/share/1088P23@Xc9le6wHj4CIBgy9C92ZIwk2y5y-rXh21_xdKNSBWQilndVe0Y6-EYeElwvcGlhq/

https://github.com/academind/cypress-e2e-testing-course-resources

ensure 保証する
common gotcha よくある落とし穴
hence したがって
backdrop 背景
noteworthy 注目すべき
slightly わずかに
inspect 検査する
curly brace 中括弧

---
/// \<referenct types="Cypress" />
auto completion

要素が含まれているか
タイトルが正しいか
https://docs.cypress.io/guides/references/assertions#Common-Assertions

cy.get('.main-header').get('img')
は
cy.get('.main-header')
cy.get('img')
と一緒

.click({force: true})

Cypress Test Run IN Isolation

data-cy attribute

.as('subtmiBtn')
cy.get('@submitBtn')

.then()
expect()

.type('hogehoge{enter}')
Hexabase Flutter SDKの使い方（リアルタイム通知）

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業向けのBaaS（Backend as a Service）を提供しています。認証やデータストア、ファイルストレージ、リアルタイム通知などの機能があり、企業向けのシステム開発に必要な機能をまるっと提供しています。

APIはREST APIとGraphQLを提供しています。そのAPIをラップしたSDKも開発を進めています。SDKは現在、TypeScriptとDart向けに開発しています。Dart向けのSDKは、もちろんFlutterでも利用できます。

この記事ではFlutter SDKについてインストールと、データストアのアイテムにリアルタイム通知について解説します。

## パッケージとソースコード

パッケージはpub.devで公開しています。

[hexabase | Flutter Package](https://pub.dev/packages/hexabase)

ソースコードはGitHubにて公開しています。ライセンスはMIT Licenseです。

[hexabase/hexabase-dart: Hexabase SDK for Dart & Flutter](https://github.com/hexabase/hexabase-dart)

## インストール

インストールは `dart pub get` で行えます。

```
dart pub get hexabase
```

## インポート

SDKをインポートします。

```dart
import 'package:hexabase/hexabase.dart';
```

## 初期化

まずインスタンスを作成します。

```dart
var client = Hexabase();
```

別なファイルで再度インポートした場合には、以下でインスタンスを取得してください。

```dart
var client = Hexabase.instance;
```

## アイテムの作成

データストア（クラウドデータベース）の行相当のデータがアイテムです。以下のようにして、新しいアイテムを作成します。

```dart
await client.setWorkspace('YOUR_WORKSPACE_ID');
var project = await client.currentWorkspace.project(id: 'YOUR_PROJECT_ID');
var datastore = await project.datastore(id: 'YOUR_DATABASE_ID');
// アイテムを作成
var item = await datastore.item();
// 保存しておく
await item.save();
```

## 購読する

このアイテムに対するコメント追加の操作で通知が行われます。以下のようにして、購読します。

```dart
item.subscribe('update', (itemSubscription) {
	// itemSubscription.comment にコメントが入ります
	// itemSubscription.item にアイテムが入ります
	// itemSubscription.user にユーザーが入ります
});
```

## コメントの作成

新しいコメントは、 `item.history()` で作成します。 `set` で値（コメント本文）を設定し、 `save` で保存します。この操作で、該当アイテムを購読しているユーザーに対して通知が行われます。

```dart
var history = item.history();
history.set('comment', 'test');
await history.save();
```

通知は自分自身にも行われます。

## 購読を停止する

購読を停止するには、 `unsubscribe` を使います。

```dart
item.unsubscribe(actionName);
```

## 通知のプロトコル

通知はSingralRを使っており、WebSocketで通信を行います。JavaScript SDKでも、Flutter SDKでも同じように通知を受け取れます。

## まとめ

リアルタイム通知機能を使えば、チャットであったりコラボレーション機能を実装できます。ぜひ、Webアプリケーション開発に役立ててください。

HexabaseのFlutter SDKを使って、堅牢なWebアプリケーションを開発してください。

[hexabase \| Dart package](https://pub.dev/packages/hexabase)
VScode 言語によってtabキーを押下したときのスペース数を変える

## 概要

VScodeにて開いているファイルのプログラミング言語によってtabキーを押下したときに入力される半角スペース数を変える方法を簡単にまとめる。

## 方法

1. setting.jsonを開く
1. 下記の内容を追記する。

    ```
    "[言語]": {
        "editor.tabSize": タブ押下1回で入力される半角スペース数,
        "editor.insertSpaces": 半角スペースとして入力するか（trueの場合）、tab文字として入力するか（falseの場合）
    },
    ```

1. 筆者はPHPのコードを書くことが多いので、デフォルトの設定を半角スペース4個に設定し、下記の様に必要になったら半角スペース2個の設定を追記していっている。

    ```setting.json
    "[blade]": {
        "editor.tabSize": 2,
        "editor.insertSpaces": true
    },
    "[json]": {
        "editor.tabSize": 2,
        "editor.insertSpaces": true
    },
    "[yaml]": {
        "editor.tabSize": 2,
        "editor.insertSpaces": true
    },
    "[javascript]": {
        "editor.tabSize": 2,
        "editor.insertSpaces": true
    },
    ```
【WordPress】Advanced Custom Fields（ACF）で絵文字が保存できない問題を解決する

日頃からお世話になっているACFで、絵文字利用前提のフィールドを作ったものの、なぜか保存できない問題に遭遇。
調べてみると、どうやら `update_post_meta` や `update_user_meta` でデータベースの `postmeta` テーブルに絵文字を含むデータを保存しようとすると、絵文字部分が空白に変換されてしまう模様。

参考：[【WordPress】絵文字を含むカスタムフィールド値のDB更新について](https://tsukuriba.co.jp/6046)

解決策としては参考リンクにある通り、保存前にデータをHTML数値エンティティにエンコードし、読み込む際はデコードする、という手順を踏めば良い模様。
ACFのドキュメントを読むと、値の保存前に何かする用のフックと、値の読み込み後に何かする用のフックが、それぞれ用意されていた。
詳細はそれぞれ公式ドキュメントを参照。

`acf/update_value`：https://www.advancedcustomfields.com/resources/acf-update_value/
`acf/load_value`：https://www.advancedcustomfields.com/resources/acf-load_value/

## 実装

以下を `function.php` に追記。
参考元リンクのコードを、ほとんどそのまま流用させていただきました。（ありがとうございます）

```function.php
// 保存前にエンコード
function my_acf_update_value( $value ) {
	return stripslashes(esc_attr(mb_encode_numericentity($value, [0x10000, 0x10FFFF, 0, 0xFFFFFF], 'UTF-8')));
}

// 読み込み後にデコード
function my_acf_load_value( $value ) {
	return esc_attr(mb_decode_numericentity($value, [0x10000, 0x10FFFF, 0, 0xFFFFFF], 'UTF-8'));
}

// acf/update_value、acf/load_valueともに
// 修飾子が使えるので、必要なフィールドタイプを指定する。
add_filter('acf/update_value/type=text', 'my_acf_update_value', 10, 1);
add_filter('acf/load_value/type=text', 'my_acf_load_value', 10, 1);

// フィールド名もしくはフィールドキーも修飾子として使用可能
// add_filter('acf/update_value/name=example_text', 'my_acf_update_value', 10, 1);
// add_filter('acf/update_value/key=field_123abcf', 'my_acf_update_value', 10, 1);

```

## ちなみに

『ACF 絵文字 保存できない』とかでググると、

**「`function.php` に `add_filter( 'run_wptexturize', '__return_false' );` を追記すればOK！」**

みたいな言説のページがちょくちょく出てくるのだけど、これは `the_title()` とか `the_content()` とかで使われているWordPressの自動文字変換機能を全部無効にするやつ。
テキストの無害化なども `wptexturize` で担っているので、あまり考え無しに使って良いものではないと思われる。
というかそもそもとして、これでは**絵文字含みのデータが保存されない問題は一切解決しない。**

WordPressに関しては、こういう「検索上位に出てくるけど実際は解決しない」という罠情報が結構あるので気をつけたい…
（最初これに引っかかって1時間ぐらい悩んでた）
rspec入門で知っておけばよさそうなこと

# はじめに

rspecについて学んでいます。

備忘録的な記事です。
# 基本の３構文
 
 🤔どうも、`describe`・`context`・`it`の３つが重要なようです。

使い方の例として、ChatGPTは以下のような例を示してきました。

```rb
# calculator_spec.rb
require 'calculator'

describe Calculator do
  describe '#add' do
    context 'when adding positive numbers' do
      it 'returns the sum of the numbers' do
        calculator = Calculator.new
        expect(calculator.add(1, 2)).to eq(3)
      end
    end

    context 'when adding negative numbers' do
      it 'returns the sum of the numbers' do
        calculator = Calculator.new
        expect(calculator.add(-1, -2)).to eq(-3)
      end
    end

    context 'when adding a positive number and a negative number' do
      it 'returns the correct sum' do
        calculator = Calculator.new
        expect(calculator.add(-1, 2)).to eq(1)
      end
    end
  end
end
```

これを見る限り、`describe`・`context`・`it`は
「テストを実行するための必須構造」というよりも、
「ベストプラクティスなテストをサポートするための構造」ぽい。

回答
> はい、その通りです。`describe`、`context`、`it` は、RSpecにおけるテストコードを整理し、可読性を高めるための構造を提供しますが、**これらがなければテストを実行できないわけではありません。** これらの構造要素は、テストの目的、テストケースの条件、期待される振る舞いを明確にするためのガイドラインとして機能し、テストコードの読みやすさやメンテナンスの容易さを大きく向上させます。

この理解は大きいですね～

# 検証メソッド`expect().to matcher()`

```rb
expect(object).to eq(expect_object)
expect(boolean).to be true
expect(variable).to be be_nil
expect(array).to be be_empty
expect(object).to be be_invalid
```
このような形で使うようです。最後の`be_invalid`は重要ですね。validation errorを出しているか。
`matcher`は`eq`とか`be`ですね。

# `factory bot`でテストデータを作成
例を出してもらいました。
```rb
# spec/factories/users.rb
FactoryBot.define do
  factory :user do
    first_name { "John" }
    last_name  { "Doe" }
    email      { "john.doe@example.com" }
    password   { "securepassword" }
  end
end
```

Factorybotを使用して`create`している例

```rb
# spec/models/user_spec.rb
RSpec.describe User, type: :model do
  describe "Validations" do
    it "is valid with valid attributes" do
      user = FactoryBot.create(:user)
      expect(user).to be_valid
    end

    it "is invalid without a first name" do
      user = FactoryBot.build(:user, first_name: nil)
      expect(user).not_to be_valid
    end
  end
end
```

DBにおける`seed`を連想しました。あれは初期データでこちらはテストデータ。永続性の点で違いがありますね。

## メソッド
- `create`：データベースにオブジェクトを保存する。レコードを利用したテストを行う場合
- `build`：データベースにオブジェクトを保存しない。中間オブジェクトの生成や、モデルレベルのバリデーションなど。

なお、以下はどちらで書いてもよいようです。
```
user = FactoryBot.create(:user)

user = create(:user)
```

```
user = FactoryBot.build(:user)

user = build(:user)
```
Parallel gemで実装した処理をRspecでは同じスレッド上で動かす

以下のようにParallelにて処理を並列スレッドで実行しているとき、

```ruby:hoges_controller.rb
def index
    procs = [
        -> { hoge1 },
        -> { hoge2 },
        -> { hoge3 }
    ]
    result = Parallel.map(procs, in_threads: 3, &:call)
end
```
Rspecではletやsubjectが変数に対してロックを獲得するため、複数スレッドで変数の参照待ちになりデッドロックが発生し、テストが永遠に終わらなくなってしまう

それを解決するために、Rspec上では直列で処理を実行するようParallelをモックして、ブロックを呼び出すだけにする

```ruby:hoges_controller_spec.rb
describe '#index' do
    subject { get hoges_path }

    # Parallel.mapの引数で渡された配列をmapしてcallするだけ
    before { allow(Parallel).to receive(:map) { |procs| procs.map(&:call) } }

    it_behaves_like 'return success'
end
```
初心者は第一言語にPython避けるべき？

## 初心者は第一言語にPython避けるべき？

(注意：本記事はプロゲートとドットインストールでの学習をメインにしている初学者向けに書いたものです。それ以外の教材で学んでいる初心者の方にはあまり関係ないかもしれない)

そのように思う理由をざっと箇条書きにすると以下

1. カリキュラムが途中で途切れる（かも）
1. アプリ開発したいなら別の選択肢も



### 1. カリキュラムが途中で途切れる（かも）
もしプロゲートやドットインストールの教材をメインに学習している場合、Webアプリ作成まで辿り着けない可能性があります。どちらもわかりやすく学べますが、PythonコースではWebアプリ作成の指導コースがありません。（Paizaという似たような学習教材はPythonでのWebアプリ開発コースを用意してくれています。）
やったことはありませんが、ProgateならRubyで、ドットインストールならPHPで、Webアプリ開発の指導までしてくれそうなコースがある気がします。
（Webアプリを作る際、その言語に紐づくフレームワークというものを用いるのが一般的です。それぞれ有名なものだと、RubyではRubyonRails、PHPならLalavel、PythonならDjangoかFlaskというフレームワークがあります。ドットインストールにはRubyonRailsの教材があり、ドットインストールにはLalavelの教材があります。）
ドットインストール、プロゲートで、言語の基礎的なところを学び、そのままWebアプリ作成まで一気に学びたい人は、 Python以外の選択肢も考えるのもありなのではないでしょうか？

### 2. アプリ開発したいなら別の選択肢も
Pythonは、なんか流行りっぽい。それで学び始めました。習うと他の言語より書きやすい気もして、Pythonでしょ。と思い学んできました。ですがPythonという言語の強みは数値計算とか統計処理とかで、Webアプリ開発に強いのはRubyという言語なのかもしれません。（RubyのフレームワークRubyonRailsはPythonで色々しないといけないところを簡単になんかするだけで、Webアプリを作れるらしいという話を聞いたことがあります。）
一度それぞれの言語が得意とすることは何か調べて、自分は何のために学びたいのかとマッチする言語を選ぶと、早めに学んだ効果を実感できるのかもしれません。

### 3. 終わりに
2年ほど学習してきて、つぶやきたくなったので書きました。何か感じることがあった場合、自分でそれを調べてみてください。そのきっかけになれば幸いです。

### 追記
追記。
自分恥ずかしながら勉強始めたての頃は、プログラミング言語＝Pythonだと思っていました。
(YoutubeかネットでPythonを推してる人の話を聞きその理由がもっともらしく聞こえたため（(Python流行ってる！とか、今人気！とか、今注目の！とか。そういうのを聞いて、流行ってんのが一番やろ！と。。）））
どの言語にするか、それを選ぶ際の知識すらないのでわからなかった。（調べてもよくわからなかった。。。）

なので、この記事を読んで、自分はこういう理由でこの言語にしたよ。とか、こういう考えでこの言語を選ぶのもいいよ。とか、コメント書いていただけると、言語選択に必要な知識を調べる際の足がかりになると思うので、ぜひ書いていただけると幸いです。
（またこの記事での自分の知識不足な点の指摘、ありがとうございます。）

あとこの言語選んで、こういうルートで勉強していったらこういうことできるようになったよーーってコメントもあったらほしいです。（こういうのも当時知りたかったので。。）

（（どの言語にするかは、その人の置かれている状況や、学ぶ目的、性格などによって様々な意見があると思います。なのでそんな意見もあるんだなって感じでいろんな意見を見て、自分で調べて決めてください））
laravel コマンド集

# 初めに
laravelの開発中によく使うコマンドをまとめました。
参考にしてください。

# laravelコマンド集

## Eloquentモデル自動生成

```php
php artisan make:model モデル名
```

## マイグレーションファイル作成

```php
php artisan make:migration create_テーブル名_table --create=テーブル名
```

# 参考文献

https://qiita.com/niisan-tokyo/items/9c799989cb535489f201

https://qiita.com/kamome_susume/items/22fe17935bbd1760b7f7

参考にさせていただきました。
ありがとうございます！
keytoolからオレオレ証明書を作成する

`keytool`コマンドを使用して`localhost`用の証明書を生成する場合、Javaのキーストア（`.keystore`または`.jks`ファイル）内に直接自己署名証明書を生成し、管理することができます。これは特にJavaアプリケーションやJavaベースのサーバー（例えばTomcatやJetty）で役立ちます。以下に、一般的な手順を示します。

1. **キーストアと自己署名証明書の生成**:
    ```
    keytool -genkeypair -alias localhost -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore localhost.p12 -validity 365
    ```
    このコマンドは以下を行います：
    - `-genkeypair`: 新しいキーペア（公開鍵と秘密鍵）を生成します。
    - `-alias localhost`: キーストア内のエントリに使用される別名を指定します。
    - `-keyalg RSA`: 鍵のアルゴリズムとしてRSAを指定します。
    - `-keysize 2048`: 鍵のサイズとして2048ビットを指定します。
    - `-storetype PKCS12`: キーストアのタイプとしてPKCS12を指定します（Java 9以降で推奨される形式）。
    - `-keystore localhost.p12`: キーストアファイルの名前と場所を指定します。
    - `-validity 365`: 証明書の有効期間を365日に設定します。

    コマンドを実行すると、キーストアのパスワード、所有者の情報（名前、組織、都市など）、およびキーペアのパスワードを入力するよう求められます。`Common Name`（CN）フィールドには`localhost`を使用してください。

2. **キーストアの内容を確認**:
    ```
    keytool -list -keystore localhost.p12
    ```
    このコマンドを使用してキーストアの内容を確認し、先ほど作成したエントリが含まれていることを確認します。

これらの手順により、`localhost`用の自己署名証明書が含まれるキーストアが生成されます。キーストア（`localhost.p12`）は、JavaベースのアプリケーションやサーバーでSSL/TLS接続を設定する際に使用されます。

注意: この自己署名証明書は開発目的には適していますが、公開サーバーで使用する場合は訪問者に警告が表示される可能性があります。本番環境では、信頼できる認証局（CA）から証明書を取得することをお勧めします。


WireMockをスタンドアローンモードで実行し、HTTPS通信のためにキーストアを指定するには、コマンドライン引数を使用して指定します。キーストアにはJava KeyStore（JKS）形式やPKCS12形式のファイルを使用でき、SSL設定のために必要な秘密鍵と公開鍵の証明書が含まれています。以下は、キーストアを指定してWireMockを起動する一般的なコマンド例です。

```shell
java -jar wiremock-standalone-{version}.jar --https-port 8443 --keystore-path path/to/your/keystore.jks --keystore-password yourkeystorepassword
```

このコマンドの各オプションは以下の通りです：

- `--https-port 8443`：WireMockにHTTPSリクエストをリッスンさせるポートを指定します。`8443`は一例で、使用環境に合わせて変更できます。
- `--keystore-path path/to/your/keystore.jks`：使用するキーストアファイルへのパスを指定します。ファイルはJKS形式かPKCS12形式である必要があります。
- `--keystore-password yourkeystorepassword`：キーストアに設定されているパスワードを指定します。

実際にコマンドを実行する際は、`{version}`を使用しているWireMockのバージョンに、`path/to/your/keystore.jks`をキーストアファイルの実際のパスに、そして`yourkeystorepassword`をキーストアのパスワードに置き換えてください。

また、必要に応じて他のオプションも追加できます。たとえば、クライアント証明書の検証を必要とする場合は、`--truststore-path`や`--truststore-password`を指定することもできます。

WireMockのドキュメントやコマンドラインのヘルプ（`java -jar wiremock-standalone-{version}.jar --help`）で、利用可能なすべてのオプションの詳細を確認してください。